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。
相关文章:

qt-OPENGL-星系仿真
qt-OPENGL-星系仿真 一、演示效果二、核心程序三、下载链接 一、演示效果 二、核心程序 #include "model.h"Model::Model(QOpenGLWidget *_glWidget) { glWidget _glWidget;glWidget->makeCurrent();initializeOpenGLFunctions(); }Model::~Model() {destroyV…...
Java实战:Spring Boot实现AOP记录操作日志
本文将详细介绍如何在Spring Boot应用程序中使用Aspect Oriented Programming(AOP)来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念,以及如何使用Spring Boot实现AOP记录操作日志。最后,我们将通过一个具体示例…...
C++ //练习 7.38 有些情况下我们希望提供cin作为接受istream参数的构造函数的默认实参,请声明这样的构造函数。
C Primer(第5版) 练习 7.38 练习 7.38 有些情况下我们希望提供cin作为接受istream&参数的构造函数的默认实参,请声明这样的构造函数。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块 Sa…...
算法:两数之和
算法:两数之和 方法一:暴力法 function twoSum(nums, target) {for (let i 0; i < nums.length; i) {for (let j i 1; j < nums.length; j) {if (nums[i] nums[j] target) {return [i, j];}}}return null; }方法二:哈希表 func…...

pytorch: ground truth similarity matrix
按照真实标签排序pair-wise相似度矩阵的Pytorch代码 本文仅作留档,用于输出可视化 Inputs: Ground-truths Y ∈ R n 1 \mathbf{Y}\in\mathbb R^{n\times 1} Y∈Rn1, Similarity matrix A ∈ R n n \mathbf{A}\in\mathbb R^{n\times n} A∈RnnOutputs: Block dia…...
鸿蒙 gnss 开关使能流程
先WiFi,后 定位,再从蓝牙到NFC,这个就是我大致熟悉开源鸿蒙代码的一个顺序流程,WiFi 的年前差不多基本流程熟悉了,当然还有很多细节和内容没有写到,后续都会慢慢的丰富起来,这一篇将开启GNSS的篇…...

设计模式-创建型模式-抽象工厂模式
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。 由于工厂方法模式中的每个工厂只生产一类产品&…...
【Go】五、Grpc 的入门使用
grpc 与 protobuf grpc 使用的是 protobuf 协议,其是一个通用的 rpc 框架,基本支持主流的所有语言、其底层使用 http/2 进行网络通信,具有较高的效率 protobuf 是一种序列化格式,这种格式具有 序列化以及解码速度快(…...
PDF加粗内容重复读取解决方案
文章目录 前言发现问题解决方案问题分析大致逻辑 show my code 前言 在使用pdfplumber读取PDF的过程中,由于加黑的内容会被莫名其妙的读取两次,带来了很大的困扰。这篇文章将给出解决方案。 发现问题 在在使用pdfplumber读取PDF的过程中,读…...
Golang 并发 Channel的用法
目录 Golang 并发 Channel的用法1. channel 的创建2. nil channel读写阻塞示例close示例 3. channel 的读写4. channel 只读只写5. 关闭channelchannel关闭后,剩余的数据能否取到读取关闭的channel,将获取零值使用ok判断,是否关闭使用for-ran…...
cfa复习资料介绍之二:notes(SchweserNotes)
什么是CFA notes? CFA资料Study Notes都是外国一些出版机构针对CFA考试提供的复习资料,而其中Schweser在国内的名气最大,用的人也最多。内容详尽并且突出重点,并且CFA Notes的内容相比于官方curriculum教材更加符合中国CFA考生的心态&#x…...

FITC Palmitate Conjugate,FITC-棕榈酸酯缀合物,可以用标准 FITC 滤光片组进行成像
FITC Palmitate Conjugate,FITC-棕榈酸酯缀合物,可以用标准 FITC 滤光片组进行成像 您好,欢迎来到新研之家 文章关键词:FITC Palmitate Conjugate,FITC-棕榈酸酯缀合物,FITC 棕榈酸酯缀合物,F…...

本机防攻击简介
定义 在网络中,存在着大量针对CPU(Central Processing Unit)的恶意攻击报文以及需要正常上送CPU的各类报文。针对CPU的恶意攻击报文会导致CPU长时间繁忙的处理攻击报文,从而引发其他业务的中断甚至系统的中断;大量正常…...

Python 进阶语法:JSON
1 什么是 JSON? 1.1 JSON 的定义 JSON 是 JavaScript Object Notation 的简写,字面上的意思是 JavaScript 对象标记。本质上,JSON 是轻量级的文本数据交换格式。轻量级,是拿它与另一种数据交换格式XML进行比较,相当轻…...
mescroll 在uni-app 运行的下拉刷新和上拉加载的组件
官网传送门: https://www.mescroll.com/uni.html 最近使用到了mescroll 但是一直都是整个页面的滚动, 最近需求有需要局部滚动, 收藏了一个博主的文章觉得写的还挺好, 传送门: https://blog.csdn.net/Minions_Fatman/article/details/134754926?spm1001.2014.3001.5506 使用…...
netty的TCP服务端和客户端实现
第一步:引入依赖 <dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.90.Final</version></dependency></dependencies> 第二步:实…...

合纵连横 – 以 Flink 和 Amazon MSK 构建 Amazon DocumentDB 之间的实时数据同步
在大数据时代,实时数据同步已经有很多地方应用,包括从在线数据库构建实时数据仓库,跨区域数据复制。行业落地场景众多,例如,电商 GMV 数据实时统计,用户行为分析,广告投放效果实时追踪ÿ…...

HBase 进阶
参考来源: B站尚硅谷HBase2.x 目录 Master 架构RegionServer 架构写流程MemStore Flush读流程HFile 结构读流程合并读取数据优化 StoreFile CompactionRegion Split预分区(自定义分区)系统拆分 Master 架构 Master详细架构 1)Meta 表格介…...

一周学会Django5 Python Web开发-Django5路由命名与反向解析reverse与resolve
锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计25条视频,包括:2024版 Django5 Python we…...
好奇!为什么gateway和springMVC之间依赖冲突?
Gateway和SpringMVC之间存在冲突,可能是因为它们分别基于不同的技术栈。具体来说: 技术栈差异:Spring Cloud Gateway 是建立在 Spring Boot 2.x 和 Spring WebFlux 基础之上的,它使用的是非阻塞式的 Netty 服务器。而 Spring MVC…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...