-1

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

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

这是我现在尝试这样做的方法,但无济于事。设置GL:

[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)。设置GL:

[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);
 }
4

1 回答 1

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

于 2013-07-29T03:50:06.200 回答