当前位置:   article > 正文

跟着cherno手搓游戏引擎【20】混合(blend)

跟着cherno手搓游戏引擎【20】混合(blend)

抽象:

Renderer.h:

  1. #pragma once
  2. #include"RenderCommand.h"
  3. #include "OrthographicCamera.h"
  4. #include"Shader.h"
  5. namespace YOTO {
  6. class Renderer {
  7. public:
  8. static void Init();
  9. static void BeginScene(OrthographicCamera& camera);
  10. static void EndScene();
  11. static void Submit(const Ref<Shader>& shader, const Ref<VertexArray>& vertexArray,const glm::mat4&transform = glm::mat4(1.0f));
  12. inline static RendererAPI::API GetAPI() {
  13. return RendererAPI::GetAPI();
  14. }
  15. private:
  16. struct SceneData {
  17. glm::mat4 ViewProjectionMatrix;
  18. };
  19. static SceneData* m_SceneData;
  20. };
  21. }

Renderer.cpp:

  1. #include"ytpch.h"
  2. #include"Renderer.h"
  3. #include <Platform/OpenGL/OpenGLShader.h>
  4. namespace YOTO {
  5. Renderer::SceneData* Renderer::m_SceneData = new Renderer::SceneData;
  6. void Renderer::Init()
  7. {
  8. RenderCommand::Init();
  9. }
  10. void Renderer::BeginScene(OrthographicCamera& camera)
  11. {
  12. m_SceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix();
  13. }
  14. void Renderer::EndScene()
  15. {
  16. }
  17. void Renderer::Submit(const Ref<Shader>& shader, const Ref<VertexArray>& vertexArray, const glm::mat4& transform)
  18. {
  19. shader->Bind();
  20. std::dynamic_pointer_cast<OpenGLShader>(shader)->UploadUniformMat4("u_ViewProjection", m_SceneData->ViewProjectionMatrix);
  21. std::dynamic_pointer_cast<OpenGLShader>(shader)->UploadUniformMat4("u_Transform", transform);
  22. /* mi.Bind();*/
  23. vertexArray->Bind();
  24. RenderCommand::DrawIndexed(vertexArray);
  25. }
  26. }

 RenderCommand.h:

  1. #pragma once
  2. #include"RendererAPI.h"
  3. namespace YOTO {
  4. class RenderCommand
  5. {
  6. public:
  7. inline static void Init() {
  8. s_RendererAPI->Init();
  9. }
  10. inline static void SetClearColor(const glm::vec4& color) {
  11. s_RendererAPI->SetClearColor(color);
  12. }
  13. inline static void Clear() {
  14. s_RendererAPI->Clear();
  15. }
  16. inline static void DrawIndexed(const Ref<VertexArray>& vertexArray) {
  17. s_RendererAPI->DrawIndexed(vertexArray);
  18. }
  19. private:
  20. static RendererAPI* s_RendererAPI;
  21. };
  22. }

 RendererAPI.h:

  1. #pragma once
  2. #include<glm/glm.hpp>
  3. #include "VertexArray.h"
  4. namespace YOTO {
  5. class RendererAPI
  6. {
  7. public:
  8. enum class API {
  9. None = 0,
  10. OpenGL = 1
  11. };
  12. public:
  13. virtual void Init() = 0;
  14. virtual void SetClearColor(const glm::vec4& color)=0;
  15. virtual void Clear() = 0;
  16. virtual void DrawIndexed(const Ref<VertexArray>& vertexArray)=0;
  17. inline static API GetAPI() { return s_API; }
  18. private:
  19. static API s_API;
  20. };
  21. }

实现:

OpenGLRendererAPI.h

  1. #pragma once
  2. #include"YOTO/Renderer/RendererAPI.h"
  3. namespace YOTO {
  4. class OpenGLRendererAPI:public RendererAPI
  5. {
  6. public:
  7. virtual void Init()override;
  8. virtual void SetClearColor(const glm::vec4& color)override;
  9. virtual void Clear()override;
  10. virtual void DrawIndexed(const Ref<VertexArray>& vertexArray) override;
  11. };
  12. }

 OpenGLRendererAPI.h

  1. #include "ytpch.h"
  2. #include "OpenGLTexture.h"
  3. #include<glad/glad.h>
  4. #include"stb_image.h"
  5. namespace YOTO {
  6. OpenGLTexture2D::OpenGLTexture2D(const std::string path)
  7. :m_Path(path)
  8. {
  9. int width, height, channels;
  10. stbi_set_flip_vertically_on_load(1);//翻转
  11. stbi_uc*data=stbi_load(path.c_str(),&width,&height,&channels,0);
  12. YT_CORE_ASSERT(data, "图片加载错误");
  13. m_Width = width;
  14. m_Height = height;
  15. GLenum internalFormat = 0,dataFormat=0;
  16. if (channels == 4) {
  17. internalFormat = GL_RGBA8;
  18. dataFormat = GL_RGBA;
  19. }
  20. else if (channels==3) {
  21. internalFormat = GL_RGB8;
  22. dataFormat = GL_RGB;
  23. }
  24. YT_CORE_ASSERT(internalFormat& dataFormat,"OpenGLTexture2D:不支持的颜色格式")
  25. //创建纹理
  26. glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID);
  27. ///告诉OpenGLm_RendererID的纹理存储的是rbg8位,宽高的缓冲区
  28. glTextureStorage2D(m_RendererID, 1, internalFormat,m_Width,m_Height);
  29. //配置参数:纹理放大时用周围颜色的平均值过滤
  30. glTextureParameteri(m_RendererID,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  31. glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  32. glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, dataFormat,GL_UNSIGNED_BYTE,data);
  33. stbi_image_free(data);
  34. }
  35. OpenGLTexture2D::~OpenGLTexture2D()
  36. {
  37. glDeleteTextures(1,&m_RendererID);
  38. }
  39. void OpenGLTexture2D::Bind(uint32_t slot) const
  40. {
  41. glBindTextureUnit(slot, m_RendererID);
  42. }
  43. }

  OpenGLRendererAPI.cpp

  1. #include "ytpch.h"
  2. #include "OpenGLRendererAPI.h"
  3. #include <glad/glad.h>
  4. namespace YOTO {
  5. void OpenGLRendererAPI::Init()
  6. {
  7. //启用混合
  8. glEnable(GL_BLEND);
  9. //设置混合函数
  10. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  11. }
  12. void OpenGLRendererAPI::SetClearColor(const glm::vec4& color)
  13. {
  14. glClearColor(color.r, color.g, color.b, color.a);
  15. }
  16. void OpenGLRendererAPI::Clear()
  17. {
  18. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  19. }
  20. void OpenGLRendererAPI::DrawIndexed(const Ref<VertexArray>& vertexArray)
  21. {
  22. glDrawElements(GL_TRIANGLES, vertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);
  23. }
  24. }

调用:

Application.cpp:

  1. #include"ytpch.h"
  2. #include "Application.h"
  3. #include"Log.h"
  4. #include "YOTO/Renderer/Renderer.h"
  5. #include"Input.h"
  6. #include <GLFW/glfw3.h>
  7. namespace YOTO {
  8. #define BIND_EVENT_FN(x) std::bind(&x, this, std::placeholders::_1)
  9. Application* Application::s_Instance = nullptr;
  10. Application::Application()
  11. {
  12. YT_CORE_ASSERT(!s_Instance, "Application需要为空!")
  13. s_Instance = this;
  14. //智能指针
  15. m_Window = std::unique_ptr<Window>(Window::Creat());
  16. //设置回调函数
  17. m_Window->SetEventCallback(BIND_EVENT_FN(Application::OnEvent));
  18. m_Window->SetVSync(false);
  19. Renderer::Init();
  20. //new一个Layer,放在最后层进行渲染
  21. m_ImGuiLayer = new ImGuiLayer();
  22. PushOverlay(m_ImGuiLayer);
  23. }
  24. Application::~Application() {
  25. }
  26. /// <summary>
  27. /// 所有的Window事件都会在这触发,作为参数e
  28. /// </summary>
  29. /// <param name="e"></param>
  30. void Application::OnEvent(Event& e) {
  31. //根据事件类型绑定对应事件
  32. EventDispatcher dispatcher(e);
  33. dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(Application::OnWindowClosed));
  34. //输出事件信息
  35. YT_CORE_INFO("Application:{0}", e);
  36. for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();) {
  37. (*--it)->OnEvent(e);
  38. if (e.m_Handled)
  39. break;
  40. }
  41. }
  42. bool Application::OnWindowClosed(WindowCloseEvent& e) {
  43. m_Running = false;
  44. return true;
  45. }
  46. void Application::Run() {
  47. WindowResizeEvent e(1280, 720);
  48. if (e.IsInCategory(EventCategoryApplication)) {
  49. YT_CORE_TRACE(e);
  50. }
  51. if (e.IsInCategory(EventCategoryInput)) {
  52. YT_CORE_ERROR(e);
  53. }
  54. while (m_Running)
  55. {
  56. float time = (float)glfwGetTime();//window平台
  57. Timestep timestep = time - m_LastFrameTime;
  58. m_LastFrameTime = time;
  59. for (Layer* layer : m_LayerStack) {
  60. layer->OnUpdate(timestep);
  61. }
  62. //将ImGui的刷新放到APP中,与Update分开
  63. m_ImGuiLayer->Begin();
  64. for (Layer* layer : m_LayerStack) {
  65. layer->OnImGuiRender();
  66. }
  67. m_ImGuiLayer->End();
  68. m_Window->OnUpdate();
  69. }
  70. }
  71. void Application::PushLayer(Layer* layer) {
  72. m_LayerStack.PushLayer(layer);
  73. layer->OnAttach();
  74. }
  75. void Application::PushOverlay(Layer* layer) {
  76. m_LayerStack.PushOverlay(layer);
  77. layer->OnAttach();
  78. }
  79. }

SandboxApp.cpp:

  1. #include<YOTO.h>
  2. #include "imgui/imgui.h"
  3. #include<stdio.h>
  4. #include <glm/gtc/matrix_transform.hpp>
  5. #include <Platform/OpenGL/OpenGLShader.h>
  6. #include <glm/gtc/type_ptr.hpp>
  7. class ExampleLayer:public YOTO::Layer
  8. {
  9. public:
  10. ExampleLayer()
  11. :Layer("Example"), m_Camera(-2.0f, 2.0f, -2.0f, 2.0f), m_CameraPosition(0){
  12. uint32_t indices[3] = { 0,1,2 };
  13. float vertices[3 * 7] = {
  14. -0.5f,-0.5f,0.0f, 0.8f,0.2f,0.8f,1.0f,
  15. 0.5f,-0.5f,0.0f, 0.2f,0.3f,0.8f,1.0f,
  16. 0.0f,0.5f,0.0f, 0.8f,0.8f,0.2f,1.0f,
  17. };
  18. m_VertexArray.reset(YOTO::VertexArray::Create());
  19. YOTO::Ref<YOTO::VertexBuffer> m_VertexBuffer;
  20. m_VertexBuffer.reset(YOTO::VertexBuffer::Create(vertices, sizeof(vertices)));
  21. {
  22. YOTO::BufferLayout setlayout = {
  23. {YOTO::ShaderDataType::Float3,"a_Position"},
  24. {YOTO::ShaderDataType::Float4,"a_Color"}
  25. };
  26. m_VertexBuffer->SetLayout(setlayout);
  27. }
  28. m_VertexArray->AddVertexBuffer(m_VertexBuffer);
  29. YOTO::Ref<YOTO::IndexBuffer>m_IndexBuffer;
  30. m_IndexBuffer.reset(YOTO::IndexBuffer::Create(indices, sizeof(indices) / sizeof(uint32_t)));
  31. m_VertexArray->AddIndexBuffer(m_IndexBuffer);
  32. std::string vertexSource = R"(
  33. #version 330 core
  34. layout(location = 0) in vec3 a_Position;
  35. layout(location = 1) in vec4 a_Color;
  36. uniform mat4 u_ViewProjection;
  37. uniform mat4 u_Transform;
  38. out vec3 v_Position;
  39. out vec4 v_Color;
  40. void main(){
  41. v_Position=a_Position;
  42. v_Color=a_Color;
  43. gl_Position =u_ViewProjection *u_Transform* vec4( a_Position,1.0);
  44. }
  45. )";
  46. //绘制颜色
  47. std::string fragmentSource = R"(
  48. #version 330 core
  49. layout(location = 0) out vec4 color;
  50. in vec3 v_Position;
  51. in vec4 v_Color;
  52. void main(){
  53. color=vec4(v_Color);
  54. }
  55. )";
  56. m_Shader.reset(YOTO::Shader::Create(vertexSource, fragmentSource));
  57. ///测试/
  58. m_SquareVA.reset(YOTO::VertexArray::Create());
  59. float squareVertices[5 * 4] = {
  60. -0.5f,-0.5f,0.0f, 0.0f,0.0f,
  61. 0.5f,-0.5f,0.0f, 1.0f,0.0f,
  62. 0.5f,0.5f,0.0f, 1.0f,1.0f,
  63. -0.5f,0.5f,0.0f, 0.0f,1.0f,
  64. };
  65. YOTO::Ref<YOTO::VertexBuffer> squareVB;
  66. squareVB.reset(YOTO::VertexBuffer::Create(squareVertices, sizeof(squareVertices)));
  67. squareVB->SetLayout({
  68. {YOTO::ShaderDataType::Float3,"a_Position"},
  69. {YOTO::ShaderDataType::Float2,"a_TexCoord"}
  70. });
  71. m_SquareVA->AddVertexBuffer(squareVB);
  72. uint32_t squareIndices[6] = { 0,1,2,2,3,0 };
  73. YOTO::Ref<YOTO::IndexBuffer> squareIB;
  74. squareIB.reset((YOTO::IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t))));
  75. m_SquareVA->AddIndexBuffer(squareIB);
  76. //测试:
  77. std::string BlueShaderVertexSource = R"(
  78. #version 330 core
  79. layout(location = 0) in vec3 a_Position;
  80. uniform mat4 u_ViewProjection;
  81. uniform mat4 u_Transform;
  82. out vec3 v_Position;
  83. void main(){
  84. v_Position=a_Position;
  85. gl_Position =u_ViewProjection*u_Transform*vec4( a_Position,1.0);
  86. }
  87. )";
  88. //绘制颜色
  89. std::string BlueShaderFragmentSource = R"(
  90. #version 330 core
  91. layout(location = 0) out vec4 color;
  92. in vec3 v_Position;
  93. uniform vec3 u_Color;
  94. void main(){
  95. color=vec4(u_Color,1.0);
  96. }
  97. )";
  98. m_BlueShader.reset(YOTO::Shader::Create(BlueShaderVertexSource, BlueShaderFragmentSource));
  99. std::string textureVertexSource = R"(
  100. #version 330 core
  101. layout(location = 0) in vec3 a_Position;
  102. layout(location = 1) in vec2 a_TexCoord;
  103. uniform mat4 u_ViewProjection;
  104. uniform mat4 u_Transform;
  105. out vec2 v_TexCoord;
  106. out vec3 v_Position;
  107. void main(){
  108. v_TexCoord=a_TexCoord;
  109. v_Position=a_Position;
  110. gl_Position =u_ViewProjection*u_Transform*vec4( a_Position,1.0);
  111. }
  112. )";
  113. //绘制颜色
  114. std::string textureFragmentSource = R"(
  115. #version 330 core
  116. layout(location = 0) out vec4 color;
  117. in vec3 v_Position;
  118. in vec2 v_TexCoord;
  119. uniform sampler2D u_Texture ;
  120. void main(){
  121. color = texture(u_Texture, v_TexCoord);
  122. // color = vec4(v_TexCoord, 0.0f, 1.0f);
  123. }
  124. )";
  125. m_TextureShader.reset(YOTO::Shader::Create(textureVertexSource, textureFragmentSource));
  126. m_Texture=YOTO::Texture2D::Create("assets/textures/Checkerboard.png");
  127. m_ChernoLogo= YOTO::Texture2D::Create("assets/textures/ChernoLogo.png");
  128. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_TextureShader)->Bind();
  129. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_TextureShader)->UploadUniformInt("u_Texture", 0);
  130. }
  131. void OnImGuiRender() override {
  132. ImGui::Begin("设置");
  133. ImGui::ColorEdit3("正方形颜色", glm::value_ptr(m_SquareColor));
  134. ImGui::End();
  135. }
  136. void OnUpdate(YOTO::Timestep ts)override {
  137. //YT_CLIENT_TRACE("delta time {0}s ({1}ms)", ts.GetSeconds(), ts.GetMilliseconds());
  138. if (YOTO::Input::IsKeyPressed(YT_KEY_LEFT)) {
  139. m_CameraPosition.x -= m_CameraMoveSpeed* ts;
  140. }
  141. else if (YOTO::Input::IsKeyPressed(YT_KEY_RIGHT)) {
  142. m_CameraPosition.x += m_CameraMoveSpeed * ts;
  143. }
  144. if (YOTO::Input::IsKeyPressed(YT_KEY_DOWN)) {
  145. m_CameraPosition.y -= m_CameraMoveSpeed * ts;
  146. }
  147. else if (YOTO::Input::IsKeyPressed(YT_KEY_UP)) {
  148. m_CameraPosition.y += m_CameraMoveSpeed * ts;
  149. }
  150. if (YOTO::Input::IsKeyPressed(YT_KEY_A)) {
  151. m_CameraRotation += m_CameraRotationSpeed * ts;
  152. }else if (YOTO::Input::IsKeyPressed(YT_KEY_D)) {
  153. m_CameraRotation -= m_CameraRotationSpeed * ts;
  154. }
  155. YOTO::RenderCommand::SetClearColor({ 0.2f, 0.2f, 0.2f, 1.0f });
  156. YOTO::RenderCommand::Clear();
  157. m_Camera.SetPosition(m_CameraPosition);
  158. m_Camera.SetRotation(m_CameraRotation);
  159. YOTO::Renderer::BeginScene(m_Camera);
  160. {
  161. static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
  162. glm::vec4 redColor(0.8f, 0.3f, 0.3f, 1.0f);
  163. glm::vec4 blueColor(0.2f, 0.3f, 0.8f, 1.0f);
  164. /* YOTO::MaterialRef material = new YOTO::MaterialRef(m_FlatColorShader);
  165. YOTO::MaterialInstaceRef mi = new YOTO::MaterialInstaceRef(material);
  166. mi.setValue("u_Color",redColor);
  167. mi.setTexture("u_AlbedoMap", texture);
  168. squreMesh->SetMaterial(mi);*/
  169. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->Bind();
  170. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->UploadUniformFloat3("u_Color",m_SquareColor);
  171. for (int y = 0; y < 20; y++) {
  172. for (int x = 0; x <20; x++)
  173. {
  174. glm::vec3 pos(x * 0.105f,y* 0.105f, 0.0);
  175. glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) * scale;
  176. /*if (x % 2 == 0) {
  177. m_BlueShader->UploadUniformFloat4("u_Color", redColor);
  178. }
  179. else {
  180. m_BlueShader->UploadUniformFloat4("u_Color", blueColor);
  181. }*/
  182. YOTO::Renderer::Submit(m_BlueShader, m_SquareVA, transform);
  183. }
  184. }
  185. m_Texture->Bind();
  186. YOTO::Renderer::Submit(m_TextureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
  187. m_ChernoLogo->Bind();
  188. YOTO::Renderer::Submit(m_TextureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
  189. //YOTO::Renderer::Submit(m_Shader, m_VertexArray);
  190. YOTO::Renderer::EndScene();
  191. }
  192. }
  193. void OnEvent(YOTO::Event& event)override {
  194. /*if (event.GetEventType() == YOTO::EventType::KeyPressed) {
  195. YOTO:: KeyPressedEvent& e = (YOTO::KeyPressedEvent&)event;
  196. YT_CLIENT_TRACE("ExampleLayer:{0}",(char)e.GetKeyCode());
  197. if (e.GetKeyCode()==YT_KEY_TAB) {
  198. YT_CLIENT_INFO("ExampleLayerOnEvent:TAB按下了");
  199. }}*/
  200. //YT_CLIENT_TRACE("SandBoxApp:测试event{0}", event);
  201. }
  202. private:
  203. YOTO::Ref<YOTO::Shader> m_Shader;
  204. YOTO::Ref<YOTO::VertexArray> m_VertexArray;
  205. YOTO::Ref<YOTO::Shader> m_BlueShader,m_TextureShader;
  206. YOTO::Ref<YOTO::VertexArray> m_SquareVA;
  207. YOTO::Ref<YOTO::Texture2D> m_Texture,m_ChernoLogo;
  208. YOTO::OrthographicCamera m_Camera;
  209. glm::vec3 m_CameraPosition;
  210. float m_CameraMoveSpeed = 5.0f;
  211. float m_CameraRotation = 0;
  212. float m_CameraRotationSpeed = 180.0f;
  213. glm::vec3 m_SquareColor = { 0.2f,0.3f,0.7f };
  214. };
  215. class Sandbox:public YOTO::Application
  216. {
  217. public:
  218. Sandbox(){
  219. PushLayer(new ExampleLayer());
  220. //PushLayer(new YOTO::ImGuiLayer());
  221. }
  222. ~Sandbox() {
  223. }
  224. private:
  225. };
  226. YOTO::Application* YOTO::CreateApplication() {
  227. printf("helloworld");
  228. return new Sandbox();
  229. }

加了个init涉及了好几个类,小改动,为了方便观察,我把整个类都复制下来了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/81161
推荐阅读
相关标签
  

闽ICP备14008679号