2012-11-22 60 views
2

我正在製作3D模型加載器。它可以加載我自己的格式。我爲Blender寫了自己的出口商,它運作良好。模型格式可以在一個模型中處理多個網格(對象)。每個網格可以具有不同的紋理。我已經寫了一個運行正常的loader,但不使用着色器。用紋理繪製多個對象不起作用

我切換到着色器,但出現問題,紋理顯示不正確。這裏是我的繪圖函數,我敢肯定這裏的錯誤在這裏:

void CModel::draw(glm::mat4 &MVP) 
{ 
    glActiveTexture(GL_TEXTURE0); 
    glEnable(GL_TEXTURE_2D); 

    for(unsigned int i=0; i<m_numObjects; i++) 
    { 
     glUseProgram(m_programID); 
     glUniformMatrix4fv(m_matrixUniform, 1, GL_FALSE, &MVP[0][0]); 

     glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]); 
     glUniform1i(m_textureUniform, 0); 

     glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]); 

     // vertices 
     glEnableVertexAttribArray(0); 
     glVertexAttribPointer(
       0,     // must match the layout in the shader. 
       3,     // size 
       GL_FLOAT,   // type 
       GL_FALSE,   // normalized? 
       sizeof(float)*8, // stride 
       (void*)0   // array buffer offset 
     ); 

     // UVs 
     glEnableVertexAttribArray(1); 
     glVertexAttribPointer(
       1, 
       2, 
       GL_FLOAT, 
       GL_FALSE, 
       sizeof(float)*8, 
       (void*)6 
     ); 

     glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]); 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 

     glUseProgram(0); 
    } 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
    glDisable(GL_TEXTURE_2D); 
} 

頂點和片段着色器也工作得很好。

以前的版本(無着色器)是這樣的(這個效果很好):

void CModel::draw() 
{ 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 
    glEnableClientState(GL_VERTEX_ARRAY); 

    glClientActiveTexture(GL_TEXTURE0); 
    glActiveTexture(GL_TEXTURE0); 
    glEnable(GL_TEXTURE_2D); 

    for(unsigned int i=0; i<m_numObjects; i++) 
    { 
     glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]); 

     glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]); 

     glTexCoordPointer(2, GL_FLOAT, sizeof(float)*8, (float*)(sizeof(float)*6)); 
     glNormalPointer( GL_FLOAT, sizeof(float)*8, (float*)(sizeof(float)*3)); 
     glVertexPointer( 3, GL_FLOAT, sizeof(float)*8, 0); 

     glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]); 

     glBindBuffer(GL_ARRAY_BUFFER, 0); 
    } 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glDisable(GL_TEXTURE_2D); 
} 

這裏是整個類:

#include "global.h" 
#include "CModel.h" 
#include "CModelLoader.h" 
#include "CShaderLoader.h" 

CModel::CModel(){} 

CModel::~CModel() 
{ 
    // TODO free memory 
} 

/** @brief Load mbm file 
    * 
    * @fileName: mdm model file name we want to load and draw 
    */ 
void CModel::init(char *fileName) 
{ 
    CModelLoader loader; 
    CShaderLoader shaders; 

    loader.loadData(fileName); 

    loader.createDataArray(m_dataArray, 
          m_dataArraySizes, 
          m_numObjects, 
          m_numElements, 
          m_textureIDs); 

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

    m_programID  = shaders.loadShaders("vertexshader.vert", "fragmentshader.frag"); 

    m_bufferIDs  = new unsigned int[m_numObjects]; 

    glGenBuffers(m_numObjects, m_bufferIDs); 
    for(unsigned int i=0; i<m_numObjects; i++) 
    { 
     glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]); 
     glBufferData(GL_ARRAY_BUFFER, sizeof(float)*m_dataArraySizes[i], m_dataArray[i], GL_STATIC_DRAW); 
    } 

} 

/** @brief Drawing the mdm model 
    * 
    */ 
void CModel::draw(glm::mat4 &MVP) 
{ 

    glEnable(GL_TEXTURE_2D); 
    glActiveTexture(GL_TEXTURE0); 

    for(unsigned int i=0; i<m_numObjects; i++) 
    { 
     glUseProgram(m_programID); 

     unsigned int matrixUniform = glGetUniformLocation(m_programID, "MVP"); 
     unsigned int textureUniform = glGetUniformLocation(m_programID, "myTextureSampler"); 

     glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, &MVP[0][0]); 
     glUniform1i(textureUniform, 0); 

     glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]); 
     glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]); 

     // vertices 
     glEnableVertexAttribArray(0); 
     glVertexAttribPointer(
       0,     // must match the layout in the shader. 
       3,     // size 
       GL_FLOAT,   // type 
       GL_FALSE,   // normalized? 
       sizeof(float)*8, // stride 
       (void*)0   // array buffer offset 
     ); 

     // UVs 
     glEnableVertexAttribArray(1); 
     glVertexAttribPointer(
       1, 
       2, 
       GL_FLOAT, 
       GL_FALSE, 
       sizeof(float)*8, 
       (void*)6 
     ); 

     glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]); 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 

     glUseProgram(0); 
    } 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 



    glDisable(GL_TEXTURE_2D); 
} 
+2

何時以及如何確定統一的位置?如果你想在安全的一面使用glGetUniformLocation,那麼每次執行glUseProgram之後都要使用glGetUniformLocation。 – datenwolf

+0

另外,您的屬性索引來自哪裏?它們在着色器中的位置在哪裏? –

+0

我在glUseProgram後放了glGetUniformLocation,但它不起作用。 來自模型文件的索引,但運行良好。 – mandyedi

回答

0

最後我解決它。問題是我使用了一個頂點,法線和紋理座標的數組,而不是將它們存儲在單獨的數組中,並將它們分開綁定。