当前位置: 首页 > news >正文

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&#xff08;AOP&#xff09;来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念&#xff0c;以及如何使用Spring Boot实现AOP记录操作日志。最后&#xff0c;我们将通过一个具体示例…...

C++ //练习 7.38 有些情况下我们希望提供cin作为接受istream参数的构造函数的默认实参,请声明这样的构造函数。

C Primer&#xff08;第5版&#xff09; 练习 7.38 练习 7.38 有些情况下我们希望提供cin作为接受istream&参数的构造函数的默认实参&#xff0c;请声明这样的构造函数。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 Sa…...

算法:两数之和

算法&#xff1a;两数之和 方法一&#xff1a;暴力法 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; }方法二&#xff1a;哈希表 func…...

pytorch: ground truth similarity matrix

按照真实标签排序pair-wise相似度矩阵的Pytorch代码 本文仅作留档&#xff0c;用于输出可视化 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&#xff0c;后 定位&#xff0c;再从蓝牙到NFC&#xff0c;这个就是我大致熟悉开源鸿蒙代码的一个顺序流程&#xff0c;WiFi 的年前差不多基本流程熟悉了&#xff0c;当然还有很多细节和内容没有写到&#xff0c;后续都会慢慢的丰富起来&#xff0c;这一篇将开启GNSS的篇…...

设计模式-创建型模式-抽象工厂模式

抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;&#xff1a;提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无须指定它们具体的类。抽象工厂模式又称为Kit模式&#xff0c;它是一种对象创建型模式。 由于工厂方法模式中的每个工厂只生产一类产品&…...

【Go】五、Grpc 的入门使用

grpc 与 protobuf grpc 使用的是 protobuf 协议&#xff0c;其是一个通用的 rpc 框架&#xff0c;基本支持主流的所有语言、其底层使用 http/2 进行网络通信&#xff0c;具有较高的效率 protobuf 是一种序列化格式&#xff0c;这种格式具有 序列化以及解码速度快&#xff08;…...

PDF加粗内容重复读取解决方案

文章目录 前言发现问题解决方案问题分析大致逻辑 show my code 前言 在使用pdfplumber读取PDF的过程中&#xff0c;由于加黑的内容会被莫名其妙的读取两次&#xff0c;带来了很大的困扰。这篇文章将给出解决方案。 发现问题 在在使用pdfplumber读取PDF的过程中&#xff0c;读…...

Golang 并发 Channel的用法

目录 Golang 并发 Channel的用法1. channel 的创建2. nil channel读写阻塞示例close示例 3. channel 的读写4. channel 只读只写5. 关闭channelchannel关闭后&#xff0c;剩余的数据能否取到读取关闭的channel&#xff0c;将获取零值使用ok判断&#xff0c;是否关闭使用for-ran…...

cfa复习资料介绍之二:notes(SchweserNotes)

什么是CFA notes? CFA资料Study Notes都是外国一些出版机构针对CFA考试提供的复习资料&#xff0c;而其中Schweser在国内的名气最大&#xff0c;用的人也最多。内容详尽并且突出重点&#xff0c;并且CFA Notes的内容相比于官方curriculum教材更加符合中国CFA考生的心态&#x…...

FITC Palmitate Conjugate,FITC-棕榈酸酯缀合物,可以用标准 FITC 滤光片组进行成像

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

本机防攻击简介

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

Python 进阶语法:JSON

1 什么是 JSON&#xff1f; 1.1 JSON 的定义 JSON 是 JavaScript Object Notation 的简写&#xff0c;字面上的意思是 JavaScript 对象标记。本质上&#xff0c;JSON 是轻量级的文本数据交换格式。轻量级&#xff0c;是拿它与另一种数据交换格式XML进行比较&#xff0c;相当轻…...

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服务端和客户端实现

第一步&#xff1a;引入依赖 <dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.90.Final</version></dependency></dependencies> 第二步&#xff1a;实…...

合纵连横 – 以 Flink 和 Amazon MSK 构建 Amazon DocumentDB 之间的实时数据同步

在大数据时代&#xff0c;实时数据同步已经有很多地方应用&#xff0c;包括从在线数据库构建实时数据仓库&#xff0c;跨区域数据复制。行业落地场景众多&#xff0c;例如&#xff0c;电商 GMV 数据实时统计&#xff0c;用户行为分析&#xff0c;广告投放效果实时追踪&#xff…...

HBase 进阶

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

一周学会Django5 Python Web开发-Django5路由命名与反向解析reverse与resolve

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计25条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…...

好奇!为什么gateway和springMVC之间依赖冲突?

Gateway和SpringMVC之间存在冲突&#xff0c;可能是因为它们分别基于不同的技术栈。具体来说&#xff1a; 技术栈差异&#xff1a;Spring Cloud Gateway 是建立在 Spring Boot 2.x 和 Spring WebFlux 基础之上的&#xff0c;它使用的是非阻塞式的 Netty 服务器。而 Spring MVC…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...