OpenGL笔记二十一之几何类设计

OpenGL笔记二十一之几何类设计

—— 2024-09-16 下午


bilibili赵新政老师的教程看后笔记

code review!

文章目录

  • OpenGL笔记二十一之几何类设计
    • 1.运行
      • 1.1.立方体运行
      • 1.2.球体运行
    • 2.几何类搭建
    • 1.立方体分析
    • 2.球体分析
    • 3.图片资源文件
    • 4.关键实现
      • 4.1.geometry.h
      • 4.2.geometry.cpp
      • 4.3.vertex.glsl
      • 4.4.fragment.glsl
      • 4.5.main.cpp

1.运行

1.1.立方体运行

在这里插入图片描述

1.2.球体运行

在这里插入图片描述

2.几何类搭建

在这里插入图片描述

在这里插入图片描述

1.立方体分析

在这里插入图片描述
将0.5替换成halfSize就可以了。

2.球体分析

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.图片资源文件

goku.jpg
在这里插入图片描述

earth.png
在这里插入图片描述

4.关键实现

4.1.geometry.h

在这里插入图片描述

代码

#pragma once

#include "core.h"

class Geometry {
public:
	Geometry();
	~Geometry();

	static Geometry* createBox(float size);
	static Geometry* createSphere(float radius);

	GLuint getVao()const { return mVao; }
	uint32_t getIndicesCount()const { return mIndicesCount; }

private:
	GLuint mVao{ 0 };
	GLuint mPosVbo{ 0 };
	GLuint mUvVbo{ 0 };
	GLuint mEbo{ 0 };

	uint32_t mIndicesCount{ 0 };
};

4.2.geometry.cpp

在这里插入图片描述

代码

#include "geometry.h"
#include <vector>

Geometry::Geometry() {

}

Geometry::~Geometry() {
	if (mVao != 0) {
		glDeleteVertexArrays(1, &mVao);
	}
	if (mPosVbo != 0) {
		glDeleteBuffers(1, &mPosVbo);
	}
	if (mUvVbo != 0) {
		glDeleteBuffers(1, &mUvVbo);
	}
	if (mEbo != 0) {
		glDeleteBuffers(1, &mEbo);
	}
}

Geometry* Geometry::createBox(float size) {
	Geometry* geometry = new Geometry();
	geometry->mIndicesCount = 36;

	float halfSize = size / 2.0f;

	float positions[] = {
		// Front face
		-halfSize, -halfSize, halfSize, halfSize, -halfSize, halfSize, halfSize, halfSize, halfSize, -halfSize, halfSize, halfSize,
		// Back face
		-halfSize, -halfSize, -halfSize, -halfSize, halfSize, -halfSize, halfSize, halfSize, -halfSize, halfSize, -halfSize, -halfSize,
		// Top face
		-halfSize, halfSize, halfSize, halfSize, halfSize, halfSize, halfSize, halfSize, -halfSize, -halfSize, halfSize, -halfSize,
		// Bottom face
		-halfSize, -halfSize, -halfSize, halfSize, -halfSize, -halfSize, halfSize, -halfSize, halfSize, -halfSize, -halfSize, halfSize,
		// Right face
		halfSize, -halfSize, halfSize, halfSize, -halfSize, -halfSize, halfSize, halfSize, -halfSize, halfSize, halfSize, halfSize,
		// Left face
		-halfSize, -halfSize, -halfSize, -halfSize, -halfSize, halfSize, -halfSize, halfSize, halfSize, -halfSize, halfSize, -halfSize
	};

	float uvs[] = {
		0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
		0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
		0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
		0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
		0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
		0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
	};

	unsigned int indices[] = {
		0, 1, 2, 2, 3, 0,   // Front face
		4, 5, 6, 6, 7, 4,   // Back face
		8, 9, 10, 10, 11, 8,  // Top face
		12, 13, 14, 14, 15, 12, // Bottom face
		16, 17, 18, 18, 19, 16, // Right face
		20, 21, 22, 22, 23, 20  // Left face
	};

	//2 VBO创建
	GLuint& posVbo = geometry->mPosVbo, uvVbo = geometry->mUvVbo;
	glGenBuffers(1, &posVbo);
	glBindBuffer(GL_ARRAY_BUFFER, posVbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

	glGenBuffers(1, &uvVbo);
	glBindBuffer(GL_ARRAY_BUFFER, uvVbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);

	//3 EBO创建
	glGenBuffers(1, &geometry->mEbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->mEbo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	//4 VAO创建
	glGenVertexArrays(1, &geometry->mVao);
	glBindVertexArray(geometry->mVao);

	glBindBuffer(GL_ARRAY_BUFFER, posVbo);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);

	glBindBuffer(GL_ARRAY_BUFFER, uvVbo);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*)0);

	//5.4 加入ebo到当前的vao
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->mEbo);

	glBindVertexArray(0);

	return geometry;
}

Geometry* Geometry::createSphere(float radius) {
	Geometry* geometry = new Geometry();

	//目标:1 位置 2 uv 3 索引
	//1 主要变量声明
	std::vector<GLfloat> positions{};
	std::vector<GLfloat> uvs{};
	std::vector<GLuint> indices{};

	//声明纬线与经线的数量
	int numLatLines = 60;//纬线
	int numLongLines = 60;//经线

	//2 通过两层循环(纬线在外,经线在内)->位置、uv
	for (int i = 0; i <= numLatLines; i++) {
		for (int j = 0; j <= numLongLines; j++) {
			float phi = i * glm::pi<float>() / numLatLines;
			float theta = j * 2 * glm::pi<float>() / numLongLines;

			float y = radius * cos(phi);
			float x = radius * sin(phi) * cos(theta);
			float z = radius * sin(phi) * sin(theta);

			positions.push_back(x);
			positions.push_back(y);
			positions.push_back(z);

			float u = 1.0 - (float)j / (float)numLongLines;
			float v = 1.0 - (float)i / (float)numLatLines;

			uvs.push_back(u);
			uvs.push_back(v);
		}
	}


	//3 通过两层循环(这里没有=号)->顶点索引
	for (int i = 0; i < numLatLines; i++) {
		for (int j = 0; j < numLongLines; j++) {
			int p1 = i * (numLongLines + 1) + j;
			int p2 = p1 + numLongLines + 1;
			int p3 = p1 + 1;
			int p4 = p2 + 1;

			indices.push_back(p1);
			indices.push_back(p2);
			indices.push_back(p3);

			indices.push_back(p3);
			indices.push_back(p2);
			indices.push_back(p4);
		}
	}


	//4 生成vbo与vao
	GLuint& posVbo = geometry->mPosVbo, uvVbo = geometry->mUvVbo;
	glGenBuffers(1, &posVbo);
	glBindBuffer(GL_ARRAY_BUFFER, posVbo);
	glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(float), positions.data(), GL_STATIC_DRAW);

	glGenBuffers(1, &uvVbo);
	glBindBuffer(GL_ARRAY_BUFFER, uvVbo);
	glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(float), uvs.data(), GL_STATIC_DRAW);

	glGenBuffers(1, &geometry->mEbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->mEbo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);

	glGenVertexArrays(1, &geometry->mVao);
	glBindVertexArray(geometry->mVao);

	glBindBuffer(GL_ARRAY_BUFFER, posVbo);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);

	glBindBuffer(GL_ARRAY_BUFFER, uvVbo);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*)0);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->mEbo);

	glBindVertexArray(0);

	geometry->mIndicesCount = indices.size();


	return geometry;
}

4.3.vertex.glsl

代码

#version 460 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aUV;

out vec2 uv;

uniform mat4 transform;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

//aPos作为attribute(属性)传入shader
//不允许更改的
void main()
{
	vec4 position = vec4(aPos, 1.0);
	position = projectionMatrix * viewMatrix * transform * position;
	gl_Position = position;
	uv = aUV;
}

4.4.fragment.glsl

代码

#version 460 core
out vec4 FragColor;

in vec2 uv;

uniform sampler2D sampler;

void main()
{
  FragColor = texture(sampler, uv);
}

4.5.main.cpp

在这里插入图片描述

代码

#include <iostream>

#include "glframework/core.h"
#include "glframework/shader.h"
#include <string>
#include <assert.h>//断言
#include "wrapper/checkError.h"
#include "application/Application.h"
#include "glframework/texture.h"

//引入相机+控制器
#include "application/camera/perspectiveCamera.h"
#include "application/camera/orthographicCamera.h"
#include "application/camera/trackBallCameraControl.h"
#include "application/camera/gameCameraControl.h"

#include "glframework/geometry.h"

/*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 设计并实现Geometry系统,用于学习方便
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*			搭建Geometry类框架
*└────────────────────────────────────────────────┘
*/

Geometry* geometry = nullptr;
Shader* shader = nullptr;
Texture* texture = nullptr;
glm::mat4 transform(1.0f);

PerspectiveCamera* camera = nullptr;
TrackBallCameraControl* cameraControl = nullptr;

void OnResize(int width, int height) {
	GL_CALL(glViewport(0, 0, width, height));
	std::cout << "OnResize" << std::endl;
}

void OnKey(int key, int action, int mods) {
	cameraControl->onKey(key, action, mods);
}

//鼠标按下/抬起
void OnMouse(int button, int action, int mods) {
	double x, y;
	app->getCursorPosition(&x, &y);
	cameraControl->onMouse(button, action, x, y);
}

//鼠标移动
void OnCursor(double xpos, double ypos) {
	cameraControl->onCursor(xpos, ypos);
}

//鼠标滚轮
void OnScroll(double offset) {
	cameraControl->onScroll(offset);
}

void prepareVAO() {
	geometry = Geometry::createBox(3.0f);
	// geometry = Geometry::createSphere(3.0f);
}

void prepareShader() {
	shader = new Shader("assets/shaders/vertex.glsl","assets/shaders/fragment.glsl");
}

void prepareTexture() {
	texture = new Texture("assets/textures/goku.jpg", 0);
	// texture = new Texture("assets/textures/earth.png", 0);
}

void prepareCamera() {
	float size = 6.0f;
	//camera = new OrthographicCamera(-size, size, size, -size, size, -size);
	camera = new PerspectiveCamera(
		60.0f, 
		(float)app->getWidth() / (float)app->getHeight(),
		0.1f,
		1000.0f
	);

	cameraControl = new TrackBallCameraControl();
	cameraControl->setCamera(camera);
	cameraControl->setSensitivity(0.4f);
}

void prepareState() {
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);
}

void render() {
	//执行opengl画布清理操作
	GL_CALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

	//绑定当前的program
	shader->begin();
	shader->setInt("sampler", 0);
	shader->setMatrix4x4("transform", transform);
	shader->setMatrix4x4("viewMatrix", camera->getViewMatrix());
	shader->setMatrix4x4("projectionMatrix", camera->getProjectionMatrix());
 
	//绑定当前的vao
	GL_CALL(glBindVertexArray(geometry->getVao()));

	//发出绘制指令
	GL_CALL(glDrawElements(GL_TRIANGLES, geometry->getIndicesCount(), GL_UNSIGNED_INT, 0));
	GL_CALL(glBindVertexArray(0));

	shader->end();
}


int main() {
	if (!app->init(800, 600)) {
		return -1;
	}

	app->setResizeCallback(OnResize);
	app->setKeyBoardCallback(OnKey);
	app->setMouseCallback(OnMouse);
	app->setCursorCallback(OnCursor);
	app->setScrollCallback(OnScroll);

	//设置opengl视口以及清理颜色
	GL_CALL(glViewport(0, 0, 800, 600));
	GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));

	prepareShader();
	prepareVAO();
	prepareTexture();
	prepareCamera();
	prepareState();

	while (app->update()) {
		cameraControl->update();
		render();
	}

	app->destroy();

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3使用provide和inject传递异步请求数据子组件接收不到

前言 一般接口返回的格式是数组或对象&#xff0c;使用reactive定义共享变量 父组件传递 const data reactive([])// 使用settimout模拟接口返回 setTimeout(() > {// 将接口返回的数据赋值给变量Object.assign(data, [{ id: 10000 }]) }, 3000);provide(shareData, dat…

ip映射域名,一般用于mysql和redis的固定映射,方便快捷打包

举个例子 192.168.3.101mysql映射到mysql.smartlink.com 192.168.3.101redis redis.smartlink.com 要将IP地址映射到域名&#xff0c;可以通过几种方式实现&#xff0c;包括修改本地主机文件&#xff08;仅适用于本地开发环境&#xff09;、设置DNS解析&#xff08;适用于生产环…

一文入门生成式AI(理解ChatGPT的原理)

一、什么是生成式AI&#xff1f; 以ChatGPT为代表的生成式AI&#xff0c;是对已有的数据和知识进行向量化的归纳&#xff0c;总结出数据的联合概率。从而在生成内容时&#xff0c;根据用户需求&#xff0c;结合关联字词的概率&#xff0c;生成新的内容。 可以这么联想&#x…

el-table表格的展开行,初始化的时候展开哪一行+设置点击行可展开功能

效果&#xff1a; 表格展开行官网使用&#xff1a; 通过设置 type"expand" 和 Scoped slot 可以开启展开行功能&#xff0c;el-table-column 的模板会被渲染成为展开行的内容&#xff0c;展开行可访问的属性与使用自定义列模板时的 Scoped slot 相同。 但是这种方法…

解决:Vue 中 debugger 不生效

目录 1&#xff0c;问题2&#xff0c;解决2.1&#xff0c;修改 webpack 配置2.2&#xff0c;修改浏览器设置 1&#xff0c;问题 在 Vue 项目中&#xff0c;可以使用 debugger 在浏览器中开启调试。但有时却不生效。 2&#xff0c;解决 2.1&#xff0c;修改 webpack 配置 通…

【农信网-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【ArcGIS Pro实操第七期】栅格数据合并、裁剪及统计:以全球不透水面积为例

【ArcGIS Pro实操第七期】批量裁剪&#xff1a;以全球不透水面积为例 准备&#xff1a;数据下载ArcGIS Pro批量裁剪数据集1 数据拼接2 数据裁剪3 数据统计&#xff1a;各栅格取值3.1 栅格计算器-精确提取-栅格数据特定值3.2 数据统计 4 不透水面积变化分析 参考 准备&#xff1…

基于springboot+vue+uniapp的驾校报名小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

OpenCV高阶操作

在图像处理与计算机视觉领域&#xff0c;OpenCV&#xff08;Open Source Computer Vision Library&#xff09;无疑是最为强大且广泛使用的工具之一。从基础的图像读取、 1.图片的上下&#xff0c;采样 下采样&#xff08;Downsampling&#xff09; 下采样通常用于减小图像的…

架构师备考的一些思考(四)

前言 对于数学&#xff0c;我们之前学的是对的&#xff0c;但不是真的&#xff0c;所以我们没有数学思维。 对于计算机&#xff0c;我们学校教的是对的&#xff0c;但不是真的&#xff0c;所以仅仅从学校学习知识的应届毕业生&#xff0c;不论985,211&#xff0c;本科&#xff…

回归预测|基于黑翅鸢优化LightGBM的数据回归预测Matlab程序 多特征输入单输出 含基础LightGBM

回归预测|基于黑翅鸢优化LightGBM的数据回归预测Matlab程序 多特征输入单输出 含基础LightGBM 文章目录 一、基本原理1. 数据准备2. LightGBM模型构建3. BKA优化4. 模型评估5. 结果分析总结 二、实验结果三、核心代码四、代码获取五、总结 回归预测|基于黑翅鸢优化LightGBM的数…

【SpringCloud】服务注册与发现 - Eureka

目录 服务注册/服务发现-Eureka背景问题描述解决思路什么是注册中心CAP 理论常见的注册中心 Eureka 介绍搭建Eureka Server创建Eureka-server 子模块引入eureka-server依赖项目构建插件完善启动类编写配置文件启动服务 服务注册引入eureka-client依赖完善配置文件启动服务 服务…

Linux基础---10进程管理

一.查看和关闭进程 1.查看进程 基础指令: ps -efPID 进程编号&#xff0c;PPID 父进程编号&#xff0c; CMD命令名称 进阶指令–查看进程的树形结构&#xff1a; yum install psmisc -y #首先安装psmisc后可直接使用pstreepstree2.关闭进程 要想关闭某个或多个进程需要知道…

解码 OpenAI 的 o1 系列大型语言模型

OpenAI 表示&#xff0c;其 Strawberry 项目已升级为新的大型语言模型 (LLM) 系列&#xff0c;公司将其命名为 OpenAI o1。 该公司表示&#xff0c;新系列模型还包括一个 o1-mini 版本&#xff0c;以提高成本效益&#xff0c;可根据其推理能力与最新的GPT-4o 模型进行区分。 …

【QGC】把QGroundControl地面站添加到Ubuntu侧边菜单栏启动

把QGroundControl地面站添加到Ubuntu侧边菜单栏启动 简介准备工作步骤 1: 创建 Desktop Entry 文件步骤 2: 编辑 Desktop Entry 文件步骤 3: 刷新应用程序菜单步骤 4: 将 QGroundControl 固定到侧边栏 环境&#xff1a; Ubuntu &#xff1a;20.04 LTS 简介 QGroundControl 是…

电信创维光猫DT741超级密码

正常的D740系是创维系列光猫如&#xff1a;SK-D740 之类的超密获取办法-光猫/adsl/cable无线一体机-恩山无线论坛 但是我这个固件是DT741v1.0 我只能说很S -B&#xff0c;这个版本如果是1.02那就可以很轻松的去用通用办法解决&#xff0c;但是呢&#xff01;还有办法就是用最传…

Unity2D游戏入门

1.导入资源 在Assets下新建文件夹 Res&#xff0c;将相关素材拖入其中&#xff08;本文中的素材仅为学习使用&#xff09;。 2.菜单 设置页面大小 选择素材&#xff0c;查看素材大小。 设置游戏视图大小。 调整工作布局方便查看 记得给场景改名为MenuScene&#xff0c;与其他…

食品包装识别系统源码分享

食品包装识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

Typora安装,使用,图片加载全流程!!!

文章目录 前言&#xff1a;安装&#xff1a;破解&#xff1a;使用typora&#xff1a;关于CSDN加载不出图片&#xff1a;创建OSS&#xff1a;设置PicGo&#xff1a; 前言&#xff1a; ​ Typora是一款非常流行的Markdown编辑器&#xff0c;简单来说就是可以方便我们写博客。拿我…

踩坑记:Poco库,MySql,解析大文本的bug

这两天在调试一个小功能&#xff0c;使用c,读取MySql。使用的是Poco库。按照官网的写法&#xff1a; std::cout << "read normal data by poco recordset "<<std::endl;Poco::Data::MySQL::Connector::registerConnector();Poco::Data::Session session(…