QT15的opengl和Dx12是什么关系

时间: 2023-12-24 16:10:19 浏览: 25
QT15是一个基于Qt框架的图形用户界面设计工具,而OpenGL和DirectX 12是两种不同的图形API(应用程序接口)。它们都可以用来实现高性能的图形渲染和计算,但是它们的底层架构和工作方式有所不同。 OpenGL是一种跨平台的图形API,可以在多种操作系统和硬件设备上使用。而DirectX 12是微软开发的一种专为Windows平台设计的图形API,主要用于游戏和娱乐应用程序。 在QT15中,OpenGL和DirectX 12可以作为渲染引擎的选择之一,开发人员可以根据具体需求选择使用哪种API来实现图形渲染和计算。因此,它们之间的关系是选择关系,而不是竞争关系。
相关问题

qt opengl assimp 加载骨骼动画完整代码

这里是一个简单的使用Qt、OpenGL和Assimp库加载带有骨骼动画的模型的示例代码: ```cpp #include <QOpenGLFunctions> #include <QOpenGLWidget> #include <QOpenGLShaderProgram> #include <QOpenGLBuffer> #include <QOpenGLTexture> #include <QMouseEvent> #include <QWheelEvent> #include <assimp/Importer.hpp> #include <assimp/scene.h> #include <assimp/postprocess.h> class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions { public: GLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) { setFocusPolicy(Qt::StrongFocus); } ~GLWidget() { makeCurrent(); m_shaderProgram.release(); m_vbo.destroy(); m_ibo.destroy(); m_vao.destroy(); doneCurrent(); } protected: void initializeGL() override { initializeOpenGLFunctions(); m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vertex.glsl"); m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fragment.glsl"); m_shaderProgram.link(); loadModel(":/models/model.dae"); glEnable(GL_DEPTH_TEST); glClearColor(0.2f, 0.2f, 0.2f, 1.0f); } void resizeGL(int width, int height) override { glViewport(0, 0, width, height); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_shaderProgram.bind(); m_shaderProgram.setUniformValue("mvpMatrix", m_projMatrix * m_cameraMatrix * m_modelMatrix); m_vao.bind(); glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, nullptr); m_vao.release(); } void mousePressEvent(QMouseEvent *event) override { m_lastPos = event->pos(); } void mouseMoveEvent(QMouseEvent *event) override { if (event->buttons() & Qt::LeftButton) { int dx = event->x() - m_lastPos.x(); int dy = event->y() - m_lastPos.y(); m_cameraYaw += dx * 0.01f; m_cameraPitch += dy * 0.01f; if (m_cameraPitch > 1.5f) m_cameraPitch = 1.5f; else if (m_cameraPitch < -1.5f) m_cameraPitch = -1.5f; updateCameraMatrix(); m_lastPos = event->pos(); update(); } } void wheelEvent(QWheelEvent *event) override { m_cameraDistance -= event->delta() * 0.01f; if (m_cameraDistance < 0.1f) m_cameraDistance = 0.1f; updateCameraMatrix(); update(); } private: void loadModel(const QString &filePath) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(filePath.toStdString(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_LimitBoneWeights); if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { qDebug() << "Error: " << importer.GetErrorString(); return; } m_boneMatrices.resize(scene->mNumMeshes); aiMatrix4x4 globalTransform = scene->mRootNode->mTransformation; globalTransform.Inverse(); loadNode(scene->mRootNode, scene, globalTransform); m_vao.create(); m_vao.bind(); m_vbo.create(); m_vbo.bind(); m_vbo.allocate(m_vertices.data(), m_vertices.size() * sizeof(Vertex)); m_shaderProgram.enableAttributeArray("position"); m_shaderProgram.setAttributeBuffer("position", GL_FLOAT, offsetof(Vertex, position), 3, sizeof(Vertex)); m_shaderProgram.enableAttributeArray("normal"); m_shaderProgram.setAttributeBuffer("normal", GL_FLOAT, offsetof(Vertex, normal), 3, sizeof(Vertex)); m_shaderProgram.enableAttributeArray("texcoord"); m_shaderProgram.setAttributeBuffer("texcoord", GL_FLOAT, offsetof(Vertex, texcoord), 2, sizeof(Vertex)); m_shaderProgram.enableAttributeArray("boneIndices"); m_shaderProgram.setAttributeBuffer("boneIndices", GL_FLOAT, offsetof(Vertex, boneIndices), 4, sizeof(Vertex)); m_shaderProgram.enableAttributeArray("boneWeights"); m_shaderProgram.setAttributeBuffer("boneWeights", GL_FLOAT, offsetof(Vertex, boneWeights), 4, sizeof(Vertex)); m_ibo.create(); m_ibo.bind(); m_ibo.allocate(m_indices.data(), m_indices.size() * sizeof(unsigned int)); m_vao.release(); } void loadNode(aiNode *node, const aiScene *scene, const aiMatrix4x4 &parentTransform) { aiMatrix4x4 transform = parentTransform * node->mTransformation; for (unsigned int i = 0; i < node->mNumMeshes; ++i) { aiMesh *mesh = scene->mMeshes[node->mMeshes[i]]; for (unsigned int j = 0; j < mesh->mNumBones; ++j) { aiBone *bone = mesh->mBones[j]; QString boneName = QString::fromStdString(bone->mName.C_Str()); if (m_boneMapping.find(boneName) == m_boneMapping.end()) { int boneIndex = m_boneMapping.size(); m_boneMapping[boneName] = boneIndex; m_boneInfo.push_back(BoneInfo{transform * bone->mOffsetMatrix, QMatrix4x4()}); } } for (unsigned int j = 0; j < mesh->mNumFaces; ++j) { aiFace &face = mesh->mFaces[j]; for (unsigned int k = 0; k < face.mNumIndices; ++k) m_indices.push_back(face.mIndices[k]); } for (unsigned int j = 0; j < mesh->mNumVertices; ++j) { Vertex vertex; vertex.position = QVector3D(mesh->mVertices[j].x, mesh->mVertices[j].y, mesh->mVertices[j].z); vertex.normal = QVector3D(mesh->mNormals[j].x, mesh->mNormals[j].y, mesh->mNormals[j].z); if (mesh->mTextureCoords[0]) { vertex.texcoord = QVector2D(mesh->mTextureCoords[0][j].x, mesh->mTextureCoords[0][j].y); } else { vertex.texcoord = QVector2D(0.0f, 0.0f); } for (unsigned int k = 0; k < 4; ++k) { vertex.boneIndices[k] = -1; vertex.boneWeights[k] = 0.0f; } for (unsigned int k = 0; k < mesh->mNumBones; ++k) { aiBone *bone = mesh->mBones[k]; QString boneName = QString::fromStdString(bone->mName.C_Str()); if (m_boneMapping.find(boneName) != m_boneMapping.end()) { int boneIndex = m_boneMapping[boneName]; vertex.boneIndices[k] = boneIndex; vertex.boneWeights[k] = bone->mWeights[j].mWeight; } } m_vertices.push_back(vertex); } } for (unsigned int i = 0; i < node->mNumChildren; ++i) { loadNode(node->mChildren[i], scene, transform); } } void updateBoneMatrices(aiNode *node, const QMatrix4x4 &parentMatrix) { QString nodeName = QString::fromStdString(node->mName.C_Str()); if (m_boneMapping.find(nodeName) != m_boneMapping.end()) { int boneIndex = m_boneMapping[nodeName]; m_boneInfo[boneIndex].finalTransform = parentMatrix * m_boneInfo[boneIndex].offsetMatrix * m_boneInfo[boneIndex].boneTransform; m_boneMatrices[boneIndex] = m_boneInfo[boneIndex].finalTransform * m_boneInfo[boneIndex].boneOffset; } QMatrix4x4 transform; transform(0, 0) = node->mTransformation.a1; transform(1, 0) = node->mTransformation.a2; transform(2, 0) = node->mTransformation.a3; transform(3, 0) = node->mTransformation.a4; transform(0, 1) = node->mTransformation.b1; transform(1, 1) = node->mTransformation.b2; transform(2, 1) = node->mTransformation.b3; transform(3, 1) = node->mTransformation.b4; transform(0, 2) = node->mTransformation.c1; transform(1, 2) = node->mTransformation.c2; transform(2, 2) = node->mTransformation.c3; transform(3, 2) = node->mTransformation.c4; transform(0, 3) = node->mTransformation.d1; transform(1, 3) = node->mTransformation.d2; transform(2, 3) = node->mTransformation.d3; transform(3, 3) = node->mTransformation.d4; QMatrix4x4 combinedTransform = parentMatrix * transform; for (unsigned int i = 0; i < node->mNumChildren; ++i) { updateBoneMatrices(node->mChildren[i], combinedTransform); } } void updateCameraMatrix() { m_cameraMatrix.setToIdentity(); m_cameraMatrix.translate(0.0f, 0.0f, -m_cameraDistance); m_cameraMatrix.rotate(m_cameraPitch, QVector3D(1.0f, 0.0f, 0.0f)); m_cameraMatrix.rotate(m_cameraYaw, QVector3D(0.0f, 1.0f, 0.0f)); } void updateAnimation(float deltaTime) { m_animationTime += deltaTime; if (m_animationTime > m_animationDuration) m_animationTime -= m_animationDuration; aiMatrix4x4 identity; identity.SetIdentity(); updateBoneMatrices(m_scene->mRootNode, identity); for (int i = 0; i < m_boneMatrices.size(); ++i) { m_shaderProgram.setUniformValue(QString("boneMatrices[%1]").arg(i), m_boneMatrices[i]); } } QOpenGLShaderProgram m_shaderProgram; QOpenGLBuffer m_vbo; QOpenGLBuffer m_ibo; QOpenGLVertexArrayObject m_vao; QVector<Vertex> m_vertices; QVector<unsigned int> m_indices; QMap<QString, int> m_boneMapping; QVector<BoneInfo> m_boneInfo; QVector<QMatrix4x4> m_boneMatrices; const aiScene *m_scene = nullptr; float m_animationTime = 0.0f; float m_animationDuration = 0.0f; float m_cameraYaw = 0.0f; float m_cameraPitch = 0.0f; float m_cameraDistance = 5.0f; QVector3D m_cameraPosition; QMatrix4x4 m_cameraMatrix; QMatrix4x4 m_modelMatrix; QMatrix4x4 m_projMatrix; QPoint m_lastPos; struct Vertex { QVector3D position; QVector3D normal; QVector2D texcoord; QVector4D boneIndices; QVector4D boneWeights; }; struct BoneInfo { aiMatrix4x4 offsetMatrix; QMatrix4x4 boneTransform; QMatrix4x4 finalTransform; QMatrix4x4 boneOffset; }; }; ``` 其中,`loadModel`函数用于加载模型,`loadNode`函数用于递归加载节点和骨骼信息,`updateBoneMatrices`函数用于更新骨骼变换矩阵,`updateAnimation`函数用于更新动画播放进度和骨骼变换矩阵,`updateCameraMatrix`函数用于更新摄像机变换矩阵。在`initializeGL`函数中调用`loadModel`函数进行模型加载,在`paintGL`函数中进行渲染。 需要注意的是,这里使用了Assimp库来加载带有骨骼动画的模型,并且使用了Qt的OpenGL相关类来进行渲染。如果要使用这段代码,请确保已经正确安装了Qt和Assimp库,并且已经将模型文件和着色器文件添加到了项目中。

已知相机旋转为(rx,ry,rz),Qt中不使用opengl如何实现鼠标移动控制模型旋转功能

要实现鼠标移动控制模型旋转功能,需要通过计算出旋转矩阵,来更新模型矩阵。 首先,需要根据鼠标移动的距离计算出旋转角度,可以使用以下代码: ```C++ float dx = mouseCurrentX - mousePreviousX; float dy = mouseCurrentY - mousePreviousY; float angleX = dx / windowWidth * 2; float angleY = dy / windowHeight * 2; ``` 其中,mouseCurrentX和mouseCurrentY是当前鼠标的位置,mousePreviousX和mousePreviousY是上一次鼠标的位置,windowWidth和windowHeight是窗口的宽度和高度。 接下来,需要根据相机的旋转角度和计算出的旋转角度,计算出新的旋转角度。可以使用以下代码: ```C++ float newRx = rx + angleX; float newRy = ry + angleY; float newRz = rz; ``` 最后,将新的旋转角度赋值给相机的旋转角度即可: ```C++ rx = newRx; ry = newRy; rz = newRz; ``` 这样,模型的旋转角度也会随着相机的旋转而改变。如果需要将旋转角度应用到模型矩阵上,可以使用以下代码: ```C++ QMatrix4x4 modelMatrix; modelMatrix.setToIdentity(); modelMatrix.translate(0, 0, -distance); modelMatrix.rotate(rx, 1, 0, 0); modelMatrix.rotate(ry, 0, 1, 0); modelMatrix.rotate(rz, 0, 0, 1); modelMatrix.translate(-centerX, -centerY, -centerZ); ``` 其中,distance是相机到模型的距离,centerX、centerY、centerZ是模型的中心点坐标。

相关推荐

最新推荐

recommend-type

Qt+OpenGL教程_for_Qt_4.5.3

很早以前网上找来的,感谢作者的整理。很好的OpenGl for Qt教程,而且很系统
recommend-type

Qt实现FTP的上传和下载的实例代码

本篇文章主要介绍了Qt实现FTP的上传和下载的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
recommend-type

Qt5开发环境下载和安装

Qt是跨平台的图形开发库,目前由Digia全资子公司 Qt Company 独立运营,官方网址: http://www.qt.io/ 也可以访问Qt项目域名:http://qt-project.org/ Qt4和Qt5下载文件详解和安装步骤详解
recommend-type

WIndows下超详细的QtMqtt编译配置教程

WIndows下超详细的QtMqtt编译配置教程,包含了QtMqtt源码下载、编译配置、QtMqtt帮助手册生成配置。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

list根据id查询pid 然后依次获取到所有的子节点数据

可以使用递归的方式来实现根据id查询pid并获取所有子节点数据。具体实现可以参考以下代码: ``` def get_children_nodes(nodes, parent_id): children = [] for node in nodes: if node['pid'] == parent_id: node['children'] = get_children_nodes(nodes, node['id']) children.append(node) return children # 测试数
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。
recommend-type

"互动学习:行动中的多样性与论文攻读经历"

多样性她- 事实上SCI NCES你的时间表ECOLEDO C Tora SC和NCESPOUR l’Ingén学习互动,互动学习以行动为中心的强化学习学会互动,互动学习,以行动为中心的强化学习计算机科学博士论文于2021年9月28日在Villeneuve d'Asq公开支持马修·瑟林评审团主席法布里斯·勒菲弗尔阿维尼翁大学教授论文指导奥利维尔·皮耶昆谷歌研究教授:智囊团论文联合主任菲利普·普雷教授,大学。里尔/CRISTAL/因里亚报告员奥利维耶·西格德索邦大学报告员卢多维奇·德诺耶教授,Facebook /索邦大学审查员越南圣迈IMT Atlantic高级讲师邀请弗洛里安·斯特鲁布博士,Deepmind对于那些及时看到自己错误的人...3谢谢你首先,我要感谢我的两位博士生导师Olivier和Philippe。奥利维尔,"站在巨人的肩膀上"这句话对你来说完全有意义了。从科学上讲,你知道在这篇论文的(许多)错误中,你是我可以依