2013-07-03 14 views
5

Ho lavorato con OpenGL per alcuni mesi e ora sto imparando tutto da solo. Ora ho ottenuto il rendering della posizione, modelli di coordinate textureProblema di skining GPU con GLSL

Sto provando a lavorare con modelli animati che eseguirò un processo di skinning dell'animazione sulla scheda grafica.

A proposito, se qualcuno vuole aiutarmi 1 su 1 fammi sapere che non mi dispiacerebbe un approccio ancora più diretto.

Ecco il mio formato del vertice

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

questo è come aggiungo i miei verts alla maniglia buffer di gpu (eventuali variabili non inizializzate a queste funzioni si trovano nel ".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; 
} 

Suppongo che il mio errore provenga da come sto inizializzando i miei dati o da come ho passato i miei dati allo shader.

Ecco una semplice chiamata alla mia creazione del programma di shader che ci vuole in un nome di file vertex shader e un nome di file frammento di shader poi una variabile per le variabili principali che vogliono essere specificato come "posizione, normali, texCoords"

CreateProgram("animTriangle.vp", 
       "animTriangle.fp", 
       5, 
       VERTEX_ATTRIB, "vVertexPos", 
       NORMAL_ATTRIB, "vVertexNormal", 
       TEXTURE_COORD_ATTRIB0, "vTexCoord", 
       COLOR_ATTRIB, "vBlendWeights", 
       COLOR2_ATTRIB, "vBoneIndices"); 

in parte questa funzione faccio un parametro di analisi, dopo aver creato e compilato il programma shader di

//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); 

ecco la mia lista di variabili, all'inizio della mia vertex shader

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 

qui è la mia vertice passo

//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)); 

ora posso caricare modelli statici bene. Quando carico i miei modelli animati mi piacciono metà modello o metà modello con alcuni pezzi mancanti in quella metà. Ho già lavorato con DirectX e mi sono imbattuto in questo problema solo quando la gpu stava leggendo correttamente i miei buffer.

Se volete ulteriori informazioni fatemi sapere. Sono stato su questo strano problema per quasi 2 settimane e mi piacerebbe davvero imparare il mio problema.

+0

Come stai passando le matrici ossee allo shader? –

+0

nello shader appare come questo / uniforme mat4 mAnimPose [40]; / nel cpp questo è come lo passo / glUniformMatrix4fv (glGetUniformLocation (pCurShader-> GetShaderProgramHandle(), "mAnimPose"), pCurBones.size(), GL_FALSE, (float *) (e pCurBones [0])); / ma attualmente nello shader non li uso solo per testare il resto del modello, quindi in pratica ho impostato i vertici da moltiplicare solo dalla matrice di proiezione della vista del modello che matrice funziona perché è quella che uso nel mio modello statico shader –

+0

scusa non mi va bene con questa sintassi del codice di commento stack over X_X –

risposta

3

Sembra che tu abbia dimenticato di inizializzare NORMAL_ATTRIB nel tuo codice. La chiamata a CreateProgram (...) non include un'associazione di NORMAL_ATTRIB con vVertexNormal nel vertex shader.

Se il vertex shader richiede il vertice normale per scopi di animazione e non si è collegato correttamente questo puntatore del vertice allo slot dell'attributo appropriato, i risultati non saranno definiti.

Allo stesso modo, il problema può anche essere dovuto a NORMAL_ATTRIB aliasing a un altro dei propri attributi a causa del fatto che non è inizializzato. Ad esempio, l'attributo 0 del vertice è in genere posizione, se si lascia NORMAL_ATTRIB non inizializzato in questo codice, si potrebbe ridefinire il puntatore di posizione del vertice con il puntatore normale.

+0

Faccio questo passo ma il mio problema è THINK è il mio boneIndices non sono corretto ho pensato che potrebbe essere stato il mio passo di vertice. ti dispiace guardando questo uno contro uno? Andon M. Coleman? perché le mie ossa stanno bene nell'animazione, ma non riesco a ottenere che la pelle si attacchi correttamente –

0

Il mio problema generale si è rivelato essere con la mia chiamata di estrazione. Stavo specificando il numero di triangoli primitivi da disegnare piuttosto che il numero di indici che sarebbe solo il mio "conteggio dei triangoli * 3".

Questo spiegherebbe perché alcuni dei modelli si sarebbero mostrati, ma sarebbero stati suddivisi.