当前位置:   article > 正文

跟着cherno手搓游戏引擎【22】CameraController、Resize

跟着cherno手搓游戏引擎【22】CameraController、Resize

前置:

YOTO.h: 

  1. #pragma once
  2. //用于YOTO APP
  3. #include "YOTO/Application.h"
  4. #include"YOTO/Layer.h"
  5. #include "YOTO/Log.h"
  6. #include"YOTO/Core/Timestep.h"
  7. #include"YOTO/Input.h"
  8. #include"YOTO/KeyCode.h"
  9. #include"YOTO/MouseButtonCodes.h"
  10. #include "YOTO/OrthographicCameraController.h"
  11. #include"YOTO/ImGui/ImGuiLayer.h"
  12. //Renderer
  13. #include"YOTO/Renderer/Renderer.h"
  14. #include"YOTO/Renderer/RenderCommand.h"
  15. #include"YOTO/Renderer/Buffer.h"
  16. #include"YOTO/Renderer/Shader.h"
  17. #include"YOTO/Renderer/Texture.h"
  18. #include"YOTO/Renderer/VertexArray.h"
  19. #include"YOTO/Renderer/OrthographicCamera.h"
  20. //入口点
  21. #include"YOTO/EntryPoint.h"

 添加方法:

OrthographicCamera.h:

  1. #pragma once
  2. #include <glm/glm.hpp>
  3. namespace YOTO {
  4. class OrthographicCamera
  5. {
  6. public:
  7. OrthographicCamera(float left, float right, float bottom, float top);
  8. void SetProjection(float left, float right, float bottom, float top);
  9. const glm::vec3& GetPosition()const { return m_Position; }
  10. void SetPosition(const glm::vec3& position) {
  11. m_Position = position;
  12. RecalculateViewMatrix();
  13. }
  14. float GetRotation()const { return m_Rotation; }
  15. void SetRotation(float rotation) {
  16. m_Rotation = rotation;
  17. RecalculateViewMatrix();
  18. }
  19. const glm::mat4& GetProjectionMatrix()const { return m_ProjectionMatrix; }
  20. const glm::mat4& GetViewMatrix()const { return m_ViewMatrix; }
  21. const glm::mat4& GetViewProjectionMatrix()const { return m_ViewProjectionMatrix; }
  22. private:
  23. void RecalculateViewMatrix();
  24. private:
  25. glm::mat4 m_ProjectionMatrix;
  26. glm::mat4 m_ViewMatrix;
  27. glm::mat4 m_ViewProjectionMatrix;
  28. glm::vec3 m_Position = { 0.0f ,0.0f ,0.0f };
  29. float m_Rotation = 0.0f;
  30. };
  31. }

OrthographicCamera.cpp:

  1. #include "ytpch.h"
  2. #include "OrthographicCamera.h"
  3. #include <glm/gtc/matrix_transform.hpp>
  4. namespace YOTO {
  5. OrthographicCamera::OrthographicCamera(float left, float right, float bottom, float top)
  6. :m_ProjectionMatrix(glm::ortho(left, right, bottom, top)), m_ViewMatrix(1.0f)
  7. {
  8. m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
  9. }
  10. void OrthographicCamera::SetProjection(float left, float right, float bottom, float top) {
  11. m_ProjectionMatrix = glm::ortho(left, right, bottom, top);
  12. m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
  13. }
  14. void OrthographicCamera::RecalculateViewMatrix()
  15. {
  16. glm::mat4 transform = glm::translate(glm::mat4(1.0f), m_Position) *
  17. glm::rotate(glm::mat4(1.0f), glm::radians(m_Rotation), glm::vec3(0, 0, 1));
  18. m_ViewMatrix = glm::inverse(transform);
  19. m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
  20. }
  21. }

封装控制类:

OrthographicCameraController.h: 

  1. #pragma once
  2. #include "YOTO/Renderer/OrthographicCamera.h"
  3. #include"YOTO/Core/Timestep.h"
  4. #include "YOTO/Event/ApplicationEvent.h"
  5. #include "YOTO/Event/MouseEvent.h"
  6. namespace YOTO {
  7. class OrthographicCameraController {
  8. public:
  9. OrthographicCameraController(float aspectRatio, bool rotation=false );//0,1280
  10. void OnUpdate(Timestep ts);
  11. void OnEvent(Event& e);
  12. OrthographicCamera& GetCamera() {
  13. return m_Camera
  14. ;
  15. }
  16. const OrthographicCamera& GetCamera()const {
  17. return m_Camera
  18. ;
  19. }
  20. private:
  21. bool OnMouseScrolled(MouseScrolledEvent &e);
  22. bool OnWindowResized(WindowResizeEvent& e);
  23. private:
  24. float m_AspectRatio;//横纵比
  25. float m_ZoomLevel = 1.0f;
  26. OrthographicCamera m_Camera;
  27. bool m_Rotation;
  28. glm::vec3 m_CameraPosition = {0.0f,0.0f,0.0f};
  29. float m_CameraRotation = 0.0f;
  30. float m_CameraTranslationSpeed = 1.0f, m_CameraRotationSpeed = 180.0f;
  31. };
  32. }

 OrthographicCameraController.cpp: 

  1. #include "ytpch.h"
  2. #include "OrthographicCameraController.h"
  3. #include"YOTO/Input.h"
  4. #include <YOTO/KeyCode.h>
  5. namespace YOTO {
  6. OrthographicCameraController::OrthographicCameraController(float aspectRatio, bool rotation)
  7. :m_AspectRatio(aspectRatio),m_Camera(-m_AspectRatio*m_ZoomLevel,m_AspectRatio*m_ZoomLevel,-m_ZoomLevel,m_ZoomLevel),m_Rotation(rotation)
  8. {
  9. }
  10. void OrthographicCameraController::OnUpdate(Timestep ts)
  11. {
  12. if (Input::IsKeyPressed(YT_KEY_A)) {
  13. m_CameraPosition.x -= m_CameraTranslationSpeed * ts;
  14. }
  15. else if (Input::IsKeyPressed(YT_KEY_D)) {
  16. m_CameraPosition.x += m_CameraTranslationSpeed * ts;
  17. }
  18. if (Input::IsKeyPressed(YT_KEY_S)) {
  19. m_CameraPosition.y -= m_CameraTranslationSpeed * ts;
  20. }
  21. else if (Input::IsKeyPressed(YT_KEY_W)) {
  22. m_CameraPosition.y += m_CameraTranslationSpeed * ts;
  23. }
  24. if (m_Rotation) {
  25. if (Input::IsKeyPressed(YT_KEY_Q)) {
  26. m_CameraRotation += m_CameraRotationSpeed * ts;
  27. }
  28. else if (Input::IsKeyPressed(YT_KEY_E)) {
  29. m_CameraRotation -= m_CameraRotationSpeed * ts;
  30. }
  31. m_Camera.SetRotation(m_CameraRotation);
  32. }
  33. m_Camera.SetPosition(m_CameraPosition);
  34. m_CameraTranslationSpeed = m_ZoomLevel;
  35. }
  36. void OrthographicCameraController::OnEvent(Event& e)
  37. {
  38. EventDispatcher dispatcher(e);
  39. dispatcher.Dispatch<MouseScrolledEvent>(YT_BIND_EVENT_FN(OrthographicCameraController::OnMouseScrolled));
  40. dispatcher.Dispatch<WindowResizeEvent>(YT_BIND_EVENT_FN(OrthographicCameraController::OnWindowResized));
  41. }
  42. bool OrthographicCameraController::OnMouseScrolled(MouseScrolledEvent& e)
  43. {
  44. m_ZoomLevel -= e.GetYOffset()*0.5f;
  45. m_ZoomLevel = std::max(m_ZoomLevel, 0.25f);
  46. m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);
  47. return false;
  48. }
  49. bool OrthographicCameraController::OnWindowResized(WindowResizeEvent& e)
  50. {
  51. m_AspectRatio = (float)e.GetWidth()/(float) e.GetHeight();
  52. m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);
  53. return false;
  54. }
  55. }

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_CameraController(1280.0f/720.0f,true){
  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=(YOTO::Shader::Create("VertexPosColor", 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=(YOTO::Shader::Create("FlatColor", BlueShaderVertexSource, BlueShaderFragmentSource));
  99. auto textureShader= m_ShaderLibrary.Load("assets/shaders/Texture.glsl");
  100. m_Texture=YOTO::Texture2D::Create("assets/textures/Checkerboard.png");
  101. m_ChernoLogo= YOTO::Texture2D::Create("assets/textures/ChernoLogo.png");
  102. std::dynamic_pointer_cast<YOTO::OpenGLShader>(textureShader)->Bind();
  103. std::dynamic_pointer_cast<YOTO::OpenGLShader>(textureShader)->UploadUniformInt("u_Texture", 0);
  104. }
  105. void OnImGuiRender() override {
  106. ImGui::Begin("设置");
  107. ImGui::ColorEdit3("正方形颜色", glm::value_ptr(m_SquareColor));
  108. ImGui::End();
  109. }
  110. void OnUpdate(YOTO::Timestep ts)override {
  111. //update
  112. m_CameraController.OnUpdate(ts);
  113. //YT_CLIENT_TRACE("delta time {0}s ({1}ms)", ts.GetSeconds(), ts.GetMilliseconds());
  114. //Render
  115. YOTO::RenderCommand::SetClearColor({ 0.2f, 0.2f, 0.2f, 1.0f });
  116. YOTO::RenderCommand::Clear();
  117. YOTO::Renderer::BeginScene(m_CameraController.GetCamera());
  118. {
  119. static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
  120. glm::vec4 redColor(0.8f, 0.3f, 0.3f, 1.0f);
  121. glm::vec4 blueColor(0.2f, 0.3f, 0.8f, 1.0f);
  122. /* YOTO::MaterialRef material = new YOTO::MaterialRef(m_FlatColorShader);
  123. YOTO::MaterialInstaceRef mi = new YOTO::MaterialInstaceRef(material);
  124. mi.setValue("u_Color",redColor);
  125. mi.setTexture("u_AlbedoMap", texture);
  126. squreMesh->SetMaterial(mi);*/
  127. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->Bind();
  128. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->UploadUniformFloat3("u_Color",m_SquareColor);
  129. for (int y = 0; y < 20; y++) {
  130. for (int x = 0; x <20; x++)
  131. {
  132. glm::vec3 pos(x * 0.105f,y* 0.105f, 0.0);
  133. glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) * scale;
  134. /* if (x % 2 == 0) {
  135. m_BlueShader->UploadUniformFloat4("u_Color", redColor);
  136. }
  137. else {
  138. m_BlueShader->UploadUniformFloat4("u_Color", blueColor);
  139. }*/
  140. YOTO::Renderer::Submit(m_BlueShader, m_SquareVA, transform);
  141. }
  142. }
  143. auto textureShader = m_ShaderLibrary.Get("Texture");
  144. m_Texture->Bind();
  145. YOTO::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
  146. m_ChernoLogo->Bind();
  147. YOTO::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
  148. //YOTO::Renderer::Submit(m_Shader, m_VertexArray);
  149. }
  150. YOTO::Renderer::EndScene();
  151. //YOTO::Renderer3D::BeginScene(m_Scene);
  152. //YOTO::Renderer2D::BeginScene(m_Scene);
  153. }
  154. void OnEvent(YOTO::Event& e)override {
  155. m_CameraController.OnEvent(e);
  156. /*if (event.GetEventType() == YOTO::EventType::KeyPressed) {
  157. YOTO:: KeyPressedEvent& e = (YOTO::KeyPressedEvent&)event;
  158. YT_CLIENT_TRACE("ExampleLayer:{0}",(char)e.GetKeyCode());
  159. if (e.GetKeyCode()==YT_KEY_TAB) {
  160. YT_CLIENT_INFO("ExampleLayerOnEvent:TAB按下了");
  161. }}*/
  162. //YT_CLIENT_TRACE("SandBoxApp:测试event{0}", event);
  163. }
  164. private:
  165. YOTO::ShaderLibrary m_ShaderLibrary;
  166. YOTO::Ref<YOTO::Shader> m_Shader;
  167. YOTO::Ref<YOTO::VertexArray> m_VertexArray;
  168. YOTO::Ref<YOTO::Shader> m_BlueShader;
  169. YOTO::Ref<YOTO::VertexArray> m_SquareVA;
  170. YOTO::Ref<YOTO::Texture2D> m_Texture,m_ChernoLogo;
  171. YOTO::OrthographicCameraController m_CameraController;
  172. glm::vec3 m_SquareColor = { 0.2f,0.3f,0.7f };
  173. };
  174. class Sandbox:public YOTO::Application
  175. {
  176. public:
  177. Sandbox(){
  178. PushLayer(new ExampleLayer());
  179. //PushLayer(new YOTO::ImGuiLayer());
  180. }
  181. ~Sandbox() {
  182. }
  183. private:
  184. };
  185. YOTO::Application* YOTO::CreateApplication() {
  186. printf("helloworld");
  187. return new Sandbox();
  188. }

测试:

 cool

修改:

添加修改视口的方法:

Render.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 OnWindowResize(uint32_t width,uint32_t height);
  10. static void BeginScene(OrthographicCamera& camera);
  11. static void EndScene();
  12. static void Submit(const Ref<Shader>& shader, const Ref<VertexArray>& vertexArray,const glm::mat4&transform = glm::mat4(1.0f));
  13. inline static RendererAPI::API GetAPI() {
  14. return RendererAPI::GetAPI();
  15. }
  16. private:
  17. struct SceneData {
  18. glm::mat4 ViewProjectionMatrix;
  19. };
  20. static SceneData* m_SceneData;
  21. };
  22. }

Render.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::OnWindowResize(uint32_t width, uint32_t height)
  11. {
  12. RenderCommand::SetViewport(0, 0, width, height);
  13. }
  14. void Renderer::BeginScene(OrthographicCamera& camera)
  15. {
  16. m_SceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix();
  17. }
  18. void Renderer::EndScene()
  19. {
  20. }
  21. void Renderer::Submit(const Ref<Shader>& shader, const Ref<VertexArray>& vertexArray, const glm::mat4& transform)
  22. {
  23. shader->Bind();
  24. std::dynamic_pointer_cast<OpenGLShader>(shader)->UploadUniformMat4("u_ViewProjection", m_SceneData->ViewProjectionMatrix);
  25. std::dynamic_pointer_cast<OpenGLShader>(shader)->UploadUniformMat4("u_Transform", transform);
  26. /* mi.Bind();*/
  27. vertexArray->Bind();
  28. RenderCommand::DrawIndexed(vertexArray);
  29. }
  30. }

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 SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
  11. s_RendererAPI->SetViewport(x,y,width,height);
  12. }
  13. inline static void SetClearColor(const glm::vec4& color) {
  14. s_RendererAPI->SetClearColor(color);
  15. }
  16. inline static void Clear() {
  17. s_RendererAPI->Clear();
  18. }
  19. inline static void DrawIndexed(const Ref<VertexArray>& vertexArray) {
  20. s_RendererAPI->DrawIndexed(vertexArray);
  21. }
  22. private:
  23. static RendererAPI* s_RendererAPI;
  24. };
  25. }

RenderAPI.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 SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
  16. virtual void Clear() = 0;
  17. virtual void DrawIndexed(const Ref<VertexArray>& vertexArray)=0;
  18. inline static API GetAPI() { return s_API; }
  19. private:
  20. static API s_API;
  21. };
  22. }

OpenGLRenderAPI.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 SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override;
  9. virtual void SetClearColor(const glm::vec4& color)override;
  10. virtual void Clear()override;
  11. virtual void DrawIndexed(const Ref<VertexArray>& vertexArray) override;
  12. };
  13. }

OpenGLRenderAPI.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::SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
  13. {
  14. glViewport(x, y, width, height);
  15. }
  16. void OpenGLRendererAPI::SetClearColor(const glm::vec4& color)
  17. {
  18. glClearColor(color.r, color.g, color.b, color.a);
  19. }
  20. void OpenGLRendererAPI::Clear()
  21. {
  22. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  23. }
  24. void OpenGLRendererAPI::DrawIndexed(const Ref<VertexArray>& vertexArray)
  25. {
  26. glDrawElements(GL_TRIANGLES, vertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);
  27. }
  28. }

OrthographicCameraController.h: 

  1. #pragma once
  2. #include "YOTO/Renderer/OrthographicCamera.h"
  3. #include"YOTO/Core/Timestep.h"
  4. #include "YOTO/Event/ApplicationEvent.h"
  5. #include "YOTO/Event/MouseEvent.h"
  6. namespace YOTO {
  7. class OrthographicCameraController {
  8. public:
  9. OrthographicCameraController(float aspectRatio, bool rotation=false );//0,1280
  10. void OnUpdate(Timestep ts);
  11. void OnEvent(Event& e);
  12. OrthographicCamera& GetCamera() {
  13. return m_Camera
  14. ;
  15. }
  16. const OrthographicCamera& GetCamera()const {
  17. return m_Camera
  18. ;
  19. }
  20. float GetZoomLevel() { return m_ZoomLevel; }
  21. void SetZoomLevel(float level) { m_ZoomLevel = level; }
  22. private:
  23. bool OnMouseScrolled(MouseScrolledEvent &e);
  24. bool OnWindowResized(WindowResizeEvent& e);
  25. private:
  26. float m_AspectRatio;//横纵比
  27. float m_ZoomLevel = 1.0f;
  28. OrthographicCamera m_Camera;
  29. bool m_Rotation;
  30. glm::vec3 m_CameraPosition = {0.0f,0.0f,0.0f};
  31. float m_CameraRotation = 0.0f;
  32. float m_CameraTranslationSpeed = 1.0f, m_CameraRotationSpeed = 180.0f;
  33. };
  34. }

OrthographicCameraController.cpp:  

  1. #include "ytpch.h"
  2. #include "OrthographicCameraController.h"
  3. #include"YOTO/Input.h"
  4. #include <YOTO/KeyCode.h>
  5. namespace YOTO {
  6. OrthographicCameraController::OrthographicCameraController(float aspectRatio, bool rotation)
  7. :m_AspectRatio(aspectRatio),m_Camera(-m_AspectRatio*m_ZoomLevel,m_AspectRatio*m_ZoomLevel,-m_ZoomLevel,m_ZoomLevel),m_Rotation(rotation)
  8. {
  9. }
  10. void OrthographicCameraController::OnUpdate(Timestep ts)
  11. {
  12. if (Input::IsKeyPressed(YT_KEY_A)) {
  13. m_CameraPosition.x -= m_CameraTranslationSpeed * ts;
  14. }
  15. else if (Input::IsKeyPressed(YT_KEY_D)) {
  16. m_CameraPosition.x += m_CameraTranslationSpeed * ts;
  17. }
  18. if (Input::IsKeyPressed(YT_KEY_S)) {
  19. m_CameraPosition.y -= m_CameraTranslationSpeed * ts;
  20. }
  21. else if (Input::IsKeyPressed(YT_KEY_W)) {
  22. m_CameraPosition.y += m_CameraTranslationSpeed * ts;
  23. }
  24. if (m_Rotation) {
  25. if (Input::IsKeyPressed(YT_KEY_Q)) {
  26. m_CameraRotation += m_CameraRotationSpeed * ts;
  27. }
  28. else if (Input::IsKeyPressed(YT_KEY_E)) {
  29. m_CameraRotation -= m_CameraRotationSpeed * ts;
  30. }
  31. m_Camera.SetRotation(m_CameraRotation);
  32. }
  33. m_Camera.SetPosition(m_CameraPosition);
  34. m_CameraTranslationSpeed = m_ZoomLevel;
  35. }
  36. void OrthographicCameraController::OnEvent(Event& e)
  37. {
  38. EventDispatcher dispatcher(e);
  39. dispatcher.Dispatch<MouseScrolledEvent>(YT_BIND_EVENT_FN(OrthographicCameraController::OnMouseScrolled));
  40. dispatcher.Dispatch<WindowResizeEvent>(YT_BIND_EVENT_FN(OrthographicCameraController::OnWindowResized));
  41. }
  42. bool OrthographicCameraController::OnMouseScrolled(MouseScrolledEvent& e)
  43. {
  44. m_ZoomLevel -= e.GetYOffset()*0.5f;
  45. m_ZoomLevel = std::max(m_ZoomLevel, 0.25f);
  46. m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);
  47. return false;
  48. }
  49. bool OrthographicCameraController::OnWindowResized(WindowResizeEvent& e)
  50. {
  51. m_AspectRatio = (float)e.GetWidth()/(float) e.GetHeight();
  52. m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);
  53. return false;
  54. }
  55. }

Application.h:

  1. #pragma once
  2. #include"Core.h"
  3. #include"Event/Event.h"
  4. #include"Event/ApplicationEvent.h"
  5. #include "YOTO/Window.h"
  6. #include"YOTO/LayerStack.h"
  7. #include"YOTO/ImGui/ImGuiLayer.h"
  8. #include "YOTO/Core/Timestep.h"
  9. #include "YOTO/Renderer/OrthographicCamera.h"
  10. namespace YOTO {
  11. class YOTO_API Application
  12. {
  13. public:
  14. Application();
  15. virtual ~Application();
  16. void Run();
  17. void OnEvent(Event& e);
  18. void PushLayer(Layer* layer);
  19. void PushOverlay(Layer* layer);
  20. inline static Application& Get() { return *s_Instance; }
  21. inline Window& GetWindow() { return *m_Window; }
  22. private:
  23. bool OnWindowClosed(WindowCloseEvent& e);
  24. bool OnWindowResize(WindowResizeEvent& e);
  25. private:
  26. std::unique_ptr<Window> m_Window;
  27. ImGuiLayer* m_ImGuiLayer;
  28. bool m_Running = true;
  29. bool m_Minimized = false;
  30. LayerStack m_LayerStack;
  31. Timestep m_Timestep;
  32. float m_LastFrameTime = 0.0f;
  33. private:
  34. static Application* s_Instance;
  35. };
  36. //在客户端定义
  37. Application* CreateApplication();
  38. }

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. dispatcher.Dispatch<WindowResizeEvent>(BIND_EVENT_FN(Application::OnWindowResize));
  35. //输出事件信息
  36. YT_CORE_INFO("Application:{0}", e);
  37. for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();) {
  38. (*--it)->OnEvent(e);
  39. if (e.m_Handled)
  40. break;
  41. }
  42. }
  43. bool Application::OnWindowClosed(WindowCloseEvent& e) {
  44. m_Running = false;
  45. return true;
  46. }
  47. bool Application::OnWindowResize(WindowResizeEvent& e)
  48. {
  49. if (e.GetWidth()==0||e.GetHeight()==0) {
  50. m_Minimized = true;
  51. return false;
  52. }
  53. m_Minimized = false;
  54. //调整视口
  55. Renderer::OnWindowResize(e.GetWidth(), e.GetHeight());
  56. return false;
  57. }
  58. void Application::Run() {
  59. WindowResizeEvent e(1280, 720);
  60. if (e.IsInCategory(EventCategoryApplication)) {
  61. YT_CORE_TRACE(e);
  62. }
  63. if (e.IsInCategory(EventCategoryInput)) {
  64. YT_CORE_ERROR(e);
  65. }
  66. while (m_Running)
  67. {
  68. float time = (float)glfwGetTime();//window平台
  69. Timestep timestep = time - m_LastFrameTime;
  70. m_LastFrameTime = time;
  71. if (!m_Minimized) {
  72. for (Layer* layer : m_LayerStack) {
  73. layer->OnUpdate(timestep);
  74. }
  75. }
  76. //将ImGui的刷新放到APP中,与Update分开
  77. m_ImGuiLayer->Begin();
  78. for (Layer* layer : m_LayerStack) {
  79. layer->OnImGuiRender();
  80. }
  81. m_ImGuiLayer->End();
  82. m_Window->OnUpdate();
  83. }
  84. }
  85. void Application::PushLayer(Layer* layer) {
  86. m_LayerStack.PushLayer(layer);
  87. layer->OnAttach();
  88. }
  89. void Application::PushOverlay(Layer* layer) {
  90. m_LayerStack.PushOverlay(layer);
  91. layer->OnAttach();
  92. }
  93. }

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_CameraController(1280.0f/720.0f,true){
  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=(YOTO::Shader::Create("VertexPosColor", 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=(YOTO::Shader::Create("FlatColor", BlueShaderVertexSource, BlueShaderFragmentSource));
  99. auto textureShader= m_ShaderLibrary.Load("assets/shaders/Texture.glsl");
  100. m_Texture=YOTO::Texture2D::Create("assets/textures/Checkerboard.png");
  101. m_ChernoLogo= YOTO::Texture2D::Create("assets/textures/ChernoLogo.png");
  102. std::dynamic_pointer_cast<YOTO::OpenGLShader>(textureShader)->Bind();
  103. std::dynamic_pointer_cast<YOTO::OpenGLShader>(textureShader)->UploadUniformInt("u_Texture", 0);
  104. }
  105. void OnImGuiRender() override {
  106. ImGui::Begin("设置");
  107. ImGui::ColorEdit3("正方形颜色", glm::value_ptr(m_SquareColor));
  108. ImGui::End();
  109. }
  110. void OnUpdate(YOTO::Timestep ts)override {
  111. //update
  112. m_CameraController.OnUpdate(ts);
  113. //YT_CLIENT_TRACE("delta time {0}s ({1}ms)", ts.GetSeconds(), ts.GetMilliseconds());
  114. //Render
  115. YOTO::RenderCommand::SetClearColor({ 0.2f, 0.2f, 0.2f, 1.0f });
  116. YOTO::RenderCommand::Clear();
  117. YOTO::Renderer::BeginScene(m_CameraController.GetCamera());
  118. {
  119. static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
  120. glm::vec4 redColor(0.8f, 0.3f, 0.3f, 1.0f);
  121. glm::vec4 blueColor(0.2f, 0.3f, 0.8f, 1.0f);
  122. /* YOTO::MaterialRef material = new YOTO::MaterialRef(m_FlatColorShader);
  123. YOTO::MaterialInstaceRef mi = new YOTO::MaterialInstaceRef(material);
  124. mi.setValue("u_Color",redColor);
  125. mi.setTexture("u_AlbedoMap", texture);
  126. squreMesh->SetMaterial(mi);*/
  127. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->Bind();
  128. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_BlueShader)->UploadUniformFloat3("u_Color",m_SquareColor);
  129. for (int y = 0; y < 20; y++) {
  130. for (int x = 0; x <20; x++)
  131. {
  132. glm::vec3 pos(x * 0.105f,y* 0.105f, 0.0);
  133. glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) * scale;
  134. /* if (x % 2 == 0) {
  135. m_BlueShader->UploadUniformFloat4("u_Color", redColor);
  136. }
  137. else {
  138. m_BlueShader->UploadUniformFloat4("u_Color", blueColor);
  139. }*/
  140. YOTO::Renderer::Submit(m_BlueShader, m_SquareVA, transform);
  141. }
  142. }
  143. auto textureShader = m_ShaderLibrary.Get("Texture");
  144. m_Texture->Bind();
  145. YOTO::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
  146. m_ChernoLogo->Bind();
  147. YOTO::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
  148. //YOTO::Renderer::Submit(m_Shader, m_VertexArray);
  149. }
  150. YOTO::Renderer::EndScene();
  151. //YOTO::Renderer3D::BeginScene(m_Scene);
  152. //YOTO::Renderer2D::BeginScene(m_Scene);
  153. }
  154. void OnEvent(YOTO::Event& e)override {
  155. m_CameraController.OnEvent(e);
  156. if (e.GetEventType() == YOTO::EventType::WindowResize) {
  157. auto& re = (YOTO::WindowResizeEvent&)e;
  158. /* float zoom = re.GetWidth() / 1280.0f;
  159. m_CameraController.SetZoomLevel(zoom);*/
  160. }
  161. }
  162. private:
  163. YOTO::ShaderLibrary m_ShaderLibrary;
  164. YOTO::Ref<YOTO::Shader> m_Shader;
  165. YOTO::Ref<YOTO::VertexArray> m_VertexArray;
  166. YOTO::Ref<YOTO::Shader> m_BlueShader;
  167. YOTO::Ref<YOTO::VertexArray> m_SquareVA;
  168. YOTO::Ref<YOTO::Texture2D> m_Texture,m_ChernoLogo;
  169. YOTO::OrthographicCameraController m_CameraController;
  170. glm::vec3 m_SquareColor = { 0.2f,0.3f,0.7f };
  171. };
  172. class Sandbox:public YOTO::Application
  173. {
  174. public:
  175. Sandbox(){
  176. PushLayer(new ExampleLayer());
  177. //PushLayer(new YOTO::ImGuiLayer());
  178. }
  179. ~Sandbox() {
  180. }
  181. private:
  182. };
  183. YOTO::Application* YOTO::CreateApplication() {
  184. printf("helloworld");
  185. return new Sandbox();
  186. }

添加了新功能,修改窗口大小在OnEvent中。

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

闽ICP备14008679号