不使用 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 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL - 在 ubuntu 的线程上创建 vbo?

OpenGL:尝试使用 VBO(顶点缓冲区对象)绘制线条,它不显示

使用带有 glew 的 VBO 访问冲突

绘图时 VAO 和 VBO 崩溃

OpenGL VBO 程序给出黑屏

在 OpenGL ES 中,多个程序可以使用相同的 VBO 并绑定到它们的属性吗?