2013-07-28 68 views
-1

在我的應用程序中,我有一個呈現STL文件的視圖。 STL文件基本上是一個帶有法線的三角形頂點列表,它們沒有索引。iOS上的OpenGL ES多個沒有索引的VBO

我找到的每個教程都解釋瞭如何使用多個VBO,但使用INDEX,並且當我嘗試使用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); 
} 
+0

就像你一樣。像索引一樣,只要沒有索引緩衝區和'glDrawArrays'就可以完成所有的操作(當然,頂點按照三角形順序排列)。請放心,*這確實很好。如果它不適合你,那麼發佈你的實際代碼並且描述更多*以哪種方式*它*「不起作用」*。 –

+0

好的,我已經發布了我的代碼的兩個版本,它們都不能與多個VBO一起工作,但是其中一個會渲染其中的一個。 – harryisaac

回答

0

這是很難知道沒有看到你的代碼究竟什麼是錯的,但如果你遵循這些常規步驟,你應該能夠人物出來。索引數據和平面數據幾乎沒有區別。如果你瞭解自己在做什麼,使用VBOs會更容易。實際上,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 +不存在。

+0

好吧,我添加了我的代碼來顯示我現在正在做什麼。我也試過你的代碼,我的變量沒有工作。它只是沒有渲染任何東西。 – harryisaac

+0

@ harry1795671你沒有提到VAO,不好意思看看。 –

+0

@ harry1795671 vertCount * sizeof(verticesBuff)* 3 * 2這看起來不對,sizeof在堆棧數組的情況下會給你整個數組的大小。在指針方面會給你一個指針的大小。頂點是否緊密包裝?如果是這樣,你確定這一步是正確的? –