跟着cherno手搓游戏引擎【15】DrawCall的封装

目标:

 Application.cpp:把渲染循环里的glad代码封装成自己的类:

#include"ytpch.h"
#include "Application.h"#include"Log.h"
#include "YOTO/Renderer/Renderer.h"
#include"Input.h"namespace YOTO {
#define BIND_EVENT_FN(x) std::bind(&x, this, std::placeholders::_1)Application* Application::s_Instance = nullptr;Application::Application() {YT_CORE_ASSERT(!s_Instance, "Application需要为空!")s_Instance = this;//智能指针m_Window = std::unique_ptr<Window>(Window::Creat());//设置回调函数m_Window->SetEventCallback(BIND_EVENT_FN(Application::OnEvent));//new一个Layer,放在最后层进行渲染m_ImGuiLayer = new ImGuiLayer();PushOverlay(m_ImGuiLayer);  //unsigned int id;//glGenBuffers(1, &id);uint32_t indices[3] = { 0,1,2 };float vertices[3 * 7] = {-0.5f,-0.5f,0.0f, 0.8f,0.2f,0.8f,1.0f,0.5f,-0.5f,0.0f,  0.2f,0.3f,0.8f,1.0f,0.0f,0.5f,0.0f,   0.8f,0.8f,0.2f,1.0f,};m_VertexArray.reset(VertexArray::Create());std::shared_ptr<VertexBuffer> m_VertexBuffer;m_VertexBuffer.reset(VertexBuffer::Create(vertices, sizeof(vertices)));{BufferLayout setlayout = {{ShaderDataType::Float3,"a_Position"},{ShaderDataType::Float4,"a_Color"}};m_VertexBuffer->SetLayout(setlayout);}m_VertexArray->AddVertexBuffer(m_VertexBuffer);std::shared_ptr<IndexBuffer>m_IndexBuffer;m_IndexBuffer.reset(IndexBuffer::Create(indices, sizeof(indices)/sizeof(uint32_t)));m_VertexArray->AddIndexBuffer(m_IndexBuffer);std::string vertexSource = R"(#version 330 corelayout(location = 0) in vec3 a_Position;layout(location = 1) in vec4 a_Color;out vec3 v_Position;out vec4 v_Color;void main(){v_Position=a_Position;v_Color=a_Color;gl_Position =vec4( a_Position+0.5,1.0);})";//绘制颜色std::string fragmentSource = R"(#version 330 corelayout(location = 0) out vec4 color;in vec3 v_Position;in vec4 v_Color;void main(){color=vec4(v_Color);})";m_Shader.reset(new Shader(vertexSource, fragmentSource));///测试/m_SquareVA.reset(VertexArray::Create());float squareVertices[3 * 4] = {-0.5f,-0.5f,0.0f,0.5f,-0.5f,0.0f, 0.5f,0.5f,0.0f,-0.5f,0.5f,0.0f};std::shared_ptr<VertexBuffer> squareVB;squareVB.reset(VertexBuffer::Create(squareVertices, sizeof(squareVertices)));squareVB->SetLayout({{ShaderDataType::Float3,"a_Position"}});m_SquareVA->AddVertexBuffer(squareVB);uint32_t squareIndices[6] = { 0,1,2,2,3,0 };std::shared_ptr<IndexBuffer> squareIB; squareIB.reset((IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t))));m_SquareVA->AddIndexBuffer(squareIB);//测试:std::string BlueShaderVertexSource = R"(#version 330 corelayout(location = 0) in vec3 a_Position;out vec3 v_Position;void main(){v_Position=a_Position;gl_Position =vec4( a_Position,1.0);})";//绘制颜色std::string BlueShaderFragmentSource = R"(#version 330 corelayout(location = 0) out vec4 color;in vec3 v_Position;void main(){color=vec4(0.2,0.3,0.8,1.0);})";m_BlueShader.reset(new Shader(BlueShaderVertexSource, BlueShaderFragmentSource));}Application::~Application() {}/// <summary>/// 所有的Window事件都会在这触发,作为参数e/// </summary>/// <param name="e"></param>void Application::OnEvent(Event& e) {//根据事件类型绑定对应事件EventDispatcher dispatcher(e);dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(Application::OnWindowClosed));//输出事件信息YT_CORE_INFO("Application:{0}",e);for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();) {(*--it)->OnEvent(e);if (e.m_Handled)break;}}bool Application::OnWindowClosed(WindowCloseEvent& e) {m_Running = false;return true;}void Application::Run() {WindowResizeEvent e(1280, 720);if (e.IsInCategory(EventCategoryApplication)) {YT_CORE_TRACE(e);}if (e.IsInCategory(EventCategoryInput)) {YT_CORE_ERROR(e);}while (m_Running){/*	glClearColor(0.2f, 0.2f, 0.2f,1);glClear(GL_COLOR_BUFFER_BIT);*/RenderCommand::SetClearColor({0.2f, 0.2f, 0.2f, 1.0f});RenderCommand::Clear();Renderer::BeginScene();{m_BlueShader->Bind();Renderer::Submit(m_SquareVA);m_Shader->Bind();Renderer::Submit(m_VertexArray);Renderer::EndScene();}//m_BlueShader->Bind();//m_SquareVA->Bind();//glDrawElements(GL_TRIANGLES, m_SquareVA->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);glBindVertexArray(m_VertexArray);//m_Shader->Bind();//m_VertexArray->Bind();//glDrawElements(GL_TRIANGLES,m_VertexArray->GetIndexBuffer()->GetCount(),GL_UNSIGNED_INT,nullptr); for (Layer* layer : m_LayerStack) {layer->OnUpdate();}//将ImGui的刷新放到APP中,与Update分开m_ImGuiLayer->Begin();for (Layer* layer : m_LayerStack) {layer->OnImGuiRender();}m_ImGuiLayer->End();m_Window->OnUpdate();}}void Application::PushLayer(Layer* layer) {m_LayerStack.PushLayer(layer);layer->OnAttach();}void Application::PushOverlay(Layer* layer) {m_LayerStack.PushOverlay(layer);layer->OnAttach();}
}

抽象:

RendererAPI.h:渲染API的抽象,包括API实现的功能都封装一下:

#pragma once
#include<glm/glm.hpp>
#include "VertexArray.h"
namespace YOTO {class RendererAPI{public:enum class API {None = 0,OpenGL = 1};public:virtual void SetClearColor(const glm::vec4& color)=0;virtual void Clear() = 0;virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray)=0;	inline static API GetAPI() { return s_API; }private:static API s_API;};
}

 RendererAPI.cpp:给当前API赋值:

#include "ytpch.h"
#include "RendererAPI.h"
namespace YOTO {RendererAPI::API RendererAPI::s_API = RendererAPI::API::OpenGL;
}

 实现:

OpenGLRendererAPI.h:实现接口,制定重写方法,在cpp中封账glad代码:

#pragma once
#include"YOTO/Renderer/RendererAPI.h"
namespace YOTO {class OpenGLRendererAPI:public RendererAPI{public:virtual void SetClearColor(const glm::vec4& color)override;virtual void Clear()override;virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray) override;};
}

 OpenGLRendererAPI.cpp:

#include "ytpch.h"
#include "OpenGLRendererAPI.h"
#include <glad/glad.h>
namespace YOTO {void OpenGLRendererAPI::SetClearColor(const glm::vec4& color){glClearColor(color.r, color.g, color.b, color.a);}void OpenGLRendererAPI::Clear(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);}void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray){glDrawElements(GL_TRIANGLES, vertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);}
}

调用:

RenderCommand.h:根据当前API调用API的一些通用方法:

#pragma once
#include"RendererAPI.h"
namespace YOTO {class RenderCommand{public:inline static void SetClearColor(const glm::vec4& color) {s_RendererAPI->SetClearColor(color);}inline static void Clear() {s_RendererAPI->Clear();}inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray) {s_RendererAPI->DrawIndexed(vertexArray);}private:static RendererAPI* s_RendererAPI;};}

 RenderCommand.cpp:(个人觉得应该在new的时候再给API的枚举赋值,在 RendererAPI

.cpp中导致可以new 其他API枚举选另一个API)(不知道后面会不会改)

#include "ytpch.h"
#include "RenderCommand.h"
#include"Platform/OpenGL/OpenGLRendererAPI.h"
namespace YOTO {RendererAPI* RenderCommand::s_RendererAPI = new OpenGLRendererAPI;
}

Renderer.h: 对command的一些方法进行进一步封装,并拓展出Begin和End方法:

#pragma once
#include"RenderCommand.h"
namespace YOTO {class Renderer {public:static void BeginScene();static void EndScene();static void Submit(const std::shared_ptr<VertexArray>& vertexArray);inline static RendererAPI::API GetAPI() {return RendererAPI::GetAPI();}};}

Renderer.cpp: 

#include"ytpch.h"
#include"Renderer.h"
namespace YOTO {void Renderer::BeginScene(){}void Renderer::EndScene(){}void Renderer::Submit(const std::shared_ptr<VertexArray>& vertexArray){vertexArray->Bind();RenderCommand::DrawIndexed(vertexArray);}
}

修改:

所有switch的枚举都改成这样(会报错,报了再改也行)

RendererAPI::API::OpenGL:

测试:

 原汁原味儿~能跑出来就对了!

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

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

相关文章

构建高效可靠的消息队列系统:设计与实现

目录 一、引言 二、设计目标 2.1、高可用性 1. 集群搭建 1.1 Docker Compose配置示例 2. 容错和恢复 2.1 异常检测与自动故障迁移 2.2 Spring Boot代码示例 3. 心跳检测 4. 优雅关闭 2.2、持久性 1. 生产者消息持久化 2. 队列的持久化 3. 消息队列的持久化 总结 …

Android Studio使用小记

复制了一个原来的项目&#xff0c;准备基于它调整一个OEM版本 因为svn服务器上分出了一个单独的版本&#xff0c;于是在工程目录下手工删除了.svn文件&#xff0c;并手工去除了vcs.xml <?xml version"1.0" encoding"UTF-8"?> <project versi…

第4章 python深度学习——(波斯美女)

第4章 机器学习基础 本章包括以下内容&#xff1a; 除分类和回归之外的机器学习形式 评估机器学习模型的规范流程 为深度学习准备数据 特征工程 解决过拟合 处理机器学习问题的通用工作流程 学完第 3 章的三个实例&#xff0c;你应该已经知道如何用神经网络解决分类问题和回归…

高通GAIA V3命令参考手册的研读学习(十三):GAIA通知

如前文《高通GAIA V3命令参考手册的研读学习&#xff08;四&#xff09;》所述&#xff0c;PDU一共有四种&#xff0c;前面已经讲了命令、回应以及错误码&#xff0c;现在来看最后一种&#xff1a;通知。 4. QTIL GAIA通知 通知发送的方向&#xff0c;是由设备发送到移动应用…

【Node.js】fs与path模块的基础使用

文章目录 前言一、什么叫做模块二、fs模块2.1 fs模块是干什么的&#xff1f;2.2 fs模块的使用导入fs模块读取文件的内容写入文件内容处理路径问题path路径模块 总结 前言 在Node.js中&#xff0c;fs模块&#xff08;文件系统模块&#xff09;是一个重要的核心模块&#xff0c;…

【操作系统】调用硬盘并且实现MBR与Loader的过渡——实战篇

一.概述 有了上一篇文章&#xff1a;【操作系统】调用硬盘并且实现MBR与Loader的过渡——原理篇的理论支持&#xff0c;我们就可以开始代码实操了&#xff0c;接下来我们将优化MBR程序&#xff0c;使其从扇区中读取出loader加载器&#xff0c;并将其存放到内存处&#xff0c;将…

springboot(ssm环保网站 绿色环保宣传系统Java系统

springboot(ssm环保网站 绿色环保宣传系统Java系统 开发语言&#xff1a;Java 框架&#xff1a;springboot&#xff08;可改ssm&#xff09; vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff0…

C++ easyX小程序:画五角星

//本小程序通过调用easyX的moveto、lineto函数画出五角星编写了FiveStar函数&#xff0c;在调用这个函数时setbkcolor、setlinecolor、setfillcolor设置了背景、线及填充颜色&#xff0c;又调用floodfill函数对五角星进行颜色填充。 //代码及注释如下&#xff1a; #include<…

excel怎么设置密码?轻松保护您的工作表

在数字化时代&#xff0c;数据的安全性显得尤为重要。excel作为我们日常工作中广泛使用的办公软件&#xff0c;其中可能包含了大量的敏感数据。为了确保这些数据不被未授权的人访问&#xff0c;本文将为您详细介绍excel怎么设置密码&#xff0c;从而有效地保护您的数据安全。 方…

基于Redis的高可用分布式锁——RedLock

目录 RedLock简介 RedLock工作流程 获取锁 释放锁 RedLock简介 Redis作者提出来的高可用分布式锁由多个完全独立的Redis节点组成&#xff0c;注意是完全独立&#xff0c;而不是主从关系或者集群关系&#xff0c;并且一般是要求分开机器部署的利用分布式高可以系统中大多数存…

delphi fmxui 做的一些跨平台app

pascal语音显然已经没落&#xff0c;但delphi还在坚挺着&#xff0c;每年都会发布新版本&#xff0c; 主要是做跨平台应用。 如果你觉得qt qml 写android app 比较麻烦&#xff0c;那可以尝试delphi 12&#xff0c;可以用c builder 尝试 android&#xff0c;ios 开发 下面的…

【Spring连载】使用Spring Data访问Redis(一)----快速指南

【Spring连载】使用Spring Data访问Redis&#xff08;一&#xff09;----快速指南 一、导入依赖二、Hello World程序 一、导入依赖 在pom.xml文件加入如下依赖就可以下载到spring data redis的jar包了&#xff1a; <dependency><groupId>org.springframework.boot…

适用于 Windows 7/8/10/11电脑的 12 款顶级数据恢复软件

很多时候&#xff0c;我们在 Windows 7 /8/10/11下不小心按了删除键&#xff0c;从而丢失了硬盘或 USB 驱动器中的重要文件和数据。在某些情况下&#xff0c;病毒或软件错误可能会损坏您的硬盘&#xff0c;从而影响您的文件。在这种情况下&#xff0c;您迫切需要一款适用于 Win…

STM32——点灯

STM32——点灯 1.开发准备 开发环境:keil5&#xff0c;STM32CubeMX 开发语言:C语言 烧录工具:ST-Link 库函数:HAL库 2.点灯 常用的GPIO HAL库函数&#xff1a; //GPIO初始化 void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init); //调制电平 void H…

怎么创建docker镜像

创建Docker镜像可以通过以下几个步骤&#xff1a; 编写Dockerfile&#xff1a;Dockerfile是一个文本文件&#xff0c;定义了镜像的构建过程。在Dockerfile中&#xff0c;可以指定基础镜像、添加应用程序代码和依赖、设置环境变量、运行命令等。根据应用程序的需求&#xff0c;编…

Labview 图像处理系统设计

1. 总体主界面设计 前面板界面如下&#xff1a; 界面总共分为一个实时采集加拍照控制模块&#xff0c;两个图像显示模块&#xff08;实时图像显示和直方图显示&#xff09;以及三个图像处理模块 前面板中各模块具体功能及使用说明如下&#xff1a; 1.当实时按钮关闭时&#x…

mysql .ibd 文件过大清理方法

问题 有一个 info_track 表用来临时存储告警推送数据&#xff0c;逻辑处理完成后&#xff0c;会执行 Delete 语句删除对应的记录。 问题&#xff1a;项目现场运行了几个月后&#xff0c;发现磁盘空间莫名占用了过多的存储&#xff0c;> 100GB&#xff0c;且无法释放。 生…

javaScript遍历数组的一些方法

1&#xff0c;for循环 for循环是最基础并且是比较常用的一种 let arr[1,2,3,4,5]for(let i0;i<arr.length;i){//分别输出1,2,3,4,5console.log(arrarr[i])} 2&#xff0c;for...of循环 使用for...of循环可以遍历数组&#xff0c;并且直接获取里面的每个元素 let arr[1,2,…

向上调整向下调整算法

目录 AdjustUp向上调整 AdjustDown向下调整 AdjustUp向上调整 前提是&#xff1a;插入数据之后&#xff0c;除去插入的数据其他的数据还是为堆 应用&#xff1a;插入数据。 先插入一个10到数组的尾上&#xff0c;再进行向上调整算法&#xff0c;直到满足堆。 性质&#xff1…

【每日一题】YACS 473:栈的判断

这是上海计算机学会竞赛 P 473 P473 P473&#xff1a;栈的判断&#xff08; 2021 2021 2021年 8 8 8月月赛 丙组 T 4 T4 T4&#xff09;标签&#xff1a;栈题意&#xff1a;给定 n n n个数字&#xff0c;已知这些数字的入栈顺序为 1 , 2 , 3... , n 1,2,3...,n 1,2,3...,n&…