当不使用某些顶点属性时,glDrawElements崩溃
glDrawElements crashes when not using certain vertex attributes
在我的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)。
这里是问题:当第一个item
渲染在GL上下文中没有纹理,glDrawElements
segfault !但是,如果渲染的第一个项目确实有纹理,它就会正常工作,并且在有纹理的项目之后的任何非纹理项目都可以正常工作(也就是说,直到创建新的上下文)。
这段代码呈现了一个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
尝试在draw调用后添加相应的 glDisableVertexAttribArray()
s:
glEnableVertexAttribArray(positionA);
if(hasTexture) glEnableVertexAttribArray(texcoordA);
// draw
glDisableVertexAttribArray(positionA);
if(hasTexture) glDisableVertexAttribArray(texcoordA);
问题是我在编译我的着色器后启用了顶点属性数组。我不应该在这里纵容他们。
我在编译着色器时启用了texcoord属性,但由于第一个项目没有使用它,glDrawElements会出现分段错误。
我通过在设置着色器时启用属性来修复这个问题。
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- C++概念:如何使用'concept'检查模板化结构的属性?
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 通过指向指针数组的指针访问子类的属性
- MSVC是否支持C++11样式的属性而不是__declspec
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 类的C++属性似乎已重新初始化
- Qt Quick-如何仅从c++代码与qml属性交互
- 用概念检查属性的类型
- C++如何将同一类的实例作为属性
- 按多个属性排序
- 主函数参数的属性
- "perf_event_attr"结构的"read_format"属性的选项到底是什么?
- C++删除未使用的类属性会导致 std::logic_error
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 使用内存地址访问结构的属性值
- C++调用具有 *this 属性的单个帮助程序函数
- C++ 在堆栈中包含多态属性的类对象存储
- C++ 命名参数习惯用语 - 未设置字符串属性
- 使用 CTRP 时,是否访问访问父构造函数 UB 中的子属性?