qt opengl assimp 加载骨骼动画完整代码
时间: 2023-07-09 10:03:21 浏览: 49
以下是使用Qt、OpenGL和Assimp库加载骨骼动画的完整代码示例:
```cpp
#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QTimer>
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
GLWidget(QWidget *parent = nullptr)
: QOpenGLWidget(parent)
{
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(update()));
}
~GLWidget()
{
makeCurrent();
m_shaderProgram->release();
delete m_shaderProgram;
delete m_texture;
glDeleteBuffers(1, &m_vbo);
glDeleteVertexArrays(1, &m_vao);
doneCurrent();
}
protected:
void initializeGL() override
{
initializeOpenGLFunctions();
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
m_shaderProgram = new QOpenGLShaderProgram();
m_shaderProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertexShader.glsl");
m_shaderProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragmentShader.glsl");
m_shaderProgram->link();
m_shaderProgram->bind();
m_texture = new QOpenGLTexture(QImage(":/texture.png"));
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 8, nullptr, GL_DYNAMIC_DRAW);
GLuint positionLocation = m_shaderProgram->attributeLocation("position");
glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
GLuint normalLocation = m_shaderProgram->attributeLocation("normal");
glEnableVertexAttribArray(normalLocation);
glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
GLuint texCoordLocation = m_shaderProgram->attributeLocation("texCoord");
glEnableVertexAttribArray(texCoordLocation);
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
m_shaderProgram->setUniformValue("texture", 0);
m_timer->start(16);
}
void resizeGL(int w, int h) override
{
glViewport(0, 0, w, h);
}
void paintGL() override
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_shaderProgram->bind();
QMatrix4x4 projectionMatrix;
projectionMatrix.perspective(45.0f, width() / (float)height(), 0.1f, 100.0f);
m_shaderProgram->setUniformValue("projectionMatrix", projectionMatrix);
QMatrix4x4 viewMatrix;
viewMatrix.translate(0.0f, 0.0f, -3.0f);
viewMatrix.rotate(m_rotation);
m_shaderProgram->setUniformValue("viewMatrix", viewMatrix);
aiMatrix4x4 identityMatrix;
aiMatrix4x4_identity(&identityMatrix);
renderNode(m_scene->mRootNode, identityMatrix);
m_rotation += 0.5f;
m_shaderProgram->release();
}
void renderNode(aiNode *node, const aiMatrix4x4 &parentTransform)
{
aiMatrix4x4 transform = parentTransform * node->mTransformation;
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
aiMesh *mesh = m_scene->mMeshes[node->mMeshes[i]];
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * mesh->mNumVertices * 8, mesh->mVertices);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mesh->mNumVertices * 3, sizeof(GLfloat) * mesh->mNumVertices * 3, mesh->mNormals);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(GLfloat) * mesh->mNumVertices * 6, sizeof(GLfloat) * mesh->mNumVertices * 2, mesh->mTextureCoords[0]);
m_texture->bind();
for (unsigned int j = 0; j < mesh->mNumBones; ++j) {
aiBone *bone = mesh->mBones[j];
aiMatrix4x4 boneTransform = transform * bone->mOffsetMatrix;
m_shaderProgram->setUniformValue("boneTransforms[" + QString::number(j) + "]", QMatrix4x4(
boneTransform.a1, boneTransform.b1, boneTransform.c1, boneTransform.d1,
boneTransform.a2, boneTransform.b2, boneTransform.c2, boneTransform.d2,
boneTransform.a3, boneTransform.b3, boneTransform.c3, boneTransform.d3,
boneTransform.a4, boneTransform.b4, boneTransform.c4, boneTransform.d4
));
}
glDrawArrays(GL_TRIANGLES, 0, mesh->mNumVertices);
}
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
renderNode(node->mChildren[i], transform);
}
}
private:
QTimer *m_timer;
QOpenGLShaderProgram *m_shaderProgram;
QOpenGLTexture *m_texture;
GLuint m_vbo;
GLuint m_vao;
float m_rotation = 0.0f;
Assimp::Importer m_importer;
const aiScene *m_scene = nullptr;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GLWidget w;
w.show();
w.makeCurrent();
w.m_scene = w.m_importer.ReadFile(":/model.dae", aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_FlipUVs | aiProcess_LimitBoneWeights);
w.doneCurrent();
return a.exec();
}
```
需要注意的是,这里使用了Assimp库来加载模型和骨骼动画,因此需要在项目中包含Assimp的头文件和库文件,并且需要在.pro文件中添加以下内容:
```
INCLUDEPATH += /path/to/assimp/include
LIBS += -L/path/to/assimp/lib -lassimp
```
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)