交错的VBO导致glDrawArrays()错误

时间:2011-04-18 05:31:31

标签: objective-c ios opengl-es rendering vbo

我最近将我的应用程序从使用OpenGL ES 1.1更改为2.0,并且在此过程中我决定使用VBO进一步优化我的代码。我想我必须掌握与ES 2.0的主要区别,并且有结果表明我在没有VBO的情况下正确地做事情,但是我被一个只在我尝试使用VBO时出现的问题所困扰

我使用包含顶点位置,颜色和大小的自定义结构(加上一些填充来对齐数据),然后在VBO中交错这个顶点数据。此数据用于渲染点精灵。问题是我在glDrawArrays()调用上获得了EXC_BAD_ACCESS。此错误的回溯如下:

#0  0x31fc7358 in gleRunVertexSubmitARM ()
#1  0x31fc87b2 in gleLLVMArrayFunc ()
#2  0x31fc872a in gleSetVertexArrayFunc ()
#3  0x31fbefcc in gleDrawArraysOrElements_ExecCore ()
#4  0x31fc4608 in glDrawArrays_IMM_Exec ()
#5  0x36ddaee2 in glDrawArrays ()
#6  0x0001cab8 in -[Renderer renderDrawingVertexBuffer:withSize:usingTexture:] (self=0x1783b0, _cmd=0x50fec, vboID=0, size=3584, drawTexture=5) at /Users/Stu/Documents/...
#7  0x000202f4 in -[EAGLView drawSmoothCurveFromPoints:endOfLine:] (self=0x195be0, _cmd=0x50d34, points=0x1956f0, endOfLine=1 '\001') at /Users/Stu/Documents/...
#8  0x0001e50c in -[EAGLView drawView:] (self=0x195be0, _cmd=0x50d8a, sender=0x0) at /Users/Stu/Documents/...
#9  0x0001e174 in -[EAGLView layoutSubviews] (self=0x195be0, _cmd=0x3297d4ac) at /Users/Stu/Documents/...
#10 0x326805fa in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#11 0x35efbf02 in -[NSObject(NSObject) performSelector:withObject:] ()
#12 0x333fbbb4 in -[CALayer layoutSublayers] ()
#13 0x333fb96c in CALayerLayoutIfNeeded ()

这是存储顶点数据的结构:

typedef struct {
    ISVertex2D vertex;     // Made up of 2 GLfloats.
    ISColor    color;      // Made up of 4 GLfloats.
    GLfloat    size;
    GLfloat    padding;
} ISPointSpriteData;

将一组数据存储在这些结构的数组中后,数据将被发送到VBO并使用glDrawArrays()进行渲染:

[renderer prepareScene];
[renderer renderBackground];

glBindBuffer(GL_ARRAY_BUFFER, penVbo);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(ISPointSpriteData) * penVboSize, sizeof(ISPointSpriteData) * vertexCount, &vertexBuffer[0].vertex);

glBindTexture(GL_TEXTURE_2D, drawTexture);

glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_COLOR);
glEnableVertexAttribArray(ATTRIB_SIZE);
glDisableVertexAttribArray(ATTRIB_TEXTURE_COORD);
glUniform1i(uniforms[UNIFORM_IS_SPRITE], GL_TRUE);

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(ISPointSpriteData), (void*)offsetof(ISPointSpriteData, vertex));
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(ISPointSpriteData), (void*)offsetof(ISPointSpriteData, color));
glVertexAttribPointer(ATTRIB_SIZE, 1, GL_FLOAT, GL_FALSE, sizeof(ISPointSpriteData), (void*)offsetof(ISPointSpriteData, size));

glDrawArrays(GL_POINTS, 0, vertexCount);     // <--- EXC_BAD_ACCESS

glDisableVertexAttribArray(ATTRIB_VERTEX);
glDisableVertexAttribArray(ATTRIB_COLOR);
glDisableVertexAttribArray(ATTRIB_SIZE);


[renderer presentScene];

这个代码在我放入VBO之前工作,唯一的改变是glVertexAttribPointer()调用的最后一个参数显然指向数据而不是偏移量。我错过了什么?我不认为这段代码特别复杂,所以我只能认为我在某处犯了一个愚蠢的错误。

由于

2 个答案:

答案 0 :(得分:4)

问题已解决:

我的代码存在一些问题,但问题中的列表并未显示所有问题。我将概述主要问题:

  • 在未列出的代码中,我正在创建 实用功能中的VBO。在 这个功能我错了 传递GLuint句柄 缓冲区(我试图通过它 在一个函数中引用 返回void)。为了利益 使我更易读,我改变了 简单地初始化它的功能 自己处理并返回它。这个 停止了程序崩溃 glDrawArrays()行(大概是 未初始化的价值必须已经存在 被分配到另一个缓冲区 某处)。

出现了一个新问题 - 屏幕被拉到黑色,绘制调用之间出现了大的延迟。这是由......引起的。

  • 之后没有解开VBO 每个抽奖电话。对于每一帧a 首先绘制背景纹理, 其次是维也纳各组织的内容。 通过离开VBO绑定 下一个背景渲染,我是 显然导致OGL有点 合适的!这不仅是原因 黑屏,但也大 平局电话之间的延迟。

希望这对处于类似情况的其他人有帮助!

答案 1 :(得分:0)

您可能必须使用glDrawElements而不是glDrawArrays。因为glDrawArrays不允许跳跃或跳过。它从一组连续的顶点读取。

“glDrawArrays()通过直接遍历数组而不跳过或跳跃来从启用的数组中读取顶点数据。因为glDrawArrays()不允许在顶点数组周围跳跃,所以仍然必须在每个面重复一次共享顶点。 “

http://www.songho.ca/opengl/gl_vertexarray.html