自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(68)
  • 收藏
  • 关注

原创 TheCherno——Engine(二十三)Renderer RendererAPI RendererCommand

这不能像是顶点数组、顶点缓冲区和索引缓冲区那样,Create函数中创建一个OpenGLVertexArray或OpenGLVertexBuffer或OpenGLIndexBuffer。Renderer(渲染器),BeginScene负责初始化相机、场景、光照等,Submit提交顶点数组,EndScene结束打扫战场。静态成员函数只能访问静态成员变量和其他静态成员函数,不能访问类的非静态成员变量或非静态成员函数。静态成员属于类本身,而不是类的某个具体对象。但这是是渲染的指令,不适合上面的方法。

2025-03-20 11:46:01 350

原创 TheCherno——Engine(二十二)Vertex Array

在DTClass项目下的src文件夹下的Renderer文件夹下,新建VertexArray.h和VertexArray.cpp。Platform下的OpenGL,新建OpenGLVertexArray.h和OpenGLVertexArray.cpp。索引缓冲区存储顶点的索引,用于定义如何将顶点组合成图元(如三角形、线段等)。由于顶点数组和缓冲区关系密切(从顶点数组可以找到缓冲区以及其中的布局)顶点数组是一个对象,用于管理顶点缓冲区、索引缓冲区和顶点布局的状态。马上要做的是:封装顶点数组。

2025-03-19 16:52:29 54

原创 TheCherno——Engine(二十一)Buffer Layout缓冲区布局

OpenGLBuffer.h 其中的OpenGLVertexBuffer中私有成员变量m_Layout,还有SetLayout和GetLayout的实现。比如 对于上图中的verteices,顶点缓冲区接受了这些float数值,还需要告诉GPU它们的“结构”如何。现在要将这个也抽象出来。

2025-03-18 18:32:21 60

原创 TheCherno——Engine(二十)Buffer抽象(顶点/索引缓冲区)

同样可以正常运行,如果要换渲染API,就弄好相应的(如DirectXBuffer指令)之后,在Renderer.cpp中,更改 RendererAPI Renderer::s_RendererAPI。首先,在DTClass项目的src文件夹中的Renderer文件夹中新建Buffer.h和Buffer.cpp,Renderer.h和Renderer.cpp。Buffer.cpp Create函数,根据RendererAPI的类别,选择创建相应的对象。这里应该采取的第二种,有的全部编译一遍。

2025-03-17 11:41:24 40

原创 TheCherno——Engine(二十)着色器

是运行在 GPU 上的小型程序,用于控制图形渲染管线的不同阶段。它们是 OpenGL 可编程渲染管线的核心组成部分,允许开发者编写自定义的图形处理逻辑。着色器是用 GLSL 编写的,它是一种类似于 C 的语言,专为图形处理设计。2将着色器源代码加载到着色器对象的代码片段 glShaderSource。6附加着色器对象给着色器程序对象 glAttachShader。构造函数中编写着色器语言,构建Shader对象。Run函数中,在绘制三角形前,绑定着色器。如果是这个着色器语言,输入红色三角形。

2025-03-16 17:07:42 39

原创 TheCherno——Engine(十九)首个三角形

表示这是一个顶点缓冲对象(VBO),用于存储顶点数据(如位置、颜色、法线等);OpenGL 是一个状态机,绑定缓冲对象后,所有相关操作(如上传数据、配置属性)都会作用于这个缓冲对象。启用顶点属性数组后,OpenGL 会从绑定的顶点缓冲对象(VBO)中读取数据,并将其传递给顶点着色器。:表示连续顶点属性之间的字节偏移量(步长)。在构造函数中,配置的内容都被VAO记录,包括两个缓冲区,以及其中的数据。是 OpenGL 中的一个对象,用于存储顶点属性的配置状态。:表示绑定的缓冲对象类型为顶点缓冲对象(VBO)。

2025-03-16 10:09:29 448

原创 TheCherno——Engine(十八)渲染上下文的抽象

渲染上下文是一个抽象的概念,表示图形 API 与 GPU 之间的连接和状态管理。它包含了当前图形渲染所需的所有状态信息,例如着色器程序、缓冲区、纹理、混合模式等。

2025-03-14 21:10:17 483

原创 TheCherno——Engine(十七)渲染开始之前

但它并不是硬件。OpenGL和GPU:

2025-03-14 15:14:20 495

原创 TheCherno——Engine(十六)ImGui - docking

调整ImGui,后面进入渲染部分了添加:停靠(docking)

2025-03-12 14:16:37 521

原创 TheCherno——Engine(十五)glm数学库

然而,写一个数学库容易,而写一个高性能的数学库还是不容易的。将glm放在DTClass项目vendor文件中。这个比较简单,就是导入了供后续使用的glm库。打断点,看cam是有值,说明glm配置成功。引擎中需要的数学,应该要算的越快越好。在premake5.lua中配置。因为后续需要向量、矩阵这些支撑。综合考虑之下,引入glm数学库。

2025-03-11 16:51:03 27

原创 TheCherno——Engine(十四)按键与鼠标键代码

在DTClass-src-DTClass文件夹下,新建KeyCodes.h和MouseButtonCodes.h。目前,如何在程序要监测是否按键W被按下,那么有 Input::IsKeyPressed(GLFW_KEY_W)这是GLFW的按键代码,使用的话要在用到这个代码的地方 #include <GLFW/glfw3.h>这里还要包含GLFW的库,但并不想我们的应用还这么依赖这个GLFW,这和依赖于spdlog有所不同。在DTClass.h中 添加 #include "DTClass/Input.h"

2025-03-11 11:29:24 49

原创 TheCherno——Engine(十三)Polling Input

在Platform文件夹下的Window文件夹新建WindowsInput.h和WindowsInput.cpp。比如:后续如何要控制相机,使用alt键和鼠标左键控制,就要在监测的地方询问,“按下(某键)了吗?polling input 目的:在程序的任何一个位置询问,嘿,这个键按下了吗?从Application 到 Window类 再到 具体的 GLFWwindow。在DTClass项目src的DTClass中新建Input.h。注意要在Winow.h和WindowsWindow中添加。

2025-03-10 21:42:44 55

原创 TheCherno——Engine(十二) ImGui事件处理

前面构建了一个ImGuiLayer,并把它推到了LayerStacke的最“顶”端(其实是尾部位置)ImGuiLayer处于LayerStack的顶层(其实是列表尾部),在处理事件时,它先进行处理。窗口事件回调中,加入KeyCode事件的回调,其中生成KeyTypedEvent对象。ImGuiLayer.h 增加了多个处理事件的私有成员函数,以及相应的头文件。每个处理函数将事件与ImGui的状态联系起来,事件改变了ImGui的状态。但是这个ImGuiLayer还不能处理事件,也就是对于事件是无动于衷的。

2025-03-10 17:20:11 41

原创 TheCherno——Engine(十一)ImGui

ImGui(Immediate Mode Graphical User Interface,即时模式图形用户界面)是一种轻量级的、代码驱动的图形用户界面库,主要用于游戏开发、工具开发和实时应用程序中。3.ImGui非常轻量,核心代码仅包含10个文件,支持多种平台和渲染后端(如DirectX、OpenGL、Vulkan等),并且可以轻松集成到自定义引擎中。在DTClass项目下的src中新建ImGui文件下,在其下建ImGuiLayer.h和ImGuiLayer.cpp。是 ImGui 的一个。

2025-03-10 10:56:45 275

原创 TheCherno——Engine(十) Glad

因为 OpenGL 是一个图形渲染 API,而 GPU(Graphics Processing Unit,图形处理单元)是执行图形渲染任务的硬件。OpenGL 的作用是提供一种标准化的方式,让开发者能够利用 GPU 的强大计算能力来实现高效的图形渲染。OpenGL(Open Graphics Library)是一个跨平台、跨语言的图形渲染 API(应用程序编程接口),用于渲染 2D 和 3D 矢量图形。glad的下载:https://glad.dav1d.de。include中是glad.h。

2025-03-06 19:21:15 289

原创 TheCherno——Engine(九)层Layer

在src-DTClass下,新建Layer.h Layer.cpp LayerStack.h 和LayerStack.cpp。在Application.cpp中给出方法的实现,并更新OnUpdate方法与OnEvent方法。层的排列 相当于一个列表,按序号0,1,... , size-1 排列。层 Layer 一个比较抽象的概念,用于呈现某些内容和处理事件。为了顺利运行,还需要在premake5.lua中进行配置。在SandboxApp.cpp中。在Application.h中。

2025-03-06 09:39:04 58

原创 TheCherno——Engine(八) 事件传回Application

当某一事件发生时,构建相应的事件类,将这个类作为参数,“传回”Application中的OnEvent函数,OnEvent函数对【窗口关闭事件】进行事件拦截,调用OnWindowClose函数进行处理,使应用终止。其中的成员函数Dispatch也是一个模板函数,需要一个函数作为参数传入,将这个类的事件类型与模板类的类型一致时,事件被传入到函数中进行后续处理。总结:监测窗口事件,生成相应的事件类,将事件类传回Application的OnEvent函数中进行相应处理。解释std::bind函数。

2025-03-05 16:37:34 53

原创 TheCherno——Engine(七) GLFW窗口

是一个开源的、跨平台的库,用于创建和管理窗口、OpenGL 或 OpenGL ES 上下文,以及处理输入设备(如键盘、鼠标和游戏手柄)。它旨在为开发者提供一个简单且高效的接口,以便快速启动和运行图形应用程序。在DTClass-src新建文件夹Platform-再新建文件夹Windows。出现了一个名为“Digital Twin Class"的粉色窗口。在dtcpch.h中添加 头文件Log.h。主要负责:管理窗口、处理输入。配置结束后,重新生成,并运行。在Core.h中添加。

2025-03-03 15:51:34 45

原创 TheCherno——Engine(六)预编译头文件

头文件通常包含大量声明和模板代码,每次编译源文件时都会重新处理这些内容。预编译头文件将这些内容预先编译并保存,避免重复处理。:多个源文件可能包含相同的头文件,预编译头文件只需编译一次,供所有源文件使用。在项目中所有的.cpp文件中都添加:#include "dtcpch.h"在DTClass项目的src中创建dtcpch.h和.cpp文件。视频中,那些非自定义头文件(预编译头文件包含的那些)都被删除了。

2025-03-02 21:12:29 28

原创 TheCherno——Engine(五)

Application中可以了解Window的所有信息,在Application的构造函数中,就可以创建一个Window类;在回调函数中,会根据相应的事件信息创建相应的事件类,例如,鼠标点击事件发生,那么创建一个鼠标点击事件类,类中应有鼠标点击的位置和点击的鼠标键这些数据;回调函数中,还会将这个事件类作为Application中OnEvent函数的参数,这样就可以将事件传回到Application,而Window可以不对Application有所认识。Application.cpp中。

2025-02-25 16:39:53 52

原创 TheCherno——Engine(四)

项目文件),从而简化项目的配置和管理。Premake 通过 Lua 脚本定义项目的结构、编译选项、依赖项等,然后根据这些定义生成 Visual Studio 所需的项目文件。不用再在项目属性中进行一一设置,而直接在.lua文件中编写好,由premake进行生成。方便跨平台,也便于配置。

2025-02-21 13:48:49 55

原创 TheCherno——Engine(三)

spdlog:是一个高效且易用的 C++ 日志库,旨在提供快速、线程安全的日志记录功能。它的设计目标是性能优越,并且非常简洁易用,适合用于高性能应用程序中。静态成员变量属于类本身,而不是类的某个实例。可以减少函数调用的开销(如栈帧的创建和销毁),适合用于简单的、频繁调用的函数。静态成员变量需要在类外进行定义和初始化(通常在类的实现文件中)。内联函数会在调用点直接展开函数体,而不是进行常规的函数调用。静态成员函数属于类本身,而不是类的某个实例。可以通过类名直接调用,而不需要创建类的对象。

2025-02-20 19:56:37 267

原创 TheCherno——Engine(二)

DTClass-src-DTClass-Core.h 这里将__declspec(dllexport) 和__declspec(dllexport)简化为DTC_API。DTClass-src-DTClass-Application.h 加了一个CreateApplication的函数声明。DTClass-src-DTClass-Application.h和.cpp。新建DTClass-src-DTClass-EntryPoint.h 头文件。Application类中的Run暂时是一个无限的循环。

2025-02-20 15:10:41 255

原创 TheCherno——Engine(一)

游戏引擎存在的意义:避免重复劳动 —— 对于这一点,我的理解是,引擎提供了一个框架,这个框架已经由引擎的设计和开发人员做好了,在后期制作游戏的时候,就是将制作游戏所需要的输入(也就是资产),有了输入和框架,这个游戏就呈现出来了。游戏引擎功能:数据A 转换为 数据B(比如,桌面上一组文件,将其读取并转换为呈现在屏幕上的图像),并总是提供与用户交互的方式。理解总结:在一个解决方案下,构建两个项目,一个项目作为引擎,动态链接到另一个作为应用程序的项目中。游戏引擎是基于数据的,不可能凭空编造数据。

2025-02-19 20:49:17 405

原创 OpenGL的学习之路 -5

人眼看世界,有一个可见范围。范围内可见,范围外不可见。在OGL中,有两种投影方式,对应两种视景体。,矩阵A变化,太阳自转,地球跟着太阳转;透视投影(可见,从视觉效果上,透视投影更符合人眼),地球自转的同时绕着太阳公转,同时,太阳也在自转。2.几个代码示例(主要目的:弄明白 变换栈),矩阵C变化,地球实现自转的效果;‘D’或者‘d’以及‘Y’或者‘y’(4)月亮绕着地球转、地球绕着太阳转。(2)键盘控制的自转和公转。1.视景体 正交投影。(上图仅学习记录用)透视投影(替换代码)(1)三个球绕红球转。

2023-11-26 22:37:54 625 1

原创 最小二乘法

最小二乘法

2023-11-24 20:51:24 170

原创 凸包的学习之路

凸包——graham scan algorithm

2023-11-19 15:27:39 259

原创 OpenGL 的学习之路-4(变换)

9个参数,三个一组,前三个是相机的位置,中间三个是相机看向的方向,后三个是相机的top方向。这里,一开始,相机位于原点位置,相机看向z轴负半轴(也就是屏幕里),相机的top方向是y轴的正方向。拍摄受相机的影响,影响相机的三个因素:相机的位置、相机的指向、相机的top方向。如果把相机比作人的眼睛的话,眼睛的位置、眼睛看向哪里、头的歪头。所有的变换操作是放在一个栈中的,在施加一个新变化上,该语句的作用是向栈中压入一个I(单位阵),也就是现在还无变换。3.如果有多个变换的函数,先施行的是最下面的,然后往上进行。

2023-11-18 21:58:56 316

原创 OpenGL的学习之路-3

令点A代表骰子的点数为1、4,点B代表骰子的点数为2、5,点C代表骰子的点数为3、6。现在开始扔,如果扔的点数为1或者4,那么取AP的中点作为新的P;如果扔到的点数为3,6,则同理取CP的中点作为新的P。同时,要把每次取得的新的P绘制出来,并保持与相应的A或B或C同色。glBegin(GL_LINES_LOOP) :给出的两个相邻的点首尾相连,最后一个点和第一个点相连,构成环。点和点之间是配对的,如果给的点的个数是奇数,那么最后一个点没有找到和他配对的点,会不起作用。明明是随机的,却呈现了规律性。

2023-11-13 15:43:57 625

原创 OpenGL学习之路-2

引入bool量isShowSubWin0, isShowSubWin1, isShowSubWin2, isShowSubWin3来判断是否应该显示该子窗口。1.回调函数myMainWinReshape中:改变窗口大小时,先将原来子窗口销毁(如果存在的话),再重新产生新的子窗口。道理上是这个样子,但是我在实际运行过程中,拖动鼠标改变窗口大小时,出现了问题。差不多是说,没有注册给窗口6的回调函数。可能和我这个freeglut有关系的。8.多窗口且子窗口能够跟随reshape的变化而变化。

2023-11-13 09:04:16 161

原创 凸包的学习之路

那么如何确定最初的那个极点呢,这里采用Lowest-then-Leftmost策略,实际上是两条准则,先找最低的点(也就是y值最小的点),如果存在多个y值相同的点,那么在找那个最左的点(也就是x值最小的点)。那极边的特性是,除了构成该极边的两个极点之外,剩下所有的点都在该极边的一边。OK啦,休息一下啦。如果是逆时针转的话,下一个极边从极点k出发,对其他点 l 进行搜索,如果新的 l 在kl的右侧,则更新极点。然后,松手,橡皮筋就会套在“最外面”的那些钉子上,会呈现出一个轮廓,这个轮廓构成的形状,就是凸包。

2023-11-12 18:26:32 252

原创 OpenGL学习之路

2.回调函数myMouse:四个参数,第一个int _button代表的是点击的是鼠标的哪个键(左键、中键、右键),int _state代表的是状态(按下DOWN、松开UP),int _x代表x坐标,int _y代表y坐标.2.glutCreateSubWindow(mainWin, 0, 0, 200, 200) : 子窗口,其主窗口为mainWin,位置(0,0),大小(200,200)按下F5之后,执行了 glutSpecialFunc(NULL),再按下其他的特殊键,也不会执行什么了。

2023-11-05 21:50:08 260

原创 数值分析:解线性方程组2

数值分析-学习记录

2023-10-30 17:07:12 283

原创 Code::Blocks+Opengl 环境搭建

code::blocks + opengl 环境搭建

2023-10-30 09:50:36 434 2

原创 【数值分析】解线性方程组

数值分析-学习记录

2023-10-28 11:27:42 310

原创 学习总结:关于C++ 4

是为data对应在内存中预留了大小为100的空间,只要存入的元素的内存大小不超过100,就不会“搬家”。但是,此时,data的大小还是0。对对象data中的元素进行循环,首先创建迭代器对象it,这个东西类似数组却不是数组,类似指针却不是指针。,可以直接向对象data中压入元素x,data的size也自然+1。这句话之后才是为vector对象data分配了20个空间。19(通过构建一个“迭代器”来探索迭代器的原理)首先,建立了一个vector类型的对象data,上述程序属于STL编程(也就是标准模板库编程)

2023-10-22 14:44:24 86

原创 学习总结:关于C++ 3

执行POW3(a++)之后,得到的是a*(a+1)*(a+1+1),那么最后a将变成a+1+1+1。BB结束之前,要告知他的父类,AA再执行析构函数。(没有函数调用的过程),调用pow3(a++),返回a*a*a,最后a将变成a+1。17(朋友类在父类中声明,相当于授权给子类能看见父类的private)15(继承中出现同名——加帽子,以及子类结束后父类也要再结束)这里不太明白的是,为什么a初始为16 0,而不是0 0。16(虚拟成员函数被继承的子类中的同名函数掩盖)如果使用内嵌函数inline。

2023-10-05 16:02:40 119

原创 Canny边缘检测

也可以直接用opencv的Canny函数,一句代码就可以实现。真的是傻瓜使用方式。这里面我觉得非极大值抑制那里的代码不太对,我在下面的代码中改了一下。Canny.h(自定义头文件)具体原理可以去某站学习。

2023-10-03 21:44:23 118

原创 学习总结:关于C++ 2

这样定义一个头文件,用宏来减少了工作量。但是,不适合多人协作编程...而C++中提供了更好的方式。疑问:为什么前面出现了"kill me!",说明是执行了析构函数?9( 宏的使用可以减少重复作用代码编写的工作量,但是...)10(结构体中使用模板template - 一)11(结构体中使用模板template - 二)8(类中成员函数之操作符的重载)project的结构如上。project的结构如上。7(类的分文件编写)

2023-10-03 11:06:43 120

原创 学习总结:关于C++ 1

(2)规定每一个结构体中都有一个this指针指向它自己,*this就是指向的具体的值。(3)在成员函数的函数头中的函数返回类型后的&,表示“引用”,作用是返回的不是一个临时开辟进行存储的空间内容(临时变量),而就是它自己!(2)函数参数带有标记&,意味着“引用”(reference),形参变成了实参的别称(同一个东西,同一块内存空间)。(4)C语言中不允许函数同名,而C++中允许,只要函数的参数不同就可以。(2)根据类构造对象时,其后参数的不同,调用不同的构造函数。4(引用,没有值传递的过程)

2023-10-02 22:41:50 127

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除