2013-07-15 94 views
0

在我的應用程序中,我使用OpenGL ES渲染從互聯網下載的文件,然後將文件解析爲頂點數組,因此必須在啓動後輸入頂點和法線數據。我是OpenGL ES的新手,但我一直在閱讀和學習。我已經設置了一個頂點和法線緩衝區,似乎工作正常,但我認爲我正在將頂點和法線數據錯誤地放入緩衝區,因爲當我加載視圖時,那裏有一個對象,它隱約類似於我想要的形狀但是三角形在各個方向上偏離,部分形狀缺失。這是我輸入我的數據到緩衝區代碼:iOS上的OpenGL ES向緩衝區添加頂點

for (int i = 0; i < triangle_cnt; i++) { 
     int base = i * 18; 
     GLfloat x1 = vertices[base]; 
     GLfloat y1 = vertices[base + 1]; 
     GLfloat z1 = vertices[base + 2]; 
     GLfloat x2 = vertices[base + 6]; 
     GLfloat y2 = vertices[base + 7]; 
     GLfloat z2 = vertices[base + 8]; 
     GLfloat x3 = vertices[base + 12]; 
     GLfloat y3 = vertices[base + 13]; 
     GLfloat z3 = vertices[base + 14]; 

     vector_t normal; 
     vector_t U; 
     vector_t V; 
     GLfloat length; 

     U.x = x2 - x1; 
     U.y = y2 - y1; 
     U.z = z2 - z1; 

     V.x = x3 - x1; 
     V.y = y3 - y1; 
     V.z = z3 - z1; 

     normal.x = U.y * V.z - U.z * V.y; 
     normal.y = U.z * V.x - U.x * V.z; 
     normal.z = U.x * V.y - U.y * V.x; 

     length = normal.x * normal.x + normal.y * normal.y + normal.z * normal.z; 
     length = sqrt(length); 

     base = i * 9; 
     verticesBuff[base] = x1; 
     verticesBuff[base + 1] = y1; 
     verticesBuff[base + 2] = z1; 

     normalsBuff[base] = normal.x; 
     normalsBuff[base + 1] = normal.y; 
     normalsBuff[base + 2] = normal.z; 

     verticesBuff[base + 3] = x2; 
     verticesBuff[base + 4] = y2; 
     verticesBuff[base + 5] = z2; 

     normalsBuff[base + 3] = normal.x; 
     normalsBuff[base + 4] = normal.y; 
     normalsBuff[base + 5] = normal.z; 

     verticesBuff[base + 6] = x3; 
     verticesBuff[base + 7] = y3; 
     verticesBuff[base + 8] = z3; 

     normalsBuff[base + 6] = normal.x; 
     normalsBuff[base + 7] = normal.y; 
     normalsBuff[base + 8] = normal.z; 

     fprintf(stderr, "%ff, %ff, %ff,   %ff, %ff, %ff, \n", x1, y1, z1, normal.x, normal.y, normal.z); 
     fprintf(stderr, "%ff, %ff, %ff,   %ff, %ff, %ff, \n", x2, y2, z2, normal.x, normal.y, normal.z); 
     fprintf(stderr, "%ff, %ff, %ff,   %ff, %ff, %ff, \n", x3, y3, z3, normal.x, normal.y, normal.z); 
    } 

,這裏是我使用的使用這些緩衝區代碼:

- (void)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); 

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

glGenBuffers(1, &_vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(verticesBuff)*3*2, NULL, GL_STATIC_DRAW); 
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verticesBuff) * vertCount * 3, verticesBuff); 
glBufferData(GL_ARRAY_BUFFER, vertCount*sizeof(normalsBuff)*3*2, NULL, GL_STATIC_DRAW); 
glBufferSubData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertCount * 3, sizeof(normalsBuff) * vertCount * 3, normalsBuff); 

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)); 

glBindVertexArrayOES(0); 

_rotMatrix = GLKMatrix4Identity; 

_quat = GLKQuaternionMake(0, 0, 0, 1); 
_quatStart = GLKQuaternionMake(0, 0, 0, 1); 
} 
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 
glClearColor(0.78f, 0.78f, 0.78f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glBindVertexArrayOES(_vertexArray); 

// Render the object with GLKit 
[self.effect prepareToDraw]; 

glVertexPointer(3, GL_FLOAT, 0, verticesBuff); 
glNormalPointer(GL_FLOAT, 0, normalsBuff); 

glDrawArrays(GL_TRIANGLES, 0, vertCount); //******************************* 

// Render the object again with ES2 
glUseProgram(_program); 

glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); 

glDrawArrays(GL_TRIANGLES, 0, vertCount); 
} 

如果我把這些日誌並將它們粘貼到頂點數組使用Apple在創建OpenGL ES應用程序時提供的代碼的示例應用程序,然後該對象渲染得非常漂亮,所以我推斷我必須將頂點數據放在錯誤的位置。

所以有人可以幫助我瞭解我在做什麼錯誤時輸入頂點和法線?任何幫助表示讚賞。

而且這是我的渲染看起來像:

bad render

而且這是在外形,至少,它應該是什麼樣子:

good render

+0

您發佈的信息太少。添加關於如何使用這些緩衝區和繪圖調用的代碼。 –

+0

好吧,我已經添加了它。 – harryisaac

回答

0

這是一個有點亂並且可能有相當多的問題。您當前所面臨的似乎是一個:

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

步幅參數(24)應sizeof(GLfloat)*3和同樣適用於法線。這是因爲您不再使用交錯頂點結構,現在您的位置座標被緊密包裝(也就是說,您現在也可以使用0作爲跨步參數)。你用這個bug產生的結果是隻有每個第二個頂點被採用,其他的被丟棄,並且當所有位置都被採用時,它開始繪製法線。此外,如果您的正常指針和偏移量設置正確,您正在讀取它們超出緩衝區,並應產生崩潰或讀取其他資源。