Reputation: 1449
I've recently found out that there is a library called "Assimp" for importing models that can be rendering animations in c++ opengl, and now I try to figure out what I have to do, in order to load a textured model and draw it...
1) What format is recommended to export animations from Blender?
2) I have a basic mesh class already, drawing a model. What would I need to modify to support animation?
My data struct:
struct ObjectData {
vector <glm::vec3> vertices, normals, colors;
vector <glm::vec2> texCoords;
vector <GLuint> vIndices, uIndices, nIndices;
vector <Material*> materials;
glm::vec3 size, center;
};
My mesh VBO and draw:
void Mesh::draw() {
if (initialized) {
shader->enable(true);
if (texture != NULL) {
texture->enable(true);
}
//Tell OpenGL which array to use
glBindVertexArray(arrayObject);
glDrawElements(renderMode, object->vIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(NULL);
shader->enable(false);
if (texture != NULL) {
texture->enable(false);
}
}
}
void Mesh::updateVBO() {
if (!initialized) {
glGenVertexArrays(1, &arrayObject);
}
//Tell OpenGL which vertex array to use from now
glBindVertexArray(arrayObject);
if (!initialized) {
glGenBuffers(VBO_COUNT, buffers);
initialized = true;
}
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_VERTEX]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * object->vertices.size(), &object->vertices.front(), GL_STATIC_DRAW);
//Set shader attribute data
glEnableVertexAttribArray(VBO_VERTEX);
glVertexAttribPointer(VBO_VERTEX, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
if (object->colors.size()) {
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_COLOR]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * object->colors.size(), &object->colors.front(), GL_STATIC_DRAW);
//Set shader attribute data
glEnableVertexAttribArray(VBO_COLOR);
glVertexAttribPointer(VBO_COLOR, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}
if (object->texCoords.size()) {
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_TEXCORD]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * object->texCoords.size(), &object->texCoords.front(), GL_STATIC_DRAW);
//Set shader attribute data
glEnableVertexAttribArray(VBO_TEXCORD);
glVertexAttribPointer(VBO_TEXCORD, 2, GL_FLOAT, GL_FALSE, NULL, NULL);
}
if (object->normals.size()) {
//Set buffer data
glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_NORMAL]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * object->normals.size(), &object->normals.front(), GL_STATIC_DRAW);
//Set shader attribute data
glEnableVertexAttribArray(VBO_NORMAL);
glVertexAttribPointer(VBO_NORMAL, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
}
//Set buffer data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[VBO_INDEX]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * object->vIndices.size(), &object->vIndices.front(), GL_STATIC_DRAW);
//Unbind vertex array
glBindVertexArray(NULL);
}
Upvotes: 0
Views: 4325
Reputation: 1598
The 'open asset import library' has a model viewer where you can preview the models with all aclaimed supported formats (including animations). I would suggest exporting your animations, to a variety of formats and see if any of them give you wrong results (i.e. render artifacts) and conclude your own awnser. Personally, I had the most success with Collada (.dae) although I used 3ds Max.
To support the animation itself (presumable skeletal): interpolate the animation data (aiNodeAnim) between the key-frames; you need to calculate the bone matrices from the interpolated animation data (create a matrix out of position/rotation etc); calculate the 'animated' vertices by transforming the 'vertices' (aiMesh/aiBone) with the bone matrices that influence them; weight all of the 'animated vertices' and sum them together; render the newly vertices. And this a basic high level overview of animations.
There are tutorials and books that can go deeper into the subject. For example ogldev's tutorial 38, Jason Gregory's Game Engine Architechture has dedicated animation chapter. You can take a look at the source code of assimps model viewer.
Upvotes: 5