2011-11-12 46 views
0

我想在openGL中實現天空盒,但由於某種原因,它沒有被正確繪製,除非我關閉背面剔除功能,即使這樣它會顯示3個三角形被搞砸了。 Maby我沒有畫出正確的三角形,但我不確定。在openGL中使用三角形的天空盒

bool Skybox::onInitialize() 
{ 
    myRadius = 100; 
    setPosition(Vector3(0.0f, 0.0f, 0.0f)); 

    //Initialize color matrix 
    myColors.push_back(Color(1.0f, 0.0f, 0.0f, 1.0f)); 
    myColors.push_back(Color(1.0f, 1.0f, 0.0f, 1.0f)); 
    myColors.push_back(Color(1.0f, 0.5f, 0.0f, 1.0f)); 
    myColors.push_back(Color(0.5f, 0.5f, 0.5f, 1.0f)); 

    //Position the key points of the cube 
    myVertices.push_back(Vertex(-myRadius, -myRadius, myRadius));//0 
    myVertices.push_back(Vertex(-myRadius, -myRadius, -myRadius));//1 
    myVertices.push_back(Vertex(myRadius, -myRadius, -myRadius));//2 
    myVertices.push_back(Vertex(myRadius, -myRadius, myRadius));//3 

    myVertices.push_back(Vertex(-myRadius, myRadius, myRadius));//4 
    myVertices.push_back(Vertex(-myRadius, myRadius, -myRadius));//5 
    myVertices.push_back(Vertex(myRadius, myRadius, -myRadius));//6 
    myVertices.push_back(Vertex(myRadius, myRadius, myRadius));//7 

    //Push back the indices that make up the triangles for each face. 
    //Bottom 
    myIndices.push_back(0); 
    myIndices.push_back(1); 
    myIndices.push_back(2); 
    myIndices.push_back(2); 
    myIndices.push_back(1); 
    myIndices.push_back(0); 

    //Top 
    myIndices.push_back(7); 
    myIndices.push_back(6); 
    myIndices.push_back(4); 
    myIndices.push_back(6); 
    myIndices.push_back(5); 
    myIndices.push_back(4); 

    //Left 
    myIndices.push_back(0); 
    myIndices.push_back(4); 
    myIndices.push_back(1); 
    myIndices.push_back(4); 
    myIndices.push_back(5); 
    myIndices.push_back(1); 

    //Right 
    myIndices.push_back(2); 
    myIndices.push_back(6); 
    myIndices.push_back(3); 
    myIndices.push_back(6); 
    myIndices.push_back(7); 
    myIndices.push_back(3); 

    //Back 
    myIndices.push_back(6); 
    myIndices.push_back(1); 
    myIndices.push_back(5); 
    myIndices.push_back(6); 
    myIndices.push_back(2); 
    myIndices.push_back(1); 

    //Front 
    myIndices.push_back(0); 
    myIndices.push_back(7); 
    myIndices.push_back(4); 
    myIndices.push_back(0); 
    myIndices.push_back(3); 
    myIndices.push_back(7); 

    //Generate Texture Coordinates 
    //Bottom 
    myTexCoords.push_back(TexCoord(0.25, 0)); 
    myTexCoords.push_back(TexCoord(0.25, 0.375)); 
    myTexCoords.push_back(TexCoord(0.5, 0.375)); 
    myTexCoords.push_back(TexCoord(0.5, 0)); 

    //Top 
    myTexCoords.push_back(TexCoord(0.25, 1)); 
    myTexCoords.push_back(TexCoord(0.25, 0.625)); 
    myTexCoords.push_back(TexCoord(0.5, 0.625)); 
    myTexCoords.push_back(TexCoord(0.5, 1)); 

    //Left 
    myTexCoords.push_back(TexCoord(0, 0.625)); 
    myTexCoords.push_back(TexCoord(0.25, 0.625)); 
    myTexCoords.push_back(TexCoord(0.25, 0.375)); 
    myTexCoords.push_back(TexCoord(0, 0.375)); 

    //Right 
    myTexCoords.push_back(TexCoord(0.5, 0.625)); 
    myTexCoords.push_back(TexCoord(0.75, 0.625)); 
    myTexCoords.push_back(TexCoord(0.75, 0.375)); 
    myTexCoords.push_back(TexCoord(0.5, 0.375)); 

    //Back 
    myTexCoords.push_back(TexCoord(0.75, 0.625)); 
    myTexCoords.push_back(TexCoord(1.0, 0.625)); 
    myTexCoords.push_back(TexCoord(1.0, 0.375)); 
    myTexCoords.push_back(TexCoord(0.75, 0.375)); 

    const string vertexShader = (GLSLProgram::glsl130Supported()) ? VERTEX_SHADER_130 : VERTEX_SHADER_120; 
    const string fragmentShader = (GLSLProgram::glsl130Supported()) ? FRAGMENT_SHADER_130 : FRAGMENT_SHADER_120; 

    if (!myTexture.load(SKY_TEXTURE)) 
    { 
     std::cerr << "Could not load the particle texture" << std::endl; 
     return false; 
    } 

    glGenTextures(1, &myTexID); 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, myTexID); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, myTexture.getWidth(), 
     myTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 
     myTexture.getImageData()); 


    m_shaderProgram = std::auto_ptr<GLSLProgram>(new GLSLProgram(vertexShader, fragmentShader)); 

    if (!m_shaderProgram->initialize()) 
    { 
     std::cerr << "Could not load the skybox shaders" << std::endl; 
     return false; 
    } 

    m_shaderProgram->bindAttrib(0, "a_Vertex"); 
    m_shaderProgram->bindAttrib(1, "a_Color"); 
    m_shaderProgram->bindAttrib(2, "a_TexCoord0"); 
    m_shaderProgram->linkProgram(); 
    m_shaderProgram->sendUniform("texture0", 0); 

    glGenBuffers(1, &myVertexBuffer); //Generate a buffer for the vertices 
    glBindBuffer(GL_ARRAY_BUFFER, myVertexBuffer); //Bind the vertex buffer 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * myVertices.size(), &myVertices[0], GL_STATIC_DRAW); //Send the data to OpenGL 

    glGenBuffers(1, &myColorBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, myColorBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Color) * myColors.size(), &myColors[0], GL_STATIC_DRAW); //Send the data to OpenGL 

    glGenBuffers(1, &myTexCoordBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, myTexCoordBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoord) * myTexCoords.size(), &myTexCoords[0], GL_STATIC_DRAW); //Send the data to OpenGL 

    glGenBuffers(1, &myIndexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, myIndexBuffer); //Bind the vertex buffer 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * myIndices.size(), &myIndices[0], GL_STATIC_DRAW); //Send the data to OpenGL 

    return true; 
} 

void Skybox::onRender() const 
{ 
    //glDisable(GL_DEPTH_TEST); 

    //glPushMatrix(); 
    glTranslatef(0.0f, 0.0f, 0.0f); 
    static float modelviewMatrix[16]; 
    static float projectionMatrix[16]; 

    m_shaderProgram->bindShader(); 

    //Get the current matrices from OpenGL 
    glGetFloatv(GL_MODELVIEW_MATRIX, modelviewMatrix); 
    glGetFloatv(GL_PROJECTION_MATRIX, projectionMatrix); 

    //Enable the point sprite and the automatic texture coordinates 
    glBindTexture(GL_TEXTURE_2D, myTexID); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glEnableVertexAttribArray(2); 

    //Send the modelview and projection matrices to the shaders 
    m_shaderProgram->sendUniform4x4("modelview_matrix", modelviewMatrix); 
    m_shaderProgram->sendUniform4x4("projection_matrix", projectionMatrix); 
    m_shaderProgram->sendUniform("texture0", 0); 

    //Bind the vertex array and set the vertex pointer to point at it 
    glBindBuffer(GL_ARRAY_BUFFER, myVertexBuffer); 
    glVertexAttribPointer((GLint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ARRAY_BUFFER, myColorBuffer); 
    glVertexAttribPointer((GLint)1, 4, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ARRAY_BUFFER, myTexCoordBuffer); 
    glVertexAttribPointer((GLint)2, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    //Bind the index array 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, myIndexBuffer); 


    //glDrawElements(GL_TRIANGLES, myIndices.size(), GL_UNSIGNED_INT, 0); 
    glPointSize(5.0f); 
    glDrawArrays(GL_TRIANGLES, 0, myIndices.size()); 

    glDisableVertexAttribArray(2); 
    glDisableVertexAttribArray(1); 
    glDisableVertexAttribArray(0); 

    // glPopMatrix(); 
} 
+2

你可能想看看如何接受答案。這是您的問題的答案旁邊的綠色複選標記。你選擇一個答案,你覺得是你的問題的正確答案。您迄今爲止所提出的任何問題都沒有完成,所以您可能需要回頭查看其中的一些問題並接受適當的答案。 –

+0

渲染代碼在哪裏?你如何將你的屬性與你的維也納組織聯繫起來?假設頂點數據甚至是正確的(我沒有檢查),並且按照正確的排列順序,很難從這種有限的代碼中判斷出什麼可能是錯誤的。我不知道「bindAttrib」是做什麼的,但是如果它設置了頂點屬性(即調用glVertexAttribPointer),那麼在VBO沒有綁定時不起作用! –

+0

我沒有看到任何綠色複選標記,也沒有人回答這個問題但是,人們總是告訴我點擊複選框,但是沒有人告訴我它在哪裏,我將渲染代碼附加到了它的末尾 – Katianie

回答

1

繪製代碼很迷茫。它有很多不妥之處,但都是源於一個根本性的誤解。

您有4種顏色,8個位置和24個紋理座標。 OpenGL不知道該怎麼做。

OpenGL只能處理唯一的頂點屬性組。所以如果你有位置和紋理座標,這些陣列的長度必須是等於。對於每個紋理座標,都有一個與之配對的特定位置,反之亦然。對於每個位置,都有一個與之配對的特定顏色,反之亦然。

是的,立方體只有8個不同的位置。但是你並沒有繪製頂點(頂點是屬性數據的集合,如果你願意的話,其中的可能包括一個位置)。你正在繪製12個三角形。每個三角形有3個頂點。

三角形只能共享頂點,前提是它們共享該頂點的頂點屬性的全部。因此,一個立方體的一個面可以由四個頂點表示,因爲兩個三角形(沿着主對角線)共享兩個共享頂點的相同位置/顏色/ texCoord。

但是不同面孔的三角形只能共用頂點數據,如果他們使用相同的位置/顏色/ texCoord三元組。在大多數情況下,你的不會。

因此,您必須複製您的位置和顏色很多。立方體的每個面將具有獨立的位置和顏色(即使它們可能使用與其他值相同的值)。

另外,請考慮完全避免紋理座標。您明顯使用着色器,因此只需將您的環境放在立方體貼圖中即可。您可以在立方體貼圖向外指向的8個角上傳遞「法線」。將它們插值爲標準,然後使用它們訪問立方體貼圖紋理。

+0

好吧,這有助於非常感謝所以,如果我要擺脫textuure座標我那有效嗎?我該如何將其轉換爲使用立方體貼圖?是的,我正在使用着色器,我不得不評論drawAttribues並使用drawElements。我想我的問題是我現在應該做什麼? – Katianie

+0

切換回drawAttributes,現在只用8 tex座標進行測試幾乎可以正確繪製立方體。立方體的一部分被剔除,但那可能是因爲索引 – Katianie