不使用 VBO 时 OpenGL 应用程序崩溃
Posted
技术标签:
【中文标题】不使用 VBO 时 OpenGL 应用程序崩溃【英文标题】:OpenGL application crashes when VBO is not used 【发布时间】:2014-09-11 20:42:25 【问题描述】:我正在尝试在 OpenGL ES 2.0 中不使用 VBO 来绘制对象。我的代码往往会不时使应用程序崩溃(并非总是如此,甚至没有任何改变)。以下是代码。我认为问题在于我只启用 m_distLocation 而不向着色器发送任何数据。所有统一值都已正确设置。我认为问题仅在于属性变量(m_posAttr 和 m_distLocation)、绑定。
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(m_posAttr);
glEnableVertexAttribArray(m_distLocation);
int posAttrSize = sizeof(float) * 2;
GLintptr posAttrStart = reinterpret_cast<GLintptr>(&vertices[0]);
glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, posAttrSize, reinterpret_cast<GLvoid*>(posAttrStart));
glVertexAttribPointer(m_distLocation, 0, GL_FLOAT, GL_FALSE, 0, 0);
glBindAttribLocation(m_programID, m_posAttr, "posAttr" );
glBindAttribLocation(m_programID, m_distLocation, "distance" );
glUniform1i(m_patternLocation, -1);
glUniform4fv(m_colorAttr, 1, vColor);
glUniform1f(m_depthAttr, z);
glUniform1f(m_zoom, _zoom / 100);
glUniform2fv(m_scale, 1, _scale);
glUniform2fv(m_translate, 1, _trans);
glUniform1f(m_theta, _theta);
glDrawArrays(et, offsetInBytesFill, nVerticesFill );
glDisableVertexAttribArray(m_posAttr);
glDisableVertexAttribArray(m_distLocation);
如果有任何帮助,我将不胜感激。
【问题讨论】:
您使用的是什么平台?安卓? 我正在使用 Qt 进行开发。 【参考方案1】:发布的代码片段有许多值得怀疑的方面:
glBindAttribLocation()
只有在glLinkProgram()
之前调用才会生效。否则,链接时将自动分配位置,除非您重新链接程序,否则您无法更改它们。要获取已分配的位置,您可以将这些调用替换为:
m_posAttr = glGetAttribLocation(m_programID, "posAttr");
m_distLocation = glGetAttribLocation(m_programID, "distance");
这些语句显然需要放在使用值之前。
glVertexAttribPointer()
调用的第二个参数是非法的:
glVertexAttribPointer(m_distLocation, 0, GL_FLOAT, GL_FALSE, 0, 0);
第二个参数是属性中组件的数量,需要为1、2、3或4。如果属性是标量浮点数,顾名思义,正确的值为1。
在同一次调用中,由于您没有使用 VBO,因此最后一个参数必须是有效指针。假设distances
是距离值的数组/向量,则调用应如下所示:
glVertexAttribPointer(m_distLocation, 1, GL_FLOAT, GL_FALSE, 0, &distances[0]);
根据变量名的建议,这看起来也可能是错误的:
glDrawArrays(et, offsetInBytesFill, nVerticesFill);
第二个参数是要绘制的第一个顶点的索引。它不是以字节为单位的。举例来说,如果您的顶点数组中有 40 个顶点的属性,并且您想从顶点 20(即顶点 20 到 29)开始绘制 10 个顶点,则调用将是:
glDrawArrays(et, 20, 10);
【讨论】:
我认为问题在于通过 m_distLocation。事情是,我不想传递任何东西,只是启用属性变量。 不确定我是否理解。如果启用属性变量,如果您不提供任何属性数据,您希望属性值来自哪里?以上是关于不使用 VBO 时 OpenGL 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章