Dynamic change of buffer data

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.

have a closer look at

glGetShaderInfoLog()

shaderinfolog

1 Like