2013-07-03 44 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”的索引数量。

这可以解释为什么有些模型会显示出来,但它会被分块。