2012-02-17 70 views
2

我目前正试图设置一个GPU皮肤(与glsl),但它不工作的方式,我会:)实际上它根本不工作。我的网消失的时候我尝试这个GLSL代码:Glsl皮肤障碍,谁可以跳呢?

layout(location = 0) in vec3 vertexPos; 
layout(location = 1) in vec2 vertexUv; 
layout(location = 2) in vec3 vertexNor; 
layout(location = 5) in ivec4 joints_influences; 
layout(location = 6) in vec4 weights_influences; 

uniform mat4 ViewProj, View, Proj, Model; 
out vec3  vertexPosEye; 
out vec3  vertexNorEye; 

const int  MAX_INFLUENCES = 4; 
const int  MAX_BONES = 50; 
uniform mat4 animation_matrices[MAX_BONES]; 
uniform mat4 inv_bind_matrices[MAX_BONES]; 

void main() 
{ 
    vertexPosEye = (View * Model * vec4(vertexPos, 1)).xyz;  // Position 
    vertexNorEye = (View * Model * vec4(vertexNor, 0)).xyz;  // Normal matrix 

    vec4 final_v = vec4(0, 0, 0, 0); 

    for (int i = 0; i < MAX_INFLUENCES; i++) 
    { 
     vec4 v =  vec4(vertexPos, 1) 
        * inv_bind_matrices[joints_influences[i]] 
        * animation_matrices[joints_influences[i]] 
        * weights_influences[i]; 

     final_v += v; 
    } 
    gl_Position = ViewProj * Model * final_v; 
} 

当我试试这个:

gl_Position = ViewProj * Model * vertexPos; 

我的网又回来了:)但没有动画了,当然......

这里是我的应用(C++)代码时,我设置VBO属性:

// Vertex position 
glGenBuffers(1, &buffer[0]); 
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); 
glBufferData(GL_ARRAY_BUFFER, vertices.pos.size() * sizeof(bVector3), &vertices.pos[0], GL_STATIC_DRAW); 

// Ibid for uv, normals, tangents and bitangents. 

// Skinning : joints index 
glGenBuffers(1, &buffer[5]); 
glBindBuffer(GL_ARRAY_BUFFER, buffer[5]); 
glBufferData(GL_ARRAY_BUFFER, vertices.joints.size() * sizeof(SkinningJoints), &vertices.joints[0], GL_STATIC_DRAW); 

// Skinning : weights 
glGenBuffers(1, &buffer[6]); 
glBindBuffer(GL_ARRAY_BUFFER, buffer[6]); 
glBufferData(GL_ARRAY_BUFFER, vertices.weights.size() * sizeof(SkinningWeights), &vertices.weights[0], GL_STATIC_DRAW); 

// Indices 
glGenBuffers(1, &buffer[7]); 
glBindBuffer(GL_ARRAY_BUFFER, buffer[7]); 
glBufferData(GL_ARRAY_BUFFER, vertices.indices.size() * sizeof(bUshort), &vertices.indices[0], GL_STATIC_DRAW); 

在主循环:

glEnableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(0)); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); 

glEnableVertexAttribArray(for uv, normals, tangents and bitangents)... 

glEnableVertexAttribArray(5); 
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(5)); 
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, 0, BUFFER_OFFSET(0)); 

glEnableVertexAttribArray(6); 
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(6)); 
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->GetBuffer(7)); 
glDrawElements(GL_TRIANGLES, m->vertices.indices.size(), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); 

这里是我的RenderingVertices结构(Barr的recomendations后):

struct RenderingVertices 
{ 
    // std::vector<Vec3> 
    vVec3      pos, nor, tang, btan; 
    vVec2      uv; 
    vUshort      indices; 

    vector<SkinningJoints>  joints; 
    vector<SkinningWeights>  weights; 
}; 

这里是我的SkinningJoints结构:

struct SkinningJoints 
{ 
    int   j[MAX_BONES_PER_VERT]; 

    SkinningJoints(Vertex::Weights weights[MAX_BONES_PER_VERT]) 
    { 
     for (bUint i = 0; i < MAX_BONES_PER_VERT; i++) 
      j[i] = weights[i].jid; 
    } 
}; 

我SkinningWeights结构几乎是一样的,与数组float而不是int。

现在,当我尝试调试关节指数,权重值和最终顶点颜色,这里是我得到:

// Shader 
color_debug = joints_influences; 

http://www.images-host.fr/view.php?img=00021800pop.jpg

color_debug = weights_influences; 

http://www.images-host.fr/view.php?img=00021800pop2.jpg

另一个有趣事情,当我尝试这个:

vec4 pop = vec4(vertexPos, 1) * animation_matrices[1] * inv_bind_matrices[1] * 1.0; 
gl_Position = ViewProj * Model * pop; 

我的所有网格实际上是旋转的,这意味着我的制服animation_matrices是好的。

任何人都可以看到我在这里做错了吗?

回答

2

您是否尝试调试皮肤属性?将顶点权重输出为颜色,以便确认您具有有意义的值?如果一切都是黑色的,你会知道去哪里看。

通过快速浏览RenderingVertices,我可以发现第一个问题。你正在向GL传递一个Vector指针,我不认为这是你想要做的。

大多数情况下,您会将蒙皮影响限制为每个顶点4个关节/重量配对。所以你可以用一个简单的数组(即SkinningJoints关节[4];)。

+0

这是我所得到的,当我把“在vec4 weights_influences布局(位置= 6);”作为颜色。 http://www.images-host.fr/view.php?img=17021756pop.jpg – 2012-02-17 16:57:15

4

我终于搞定了。对于那些谁可能有兴趣,这里是我做错了:

当我送关节指数阵列GLSL,而不是做这样的:

glEnableVertexAttribArray(5); 
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(5)); 
glVertexAttribPointer(5, 4, GL_INT, GL_FALSE, 0, BUFFER_OFFSET(0)); 

我需要做的是:

glEnableVertexAttribArray(5); 
glBindBuffer(GL_ARRAY_BUFFER, m->GetBuffer(5)); 
glVertexAttribIPointer(5, 4, GL_INT, 0, BUFFER_OFFSET(0)); 

你必须仔细观察以找出差异。我不需要调用glVertexAttribPointer(),而需要调用glVertexAttribIPointer(),因为关节索引是int

希望这会帮助别人一天。