使用C++搭配OpenGL写了一个RenderEngine

2023-10-27

**最近在学习OpenGL,看书看的再多,也不如自己动手写一个来看看,耗时一个多月,由于才学不久,各位大佬勿喷。
用到了glfw Imgui glm这几个库,整合的资源里都带了。

相机类
#ifndef CAMERA_H
#define CAMERA_H

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <vector>

// 定义几个相机移动的动作,用作抽象,以避免使用特定于窗口系统的输入方法
enum Camera_Movement
{
	FORWORD,
	BACK,
	LEFT,
	RIGHT
};

// 默认的相机的值
const float YAW = 90.0f;
const float PITCH = 0.0f;
const float SPEED = 2000.0f;
const float SENSITIVITY = 0.1f;
const float ZOOM = 60.0f;
const float MAX_FOV = 100.0f;


// 一个相机的抽象基类,处理输入并计算相应的欧拉角,向量,矩阵用于OpenGL
class Camera
{
public:
	// 相机属性
	glm::vec3 Position;
	glm::vec3 Front;
	glm::vec3 Up;
	glm::vec3 Right;
	glm::vec3 WorldUp;

	// 欧拉角
	float Yaw;
	float Pitch;

	// 选择相机
	float MovementSpeed;
	float MouseSensitivity;
	float Zoom;

	// 向量构造函数
	Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) :Front(glm::vec3(0.0f, 0.0f, -5.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
	{
		Position = position;
		WorldUp = up;
		Yaw = yaw;
		Pitch = pitch;
		UpdateCameraVector();
	}

	// 标量指构造函数
	Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) : Front(glm::vec3(0.0f, 0.0f, -0.1f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM)
	{
		Position = glm::vec3(posX,posY,posZ);
		WorldUp = glm::vec3(upX,upY,upZ);
		Yaw = yaw;
		Pitch = pitch;
		UpdateCameraVector();
	}

	// 返回使用欧拉角和LookAt矩阵计算的视图矩阵
	glm::mat4 GetViewMatrix()
	{
		UpdateCameraVector();
		
		return glm::lookAt(Position, Position + Front, Up);
	}

	// 处理任何从类似键盘和输入系统接受的输入,接受摄像机定义的ENUM形式的输入参数(从窗口系统中抽象它)
	void ProcessKeyboard(Camera_Movement direction, float deltaTime)
	{
		float velocity = MovementSpeed * deltaTime;
		switch (direction)
		{
		case FORWORD:
			Position += Front * velocity;
			break;
		case BACK:
			Position -= Front * velocity;
			break;
		case RIGHT:
			Position += Right * velocity;
			break;
		case LEFT:
			Position -= Right * velocity;
			break;
		}
	}

	float Random2D(glm::vec2 st)
	{
		return glm::fract(glm::sin(glm::dot(st, glm::vec2(12.9898f, 78.233f))) * 43758.5453123f);
	}

	float InterpolateNoise(int ind, float x, float y)
	{
		float integer_x = float(x);
		float fractional_x = glm::fract(x);
		float integer_y = float(y);
		float fractional_y = glm::fract(y);
		glm::vec2 randomInput = glm::vec2(integer_x, integer_y);
		float a = Random2D(randomInput);
		float b = Random2D(randomInput + glm::vec2(1.0f, 0.0f));
		float c = Random2D(randomInput + glm::vec2(0.0f, 1.0f));
		float d = Random2D(randomInput + glm::vec2(1.0f, 1.0f));
	
		glm::vec2 w = glm::vec2(fractional_x, fractional_y);
		w = w * w * w * (10.0f + w * (-15.0f + 6.0f * w));
		float k0 = a,
			k1 = b - a,
			k2 = c - a,
			k3 = d - c - b + a;
	
		return k0 + k1 * w.x + k2 * w.y + k3 * w.x * w.y;
	}

	

	float perlin(glm::vec2 st, int octaves, float freq, float gDispFactor)
	{
		glm::mat2 m;
		m[0][0] = 0.8;
		m[0][1] = -0.6;
		m[1][0] = 0.6;
		m[1][1] = 0.8;

		float persistence = 0.5;
		float total = 0.0,
			frequency = 0.005 * freq,
			amplitude = gDispFactor;
		for (int i = 0; i < octaves; ++i)
		{
			frequency *= 2.0;
			amplitude *= persistence;

			glm::vec2 v = frequency * st;
			total += InterpolateNoise(0, v.x, v.y) * amplitude;
		}

		return total * total * total;
	}

	void ProjectCameraPosition()
	{
		glm::vec2 st = glm::vec2(Position.x, Position.y);
		float y = perlin(st, 13, 0.01, 20);
		Position.y = y;
	}

	// 处理从鼠标输入系统接受的输入,
	void ProcessMouseMovement(float xoffset, float yoffset, bool constrainPitch = true)
	{
		xoffset *= MouseSensitivity;
		yoffset *= MouseSensitivity;

		Yaw += xoffset;
		Pitch += yoffset;

		// 确保当pithch超过界限时,屏幕不会反转
		if (constrainPitch)
		{
			if (Pitch > 89.0f)
				Pitch = 89.0f;
			if (Pitch < -89.0f)
				Pitch = -89.0f;
		}

		// 使用更新的欧拉角、(前面、右边和上面)的向量
		UpdateCameraVector();
	}

	// 处理从鼠标滚动事件接受到的输入,只需要输入垂直轮轴
	void ProcessMouseScroll(float yoffset)
	{
		if (Zoom >= 1.0f && Zoom < MAX_FOV)
			Zoom -= yoffset;
		if (Zoom <= 1.0f)
			Zoom = 1.0f;
		if (Zoom > MAX_FOV)
			Zoom = MAX_FOV;
	}
	void invertPitch() {
		this->Pitch = -Pitch;
		UpdateCameraVector();
	}

private:
	 // 以相机的欧拉角计算前向量(更新)
	void UpdateCameraVector()
	{
		// 计算新的前向量
		glm::vec3 front;
		front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
		front.y = sin(glm::radians(Pitch));
		front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
		Front = glm::normalize(front);
	
		// 还要重新计算右和向上向量
		Right = glm::normalize(glm::cross(Front, WorldUp));	 // 将向量归一化,因为你向上或向下看的次数越多,它们的长度就越接近0,这会导致运动变慢。
	
		Up = glm::normalize(glm::cross(Right, Front));
	}



};

#endif
场景截图

在这里插入图片描述

下载链接: https://download.csdn.net/download/weixin_44294809/12053472

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用C++搭配OpenGL写了一个RenderEngine 的相关文章

随机推荐

  • 【基础知识】BSS段,数据段,代码段,堆栈段

    在了解BSS段他们之前 我们先来看一下他们在内存中的位置 BSS段 bss segmen BSS 是 Block Started by Symbol 的简称 通常是指用来存放程序中未初始化的全局变量的内存区域 属于静态内存分配 在可执行文件
  • swiper的使用,一次显示多个,竖着排列,多行多列

  • C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法

    学C 的时候 这几个输入函数弄的有点迷糊 这里做个小结 为了自己复习 也希望对后来者能有所帮助 如果有差错的地方还请各位多多指教 本文所有程序均通过VC 6 0运行 1 cin 2 cin get 3 cin getline 4 getli
  • 数据库连接池概念、原理、运行机制浅谈

    概述 数据库连接池是负责分配 管理和释放数据库连接 它允许应用程序重复使用一个现有的数据库连接 而不是再重新建立一个 那么其中的运行机制又是怎样的呢 今天主要介绍一下数据库连接池原理和常用的连接池 01 为什么要使用连接池 数据库连接是一种
  • NoPadding填充方式不会对明文块进行填充,就会出现“Input length not multiple of 8 bytes“

    DES ECB PKCS5Padding和DES ECB NoPadding的区别 DES是一种对称加密算法 它可以使用不同的模式和填充方式进行加密 在Java Cipher API中 提供了四种DES加密模式 ECB CBC CFB和OF
  • 微信小程序实现类3D轮播图

    在写微信小程序时 有写到实现3D轮播图的效果 可以直接使用微信小程序中自带的组件swiper来实现 效果图如下 1 swiper的相关属性 indicator dots 是否显示小圆点 也可以自己重新设置小圆点 circular 是否衔接滑
  • 网安入门须知:注释的危害居然这么大?——注释漏洞导致的信息泄露

    隔壁大娘收到了一条匿名短信 里面记录了大娘跟隔壁老王的开房记录 并勒索二百五十块巨款 大娘略加思索后 便提着刀冲到狗剩家门口 一刀砍在门口的卷帘门上 隔壁大娘 狗剩 你给我出来 注释导致的信息泄露 一 什么是信息泄露漏洞 二 信息泄露有什么
  • 百度刘超

    百度总监爆料刘超这几年在做什么 2016年百度用户体验部总监刘超创立百度UE讲堂的线上课 同年7月在IXDC大会上演讲引起热议和批评 2016年7月百度迫于压力免去刘超总监职位 从此刘超在媒体上消失 事情已经过了4年了 刘超这几年在做什么
  • NVIDIA安装驱动不成功的解决方式

    很多小朋友在重装或升级nvidia驱动时出现这样的错误 或是GeForce Experience安装不成功 如果排除了显示型号不对 系统没打补丁等原因 那么主要就是因为系统自动安装的驱动或是第三方安装的驱动赖在系统里 与你下载的新驱动产生冲
  • High-Resolution Image Synthesis with Latent Diffusion Models论文阅读+代码复现

    摘要 扩散模型在图像数据和其他数据上实现了最先进的合成结果 并且它的公式允许引导机制来控制图像生成的过程而无需重新训练 然而 这种模型直接在像素空间上操作 因此 功能强大的扩散模型通常需要花费大量的计算资源与推理时间 为了在有限的计算资源上
  • Elasticsearch6.4专题之杂记:遇到的异常与解决方案2

    11 lucene util BytesRefHash MaxBytesLengthExceededException bytes can be at most 32766 in length got 56965 解决方案 设置keywor
  • python界面怎么改颜色_Python界面怎么换颜色?求解!!!

    打开电脑 找到idle 并打开idle界面 打开之后默认经典的编码界面如下 白色背景 中文字体 字号也比较小 点击如图所示options选项 工具栏第五个按钮选择 这个按钮下方有一个configure idle选项 意思是配置idle 选中
  • SPI协议读写SD卡介绍

    前言 在前面的文章中 我们主要介绍了如何利用SDIO协议对SD卡进行读写操作的流程及注意事项 虽然SDIO协议读写SD卡的效率很高 但是 操作却比较麻烦 另外 还需要使用的芯片具有SDIO外设 这对于不具备SDIO外设的芯片而言 绝对是一个
  • 弱网测试用什么农_弱网测试方法整理

    说明 首先看一下其他文章对弱网测试的描述 弱网测试 属于健壮性测试的内容 为什么要做呢 现在IT行业飞速发展 各种APP都有 尤其是现在的人们更习惯在上下班的路上去关注一些新闻 看看股市 小说 直播 玩游戏等等 那么就会面临一个问题 在地铁
  • leetcode分类刷题:二叉树(一、简单的层序遍历)

    二叉树的深度优先遍历题目是让我有点晕 先把简单的层序遍历总结下吧 配合队列进行的层序遍历在逻辑思维上自然直观 不容易出错 102 二叉树的层序遍历 本题是二叉树的层序遍历模板 每次循环将一层节点出队 再将一层节点入队 也是所有可用层序遍历解
  • 小程序开发调用微信支付以及微信回调地址配置

    首先观看微信提供的文档 https pay weixin qq com wiki doc api wxa wxa api php chapter 7 3 index 1 清楚调用微信支付必须传递的参数 因为微信提供了小程序唤起微信支付的方法
  • emoji数据清洗

    在对微博等文本数据进行处理的时候发现以往的颜文字之外还会抓取到emoji数据 这部分虽然可以匹配到 但是经常挂一漏万 在网上检索到有一个emoji库可以使用 直接pip安装emoji库 import emoji import re def
  • Postman —— 配置环境变量

    PostMan是一套比较方便的接口测试工具 但我们在使用过程中 可能会出现创建了API请求 但API的URL会随着服务器IP地址的变化而改变 这样的情况下 如果每一个API都重新修改URL的话那将是非常的麻烦 所以PostMan中也提供环境
  • 第二届“移动云杯”大赛医疗行业应用子赛道答疑会成功召开

    为帮助参赛团队了解第二届 移动云杯 算力网络应用创新大赛的命题背景 作品立意 提高作品质量 9月13日 我们召开了第二届 移动云杯 大赛答疑会 特别针对医疗行业应用子赛道的赛题作讲解和答疑 赛题背景 随着科技的不断进步 精准医学技术得到了广
  • 使用C++搭配OpenGL写了一个RenderEngine

    最近在学习OpenGL 看书看的再多 也不如自己动手写一个来看看 耗时一个多月 由于才学不久 各位大佬勿喷 用到了glfw Imgui glm这几个库 整合的资源里都带了 相机类 ifndef CAMERA H define CAMERA