当前位置:   article > 正文

跟着cherno手搓游戏引擎【25】封装2DRenderer,封装shader传参,自定义Texture

跟着cherno手搓游戏引擎【25】封装2DRenderer,封装shader传参,自定义Texture

封装2DRenderer:

Renderer.h:

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

Renderer2D.h:专门渲染2D的类,负责“画什么”的问题

  1. #pragma once
  2. #include "OrthographicCamera.h"
  3. #include"Texture.h"
  4. namespace YOTO {
  5. class Renderer2D
  6. {
  7. public:
  8. //为什么渲染器是静态的:
  9. static void Init();
  10. static void ShutDown();
  11. static void BeginScene(const OrthographicCamera& camera);
  12. static void EndScene();
  13. static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color);
  14. static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color);
  15. static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D> texture);
  16. static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D> texture);
  17. private:
  18. private:
  19. };
  20. }

 Renderer2D.cpp:

  1. #include "ytpch.h"
  2. #include "Renderer2D.h"
  3. #include"VertexArray.h"
  4. #include"Shader.h"
  5. //#include "Platform/OpenGL/OpenGLShader.h"
  6. #include <glm/gtc/matrix_transform.hpp>
  7. #include "RenderCommand.h"
  8. namespace YOTO {
  9. struct Renderer2DStorage {
  10. Ref<VertexArray> QuadVertexArray;
  11. //Ref<Shader> FlatColorShader;
  12. Ref<Shader> TextureShader;
  13. Ref<Texture2D> WhiteTexture;
  14. };
  15. static Renderer2DStorage* s_Data;
  16. void Renderer2D::Init()
  17. {
  18. s_Data = new Renderer2DStorage();
  19. s_Data->QuadVertexArray = VertexArray::Create();
  20. float squareVertices[5 * 4] = {
  21. -0.5f,-0.5f,0.0f,0.0f,0.0f,
  22. 0.5f,-0.5f,0.0f,1.0f,0.0f,
  23. 0.5f,0.5f,0.0f,1.0f,1.0f,
  24. -0.5f,0.5f,0.0f,0.0f,1.0f,
  25. };
  26. Ref<VertexBuffer> squareVB;
  27. squareVB.reset(VertexBuffer::Create(squareVertices, sizeof(squareVertices)));
  28. squareVB->SetLayout({
  29. {ShaderDataType::Float3,"a_Position"},
  30. {ShaderDataType::Float2,"a_TexCoord"}
  31. });
  32. s_Data->QuadVertexArray->AddVertexBuffer(squareVB);
  33. uint32_t squareIndices[6] = { 0,1,2,2,3,0 };
  34. Ref<IndexBuffer> squareIB;
  35. squareIB.reset((IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t))));
  36. s_Data->QuadVertexArray->AddIndexBuffer(squareIB);
  37. s_Data->WhiteTexture = Texture2D::Create(1, 1);
  38. uint32_t whiteTextureData = 0xffffffff;
  39. s_Data->WhiteTexture->SetData(&whiteTextureData,sizeof(uint32_t));
  40. //s_Data->FlatColorShader =Shader::Create("assets/shaders/FlatColor.glsl");
  41. s_Data->TextureShader= Shader::Create("assets/shaders/Texture.glsl");
  42. s_Data->TextureShader->Bind();
  43. s_Data->TextureShader->SetInt("u_Texture", 0);
  44. }
  45. void Renderer2D::ShutDown()
  46. {
  47. delete s_Data;
  48. }
  49. void Renderer2D::BeginScene(const OrthographicCamera& camera)
  50. {
  51. /*s_Data->FlatColorShader->Bind();
  52. s_Data->FlatColorShader->SetMat4("u_ViewProjection",camera.GetViewProjectionMatrix());*/
  53. s_Data->TextureShader->Bind();
  54. s_Data->TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
  55. }
  56. void Renderer2D::EndScene()
  57. {
  58. }
  59. void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color)
  60. {
  61. DrawQuad({ position.x,position.y,0.0f }, size, color);
  62. }
  63. void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color)
  64. {
  65. //s_Data->FlatColorShader->Bind();
  66. //s_Data->FlatColorShader->SetFloat4("u_Color", color);
  67. //s_Data->TextureShader->Bind();
  68. s_Data->TextureShader->SetFloat4("u_Color", color);
  69. s_Data->WhiteTexture->Bind();
  70. glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) /**rotation*/ * glm::scale(glm::mat4(1.0f), {size.x,size.y,1.0f});
  71. s_Data->TextureShader->SetMat4("u_Transform", transform);
  72. s_Data->QuadVertexArray->Bind();
  73. RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
  74. }
  75. void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D> texture)
  76. {
  77. DrawQuad({ position.x,position.y,0.0f }, size, texture);
  78. }
  79. void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D> texture)
  80. {
  81. //s_Data->TextureShader->Bind();
  82. s_Data->TextureShader->SetFloat4("u_Color", {0.2f,0.3f,0.8f,0.5f});
  83. texture->Bind();
  84. glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) /**rotation*/ * glm::scale(glm::mat4(1.0f), { size.x,size.y,1.0f });
  85. s_Data->TextureShader->SetMat4("u_Transform", transform);
  86. s_Data->QuadVertexArray->Bind();
  87. RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
  88. }
  89. }

封装Shader传参:

Shader.h:添加SetInt、SetFloat3...等等Set方法

  1. #pragma once
  2. #include <string>
  3. #include<glm/glm.hpp>
  4. namespace YOTO {
  5. class Shader {
  6. public:
  7. virtual~Shader()=default;
  8. virtual void Bind()const=0;
  9. virtual void UnBind()const=0;
  10. virtual void SetInt(const std::string& name,int value) = 0;
  11. virtual void SetFloat3(const std::string& name, const glm::vec3& value) = 0;
  12. virtual void SetFloat4(const std::string& name, const glm::vec4& value) = 0;
  13. virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0;
  14. virtual const std::string& GetName()const = 0;
  15. static Ref<Shader> Create(const std::string& filepath);
  16. static Ref<Shader> Create(const std::string&name, const std::string& vertexSrc, const std::string& fragmentSrc);
  17. };
  18. class ShaderLibrary {
  19. public:
  20. void Add(const Ref<Shader>& shader);
  21. void Add(const std::string &name,const Ref<Shader>& shader);
  22. Ref<Shader> Load(const std::string filepath);
  23. Ref<Shader> Load(const std::string &name,const std::string filepath);
  24. Ref<Shader> Get(const std::string& name);
  25. bool Exists(const std::string& name);
  26. private:
  27. std::unordered_map<std::string,Ref<Shader>> m_Shaders;
  28. };
  29. }

OpenGLShader.h:同Shader.h

  1. #pragma once
  2. #include <string>
  3. #include "YOTO/Renderer/Shader.h"
  4. #include <glm/glm.hpp>
  5. typedef unsigned int GLenum;
  6. namespace YOTO {
  7. class OpenGLShader:public Shader {
  8. public:
  9. OpenGLShader(const std::string& filepath);
  10. OpenGLShader(const std::string &name,const std::string& vertexSrc, const std::string& fragmentSrc);
  11. ~OpenGLShader();
  12. void Bind()const override;
  13. void UnBind()const override;
  14. virtual void SetInt(const std::string& name, int value) override;
  15. virtual void SetFloat3(const std::string& name, const glm::vec3& value) override;
  16. virtual void SetFloat4(const std::string& name, const glm::vec4& value)override;
  17. virtual void SetMat4(const std::string& name, const glm::mat4& value) override;
  18. virtual const std::string& GetName()const override { return m_Name; }
  19. void UploadUniformMat4(const std::string& name, const glm::mat4& matrix);
  20. void UploadUniformMat3(const std::string& name, const glm::mat3& matrix);
  21. void UploadUniformFloat4(const std::string& name, const glm::vec4& values);
  22. void UploadUniformFloat3(const std::string& name, const glm::vec3& values);
  23. void UploadUniformFloat2(const std::string& name, const glm::vec2& values);
  24. void UploadUniformFloat(const std::string& name, float values);
  25. void UploadUniformInt(const std::string& name, int values);
  26. private:
  27. std::string ReadFile(const std::string filepath);
  28. std::unordered_map<GLenum,std::string> PreProcess(const std::string& source);
  29. void Compile(const std::unordered_map<GLenum, std::string>& shaderSources);
  30. private:
  31. uint32_t m_RendererID;
  32. std::string m_Name;
  33. }
  34. ;
  35. }

OpenGLShader.cpp: 

  1. #include "ytpch.h"
  2. #include "OpenGLShader.h"
  3. #include <glad/glad.h>
  4. #include<glm/gtc/type_ptr.hpp>
  5. namespace YOTO {
  6. static GLenum ShaderTypeFromString(const std::string& type) {
  7. if (type == "vertex") {
  8. return GL_VERTEX_SHADER;
  9. }
  10. if (type == "fragment" || type == "pixel") {
  11. return GL_FRAGMENT_SHADER;
  12. }
  13. YT_CORE_ASSERT(false, "不知道的shader类型");
  14. return 0;
  15. }
  16. OpenGLShader::OpenGLShader(const std::string& filepath)
  17. {
  18. std::string source = ReadFile(filepath);
  19. YT_CORE_ASSERT(source.size(), "GLSL读取的字符串为空");
  20. auto shaderSources = PreProcess(source);
  21. Compile(shaderSources);
  22. auto lastSlash = filepath.find_last_of("/\\");
  23. lastSlash = lastSlash == std::string::npos ? 0 : lastSlash + 1;
  24. auto lastDot = filepath.rfind('.');
  25. auto count = lastDot == std::string::npos ? filepath.size() - lastSlash : lastDot - lastSlash;
  26. m_Name=filepath.substr(lastSlash, count);
  27. }
  28. OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc)
  29. :m_Name(name){
  30. std::unordered_map<GLenum, std::string >sources;
  31. sources[GL_VERTEX_SHADER] = vertexSrc;
  32. sources[GL_FRAGMENT_SHADER] = fragmentSrc;
  33. Compile(sources);
  34. }
  35. OpenGLShader::~OpenGLShader()
  36. {
  37. glDeleteProgram(m_RendererID);
  38. }
  39. std::string OpenGLShader::ReadFile(const std::string filepath)
  40. {
  41. std::string result;
  42. std::ifstream in(filepath, std::ios::in | std::ios::binary);
  43. if (in) {
  44. in.seekg(0, std::ios::end); // 将指针放在最后面
  45. result.resize(in.tellg()); // 初始化string的大小, in.tellg()返回位置
  46. in.seekg(0, std::ios::beg); // in指回头部
  47. in.read(&result[0], result.size()); // in读入放在result指向的内存中
  48. }
  49. else {
  50. YT_CORE_ERROR("不能打开文件:{0}", filepath);
  51. }
  52. return result;
  53. }
  54. std::unordered_map<GLenum, std::string> OpenGLShader::PreProcess(const std::string& source)
  55. {
  56. std::unordered_map<GLenum, std::string> shaderSources;
  57. std::string typeToken = "#type";
  58. size_t typeTokenLen = typeToken.size();
  59. size_t findCurPos = source.find(typeToken, 0);
  60. size_t findNextPos = findCurPos;
  61. while (findNextPos != std::string::npos) {
  62. size_t curlineEndPos = source.find_first_of("\r\n", findCurPos);///r/n写错为/r/n
  63. YT_CORE_ASSERT(curlineEndPos != std::string::npos, "解析shader失败");
  64. size_t begin = findCurPos + typeTokenLen + 1;
  65. std::string type = source.substr(begin, curlineEndPos - begin);// 获取到是vertex还是fragment
  66. YT_CORE_ASSERT(ShaderTypeFromString(type), "无效的shader的类型 ");
  67. size_t nextLinePos = source.find_first_not_of("\r\n", curlineEndPos);
  68. findNextPos = source.find(typeToken, nextLinePos);
  69. // 获取到具体的shader代码
  70. shaderSources[ShaderTypeFromString(type)] = source.substr(nextLinePos, findNextPos - (nextLinePos == std::string::npos ? source.size() - 1 : nextLinePos));
  71. findCurPos = findNextPos;
  72. }
  73. return shaderSources;
  74. /*
  75. 用find,而不是find_firtst_of,因为
  76. find返回完全匹配的字符串的的位置;
  77. find_first_of返回被查匹配字符串中某个字符的第一次出现位置。
  78. std::string::npos是一个非常大的数
  79. source.substr(0, source.size() + 10000)截取到从头到末尾,不会报错
  80. */
  81. }
  82. void OpenGLShader::Compile(const std::unordered_map<GLenum, std::string>& shaderSources)
  83. {
  84. GLuint program = glCreateProgram();
  85. YT_CORE_ASSERT(shaderSources.size()<=2,"OpenGLShader:shader只支持两种!")
  86. std::array<GLenum,2>glShaderIDs;
  87. int glShaderIDIndex=0;
  88. for (auto& kv : shaderSources) {
  89. GLenum type = kv.first;
  90. const std::string& source = kv.second;
  91. // Create an empty vertex shader handle
  92. GLuint shader = glCreateShader(type);
  93. // Send the vertex shader source code to GL
  94. // Note that std::string's .c_str is NULL character terminated.
  95. const GLchar* sourceCStr = source.c_str();
  96. glShaderSource(shader, 1, &sourceCStr, 0);
  97. // Compile the vertex shader
  98. glCompileShader(shader);
  99. GLint isCompiled = 0;
  100. glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
  101. if (isCompiled == GL_FALSE)
  102. {
  103. GLint maxLength = 0;
  104. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
  105. // The maxLength includes the NULL character
  106. std::vector<GLchar> infoLog(maxLength);
  107. glGetShaderInfoLog(shader, maxLength, &maxLength, &infoLog[0]);
  108. // We don't need the shader anymore.
  109. glDeleteShader(shader);
  110. // Use the infoLog as you see fit.
  111. // In this simple program, we'll just leave
  112. YT_CORE_ERROR("{0} ", infoLog.data());
  113. YT_CORE_ASSERT(false, "shader 编译失败!");
  114. break;
  115. }
  116. // Attach our shaders to our program
  117. glAttachShader(program, shader);
  118. glShaderIDs[glShaderIDIndex++]=shader;
  119. }
  120. // Link our program
  121. glLinkProgram(program);
  122. // Note the different functions here: glGetProgram* instead of glGetShader*.
  123. GLint isLinked = 0;
  124. glGetProgramiv(program, GL_LINK_STATUS, (int*)&isLinked);
  125. if (isLinked == GL_FALSE)
  126. {
  127. GLint maxLength = 0;
  128. glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
  129. // The maxLength includes the NULL character
  130. std::vector<GLchar> infoLog(maxLength);
  131. glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
  132. // We don't need the program anymore.
  133. glDeleteProgram(program);
  134. // Don't leak shaders either.
  135. for (auto id : glShaderIDs) {
  136. glDeleteShader(id);
  137. }
  138. // Use the infoLog as you see fit.
  139. // In this simple program, we'll just leave
  140. YT_CORE_ERROR("{0} ", infoLog.data());
  141. YT_CORE_ASSERT(false, "shader link failure!");
  142. return;
  143. }
  144. // Always detach shaders after a successful link.
  145. for (auto id : glShaderIDs) {
  146. glDetachShader(program, id);
  147. }
  148. m_RendererID = program;
  149. }
  150. void OpenGLShader::Bind() const
  151. {
  152. glUseProgram(m_RendererID);
  153. }
  154. void OpenGLShader::UnBind() const
  155. {
  156. glUseProgram(0);
  157. }
  158. void OpenGLShader::SetInt(const std::string& name, int value)
  159. {
  160. UploadUniformInt(name, value);
  161. }
  162. void OpenGLShader::SetFloat3(const std::string& name, const glm::vec3& value)
  163. {
  164. UploadUniformFloat3(name, value);
  165. }
  166. void OpenGLShader::SetFloat4(const std::string& name, const glm::vec4& value)
  167. {
  168. UploadUniformFloat4(name, value);
  169. }
  170. void OpenGLShader::SetMat4(const std::string& name, const glm::mat4& value)
  171. {
  172. UploadUniformMat4(name, value);
  173. }
  174. void OpenGLShader::UploadUniformMat4(const std::string& name, const glm::mat4& matrix)
  175. {
  176. GLint loacation = glGetUniformLocation(m_RendererID, name.c_str());
  177. glUniformMatrix4fv(loacation, 1, GL_FALSE, glm::value_ptr(matrix));
  178. }
  179. void OpenGLShader::UploadUniformMat3(const std::string& name, const glm::mat3& matrix)
  180. {
  181. GLint loacation = glGetUniformLocation(m_RendererID, name.c_str());
  182. glUniformMatrix3fv(loacation, 1, GL_FALSE, glm::value_ptr(matrix));
  183. }
  184. void OpenGLShader::UploadUniformFloat4(const std::string& name, const glm::vec4& values)
  185. {
  186. GLint loacation = glGetUniformLocation(m_RendererID, name.c_str());
  187. glUniform4f(loacation, values.x, values.y, values.z, values.w);
  188. }
  189. void OpenGLShader::UploadUniformFloat3(const std::string& name, const glm::vec3& values)
  190. {
  191. GLint loacation = glGetUniformLocation(m_RendererID, name.c_str());
  192. glUniform3f(loacation, values.x, values.y, values.z);
  193. }
  194. void OpenGLShader::UploadUniformFloat2(const std::string& name, const glm::vec2& values)
  195. {
  196. GLint loacation = glGetUniformLocation(m_RendererID, name.c_str());
  197. glUniform2f(loacation, values.x, values.y);
  198. }
  199. void OpenGLShader::UploadUniformFloat(const std::string& name, float values)
  200. {
  201. GLint loacation = glGetUniformLocation(m_RendererID, name.c_str());
  202. glUniform1f(loacation, values);
  203. }
  204. void OpenGLShader::UploadUniformInt(const std::string& name, int values)
  205. {
  206. GLint loacation = glGetUniformLocation(m_RendererID, name.c_str());
  207. glUniform1i(loacation, values);
  208. }
  209. }

添加自定义Texture方法:

Texture.h:添加新的Create方法:根据宽高添加

  1. #pragma once
  2. namespace YOTO {
  3. class Texture
  4. {
  5. public:
  6. virtual ~Texture() = default;
  7. virtual uint32_t GetWidth()const = 0;
  8. virtual uint32_t GetHeight()const = 0;
  9. virtual void SetData(void* data, uint32_t size) = 0;
  10. virtual void Bind(uint32_t slot=0)const = 0;
  11. };
  12. class Texture2D :public Texture
  13. {
  14. public:
  15. static Ref<Texture2D>Create(uint32_t width,uint32_t height);
  16. static Ref<Texture2D>Create(const std::string& path);
  17. };
  18. }

Texture.cpp: 

  1. #include "ytpch.h"
  2. #include "Texture.h"
  3. #include"Renderer.h"
  4. #include "Platform/OpenGL/OpenGLTexture.h"
  5. namespace YOTO {
  6. Ref<Texture2D> Texture2D::Create(uint32_t width, uint32_t height)
  7. {
  8. switch (Renderer::GetAPI())
  9. {
  10. case RendererAPI::API::None:
  11. YT_CORE_ASSERT(false, "Texture2D:API为None不支持");
  12. return nullptr;
  13. case RendererAPI::API::OpenGL:
  14. return CreateRef<OpenGLTexture2D>(width,height);
  15. }
  16. YT_CORE_ASSERT(false, "Buffer:未知API");
  17. return nullptr;
  18. }
  19. Ref<Texture2D> Texture2D::Create(const std::string& path)
  20. {
  21. switch (Renderer::GetAPI())
  22. {
  23. case RendererAPI::API::None:
  24. YT_CORE_ASSERT(false, "Texture2D:API为None不支持");
  25. return nullptr;
  26. case RendererAPI::API::OpenGL:
  27. return CreateRef<OpenGLTexture2D>(path);
  28. }
  29. YT_CORE_ASSERT(false, "Buffer:未知API");
  30. return nullptr;
  31. }
  32. }

OpenGLTexture.h:同Texture.h相同,且添加设置texture数据的方法SetData:

  1. #pragma once
  2. #include"YOTO/Renderer/Texture.h"
  3. #include<glad/glad.h>
  4. namespace YOTO {
  5. class OpenGLTexture2D:public Texture2D
  6. {
  7. public:
  8. OpenGLTexture2D(uint32_t width,uint32_t height);
  9. OpenGLTexture2D(const std::string path);
  10. virtual~OpenGLTexture2D();
  11. virtual uint32_t GetWidth()const override { return m_Width; }
  12. virtual uint32_t GetHeight()const override { return m_Height; }
  13. virtual void SetData(void* data, uint32_t size)override;
  14. virtual void Bind(uint32_t slot=0)const override;
  15. private:
  16. std::string m_Path;
  17. uint32_t m_Width, m_Height;
  18. uint32_t m_RendererID;
  19. GLenum m_InternalFormat, m_DataFormat;
  20. };
  21. }

OpenGLTexture.cpp: 

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

Sandbox2D.h:添加m_CheckerboardTexture

  1. #pragma once
  2. #include "YOTO.h"
  3. class Sandbox2D :public YOTO::Layer
  4. {public:
  5. Sandbox2D();
  6. virtual ~Sandbox2D() = default;
  7. virtual void OnAttach()override;
  8. virtual void OnDetach()override;
  9. void OnUpdate(YOTO::Timestep ts)override;
  10. virtual void OnImGuiRender() override;
  11. void OnEvent(YOTO::Event& e)override;
  12. private:
  13. YOTO::OrthographicCameraController m_CameraController;
  14. YOTO::Ref<YOTO::Shader> m_FlatColorShader;
  15. YOTO::Ref<YOTO::VertexArray> m_SquareVA;
  16. YOTO::Ref<YOTO::Texture2D>m_CheckerboardTexture;
  17. glm::vec4 m_SquareColor = { 0.2f,0.3f,0.7f,1.0f };
  18. };

化简Sandbox2D:

Sandbox2D.cpp:把传shader参数的代码注释掉 ,统一使用DrawQuad封装;负责“怎么画”的问题:

  1. #include "Sandbox2D.h"
  2. #include <imgui/imgui.h>
  3. #include <glm/gtc/matrix_transform.hpp>
  4. //#include <Platform/OpenGL/OpenGLShader.h>
  5. #include <glm/gtc/type_ptr.hpp>
  6. Sandbox2D::Sandbox2D()
  7. :Layer("Sandbox2D"), m_CameraController(1280.0f / 720.0f, true)
  8. {
  9. }
  10. void Sandbox2D::OnAttach()
  11. {
  12. m_CheckerboardTexture = YOTO::Texture2D::Create("assets/textures/Checkerboard.png");
  13. }
  14. void Sandbox2D::OnDetach()
  15. {
  16. }
  17. void Sandbox2D::OnUpdate(YOTO::Timestep ts)
  18. { //update
  19. m_CameraController.OnUpdate(ts);
  20. //Render
  21. YOTO::RenderCommand::SetClearColor({ 0.2f, 0.2f, 0.2f, 1.0f });
  22. YOTO::RenderCommand::Clear();
  23. YOTO::Renderer2D::BeginScene(m_CameraController.GetCamera());
  24. {
  25. static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
  26. glm::vec4 redColor(0.8f, 0.3f, 0.3f, 1.0f);
  27. glm::vec4 blueColor(0.2f, 0.3f, 0.8f, 1.0f);
  28. /*std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_FlatColorShader)->Bind();
  29. std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_FlatColorShader)->UploadUniformFloat4("u_Color", m_SquareColor);
  30. YOTO::Renderer::Submit(m_FlatColorShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));*/
  31. YOTO::Renderer2D::DrawQuad({ -1.0f,0.0f }, { 0.8f,0.8f }, {0.8f,0.2f,0.3f,1.0f});
  32. YOTO::Renderer2D::DrawQuad({ 0.5f,-0.5f }, { 0.5f,0.75f }, { 0.2f,0.3f,0.8f,1.0f });
  33. YOTO::Renderer2D::DrawQuad({ 0.0f,0.0f,-0.1f }, {10.0f,10.0f }, m_CheckerboardTexture);
  34. YOTO::Renderer2D::EndScene();
  35. }
  36. }
  37. void Sandbox2D::OnImGuiRender()
  38. {
  39. ImGui::Begin("设置");
  40. ImGui::ColorEdit4("正方形颜色", glm::value_ptr(m_SquareColor));
  41. ImGui::End();
  42. }
  43. void Sandbox2D::OnEvent(YOTO::Event& e)
  44. {
  45. m_CameraController.OnEvent(e);
  46. }

小修改:

OpenGLRendererAPI.cpp:DrawIndexed中添加解绑Texture:

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

flatColor.glsl:

  1. #type vertex
  2. #version 330 core
  3. layout(location = 0) in vec3 a_Position;
  4. uniform mat4 u_ViewProjection;
  5. uniform mat4 u_Transform;
  6. void main(){
  7. gl_Position =u_ViewProjection*u_Transform*vec4( a_Position,1.0);
  8. }
  9. #type fragment
  10. #version 330 core
  11. layout(location = 0) out vec4 color;
  12. uniform vec4 u_Color ;
  13. void main(){
  14. color =u_Color;
  15. }

Texture.glsl:

  1. #type vertex
  2. #version 330 core
  3. layout(location = 0) in vec3 a_Position;
  4. layout(location = 1) in vec2 a_TexCoord;
  5. uniform mat4 u_ViewProjection;
  6. uniform mat4 u_Transform;
  7. out vec2 v_TexCoord;
  8. out vec3 v_Position;
  9. void main(){
  10. v_TexCoord=a_TexCoord;
  11. v_Position=a_Position;
  12. gl_Position =u_ViewProjection*u_Transform*vec4( a_Position,1.0);
  13. }
  14. #type fragment
  15. #version 330 core
  16. layout(location = 0) out vec4 color;
  17. in vec3 v_Position;
  18. in vec2 v_TexCoord;
  19. uniform vec4 u_Color ;
  20. uniform sampler2D u_Texture ;
  21. void main(){
  22. color = texture(u_Texture, v_TexCoord*10.0f)*u_Color;
  23. }

YOTO.h:添加:

#include"YOTO/Renderer/Renderer2D.h"

Core.h:

  1. #pragma once
  2. #include<memory>
  3. //用于dll的宏
  4. #ifdef YT_PLATFORM_WINDOWS
  5. #if YT_DYNAMIC_LINK
  6. #ifdef YT_BUILD_DLL
  7. #define YOTO_API __declspec(dllexport)
  8. #else
  9. #define YOTO_API __declspec(dllimport)
  10. #endif // DEBUG
  11. #else
  12. #define YOTO_API
  13. #endif
  14. #else
  15. #error YOTO_ONLY_SUPPORT_WINDOWS
  16. #endif // YOTO_PLATFORM_WINDOWS
  17. #ifdef YT_DEBUG
  18. #define YT_ENABLE_ASSERTS
  19. #endif
  20. #ifdef YT_ENABLE_ASSERTS
  21. #define YT_CLIENT_ASSERT(x,...) {if(!(x)){YT_CLIENT_ERROR("断言错误:{0}",__VA_ARGS__);__debugbreak();}}
  22. #define YT_CORE_ASSERT(x,...) {if(!(x)){YT_CORE_ERROR("断言错误:{0}",__VA_ARGS__);__debugbreak();}}
  23. #else
  24. #define YT_CLIENT_ASSERT(x,...)
  25. #define YT_CORE_ASSERT(x,...)
  26. #endif // YT_ENABLE_ASSERTS
  27. #define BIT(x)(1<<x)
  28. //绑定事件定义
  29. #define YT_BIND_EVENT_FN(fn) std::bind(&fn, this, std::placeholders::_1)
  30. namespace YOTO {
  31. template<typename T>
  32. using Scope = std::unique_ptr<T>;
  33. template<typename T>
  34. using Ref = std::shared_ptr<T>;
  35. template<typename T,typename ...Args>
  36. constexpr Scope<T> CreateScope(Args&&...args) {
  37. return std::make_shared<T>(std::forward<Args>(args)...);
  38. }
  39. template<typename T, typename ...Args>
  40. constexpr Ref<T> CreateRef(Args&&...args) {
  41. return std::make_shared<T>(std::forward<Args>(args)...);
  42. }
  43. }

测试:

cool! 

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

闽ICP备14008679号