【问题标题】:glDrawElements crashes when not using certain vertex attributes不使用某些顶点属性时 glDrawElements 崩溃
【发布时间】:2013-01-12 03:19:48
【问题描述】:

在我的 OpenGL 程序中,我有两个着色器。一个渲染纹理,另一个渲染纯色。编译和链接着色器后,我根据天气启用纹理坐标顶点属性数组,着色器是否包含该属性。

//This code is called after the shaders are compiled.

//Get the handles
textureU = glGetUniformLocation(program,"texture");
tintU = glGetUniformLocation(program,"tint");
viewMatrixU = glGetUniformLocation(program,"viewMatrix");
transformMatrixU = glGetUniformLocation(program,"transformMatrix");
positionA = glGetAttribLocation(program,"position");
texcoordA = glGetAttribLocation(program,"texcoord");

//Detect if this shader can handle textures
if(texcoordA < 0 || textureU < 0) hasTexture = false;
else hasTexture = true;

//Enable Attributes
glEnableVertexAttribArray(positionA);
if(hasTexture) glEnableVertexAttribArray(texcoordA);

如果我正在渲染带纹理的itemverts 中的每个元素都包含 5 个值 (x,y,z,tx,ty),但如果项目不是纹理,则 @ 中的每个元素987654324@ 仅包含 3 个值 (x,y,z)。

问题来了:当在 GL 上下文中渲染的第一个 item 没有纹理时,glDrawElements segfaults!但是,如果渲染的第一个项目确实有纹理,则它可以正常工作,并且纹理后的任何未纹理项目都可以正常工作(也就是说,直到创建新的上下文)。

这段代码渲染了一个item

glBindBuffer(GL_ARRAY_BUFFER,engine->vertBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*item->verts.size(),&item->verts[0],GL_DYNAMIC_DRAW);

item->shader->SetShader();

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,engine->elementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLuint) * item->indicies.size(),&item->indicies[0],GL_DYNAMIC_DRAW);

if(item->usingTexture)
    item->shader->SetTexture(item->texture->handle);

glUniformMatrix4fv(item->shader->transformMatrixU,1,GL_TRUE,&item->matrix.contents[0]);
glUniformMatrix4fv(item->shader->viewMatrixU,1,GL_TRUE,&item->batch->matrix.contents[0]);
glUniform4f(item->shader->tintU,item->color.x,item->color.y,item->color.z,item->color.w);

glDrawElements(GL_TRIANGLES,item->indicies.size(),GL_UNSIGNED_INT,0); //segfault

这是上面看到的设置着色器的函数。

glUseProgram(program); currentShader = program;
GLsizei stride = 12;
if(hasTexture) stride = 20;
glVertexAttribPointer(positionA,3,GL_FLOAT,GL_FALSE,stride,0);
if(hasTexture)
    glVertexAttribPointer(texcoordA,2,GL_FLOAT,GL_FALSE,stride,(void*)12);

据我所知,这个问题在英特尔集成显卡上并不明显,似乎相当宽松。

编辑:如果知道有用的话,我正在使用 GLFW 和 GLEW。

【问题讨论】:

    标签: c++ opengl shader vertex-attributes


    【解决方案1】:

    尝试在你的draw call之后添加相应的glDisableVertexAttribArray()s:

    glEnableVertexAttribArray(positionA);
    if(hasTexture) glEnableVertexAttribArray(texcoordA);
    // draw
    glDisableVertexAttribArray(positionA);
    if(hasTexture) glDisableVertexAttribArray(texcoordA);
    

    【讨论】:

      【解决方案2】:

      问题是我在编译着色器后启用了顶点属性数组。这不是我应该启用它们的地方。

      我在编译着色器时启用了 texcoord 属性,但由于第一项没有使用它,glDrawElements 会出现段错误。

      我通过在设置着色器时启用该属性来解决此问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多