iOS上的OpenGL ES多个没有指数的VBO

时间:2013-07-28 21:50:18

标签: ios opengl-es vbo

在我的应用程序中,我有一个呈现STL文件的视图。 STL文件本质上是一个带有法线的三角形顶点列表,它们没有索引。

我找到的每个教程都解释了如何使用多个VBO但使用Indices,当我尝试使用drawArrays而不是drawElements时,它不起作用。我是OpenGL的新手,如果有人可以提供使用多个VBO进行设置并在没有索引的情况下绘制它们的代码示例,我将非常感激。

以下是我现在尝试这样做的方法无济于事。 SetupGL:

[EAGLContext setCurrentContext:self.context];

[self loadShaders];

self.effect = [[GLKBaseEffect alloc] init];
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(.05f, .55f, 1.0f, 1.0f);

glEnable(GL_DEPTH_TEST);
glClearColor(0.88f, 0.88f, 0.88f, 1.0f);

//---- First Vertex Array Object --------
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glBindVertexArrayOES(_vertexArray);

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(verticesBuff) * 3 * 2, verticesBuff, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

//----- Second Vertex Array Object ----------
glGenBuffers(1, &_gridVertexBuffer);

glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, gridVertCount*sizeof(gridVerticesBuff) * 3 * 2, NULL, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArrayOES(0);

这是我的抽奖代码:

glBindVertexArrayOES(_vertexArray);

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, vertCount);

///////// second VBO and shader program:
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 108);

此外,这里是我之前使用的代码,它不会渲染两个数组,但它会渲染一个(verticesBuff)。 SetupGL:

[EAGLContext setCurrentContext:self.context];

[self loadShaders];

self.effect = [[GLKBaseEffect alloc] init];
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(.05f, .55f, 1.0f, 1.0f);

glEnable(GL_DEPTH_TEST);
glClearColor(0.88f, 0.88f, 0.88f, 1.0f);

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_gridVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBufferData(GL_ARRAY_BUFFER, 108 * sizeof(gridVerticesBuff), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(gridVerticesBuff) * 108, gridVerticesBuff);


glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(verticesBuff) * 3 * 2, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verticesBuff) * vertCount * 3, verticesBuff);

glBindVertexArrayOES(0);

这是绘图代码:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if (loaded) {
    // Render the object with GLKit
    [self.effect prepareToDraw];


    glBindVertexArrayOES(_gridVertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, _gridVertexBuffer);
    glDrawArrays(GL_TRIANGLES, 0, 108);

    glBindVertexArrayOES(_vertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glDrawArrays(GL_TRIANGLES, 0, vertCount);
 }

1 个答案:

答案 0 :(得分:0)

如果没有看到您的代码,很难确切地知道出了什么问题,但是如果您按照这些一般步骤进行操作,您应该能够弄明白。索引数据和平面数据之间几乎没有区别。如果您了解他们正在做什么,使用VBO会更容易。基本上,VBO允许您将常见的顶点数据预加载到图形卡上,因此无需在每次绘制调用时重新加载。考虑到这一点,您需要考虑如何将正常绘制调用中使用的所有顶点数据打包到单个内存缓冲区中。

创建缓冲区:

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, totalBufferSize, NULL, GL_STATIC_DRAW); /* totalBufferSize is sizeof vertices buffer + sizeof normals buffer */
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexBufferSize, vertexBuffer); /* offset 0 */
glBufferSubData(GL_ARRAY_BUFFER, vertexBufferSize, normalBufferSize, normalBuffer); /* offset vertexbufferSize */

绘制缓冲区:

 glBindBuffer(GL_ARRAY_BUFFER, vbo);
 glVertexAttribPointer(VERTEX_ATTRIB ..., ((char*)NULL) + 0); /* start at beginning (0 offset) of the vertex buffer */
 glVertexAttribPointer(NORMAL_ATTRIB ..., ((char*)NULL) + vertexBufferSize); /* start at normal subdata (offset vertexBufferSize) of the vertex buffer */ 

 glDrawArrays(..., vertexCount);

(char*)NULL事情可能看起来有点奇怪。您将偏移量传入当前绑定的VBO,而不是将指针传递给RAM中的缓冲区。函数的参数仍然需要一个指针,因此指针的地址用作偏移量。理解NULL为0并将代码视为(char*)NULL +不存在。