2013-02-16 396 views
2

我在玩OpenGL頂點顏色。基本上,我畫了一個由2個三角形組成的正方形。我能夠按照我想要的方式爲第一個三角形着色,但第二個三角形沒有按照我的預期着色。過去兩天我一直在研究這個問題,但我無法弄清楚,所以我在這裏尋求一些指導。C++ OpenGL - 頂點顏色

這裏是我的代碼:

void Construct_Cube() 
{ 
    //--------------------- 
    //Init cube's vertices 

    float Vertices_Temp[] = 
    { 
     0, 0, 0, //bottom-left corner 
     0, 1, 0, //top-left 
     1, 1, 0, //top-right 
     1, 0, 0 //bottom-right 
    }; 

    for(int i = 0; i < (sizeof(Vertices_Temp)/sizeof(GLfloat)); i++) 
    { 
     Vertices_Cube.push_back(Vertices_Temp[i]); 
    } 

    //--------------------------- 
    //Init cube's draw order list 
    int tempOrder[] = { 0, 1, 2, 0, 3, 2}; 

    for(int i = 0; i < (sizeof(tempOrder)/sizeof(int)); i++) 
    { 
     drawOrder_Cube.push_back(tempOrder[i]); 
    } 

    //------------------ 
    //Init cube's color 
    Color_Cube.resize(18); 

    //Color of each triangle (Red-Green-Yellow) 
    for(int i = 0; i < 18;) 
    { 
     Color_Cube[i++] = 1.0f; 
     Color_Cube[i++] = 0.0f; 
     Color_Cube[i++] = 0.0f; 

     Color_Cube[i++] = 0.0f; 
     Color_Cube[i++] = 1.0f; 
     Color_Cube[i++] = 0.0f; 

     Color_Cube[i++] = 1.0f; 
     Color_Cube[i++] = 1.0f; 
     Color_Cube[i++] = 0.0f; 
    } 

    glGenVertexArrays(1, &VAO_Cube); 
    glBindVertexArray(VAO_Cube); 

    //------------------- 
    //Buffer for vertices 
    glGenBuffers(1, &VBO_Cube_Vertices); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO_Cube_Vertices); 
    glEnableVertexAttribArray(0); 

    //Passing CartesianSys coord data into the ARRAY_BUFFER 
    glBufferData(GL_ARRAY_BUFFER, (Vertices_Cube.size())*sizeof(float), &Vertices_Cube[0], GL_STATIC_DRAW); 
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); //size = 3 (X,Y,Z) 

    //---------------- 
    //Buffer for color 
    glGenBuffers(1, &VBO_Cube_Color); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO_Cube_Color); 
    glEnableVertexAttribArray(1); 

    glBufferData(GL_ARRAY_BUFFER, (Color_Cube.size())*sizeof(float), &Color_Cube[0], GL_STATIC_DRAW); 
    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, (void *)36); //size = 3 (R,G,B) 

    glBindVertexArray(0); //Unbind VAO 
} 

void draw() 
{ 
    glBindVertexArray(VAO_Cube); //Bind VAO 
    glDrawElements(GL_TRIANGLES, drawOrder_Cube.size(), GL_UNSIGNED_INT, &drawOrder_Cube[0]); 
    glBindVertexArray(0); //Unbind VAO 
} 

這是什麼樣子:

enter image description here

第1三角形有正確的顏色:分別是 「紅,綠,黃」 的「左下,左上,右上「。

但是,第2個三角形在「左下,右下,右上」沒有正確的顏色:「紅色,黑色,黃色(?)」而不是「紅色,綠色和黃色」。最初,我想也許我錯過了顏色數組中的一些顏色值(因此,由於「0」是默認值,所以它出現「黑色」)。但是,我的顏色數組(Color_Cube [])已正確初始化:我的方形的6個頂點有18種顏色元素。

然而,隨着彩色陣列打了一下後,我發現一個很奇怪:

如果我只初始化數組的第9個元素,我變成方形全黑的!

for(int i = 0; i < 9;) 
{ 
    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 0.0f; 
    Color_Cube[i++] = 0.0f; 

    Color_Cube[i++] = 0.0f; 
    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 0.0f; 

    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 0.0f; 
} 

爲什麼它會全黑?它應該是第一個三角形的顏色嗎?

然後,如果我初始化數組的最後9個元素,方形彩色起來完全像從前那樣(第1三角形有正確的顏色,但不是第二個三角形)

for(int i = 9; i < 18;) 
{ 
    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 0.0f; 
    Color_Cube[i++] = 0.0f; 

    Color_Cube[i++] = 0.0f; 
    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 0.0f; 

    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 1.0f; 
    Color_Cube[i++] = 0.0f; 
} 

爲什麼它當我只通過了最後3個頂點的顏色時,兩個三角形的顏色都變了嗎?是否應該讓第一個三角形變成黑色而第二個三角形變成「紅色,綠色,黃色」?

看起來好像顏色數組的前9個元素完全被忽略了。爲什麼???

所以,我被困在那裏。我想也許我在glVertexAttribPointer()的偏移值中犯了一個錯誤。然而,經過雙重檢查這些功能,我沒有看到任何東西錯了,或者也許我失去了一些東西:

//Buffer for vertices 
glEnableVertexAttribArray(0); 
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

//Buffer for color 
glEnableVertexAttribArray(1); 
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, (void *)36); 
我不使用Alpha值

,所以我有18輛花車總在頂點數組(前9個浮點數是三角形座標,最後9個浮點數是三角形的顏色,頂點數組從第0個位置開始,而顏色數組從第36個位置開始)。

我在這裏錯過了什麼?在過去的兩天裏,我無法弄清楚哪裏出了問題,於是我來到這裏尋求一些指導和指導。

預先感謝您。

+0

我對顏色屬性和偏移有點困惑,但嘗試將'tempOrder'改爲'{0,1,2,3,0,2}'。 – 2013-02-16 02:32:39

+0

你以我從未見過的方式做了一切。遞增for循環中的迭代器。而不是使用跨度交叉指向數據。複雜度+1。 – Kaliber64 2013-02-16 03:18:37

+0

你正在強姦'for'循環......它什麼都不執行,可能只會導致錯誤(例如,你是否曾經意外刪除了身體的一條線) – example 2013-02-16 09:19:31

回答

3

當您爲顏色調用glVertexAttribPointer時,最後一個參數(指針)應該爲0。指針將是從顏色緩衝區(不是頂點數組)開始到重要數據開始處的字節偏移量。 Color_Cube中的顏色從字節0開始。

當您指定36字節的指針時,表示顏色數據從Color_Cube的第36個字節開始,它實際上是第4種顏色。從這一點上只有3種顏色。這就是爲什麼一個角落是黑色的:該頂點沒有顏色。當您僅用前三種顏色初始化Color_Cube時,從第36個字節開始沒有更多顏色,整個正方形變爲黑色。

另外:

Vertices_Cube有12個元素,但Color_Cube具有18. 因爲只有在Vertices_Cube四個頂點,你應該在Color_Cube只有四種顏色,因爲使用的是相同的索引緩衝器指頂點和顏色緩衝區。

+0

Bingo!它工作得很好。非常感謝。我現在明白了。 – TATN 2013-02-16 09:24:09