Learn QOpenGL 读取obj模型

news/2024/11/3 2:58:48 标签: qt, c++
/* 
**  File name:   OpenGLModelWidget.h
**  Author:      
**  Date:        2024-10-31
**  Brief:       读取模型文件并渲染的OpenGL控件
**  Copyright (C) 1392019713@qq.com All rights reserved.
*/

#ifndef OpenGLModelWidget_H
#define OpenGLModelWidget_H

#include <QOpenGLWidget>
#include <QOpenGlFunctions_3_3_Core>
#include <QMatrix4x4>
#include <QVector2D>
#include <QVector3D>
#include <QMouseEvent>
#include <array>
#include "glm/glm.hpp"
#include "glm/ext.hpp"

/*
*@brief 定义顶点、法线、纹理坐标、面数据结构
*/
struct Vertex {
   
	glm::vec3 position;
	glm::vec3 normal;
};

/*
*@brief 读取模型文件并渲染的OpenGL控件
*/
class COpenGLModelWidget : public QOpenGLWidget, QOpenGLFunctions_3_3_Core
{
   
	Q_OBJECT
public:
	COpenGLModelWidget(QWidget*parent = nullptr);

	virtual ~COpenGLModelWidget();

	/*
	* @brief 加载模型文件
	* @param strModelFile 模型文件路径
	* @return 无
	*/
	void LoadOBJModel(const std::string& strModelFile);

	void SetShaderFilePath(const std::string& strVertFilePath, const std::string& strfragFilePath); //设置着色器文件路径

protected:
	void initializeGL();

	void paintGL();

	void resizeGL(int width, int height);

	void mouseMoveEvent(QMouseEvent* event);

	void mousePressEvent(QMouseEvent* event);

	void wheelEvent(QWheelEvent* event);

	void mouseReleaseEvent(QMouseEvent* event);

	void keyPressEvent(QKeyEvent* event);

	void keyReleaseEvent(QKeyEvent* event);

private:
	void AutoNormal(); //计算法线

	std::string GetFileConTent(const std::string& strFilePath) const;

	glm::vec3 ComputeNormalBiased(glm::vec3 const& a, glm::vec3 const& b,
		glm::vec3 const& c); //计算平滑法线

	glm::mat4x4 GetViewMatrix() const; //视图矩阵

	glm::mat4x4 GetProjectionMatrix() const; //投影矩阵

	void NormalizeAngle(int &nAngle); //修正角度

	void Orbit(glm::vec2 delta, bool isDrift); //轨道旋转

	void Zoom(float delta, bool isHitchcock); //缩放

	void Pan(glm::vec2 delta);//平移

private:
	std::vector<Vertex> m_vecVertices; //顶点数据

	std::vector<glm::uvec3> m_vecFaces; //面数据

	unsigned int m_unVAO; //顶点数组对象
	unsigned int m_unVBO; //顶点缓冲对象
	unsigned int m_unEBO; //索引缓冲对象
	unsigned int m_unShaderProgram; //着色器程序

	std::string m_strFragFilePath; //片元着色器文件路径
	std::string m_strVertFilePath; //顶点着色器文件路径

	glm::vec2 lastpos;
	bool moving = false;
	glm::vec3 eye = {
    0, 0, 5 };
	glm::vec3 lookat = {
    0, 0, 0 };
	glm::vec3 up_vector = {
    0, 1, 0 };
	glm::vec3 keep_up_axis = {
    0, 1, 0 };
	float focal_len = 40.0f;
	float film_height = 24.0f;
	float film_width = 32.0f;
	float zoom_speed = 0.2f;
	float orbit_speed = 1.0f;
	float drift_speed = 1.0f;
	float pan_speed = 2.0f;
	int zoom_axis = 1;

	glm::vec2 mousePos;
};

#endif // !

#include "../Include/OpenGLModelWidget.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <QMatrix3x3>
    
COpenGLModelWidget::COpenGLModelWidget(QWidget* parent)
	: QOpenGLWidget(parent)
{
   

}

COpenGLModelWidget::~COpenGLModelWidget()
{
   
    makeCurrent(); 
    glDeleteBuffers(1, &m_unVBO);
    glDeleteVertexArrays(1, &m_unVAO);
    glDeleteProgram(m_unShaderProgram);
    doneCurrent();
}

void COpenGLModelWidget::LoadOBJModel(const std::string& strModelFile)
{
   
    std::ifstream file(strModelFile);
    if (!file.is_open()) {
   
        std::cerr << "Failed to open file: " << strModelFile << std::endl;
        return;
    }

    std::string line;
    while (std::getline(file, line)) 
    {
   
        if (line.substr(0, 2) == "v ") //顶点
        {
   
            std::istringstream s(line.substr(2));
            glm::vec3 vertex;
            s >> vertex.x >> vertex.y >> vertex.z;
            m_ve

http://www.niftyadmin.cn/n/5735915.html

相关文章

项目模块十二:TcpServer模块

一、模块设计思路 1、目的 对所有模块整合&#xff0c;实现一个服务器模块供外部快速搭建服务器。 2、管理 监听套接字 主 Reactor&#xff0c;创建 EventLoop _baseloop 对象&#xff0c;进行对监听套接字的管理 哈希表管理所有新连接的 Channel 创建线程池进行连接的事…

掌握ElasticSearch(七):相关性评分

文章目录 一、Elasticsearch的打分机制1.TF-IDFTF-IDF 概述基本公式示例 2.BM25BM25 概述配置参数 二、boosting调整打分1. match 查询2. multi_match 查询3. bool 查询4. boosting 查询5.动态 Boosting 三、Elasticsearch的查询再打分策略查询阶段&#xff08;Query Phase&…

iOS用rime且导入自制输入方案

iPhone 16 的 cantonese 只能打传统汉字&#xff0c;没有繁简转换&#xff0c;m d sh d。考虑用「仓」输入法 [1] 使用 Rime 打字&#xff0c;且希望导入自制方案 [2]。 仓输入法有几种导入方案的方法&#xff0c;见 [3]&#xff0c;此处记录 wifi 上传法。准备工作&#xff1…

七、MapReduce 编程模型:原理、流程与应用场景

MapReduce 编程模型&#xff1a;原理、流程与应用场景 在当今大数据时代&#xff0c;MapReduce 编程模型作为一种强大的分布式计算框架&#xff0c;对于处理海量数据具有至关重要的作用。它以其简洁而高效的设计理念&#xff0c;在众多领域得到了广泛的应用。本文将深入探讨 M…

《使用Gin框架构建分布式应用》阅读笔记:p307-p392

《用Gin框架构建分布式应用》学习第16天&#xff0c;p307-p392总结&#xff0c;总86页。 一、技术总结 1.AWS chapter 08讲使用AWS进行部署&#xff0c;可以根据需要选择是否阅读。因为使用到的概率很小&#xff0c;且还要绑卡&#xff0c;本人选择跳过。 2.CI/CD (1)什么…

微服务基础拆分实践(第一篇)

目录 前言 一、认识微服务 1.1 单体架构 VS 微服务架构 1.2 微服务的集大成者&#xff1a;SpringCloud 1.3 微服务拆分原则 1.4 微服务拆分方式 二、微服务拆分入门步骤 &#xff1a;以拆分商品模块为例 三、服务注册订阅与远程调用&#xff1a;以拆分购物车为例 3.1 …

基于 Java(SpringBoot)+MySQL 开发古诗词学习网站

古诗词系统设计与实现 引言 编写目的 为了保证项目团队按时保质地完成项目目标&#xff0c;便于项目团队成员更好地了解项目情况&#xff0c;使项目工作开展的各个过程合理有序&#xff0c;有必要以文件化的形式&#xff0c;把对于在项目生命周期内的工作任务范围、各项工作…

ProcDump配合mimikatz获取Windows系统账户和密码等信息

免责申明 本文仅是用于学习研究Windows系统的安全性实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国家地区相关法规内容【学法时习之丨网…