2013-07-03 69 views
5

我一直在使用openGL幾個月,現在只是自己學習。現在我已經得到渲染位置,紋理座標模型使用GLSL GPU剝皮問題

我正在嘗試使用動畫模型,我將在顯卡上進行動畫蒙皮處理。

順便說一句,如果有人想幫助我1對1讓我知道我不介意更直接的做法。

這裏是我的頂點格式

struct VERTEX_ANIMATED 
{ 
    float3 position; 
    float3 normal; 
    float2 texCoord; 
    float weights[4]; 
    unsigned boneIndices[4]; 
}; 

這是我怎麼加我的綠黨到GPU緩存處理(在這些功能中的任何未初始化變量位於「.H」)

bool CVertexBuffer::IncreaseVerts(const unsigned int uiNumVerts) 
{ 
    //create our increase by value 
    unsigned uiIncrement = (uiNumVerts/BUFFER_INCREASE_SIZE) * BUFFER_INCREASE_SIZE + BUFFER_INCREASE_SIZE; 
    m_uiNumVerts += uiIncrement; 

    //bind to our buffer 
    void* buffer1; 
    if (GLEW_ARB_vertex_shader) 
    { 
     glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_uiVertBufferHandle); 

     //make sure our buffer exists 
     buffer1 = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE); 
    } 
    else 
    { 
     glBindBuffer(GL_ARRAY_BUFFER, m_uiVertBufferHandle); 

     //make sure our buffer exists 
     buffer1 = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); 
    } 

    if(buffer1) 
    { 
     //collection of all our data 
     void* buffer2 = new char[ (m_uiNumVerts)*sizeof(VertexFormat) ]; 
     memset(buffer2, 0, (m_uiNumVerts)*sizeof(VertexFormat)); 
     memcpy(buffer2, buffer1, (m_uiNumVerts - uiIncrement)*sizeof(VertexFormat) ); 

     //create a new buffer 
     //unsigned uiNewHandle; 

     if (GLEW_ARB_vertex_shader) 
     { 
      //allocate our new storage space, and store our data in there 
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, (m_uiNumVerts*sizeof(VertexFormat)), buffer2, GL_DYNAMIC_READ); 

      //lock our buffer 
      //void* buffer2 = glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE);  

      //unlock our buffer2 
      //if(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB) == GL_FALSE) 
      // return false; 
      //} 

      //reset what we are bound to 
      glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 
     } 
     else 
     { 
      //allocate our new storage space, and store our data in there 
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, (m_uiNumVerts*sizeof(VertexFormat)), buffer2, GL_DYNAMIC_READ); 

      //reset what we are bound to 
      glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 
     } 

     //delete our buffer 
     free(buffer2); 

     //Unmap our currently mapped buffer 
     glUnmapBuffer(GL_ARRAY_BUFFER); 

    return true; 
} 

unsigned int CVertexBuffer::AddVerts(const VERTEX_ANIMATED* pVerts, unsigned int iNumVerts) 
{ 
    //Save the location to copy to 
    unsigned int uiVertLocation = m_uiVertsUsed; 

    m_uiVertsUsed += iNumVerts; 

    if(m_uiVertsUsed > m_uiNumVerts) 
    { 
     IncreaseVerts(m_uiVertsUsed - m_uiNumVerts); 
    } 

    if(GLEW_ARB_vertex_program) 
    { 
     //bind the buffer we're gonna mess with 
     glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_uiVertBufferHandle); 

     //get the pointer position where we can add verts 
     void* pPositionBuffer = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE ); 

     //now copy into our memory spot 
     //which we need to move to the right position 
     memcpy(((char*)pPositionBuffer) + (uiVertLocation*sizeof(VertexFormat)), pVerts, iNumVerts*sizeof(VertexFormat)); 

     //now stop mapping 
     glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); 
    } 
    else 
    { 
     //bind the buffer we're gonna mess with 
     glBindBuffer(GL_ARRAY_BUFFER, m_uiVertBufferHandle); 

     //get the pointer position where we can add verts 
     void* pPositionBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); 

     //now copy into our memory spot 
     //which we need to move to the right position 
     memcpy(((char*)pPositionBuffer) + (uiVertLocation*sizeof(VertexFormat)), pVerts, iNumVerts*sizeof(VertexFormat)); 

     //now stop mapping 
     glUnmapBuffer(GL_ARRAY_BUFFER); 
    } 

    return uiVertLocation; 
} 

我假設我的錯誤來自於我如何初始化我的數據或如何將數據傳遞給着色器。

下面是一個簡單的調用我的着色器程序創建它需要在一個頂點着色器文件名,然後碎片着色器文件名稱爲希望如「位置,法線,texCoords」

被指定主要變量的變量
CreateProgram("animTriangle.vp", 
       "animTriangle.fp", 
       5, 
       VERTEX_ATTRIB, "vVertexPos", 
       NORMAL_ATTRIB, "vVertexNormal", 
       TEXTURE_COORD_ATTRIB0, "vTexCoord", 
       COLOR_ATTRIB, "vBlendWeights", 
       COLOR2_ATTRIB, "vBoneIndices"); 
在側

這個功能我做了參數解析已創建和編譯的着色器程序

//make sure to use our program to setup our handles 
glUseProgram(m_uiProgramHandle); 

//start from this parameter 
va_start(parseList, szFragmentShaderName); 

//read in number of variables if any 
uiNum = va_arg(parseList, unsigned); 

//for loop through our attribute pairs 
int enumType = 0; 
for(unsigned x = 0; x < uiNum; ++x) 
{ 
    //specify our attribute locations 
    enumType = va_arg(parseList, int); 
    char* name = va_arg(parseList, char*); 
    glBindAttribLocation(m_uiProgramHandle, enumType, name); 
} 

//end our list parsing 
va_end(parseList); 

這裏以後就是我的變量列表在我的頂點着色器的開始

in vec3 vVertexPos;  // position 
in vec3 vVertexNormal; // normal 
in vec2 vTexCoord;  // texture coordinate.... 
in vec4 vBlendWeights; // the weights pull of the related bone 
in ivec4 vBoneIndices; // the indicators of which bones we are influenced by 

這裏是我的頂點步幅

//set which vertices we will be using 
glBindBuffer(GL_ARRAY_BUFFER, m_uiVertBufferHandle); 

//enable these vertex attributes 
glEnableVertexAttribArray(VERTEX_ATTRIB); 
glEnableVertexAttribArray(NORMAL_ATTRIB); 
glEnableVertexAttribArray(TEXTURE_COORD_ATTRIB0); 
glEnableVertexAttribArray(COLOR_ATTRIB); 
glEnableVertexAttribArray(COLOR2_ATTRIB); 

//specify our vertex attribute 
glVertexAttribPointer(VERTEX_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(0)); 

//specify our normal attribute 
glVertexAttribPointer(NORMAL_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(12)); 

//specify our texture attribute 
glVertexAttribPointer(TEXTURE_COORD_ATTRIB0, 2, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(24)); 

//specify our bone weight attribute location 
glVertexAttribPointer(COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(32)); 

//specify our bone indice attribute location 
glVertexAttribPointer(COLOR2_ATTRIB, 4, GL_INT, GL_FALSE, sizeof(VERTEX_ANIMATED), BUFFER_OFFSET(48)); 

現在我可以加載靜態模型就好了。當我加載我的動畫模型時,我會看到模型的一半或模型的一半,而在那一半上缺少一些塊。之前我曾與DirectX一起工作過,當我正確地讀取緩衝區時,我只遇到過這個問題。

如果你們想要更多信息,請告訴我。我一直在這個奇怪的問題上差不多兩個星期,真的很想知道我的問題。

+0

你如何將骨骼矩陣傳遞給着色器? –

+0

在着色器中看起來像這樣 / uniform mat4 mAnimPose [40]; / 在在.cpp這是我如何將它傳遞 / glUniformMatrix4fv(glGetUniformLocation(pCurShader-> GetShaderProgramHandle(), 「mAnimPose」),pCurBones.size(),GL_FALSE,(浮子*)(&pCurBones [0]) ); / 但目前在着色器中,我不使用它們只是爲了測試模型的其餘部分,所以我基本上只設置矩陣乘以矩陣工作的模型視圖投影矩陣,因爲它是我在靜態模型中使用的矩陣着色器 –

+0

對不起,我對這個堆棧溢出評論代碼語法不太好X_X –

回答

3

看起來您可能已經忘記在您的代碼中初始化NORMAL_ATTRIB。您撥打CreateProgram (...)的電話不包括頂點着色器中的NORMAL_ATTRIBvVertexNormal的關聯。

如果您的頂點着色器需要用於動畫目的的頂點法線,並且您沒有將此頂點指針正確地連接到適當的屬性槽,則結果將是未定義的。

同樣,問題也可能是由於NORMAL_ATTRIB由於未初始化而導致您的另一個屬性出現混淆。例如,頂點屬性0通常是位置,如果在此代碼中未初始化NORMAL_ATTRIB,則可能會用正常指針重新定義頂點位置指針。

+0

我做了這一步,但我的問題,我認爲是我的boneIndices不正確我認爲這可能是我的頂點跨度。你介意看看這一個@Andon M. Coleman嗎?因爲我的骨頭在動畫中沒問題,但我似乎無法讓皮膚正確連接 –

0

我的整體問題原來是我的平局。我正在指定要繪製的原始三角形的數量,而不是隻是我的「三角形數量* 3」的索引數量。

這可以解釋爲什麼有些模型會顯示出來,但它會被分塊。