2012-10-11 129 views
0

我從Xcode中的Apple-spypplication iOS OpenGL遊戲模板開始,我有一個結構數組(更多的結構數組結構,如果您願意的話)我試圖與OpenGL VBO一起使用。然而,雖然我沒有錯誤,但屏幕上沒有任何東西。將結構數組傳遞給glVertexAttribPointer

首先我創建並填充這個類型爲VecAttributeType的數組,該數組又有3個其他結構:vPosition,vTCoordinates和vNormal。 然後,我嘗試將數組複製到VBO,並通過glVertexAttribPointer將頂點着色器中的相應in /屬性綁定到位置和法線(表示偏移方面的VecAttributeType.vPosition和VecAttributeType.vNormal)。 然後我嘗試渲染。

,並沒有什麼得出:/

你要知道,在arrayOfStructs包含繪製模型所需的所有頂點。也就是說,我沒有使用頂點的索引。相反,對於這個測試,我正在瀏覽obj中的面部定義和每個索引,檢索適當的頂點,紋理,法線並將其複製到arraOfStructures中。

因此,例如,在OBJ格式經典的立方體,該文件列出8個頂點,但我最終arrayOfStructs具有長度12並有12層VecAttributeType結構在裏面,每一個合適的位置,紋理座標和正常爲頂點,派生自obj文件的臉部定義中的索引。是的,我將f定義中的指數抵消了-1,以說明obj文件索引從1開始的事實。

我的猜測是,我只是計算了職位在VBO中的偏移量和法線錯誤。我想是這樣,因爲我已經試過印刷在第一VecAttributeType第一位置的x座標在arrayOfStructures像這樣:

NSLog(@"\nTEST:\nfirst vertex X = %f", arrayOfStructs[0].vPosition.x); 

和我得到的預期值,同時試圖打印,像這樣:

char* address = (char*)arrayOfStructs+offsetof(VecAttributeType, vPosition.x); 
    float b = *address; 
    NSLog(@"\nTEST:\nfirst vertex X = %f", b); 

改爲打印0(正確的值應爲1);

這裏是代碼的有關章節:

//Inside a c++ class I'm parsing an Obj and creating the vertex attribute array: 
typedef struct 
{ 
    float x; 
    float y; 
    float z; 

} Vec3fType; 

typedef struct 
{ 
    float s; 
    float t; 

} Vec2fType; 

typedef struct 
{ 
    int p; 
    int n; 
    int t; 

} Vec3iType; 

typedef struct 
{ 
    Vec3fType vPosition; 
    Vec3fType vNormal; 
    Vec2fType vTCoordinates; 

} VecAttributeType; 

int arrayLength = // Some number; 
VecAttributeType* arrayOfStructs = new VecAttributeType[arrayLength]; 

// Populate the array. 

// . . . 

// Then, in the ViewController (Objective-C) class, I try binding to the VBO and getting the offsets right: 


[EAGLContext setCurrentContext:self.context]; 

[self loadShaders]; 

glEnable(GL_DEPTH_TEST); 

GLuint _vertexBuffer; 
glGenBuffers(1, &_vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(VecAttributeType)*arrayLength, arrayOfStructs, GL_STATIC_DRAW); 
glEnableVertexAttribArray(GLKVertexAttribPosition); 
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), BUFFER_OFFSET(0) + offsetof(VecAttributeType, vPosition) + offsetof(Vec3fType, x)); 
glEnableVertexAttribArray(GLKVertexAttribNormal); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), BUFFER_OFFSET(0) + offsetof(VecAttributeType, vNormal) + offsetof(Vec3fType, x)); 

最後,繪圖代碼是:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{ 
    glClearColor(1.f, 0.f, 0.f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glBindVertexArrayOES(_vertexArray); 

    // 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, arrayLength); 
} 

任何想法?

回答

0

好,我知道了...... 在某些時候我忘了我用的是VAO擴展(glBindVertexArrayOES)事實證明,並在VBO安裝結束禁用後,我幾乎忘了,使之在glkView:draInRect:

我上面的代碼顯示它已啓用,但只是導致我創建了一個新項目,將相關代碼段複製到SO上發佈之前。

此外,glVertexAttribPointer線可以更緊湊地重寫有點像這樣:

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType),(void*)offsetof(VecAttributeType, vPosition.x)); 
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), (void*)offsetof(VecAttributeType, vNormal.x));