Hi. I make a skeletal animation and for that i must to change vertices. I took code from internet and included it in my code. In the code i calculate bones and to make the model move i multiply bones by positions of vertices. All good, animation works. But for that i must to call “glBufferData” every frame. It’s wrong. But i can’t help it. If I put “glBufferData” somewhere else then model is not display. U can say “don’t do this, use shader”, and you’ll be right, but i can’t. My computer is old (openGL 3.2) and if i run this logic into shader i get error “Vertex shader(s) were not successfully compiled before glLinkProgram() was called. Link failed.”, so i do it in theCPU.
logic code
/*called in the constructor*/
void Mesh::setupMesh()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(PosNorm), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(PosNorm), (void*)offsetof(PosNorm, Norm));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(PosNorm),(void*)offsetof(PosNorm, Tex));
glBindVertexArray(0);
}
/*called in main while*/
void Mesh::Draw(Shader &shader, vector<mat4> bones)
{
for(int iter = 0; iter < indices.size(); iter++)
{
vec4 totalPosition = vec4(0.0f);
vec3 localNormal = vec3(0.0f);
for(int i = 0; i < MAX_BONE_INFLUENCE; i++)
{
auto boneId = vertices[iter].m_BoneIDs[i];
auto pos = vertices[iter].Position;
auto weights = vertices[iter].m_Weights;
auto norm = vertices[iter].Normal;
if(boneId == -1) continue;
if(boneId >= 100)
{
totalPosition = vec4(pos,1);
break;
}
vec4 localPosition = bones[boneId] * vec4(pos,1);
totalPosition += localPosition * vec4(weights[i]);
localNormal = mat3(bones[boneId]) * norm;
}
verts[iter].Pos = vec3(totalPosition);
verts[iter].Norm = localNormal;
}
glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(PosNorm), &verts[0], GL_STATIC_DRAW);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
/*vertex shader*/
#version 150 core
in vec3 pos;
in vec3 norm;
in vec2 tex;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
out vec2 TexCoords;
void main()
{
vec3 localNormal = norm;
gl_Position = projection * view * model * vec4(pos, 1);
TexCoords = tex;
}
Also, Draw method uses loop
for(int iter = 0; iter < indices.size(); iter++)
I guess it is not good but how to do it differently i don’t know.