2013-07-03 9 views
5

Pracowałem z OpenGL przez kilka miesięcy, ucząc się wszystkiego od nowa. Teraz mam do renderowania pozycji, modele współrzędnych teksturyProblem z skórowaniem GPU za pomocą GLSL

Próbuję pracować z animowanymi modelami, które zrobię proces skórki animacji na karcie graficznej.

Przy okazji, jeśli ktoś chce mi pomóc 1 na 1, daj mi znać, nie miałbym nic przeciwko jeszcze bardziej bezpośredniemu podejściu.

Oto moja Format wierzchołek

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

to jak mogę dodać moje Verts do uchwytu bufora GPU (dowolny zmienne niezainicjalizowane w tych funkcjach znajdują się w ".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; 
} 

Zakładam, że mój błąd wynika z tego, jak inicjuję moje dane lub jak przekazuję moje dane do modułu cieniującego.

Oto prosty wezwanie do mojego stworzenia programu shaderów trwa w nazwie pliku vertex shader i nazwa pliku fragment shader następnie zmienna dla głównych zmiennych, które chcą być określone takie jak „Pozycja, normalne, texCoords”

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

w bok to funkcja robię analizowania parametrów po utworzeniu i skompilowane programowi Shader

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

oto moja lista zmiennych na początku mojego 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 

tutaj jest mój wierzchołek krok

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

teraz mogę załadować modele statyczne dobrze. Kiedy ładuję moje animowane modele, dostaję się jak połowa modelu lub połowa modelu z brakującymi częściami na tej połowie. Pracowałem wcześniej z DirectX i tylko natknąłem się na ten problem, kiedy gpu prawidłowo odczytało moje bufory.

Jeśli chcieliby Państwo uzyskać więcej informacji, daj mi znać. Byłem w tym dziwnym problemie przez prawie 2 tygodnie i bardzo chciałbym nauczyć się mojego problemu.

+0

Jak przekazujesz matryce kostne do modułu cieniującego? –

+0

w module cieniującym wygląda to tak: / /uniform mat4 mAnimPose [40]; / w .cpp ten sposób przekazać go / glUniformMatrix4fv (glGetUniformLocation (pCurShader-> GetShaderProgramHandle() "mAnimPose") pCurBones.size() GL_FALSE (pływak *) (i pCurBones [0])); / ale obecnie w module cieniującym nie używam ich tylko po to, aby przetestować resztę modelu, więc w zasadzie ustawię mnożniki, aby były mnożone tylko przez matrycę rzutowania widoku modelu, którą to macierz działa, ponieważ jest tą, której używam w moim modelu statycznym shader –

+0

Przepraszam, nie jestem dobra z tą składową kodu komentarza X_X –

Odpowiedz

3

Wygląda na to, że mógł zapomnieć zainicjować kod NORMAL_ATTRIB. Twój telefon do CreateProgram (...) nie zawiera powiązania z NORMAL_ATTRIB z vVertexNormal w twoim werteksie cieniującym.

Jeśli twój moduł do cieniowania wierzchołków wymaga normalnego wierzchołka dla celów animacji i nie podłączyłeś poprawnie tego wskaźnika do odpowiedniego przedziału atrybutów, wyniki będą niezdefiniowane.

Problem może również wynikać z aliasingu do innego atrybutu z powodu pozostawienia go niezainicjowanego. Na przykład atrybut wierzchołka 0 jest zwykle pozycją, jeśli pozostawisz niezainicjowany w tym kodzie NORMAL_ATTRIB, możesz ponownie zdefiniować wskaźnik pozycji wierzchołka za pomocą normalnego wskaźnika.

+0

Zrobiłem ten krok, ale mój problem i myślę, że to moja kość. Nie są właściwe. Pomyślałem, że to był mój krok w vertexie. Czy masz ochotę spojrzeć na to jedno na jedno @Andon M. Coleman? ponieważ moje kości są w porządku w obrębie animacji, ale nie mogę sprawić, że skóra odpowiednio się do niej przyczepi –

0

Mój ogólny problem okazał się być z moim wezwaniem do losowania. Określiłem liczbę rysowanych prymitywnych trójkątów, a nie liczbę wskaźników, które byłyby po prostu moją "liczbą trójkątów * 3".

To wyjaśniałoby, dlaczego niektóre modele pojawiałyby się, ale byłyby porąbane.

Powiązane problemy