2014-02-19 35 views
0

我正在爲我的應用程序使用.obj加載程序,爲此,我設置了索引數組和頂點數組,並在運行時初始化它們。設置指數和頂點數組openGL ES

這是怎樣的結構定義:

typedef struct { 
    float Position[3]; 
    float Color[4]; 
    float TexCoord[2]; 
} Vertex; 

typedef struct { 
    GLuint v1; 
    GLuint v2; 
    GLuint v3; 
} Face3D; 

,這是陣列如何在.h文件:

Vertex* VerticesArr; 
Face3D* Faces; 

但是,當我初始化他們,我看到關於我的什麼屏幕,而不是使用這種方式:

const Vertex Vertices[] = { 
    {{1, -1, 0}, {1, 0, 0, 1},{0,0}}, 
    {{1, 1, 0}, {0, 1, 0, 1},{0,0}}, 
    {{-1, 1, 0}, {0, 0, 1, 1},{0,0}}, 
    {{-1, -1, 0}, {0, 0, 0, 1},{0,0}} 
}; 

const GLubyte Indices[] = { 
    0, 1, 2, 
    2, 3, 0 
}; 

通過使用這些const數組,我得到在屏幕上的繪圖。

我的問題是,正在使用索引和頂點數組,我甚至有可能嗎? 我相信是這樣,它似乎是錯的。

這是我的VBO上左右逢源的設置如何我前面介紹:

- (void)setupVBOs { 

    GLuint vertexBuffer; 
    glGenBuffers(1, &vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(VerticesArr), VerticesArr, GL_STATIC_DRAW); 

    GLuint indexBuffer; 
    glGenBuffers(1, &indexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Faces), Faces, GL_STATIC_DRAW); 

} 

,我用畫元素的方式:

glDrawElements(GL_POINTS, sizeof(Faces)/sizeof(Faces[0]), GL_UNSIGNED_INT, 0); 

我做檢查,這兩個陣列正在初始化他們應該這樣做,而且他們這樣做。

這是我爲他們分配空間:

// Allocate space for the Vertices array 
NSLog(@"Size of vertice is: %lu",sizeof(Vertex)); 
VerticesArr = (Vertex*)(malloc(sizeof(Vertex) * vertexCombinations.count)); 
// Allocate space for the Faces 
NSLog(@"Size of face is: %lu",sizeof(Face3D)); 
Faces = (Face3D*)(malloc(sizeof(Face3D)*faceCount)); 

回答

1

的潛在問題:

1)C不保證結構的緊密堆積。所以例如編譯器可能會查看您的Face3D,發現它的長度爲12個字節,並決定將其填充到16個字節 - 每個結構最後會有四個未使用的字節,因爲這樣做可能會使單個結構更快地讀取。同樣,它保留在結構中各個項目之間填充的權利。您使用的是原生大小的單位,所以填充不一定可能,但您的編譯器保留添加它的權利,並依靠嚴格的打包方式依賴未定義的行爲。

2)sizeof(Faces)/sizeof(Faces[0]) - sizeof(struct Face3D)sizeof(GLuint)的數量非常不同,所以即使您的結構緊湊,這是您的兩段代碼之間的區別。

您可以在運行時檢查是否有其他地方的sizeof(struct Face3D) == sizeof(GLuint)*3和等效測試。如果是這樣,那麼你可以直接將結構傳遞給glBufferData。如果不是,那麼你可能只是通過一個適當的步幅glVertexAttribPointer,這取決於確切的填充,但更有可能你需要顯式地將序列化到非結構化數組以獲得OpenGL的好處。

+0

非常感謝你的回答tommy,你是否建議我應該爲索引創建一個'GLuint'數組?意思是不使用'Face3D'結構並且只是一個接一個地添加它們?將openGL知道如何分離x,y,z?我的意思是去1,2,3等? – Itzik984

+0

順便說一句,我只是檢查,確實'sizeof(結構Face3D)== sizeof(GLuint)* 3',但現在我只得到了一半的obj繪製。這並不容易處理! – Itzik984

+1

爲了完全安全,您應該將結構化數據反序列化爲原始數組,以獲得OpenGL的好處。只需爲'glBufferData'編寫自己的包裝器,即'malloc'是一個合適大小的數組,遍歷結構體填充數組,然後通過'glBufferData'本身發佈數組。 – Tommy

2

我看到的第一個問題是在這部分代碼:

- (void)setupVBOs { 

    GLuint vertexBuffer; 
    glGenBuffers(1, &vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(VerticesArr), VerticesArr, GL_STATIC_DRAW); 

    GLuint indexBuffer; 
    glGenBuffers(1, &indexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Faces), Faces, GL_STATIC_DRAW); 

} 

當您創建常量數組sizeof(Faces)將返回你的數組的大小,但是當你動態地分配他們,那麼sizeof(Faces)將是大小一個指針(通常是4個字節)。我看到的第二個問題是,在靜態分配期間,您的indecies是GLUByte,但在Face3D中,它們是GLUInt。不知道這是否是一個問題,但似乎可能。

+0

對於'Faces'的大小,VerticesArr的大小是一樣的......現在我得到了圖紙,但只是一半的模型。得到了關於從哪裏開始調試的任何提示? – Itzik984

+0

沒關係,明白了:)謝謝! – Itzik984