OpenGL glDrawElements 没有颜色

Posted

技术标签:

【中文标题】OpenGL glDrawElements 没有颜色【英文标题】:OpenGL glDrawElements has no color 【发布时间】:2014-03-07 13:50:32 【问题描述】:

我正在尝试使用我编写的着色器使用 OpenGL 绘制一个立方体,我可以看到形状但看不到颜色。

#define EDGE_LENGTH 0.6
enum VertexAttrib

    ATTRIB_VERTEX = 0, ATTRIB_COLOR
;
int main()

    GLfloat cubeAttribs[] =
    
        -EDGE_LENGTH / 2,   EDGE_LENGTH / 2,    -EDGE_LENGTH / 2,   // 0 front left top vertex
        1.0f,   0.0f,   0.0f,   // red
        -EDGE_LENGTH / 2,   -EDGE_LENGTH / 2,   -EDGE_LENGTH / 2,   // 1 front left bottom vertex
        1.0f,   1.0f,   0.0f,   // yellow
        EDGE_LENGTH / 2,    -EDGE_LENGTH / 2,   -EDGE_LENGTH / 2,   // 2 front right bottom vertex
        0.0f,   1.0f,   0.0f,   // green
        EDGE_LENGTH / 2,    EDGE_LENGTH / 2,    -EDGE_LENGTH / 2,   // 3 front right top vertex
        0.0f,   0.0f,   1.0f,   // blue
        EDGE_LENGTH / 2,    EDGE_LENGTH / 2,    EDGE_LENGTH / 2,    // 4 back right top vertex
        1.0f,   0.0f,   1.0f,   // purple
        EDGE_LENGTH / 2,    -EDGE_LENGTH / 2,   EDGE_LENGTH / 2,    // 5 back right bottom vertex
        1.0f,   0.5f,   0.2f,   // orange
        -EDGE_LENGTH / 2,   -EDGE_LENGTH / 2,   EDGE_LENGTH / 2,    // 6 back left bottom vertex
        1.0f,   1.0f,   1.0f,   // white
        -EDGE_LENGTH / 2,   EDGE_LENGTH / 2,    EDGE_LENGTH / 2,    // 7 back left top vertex
        0.0f,   1.0f,   1.0f    // cyan
    ;
    GLushort cubeIndices[] =
    
        0, 1, 2, 3, // front face
        3, 2, 5, 4, // right face
        4, 5, 6, 7, // back face
        7, 6, 1, 0, // left face
        0, 3, 4, 7, // top face
        6, 5, 2, 1  // bottom face
    ;
/* create window and make GL contex */
    ... ...
/* create shader program and use the program */
    ... ...
    GLuint vertexArrayObject;
    GLuint vertexBufferObject;
    GLuint indexBuffer;

/* create vertex array object and bind to it */
    glGenVertexArrays(1, &vertexArrayObject);
    glBindVertexArray(vertexArrayObject);
/* create vertex buffer object */
    glGenBuffers(1, &vertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
/* enable Attributes */
    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glEnableVertexAttribArray(ATTRIB_COLOR);
/* send vertex position and color data to graphic card memory */
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeAttribs), cubeAttribs, GL_STREAM_DRAW);
    glVertexAttribPointer( ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE,
                        6 * sizeof(GLfloat), (const GLvoid *)0 );
    glVertexAttribPointer( ATTRIB_COLOR, 3, GL_FLOAT, GL_FALSE,
                        6 * sizeof(GLfloat), (const GLvoid *) ( 3 * sizeof(GLfloat) ) );

/* create index buffer object */
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
/* send index data to graphic card memory */
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STREAM_DRAW);

/* bind to the VAO */
    glBindVertexArray(vertexArrayObject);
    while ( !glfwWindowShouldClose(window) )
    
        glClearColor(0.0f, 0.5f, 1.0f, 1.0f);   CHECK_GL_ERROR
        glClear(GL_COLOR_BUFFER_BIT);   CHECK_GL_ERROR
    /* draw the cube */
        glDrawElements(GL_QUADS, 4 * 6, GL_UNSIGNED_SHORT, (const GLvoid *)0);  CHECK_GL_ERROR
        glFlush();
        glfwSwapBuffers(window);
        glfwPollEvents();
    
    return 0;

着色器相当简单。

顶点着色器:

#version 440
layout(location = 0) in vec4 vertexPos;
layout(location = 1) in vec3 vertexColor;
smooth out vec3 vColor;
void main()

    gl_Position = vertexPos;
    vColor = vertexColor;

片段着色器:

#version 440
smooth in vec3 vColor;
out vec3 outColor;
void main()

    outColor = vColor;

程序编译并运行,我看到蓝色背景和一个背面方块,但没有颜色。我错过了什么?

之前我写了我的“第一个三角形”,它不是基于索引的渲染,它使用glDrawArrays来渲染,颜色看起来很完美。着色器和程序结构几乎相同,我试图找出差异,但不知道。

【问题讨论】:

【参考方案1】:

您正在使用已告知 OpenGL 的自定义片段输出。没有它,如果使用兼容性配置文件,它期望通过特殊的内置变量gl_FragColor 发出片段颜色。但是使用核心配置文件,您需要使用glBindFragDataLocation 将片段着色器输出与渲染缓冲区目标相关联。在大多数情况下,您只有一个渲染目标0。所以在你的情况下,在创建程序对象调用之后

glBindFragDataLocation(program, 0, "outColor");

【讨论】:

您好,感谢您的回复。这个问题其实是我自己的愚蠢造成的。拼写错误导致我的片段着色器未链接到着色器程序。而且我发现没有必要明确指定片段数据位置。还是非常感谢 !!! :)

以上是关于OpenGL glDrawElements 没有颜色的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL - glDrawElements vs 顶点数组对象

glDrawElements中的OpenGL SegFault

无法让 openGL 的 glDrawElements 与几何着色器一起使用

OpenGL - 使用 glDrawElements 错误地映射纹理

OpenGL ES - glDrawElements - 无法理解索引

OpenGL glDrawElements