qt-OPENGL-星系仿真

qt-OPENGL-星系仿真

  • 一、演示效果
  • 二、核心程序
  • 三、下载链接


一、演示效果

在这里插入图片描述

二、核心程序

#include "model.h"Model::Model(QOpenGLWidget *_glWidget)
{   glWidget = _glWidget;glWidget->makeCurrent();initializeOpenGLFunctions();
}Model::~Model()
{destroyVBOs();
}void Model::destroyVBOs()
{glDeleteBuffers(1, &vboVertices);glDeleteBuffers(1, &vboIndices);glDeleteBuffers(1, &vboNormals);glDeleteBuffers(1, &vboTexCoords);glDeleteBuffers(1, &vboTangents);glDeleteVertexArrays(1, &vao);vboVertices = 0;vboIndices = 0;vboNormals = 0;vboTexCoords = 0;vboTangents = 0;vao = 0;
}void Model::createVBOs()
{glWidget->makeCurrent();destroyVBOs();glGenVertexArrays(1, &vao);glBindVertexArray(vao);glGenBuffers(1, &vboVertices);glBindBuffer(GL_ARRAY_BUFFER, vboVertices);glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(QVector4D), vertices.get(), GL_STATIC_DRAW);glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, nullptr);glEnableVertexAttribArray(0);vertices.reset();glGenBuffers(1, &vboNormals);glBindBuffer(GL_ARRAY_BUFFER, vboNormals);glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(QVector3D), normals.get(), GL_STATIC_DRAW);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);glEnableVertexAttribArray(1);normals.reset();glGenBuffers(1, &vboTexCoords);glBindBuffer(GL_ARRAY_BUFFER, vboTexCoords);glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(QVector2D), texCoords.get(), GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vboTexCoords);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr);glEnableVertexAttribArray(2);texCoords.reset();glGenBuffers(1, &vboTangents);glBindBuffer(GL_ARRAY_BUFFER, vboTangents);glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(QVector4D), tangents.get(), GL_STATIC_DRAW);glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 0, nullptr);glEnableVertexAttribArray(3);tangents.reset();glGenBuffers(1, &vboIndices);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices);glBufferData(GL_ELEMENT_ARRAY_BUFFER, numFaces * 3 * sizeof(unsigned int), indices.get(), GL_STATIC_DRAW);indices.reset();
}void Model::drawModel()
{float fixedAngle = -90.0f;modelMatrix.setToIdentity();modelMatrix.translate(position);modelMatrix.rotate(angle, 0.0, 1.0, 0.0);modelMatrix.rotate(fixedAngle, 1.0, 0.0, 0.0);modelMatrix.scale(invDiag * scale, invDiag * scale, invDiag*scale);modelMatrix.translate(-midPoint);GLuint locModel = 0;GLuint locNormalMatrix = 0;GLuint locShininess = 0;locModel = glGetUniformLocation(shaderProgram, "model");locNormalMatrix = glGetUniformLocation(shaderProgram, "normalMatrix");locShininess = glGetUniformLocation(shaderProgram, "shininess");glBindVertexArray(vao);// GL_CHECK(glUseProgram(shaderProgram[shaderIndex]));glUniformMatrix4fv(locModel, 1, GL_FALSE, modelMatrix.data());glUniformMatrix3fv(locNormalMatrix, 1, GL_FALSE, modelMatrix.normalMatrix().data());glUniform1f(locShininess, static_cast<GLfloat>(material.shininess));if (textureID){GLuint locColorTexture = 0;locColorTexture = glGetUniformLocation(shaderProgram, "colorTexture");glUniform1i(locColorTexture, 0);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, textureID);}glDrawElements(GL_TRIANGLES, numFaces * 3, GL_UNSIGNED_INT, 0);
}void Model::readOFFFile(QString const &fileName)
{std::ifstream stream;stream.open(fileName.toUtf8(),std::ifstream::in);if (!stream.is_open()){qWarning("Cannot open file.");return;}std::string line;stream >> line;stream >> numVertices >> numFaces >> line;// http://en.cppreference.com/w/cpp/memory/unique_ptr/make_uniquevertices = std::make_unique<QVector4D[]>(numVertices);indices = std::make_unique<unsigned int[]>(numFaces * 3);if (numVertices > 0){float minLim = std::numeric_limits<float>::lowest();float maxLim = std::numeric_limits<float>::max();QVector4D max(minLim, minLim, minLim, 1.0);QVector4D min(maxLim, maxLim, maxLim, 1.0);for (unsigned int i = 0; i < numVertices; ++i){float x, y, z;stream >> x >> y >> z;max.setX(std::max(max.x(), x));max.setY(std::max(max.y(), y));max.setZ(std::max(max.z(), z));min.setX(std::min(min.x(), x));min.setY(std::min(min.y(), y));min.setZ(std::min(min.z(), z));vertices[i] = QVector4D(x, y, z, 1.0);}midPoint = QVector3D((min + max) * 0.5);invDiag = 1 / (max - min).length();}for (unsigned int i = 0; i < numFaces; ++i){unsigned int a, b, c;stream >> line >> a >> b >> c;indices[i * 3 + 0] = a;indices[i * 3 + 1] = b;indices[i * 3 + 2] = c;}stream.close();createNormals();createTexCoords();createTangents();createVBOs();
}void Model::createNormals()
{normals = std::make_unique<QVector3D[]>(numVertices);for (unsigned int i = 0; i < numFaces; ++i){QVector3D a = QVector3D(vertices[indices[i * 3 + 0]]);QVector3D b = QVector3D(vertices[indices[i * 3 + 1]]);QVector3D c = QVector3D(vertices[indices[i * 3 + 2]]);QVector3D faceNormal = QVector3D::crossProduct((b - a), (c - b));// Accumulates face normals on the verticesnormals[indices[i * 3 + 0]] += faceNormal;normals[indices[i * 3 + 1]] += faceNormal;normals[indices[i * 3 + 2]] += faceNormal;}for (unsigned int i = 0; i < numVertices; ++i){normals[i].normalize();}
}void Model::createTexCoords()
{texCoords = std::make_unique<QVector2D[]>(numVertices);// Compute minimum and maximum valuesauto minz = std::numeric_limits<float>::max();auto maxz = std::numeric_limits<float>::lowest();for (unsigned int i = 0; i < numVertices; ++i){minz = std::min(vertices[i].z(), minz);maxz = std::max(vertices[i].z(), maxz);}for (unsigned int i = 0; i < numVertices; ++i){auto s = (std::atan2(vertices[i].y(), vertices[i].x()) + M_PI) / (2 * M_PI);auto t = 1.0f - (vertices[i].z() - minz) / (maxz - minz);texCoords[i] = QVector2D(s, t);}
}void Model::loadTexture(const QImage &image)
{if (textureID){glDeleteTextures(1, &textureID);}glGenTextures(1, &textureID);glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glGenerateMipmap(GL_TEXTURE_2D);
}void Model::createTangents()
{tangents = std::make_unique<QVector4D[]>(numVertices);std::unique_ptr<QVector3D[]> bitangents;bitangents = std::make_unique<QVector3D[]>(numVertices);for (unsigned int i = 0; i < numFaces ; ++i){unsigned int i1 = indices[i * 3 + 0];unsigned int i2 = indices[i * 3 + 1];unsigned int i3 = indices[i * 3 + 2];QVector3D E = vertices[i1].toVector3D();QVector3D F = vertices[i2].toVector3D();QVector3D G = vertices[i3].toVector3D();QVector2D stE = texCoords[i1];QVector2D stF = texCoords[i2];QVector2D stG = texCoords[i3];QVector3D P = F - E;QVector3D Q = G - E;QVector2D st1 = stF - stE;QVector2D st2 = stG - stE;QMatrix2x2 M;M(0, 0) =  st2.y();M(0, 1) = -st1.y();M(1, 0) = -st2.x();M(1, 1) =  st1.x();M *= (1.0 / (st1.x() * st2.y() - st2.x() * st1.y()));QVector4D T = QVector4D (M(0, 0) * P.x() + M(0, 1) * Q.x(),M(0, 0) * P.y() + M(0, 1) * Q.y(),M(0, 0) * P.z() + M(0, 1) * Q.z(), 0.0);QVector3D B = QVector3D (M(1, 0) * P.x() + M(1, 1) * Q.x(),M(1, 0) * P.y() + M(1, 1) * Q.y(),M(1, 0) * P.z() + M(1, 1) * Q.z());tangents[i1] += T;tangents[i2] += T;tangents[i3] += T;bitangents[i1] += B;bitangents[i2] += B;bitangents[i3] += B;}for (unsigned int i = 0; i < numVertices; ++i){const QVector3D &n = normals[i];const QVector4D &t = tangents[i];tangents[i] = (t - n * QVector3D::dotProduct(n, t.toVector3D())).normalized();QVector3D b = QVector3D::crossProduct(n, t.toVector3D());double hand = QVector3D::dotProduct(b, bitangents[i]);tangents[i].setW((hand < 0.0) ? -1.0 : 1.0);}
}

三、下载链接

https://download.csdn.net/download/u013083044/88861312。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/484739.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink双流(join)

一、介绍 Join大体分类只有两种&#xff1a;Window Join和Interval Join Window Join有可以根据Window的类型细分出3种&#xff1a;Tumbling(滚动) Window Join、Sliding(滑动) Window Join、Session(会话) Widnow Join。 &#x1f338;Window 类型的join都是利用window的机制…

SpringIOC之support模块StaticApplicationContext

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

数据库事物复习

事务 比如说将张三的银行账户拿出一千给李四&#xff0c;首先需要查询张三的账户余额&#xff0c;扣除1000&#xff0c;然后如果给李四加上1000的过程中出现异常会回滚事务&#xff0c;临时修改的数据会回复回去。 -- 1. 查询张三账户余额 select * from account where name …

Leetcode535(设计短网址)

例题&#xff1a; https://leetcode.cn/problems/encode-and-decode-tinyurl/description/ 分析&#xff1a; 题目要求可以将一个长网址变成一个短网址&#xff08;encode&#xff09;&#xff0c;也可以通过短网址找到原来的长网址&#xff0c;我们可以使用两个hashMap集合来实…

Flutter插件开发指南01: 通道Channel的编写与实现

Flutter插件开发指南01: 通道Channel的编写与实现 视频 https://www.bilibili.com/video/BV1ih4y1E7E3/ 前言 本文将会通过一个加法计算&#xff0c;来实现 Channel 的双向通讯&#xff0c;让大家有个一个体会。 Flutter插件 Flutter插件是Flutter应用程序与原生平台之间的桥…

【Vuforia+Unity】AR05-实物3D模型识别功能实现

对于3D物体的识别&#xff0c;可以是虚拟的也可以是实物的&#xff0c;但是对于虚拟的三维模型意义不大&#xff0c;我们完全可以把三维模型放在屏幕上截一张图&#xff0c;以图片识别的方式召唤数字内容&#xff0c;不过在虚拟现实中或许有用。 因此本文探讨的技术路线主要是…

新疆营盘古城及古墓群安防舱体实施方案

3 总体布局 3.1设计原则 3.1.1执行有效的国家标准、国家军用标准和行业标准&#xff1b; 3.1.2满足指标要求&#xff1b; 3.1.3采用通用化、模块化设计&#xff0c;提高设备可维修性&#xff1b; 3.1.4采用人机工程学知识进行设计&#xff0c;充分考虑安全性。 3.2 总体…

Flutter 3.19.0 版本新特性

其实在每个版本的更新中呢&#xff0c;都会合并很多很多的这个合并请求、还有开发建议&#xff0c;那么本版本的也不例外&#xff0c;社区官方发布的公告是合并了168个社区成员的1429个拉请求。 当然&#xff0c;如果你的时间允许的话&#xff0c;你可以去查看一下这些请求&am…

算法-搜索二维矩阵 II

1、题目来源 240. 搜索二维矩阵 II - 力扣&#xff08;LeetCode&#xff09; 2、题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#x…

【力扣hot100】刷题笔记Day9

前言 阴天睡得还挺舒服&#xff0c;9点半才醒&#xff0c;用刷题开启美好新一天&#xff01; 141. 环形链表 - 力扣&#xff08;LeetCode&#xff09; 哈希表 class Solution:def hasCycle(self, head: Optional[ListNode]) -> bool:seen set() # 哈希集合# seen {} #…

【Java 面试题】MySQL与Redis 如何保证双写一致性

目录 方案一:延时双删方案二: 删除缓存重试机制方案三:读取biglog异步删除缓存系列文章版本记录方案一:延时双删 延时双删流程 先删除缓存再更新数据库休眠一会(比如1秒),再次删除缓存。这个休眠一会,一般多久呢?都是1秒? 这个休眠时间 = 读业务逻辑数据

dell戴尔电脑灵越系列Inspiron 15 3520原厂Win11系统中文版/英文版

Dell戴尔笔记本灵越3520原装出厂Windows11系统包&#xff0c;恢复出厂开箱预装OEM系统 链接&#xff1a;https://pan.baidu.com/s/1mMOAnvXz5NCDO_KImHR5gQ?pwd3nvw 提取码&#xff1a;3nvw 原厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office办公软件、MyD…