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

news2024/9/19 9:51:44

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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

您使用过哪些AI集成工具提升工作效率

您使用过哪些AI集成工具提升工作效率 随着AI技术的飞速发展&#xff0c;个人开始寻求高效的方法来构建和管理定制化模型&#xff0c;以简化复杂的开发过程&#xff0c;提高工作效率。说起用AI集成工具来提高工作效率&#xff0c;个人作为开发者&#xff0c;确实在使用AI代码辅助…

进口车电子信息单二维码解密

目录 效果 二维码信息 解密后信息 进口车电子信息单二维码解密 效果 二维码信息 QzcOcj0yNsb9cVZsGoZKBOrBbn4RJ6O0N4q9/R10ANBvPgWt1vO75YmnWHsImhQUluNYC/OUYwWiO2IljHAhPmSAm3BieWZpXwi1IGWzLKAkRGkTUpqhT2pwEhkbMKcFsfsBfxh9MT1KRy2YaDvLKwLvOVHp7ZJUh4DdDof6GBGfsvam…

Json和Http专栏

json 理论 什么是JSON? 规则 被大括号包括的是JSON对象,被中括号包括的是JSON数组. JSON数组JSON对象 实验 构建JSON 用代码实现如下json内容: //构建JSON void WirteJson() {QJsonObject rootObject;//1.插入name字段rootObject.insert("name","china&quo…

OpenAI o1:隐含在训练与推理间的动态泛化与流形分布

随着OpenAI o1发布&#xff0c;进一步激发了产业与学术各界对AGI的期待以及new scaling law下的探索热情&#xff0c;也看到来自社区和专业机构对o1的阐释&#xff0c;但总感觉还差点什么&#xff0c;因此决定以自己的角度分篇幅梳理下&#xff0c;并分享给大伙&#xff1a; O…

使用mlp算法对Digits数据集进行分类

程序功能 这个程序使用多层感知机&#xff08;MLP&#xff09;对 Digits 数据集进行分类。程序将数据集分为训练集和测试集&#xff0c;创建并训练一个具有两个隐藏层的 MLP 模型。训练完成后&#xff0c;模型对测试数据进行预测&#xff0c;并通过准确率、分类报告和混淆矩阵…

vmvare如何给centos7 设置静态IP地址

本章教程,主要介绍如何在vmvare中如何给虚拟机中设置静态IP地址。本章教程中使用的linux发行版是centos7。 目前没有静态IP地址,并且不能联网,此时我们需要给它配置一个静态IP,并且可以实现联网功能。 一、前置步骤 1、网络设置 2、添加网络 添加一个虚拟机网络,选择VMne…

C++笔记---stack和queue

1. stack的介绍及重要接口 stack---栈&#xff0c;是一种“先进后出&#xff0c;后进先出”的数据结构。 此处的stack是STL库中定义的一个类模板&#xff0c;用于实例化出存储各种类型数据的栈。 bool empty() const;判断栈是否为空(空true/非空false)size_t size() const;返…

Kafka日志索引详解与常见问题分析

目录 一、Kafka的Log日志梳理 1、Topic下的消息是如何存储的&#xff1f; 1. log文件追加记录所有消息 2. index和timeindex加速读取log消息日志 2、文件清理机制 1. 如何判断哪些日志文件过期了 2. 过期的日志文件如何处理 3、Kafka的文件高效读写机制 1. Kafka的文件…

刷题日记【160. 相交链表】

160. 相交链表 这虽然是道简单题&#xff0c;但是最简单的方法&#xff08;Set数组存一边然后另一边遍历判断当前结点是否存在于另一边&#xff09;性能很一般&#xff0c;可以思考用双指针来优化写法&#xff08;可以将空间复杂度降至 O(1)&#xff09; 捋思路时&#xff0c;…

Maya怎么把黑色的面反转为白色面

1、选中需要调整的面。 2、点击菜单栏中的“网格显示”&#xff0c;再点击点击“反转(Reverse)”。 3、反转后&#xff0c;原本黑色的面将会变成正常的面&#xff0c;法线方向也会相应改变。 按住ctrlshift鼠标中键 拖动快捷图标至工具栏

NullPointerException 是什么, 如何修复?

下面是chatGPT 01的回复&#xff1a; **NullPointerException**&#xff08;空指针异常&#xff09;是在 Java 等编程语言中出现的运行时错误&#xff0c;当你尝试使用一个尚未初始化的对象引用&#xff08;即&#xff0c;指向 null&#xff09;时就会发生。这个异常表示你的程…

金融教育进乡村:红土散户联盟教你如何分辨好坏资产

2024年8月&#xff0c;【红土散户联盟】再度将关注的目光投向了农村地区&#xff0c;特别是那些经济不发达的地区。作为一个致力于为社会带来积极改变的组织&#xff0c;红土散户联盟再次举办了农村理财讲座&#xff0c;旨在帮助这些地区的居民提高他们的财务管理能力和投资意识…

OJ题-反转链表

给你一个单链表的头节点&#xff0c;请反转链表&#xff0c;并返回新的链表 eg&#xff1a; 1,2,3,4,5--->5,4,3,2,1 //反转链表 struct ListNode* reverseList(struct ListNode* head) {//定义三个变量struct ListNode* n1, * n2, * n3;n1 NULL;n2 head;n3 head->n…

图解Self-Attention和代码实现,大语言模型基础思维导图

文章目录 1 Self-Attention的概念注意优缺点 2 Self-Attention的原理Q,K,V, and Self-Attention计算公式代码实现 Self-Attention的计算细节输入是如何Embedding的&#xff1f;Word EmbeddingsSentence EmbeddingsPre-trained Embeddings SelfAttention是如何计算的计算图 4 Se…

为什么说开放式耳机比入耳式的好?学生党必入的蓝牙耳机推荐

因为开放式耳机相比入耳式耳机更具优势&#xff0c;具体如下&#xff1a; 佩戴舒适度更高&#xff1a; 开放式耳机通常不需要插入耳道&#xff0c;不会对耳道产生压迫&#xff0c;长时间佩戴耳朵不易感到闷热、疼痛或不适&#xff0c;减少了对耳部的物理压迫和摩擦&#xff0…

单硬盘安装Win10和麒麟V10双系统指导建议

随着信创电脑的普及,国产操作系统也逐渐走进了大家的视野,许多人选择了国产操作系统来体验其开源、安全、高效的特性,而Windows系统也是大多数人习惯使用的操作系统。一台电脑上同时安装银河麒麟V10和Windiows10双系统也成为了非常常见的需求。那么,如何在一台电脑上安装银…

阿里员工爆料:阿里前CTO张建峰,也是中专毕业的!之前觉得大专生做到 P9已经很牛了,现在看来,原来中专生也能成为合伙人

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

AI大模型在知识管理平台上的应用:泛微·采知连实现自动采集.精准搜索.智能问答.主动推荐

AI技术的发展&#xff0c;正在推动组织知识管理模式发生变革。知识管理系统通过各种应用实现知识体系落地&#xff0c;当前聚焦于整合生成式AI技术&#xff0c;以提升业务效率。 组织在数字化进程中面临着知识增量增多、知识更新频率变快、知识与业务结合更紧密等挑战&#xff…

三种mybatis表的列名和对象属性名不一致处理方法

目录 三种mybatis表的列名和对象属性名不一致处理方法 1.使用 resultMap 映射 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff09;测试代码 4&#xff09;测试结果 ​编辑 2.使用别名 1&#xff09;mapper 2&#xff09;mapper.xml 3&#xff09;测试代码 4&#xff0…

浅谈vue2.0与vue3.0的区别(整理十六点)

目录 1. 实现数据响应式的原理不同 2. 生命周期不同 3. vue 2.0 采用了 option 选项式 API&#xff0c;vue 3.0 采用了 composition 组合式 API 4. 新特性编译宏 5. 父子组件间双向数据绑定 v-model 不同 6. v-for 和 v-if 优先级不同 7. 使用的 diff 算法不同 8. 兄弟组…