【问题标题】:confused trying to draw coloured elements for drawing using using glDrawElements using vertex and fragment shaders混淆尝试使用 glDrawElements 使用顶点和片段着色器绘制彩色元素进行绘图
【发布时间】:2015-08-20 13:14:46
【问题描述】:

我正在创建一组类以从 COLLADA 文件中读取 3d 对象。我从一些基本代码开始读取位置和法线并用 opengl 绘制它们。我添加了代码以成功缩放顶点,并添加了我需要读取的与 COLLAD 文件中每个图形元素相关的颜色或纹理的所有代码。但现在我需要添加代码来用颜色绘制顶点。我创建了缓冲区对象数组来容纳每个顶点数组和缓冲区对象的颜色数组。 这是我必须根据从 COLLADA 文件中获得的数据构建数组的代码: 请记住,我仍在创建它并不完美。

// Set vertex coordinate data
        glBindBuffer(GL_ARRAY_BUFFER, vbosPosition[i]);
        glBufferData(GL_ARRAY_BUFFER, col->vectorGeometry[i].map["POSITION"].size,
            scaledData, GL_STATIC_DRAW);
        free(scaledData);


        loc = glGetAttribLocation(program, "in_coords");//get a GLuint for the attribute and put it into GLuint loc.
        glVertexAttribPointer(loc, col->vectorGeometry[i].map["POSITION"].stride, col->vectorGeometry[i].map["POSITION"].type, GL_FALSE, 0, 0);//glVertexAttribPointer — loc specifies the index of the generic vertex attribute to be modified.
        glEnableVertexAttribArray(0);
#ifdef Testing_Mesh3D
        PrintGLVertex(vbosPosition[i], col->vectorGeometry[i].map["POSITION"].size / 4);
#endif      // Set normal vector data
        glBindBuffer(GL_ARRAY_BUFFER, vbosNormal[i]);
        glBufferData(GL_ARRAY_BUFFER, col->vectorGeometry[i].map["NORMAL"].size, col->vectorGeometry[i].map["NORMAL"].data, GL_STATIC_DRAW);
        loc = glGetAttribLocation(program, "in_normals");
        glVertexAttribPointer(loc, col->vectorGeometry[i].map["NORMAL"].stride, col->vectorGeometry[i].map["NORMAL"].type, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, vbosColor[i]);
        Material* material = col->mapGeometryUrlToMaterial2Effect[col->vectorGeometry[i].id];
        if (material->effect1.size() > 0)
        {
            Effect effect1 = material->effect1[0];
            if (effect1.type == enumEffectTypes::color)
            {
                Color color = effect1.color;
                glBufferData(GL_ARRAY_BUFFER, color.length, color.values, GL_STATIC_DRAW);
                loc = glGetAttribLocation(program, "in_colors");
                glVertexAttribPointer(loc, color.length, color.type, GL_FALSE, 0, 0);

            }
            else
            {

            }

        }

    }
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

// Initialize uniform data
void Mesh3D::InitializeUniforms(GLuint program) {

    GLuint program_index, ubo_index;
    struct LightParameters params;

    // Specify the rotation matrix
    glm::vec4 diff_color = glm::vec4(0.3f, 0.3f, 1.0f, 1.0f);
    GLint location = glGetUniformLocation(program, "diffuse_color");
    glUniform4fv(location, 1, &(diff_color[0]));

    // Initialize UBO data
    params.diffuse_intensity = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f);
    params.ambient_intensity = glm::vec4(0.3f, 0.3f, 0.3f, 1.0f);
    params.light_direction = glm::vec4(-1.0f, -1.0f, 0.25f, 1.0f);

    // Set the uniform buffer object
    glUseProgram(program);
    glGenBuffers(1, &ubo);
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
    glBufferData(GL_UNIFORM_BUFFER, 3 * sizeof(glm::vec4), &params, GL_STREAM_DRAW);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);
    glUseProgram(program);

    // Match the UBO to the uniform block
    glUseProgram(program);
    ubo_index = 0;
    program_index = glGetUniformBlockIndex(program, "LightParameters");
    glUniformBlockBinding(program, program_index, ubo_index);
    glBindBufferRange(GL_UNIFORM_BUFFER, ubo_index, ubo, 0, 3 * sizeof(glm::vec4));
    glUseProgram(program);

这是一个监听器文件,其中包含两个字符串文字,其中包含用于构建顶点和片段着色器的字符串。我再次对此不熟悉,不确定如何修改着色器以包含彩色顶点,我已经开始为四种浮点颜色(包括 alpha)添加输入 vec4。有什么帮助吗?

#pragma once
#ifndef Included_shaders
#define Included_shaders

#include<stdio.h>
#include<iostream>
static std::string  shaderVert = "#version 330\n"
"in vec3 in_coords;\n"
"in vec3 in_normals;\n"
"in vec4 in_colors; \n"//added by me
"out vec3 vertex_normal;\n"
"void main(void) {\n"
"vertex_normal = in_normals;\n"
"gl_Position = vec4(in_coords, 1.0);\n"
"}\n";

static std::string shaderFrag = "#version 330\n"
"in vec3 vertex_normal;\n"
"out vec4 output_color;\n"
"layout(std140) uniform LightParameters{\n"
"vec4 diffuse_intensity;\n"
"vec4 ambient_intensity;\n"
"vec4 light_direction;\n"
"};\n"
"uniform vec4 diffuse_color;\n"
"void main() {\n"
"/* Compute cosine of angle of incidence */\n"
"float cos_incidence = dot(vertex_normal, light_direction.xyz);\n"
"cos_incidence = clamp(cos_incidence, 0, 1);\n"
"/* Compute Blinn term */\n"
"vec3 view_direction = vec3(0, 0, 1);\n"
"vec3 half_angle = normalize(light_direction.xyz + view_direction);\n"
"float blinn_term = dot(vertex_normal, half_angle);\n"
"blinn_term = clamp(blinn_term, 0, 1);\n"
"blinn_term = pow(blinn_term, 1.0);\n"
"/* Set specular color and compute final color */\n"
"vec4 specular_color = vec4(0.25, 0.25, 0.25, 1.0);\n"
"output_color = ambient_intensity * diffuse_color +\n"
"diffuse_intensity * diffuse_color * cos_incidence +\n"
"diffuse_intensity * specular_color * blinn_term;\n"
"}\n";
#endif

最后,这是我正在修改以绘制彩色元素的功能

void Mesh3D::DrawToParent()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Draw elements of each mesh in the vector
    for (int i = 0; i<nVectorGeometry; i++)
    {
        glBindVertexArray(vaos[i]);
        glDrawElements(col->vectorGeometry[i].primitive/*This is 4 for GL_Triangles*/, col->vectorGeometry[i].index_count,
            GL_UNSIGNED_SHORT, col->vectorGeometry[i].indices);
    }
    glBindVertexArray(0);
    glutSwapBuffers();
}

我对 glVertexAttribPointer 和 glGetAttribLocation 有点困惑,尽管我想我明白了基本的想法。我用对了吗?

我是否正确设置了颜色的缓冲区对象。我是否正确我在这个缓冲区中的每个顶点都有一个颜色,现在我只放置了适用于这个数组中所有关联缓冲区的单一颜色并且可能需要更改它?

当我调用 glDrawElements 时,我究竟如何绘制彩色顶点?

不要只让我参考 opengl 的资源,很多冗长的解释对我来说毫无意义。

【问题讨论】:

  • 有点离题:您应该将着色器存储在文件中。使它们更容易编码,如果你不硬编码它们,你可以在运行时交换它们。
  • 你说你不想要OpenGL资源,但是你试过这个吗? opengl-tutorial.org/intermediate-tutorials/…

标签: opengl colors drawing


【解决方案1】:

使您的顶点着色器输出颜色并让片段着色器将其作为输入。颜色将在顶点之间进行插值。

是的,看来您已经正确理解了 glAttribPointer。

DrawElements 获取您要绘制的顶点的索引。最后一个参数不应包含索引。相反,它可能应该为空。索引应使用glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...) 指定。

如果颜色缓冲区被正确绑定,您不需要为颜色做任何特殊的 id drawElements。着色器将获取所有启用的属性数组。

如果您运行代码并告诉我您遇到了什么问题,我可以为您提供更好的帮助。如果代码更容易阅读也会有所帮助。如果你把它分成十行以下的函数,你自己可能会发现一些错误,并可能删除一些重复。

【讨论】:

  • 修改了我的代码,所以我在另一个问题中再次发布了它,而不是更改这个stackoverflow.com/questions/30675949/…
  • 哦,我留下了最后一个论点,如果没有它,什么都没有画出来!
猜你喜欢
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-17
  • 2017-05-16
  • 2019-01-24
  • 1970-01-01
  • 2018-07-15
相关资源
最近更新 更多