在我的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);
如果我渲染的是item
纹理,verts
中的每个元素都包含5个值(x,y,z,tx,ty),但如果该项不是纹理, verts
中的每个元素只包含3个值(x,y,z)。
问题在于:当GL上下文中呈现的第一个item
没有纹理时,glDrawElements
会出现段错误!但是,如果渲染的第一个项目确实具有纹理,则它可以正常工作,并且纹理化后的任何未纹理化项目都可以正常工作(即,直到创建新的上下文)。
这段代码呈现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。
答案 0 :(得分:2)
在绘制调用后尝试添加相应的glDisableVertexAttribArray()
:
glEnableVertexAttribArray(positionA);
if(hasTexture) glEnableVertexAttribArray(texcoordA);
// draw
glDisableVertexAttribArray(positionA);
if(hasTexture) glDisableVertexAttribArray(texcoordA);
答案 1 :(得分:0)
问题是我在编译着色器后启用了顶点属性数组。这不是我应该启用它们的地方。
我在编译着色器时启用了texcoord属性,但由于第一项没有使用它,glDrawElements会出现段错误。
我通过在设置着色器时启用该属性来修复此问题。