引言 上一节我们将引擎转变为静态库并消除了所有警告和错误。今天我们将进入渲染模块。
首先我们的渲染器需要 Context。在 OpenGL 中真的非常简单,事实上 glfw 为我们处理了几乎所有这些(对于 Vulkan 则要复杂得多)。
Context 类设计 考虑到之后会使用不同的图形 API,我们在 Infinite/
目录下新建 Renderer
文件夹,在其中新建 GraphicsContext.h
作为父类:
#pragma once namespace Infinite { class GraphicsContext { public : virtual void Init () = 0 ; virtual void SwapBuffers () = 0 ; }; }
该父类包含了初始化 Init()
和交换缓存 SwapBuffers()
两个方法的声明。
接着我们在 Platform/OpenGL
目录下新建 OpenGLContext.h
和 OpenGLContext.cpp
作为针对 OpenGL API 的 Context 类。
#pragma once #include "Infinite/Renderer/GraphicsContext.h" struct GLFWwindow ;namespace Infinite { class OpenGLContext : public GraphicsContext { public : OpenGLContext (GLFWwindow* windowHandle); virtual void Init () override ; virtual void SwapBuffers () override ; private : GLFWwindow* m_WindowHandle; }; }
OpenGLContext.cpp
将我们之前 WindowsWindow.cpp
的方法封装于此:
#include "ifnpch.h" #include "OpenGLContext.h" #include <GLFW/glfw3.h> #include <glad/glad.h> #include <GL/GL.h> namespace Infinite { OpenGLContext::OpenGLContext (GLFWwindow* windowHandle) : m_WindowHandle (windowHandle) { IFN_CORE_ASSERT (windowHandle, "Window handle is null!" ) } void OpenGLContext::Init () { glfwMakeContextCurrent (m_WindowHandle); int status = gladLoadGLLoader ((GLADloadproc)glfwGetProcAddress); IFN_CORE_ASSERT (status, "Failed to initialize Glad!" ); } void OpenGLContext::SwapBuffers () { glfwSwapBuffers (m_WindowHandle); } }
窗口调整 在 WindowsWindow.h
中新建我们的 Context:
#pragma once #include "Window.h" #include <GLFW/glfw3.h> #include "Infinite/Renderer/GraphicsContext.h" namespace Infinite { class WindowsWindow : public Window { public: WindowsWindow(const WindowProps& props); virtual ~WindowsWindow(); void OnUpdate() override; inline unsigned int GetWidth() const override { return m_Data.Width; } inline unsigned int GetHeight() const override { return m_Data.Height; } // Window attributes inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; } void SetVSync(bool enabled) override; bool IsVSync() const override; inline virtual void* GetNativeWindow() const { return m_Window; } private: virtual void Init(const WindowProps& props); virtual void Shutdown(); private: GLFWwindow* m_Window; + GraphicsContext* m_Context; struct WindowData { std::string Title; unsigned int Width, Height; bool VSync; EventCallbackFn EventCallback; }; WindowData m_Data; }; }
之后 WindowsWindow.cpp
替换为我们 Context 类方法:
#include "Infinite/Events/MouseEvent.h" #include "Infinite/Events/KeyEvent.h" +#include "Platform/OpenGL/OpenGLContext.h" #include <GLAD/glad.h> namespace Infinite { @@ -48,9 +50,10 @@ namespace Infinite { } m_Window = glfwCreateWindow((int)props.Width, (int)props.Height, m_Data.Title.c_str(), nullptr, nullptr); - glfwMakeContextCurrent(m_Window); - int status = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); - IFN_CORE_ASSERT(status, "Failed to initialize GLAD!"); + m_Context = new OpenGLContext(m_Window); + m_Context->Init(); glfwSetWindowUserPointer(m_Window, &m_Data); SetVSync(true); @@ -155,7 +158,7 @@ namespace Infinite { void WindowsWindow::OnUpdate() { glfwPollEvents(); - glfwSwapBuffers(m_Window); + m_Context->SwapBuffers(); } void WindowsWindow::SetVSync(bool enabled)
调试