#include "Renderer.h" #include "Engine.h" RendererData Renderer::s_Data; float Renderer::s_DeltaTime = 0.0f; float Renderer::s_LastFrame = 0.0f; bool Renderer::s_FirstMouse = true; float Renderer::s_LastX; float Renderer::s_LastY; Renderer::Renderer() = default; Renderer::~Renderer() { Shutdown(); } void Renderer::Init() { if (!gladLoadGLLoader(reinterpret_cast(glfwGetProcAddress))) { std::cerr << "Failed to initialize GLAD" << std::endl; return; } SetVariables(); LoadShaders(); SetupBuffers(); SetCallbacks(); } void Renderer::SetVariables() { s_Data.m_Scene = new Scene(); s_Data.m_Camera = new Camera(glm::vec3(0.0f, 0.0f, 3.0f)); s_Data.m_Cube = new Cube("Cube"); s_Data.m_ClearColor = new glm::vec3(0.0f, 0.1f, 0.2f); s_Data.m_Scene->AddCube(std::shared_ptr(s_Data.m_Cube)); } RendererData& Renderer::GetData() { return s_Data; } void Renderer::LoadShaders() { s_Data.m_Shader = new Shader(ENGINE_RESOURCES_PATH"shaders/vertex.glsl", ENGINE_RESOURCES_PATH"shaders/fragment.glsl"); } void Renderer::SetupBuffers() { s_Data.m_VAO = new VertexArray(); s_Data.m_VBO = new VertexBuffer(); s_Data.m_IBO = new IndexBuffer(); s_Data.m_VAO->Bind(); s_Data.m_VBO->SetData(sizeof(float) * Cube::GetVertices().size(), Cube::GetVertices().data()); s_Data.m_IBO->SetData(sizeof(unsigned int) * Cube::GetIndices().size(), Cube::GetIndices().data()); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), nullptr); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), reinterpret_cast(3 * sizeof(float))); glEnableVertexAttribArray(1); VertexArray::Unbind(); VertexBuffer::Unbind(); IndexBuffer::Unbind(); s_Data.m_FBO = new FrameBuffer(); WindowSize windowSize = Engine::Get()->GetWindow()->GetSize(); s_Data.m_FBO->AttachTexture(windowSize.Width, windowSize.Height); FrameBuffer::Unbind(); } void Renderer::SetCallbacks() { glfwSetWindowSizeCallback(Engine::Get()->GetWindow()->GetNativeWindow(), [](GLFWwindow* window, int width, int height) { SetupBuffers(); }); glfwSetFramebufferSizeCallback(Engine::Get()->GetWindow()->GetNativeWindow(), [](GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); }); glfwSetScrollCallback(Engine::Get()->GetWindow()->GetNativeWindow(), [](GLFWwindow* window, double xOffset, double yOffset) { s_Data.m_Camera->ProcessMouseScroll(static_cast(yOffset)); }); } void Renderer::Render() { auto currentFrame = static_cast(glfwGetTime()); s_DeltaTime = currentFrame - s_LastFrame; s_LastFrame = currentFrame; s_Data.m_FBO->Bind(); glfwPollEvents(); ProcessInput(Engine::Get()->GetWindow()->GetNativeWindow()); glEnable(GL_DEPTH_TEST); glClearColor(s_Data.m_ClearColor->x, s_Data.m_ClearColor->y, s_Data.m_ClearColor->z, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); s_Data.m_Shader->Use(); s_Data.m_Cube->Draw(); const glm::mat4& model = *s_Data.m_Cube->GetModelMatrix(); const glm::mat4& view = s_Data.m_Camera->GetViewMatrix(); WindowSize size = Engine::Get()->GetWindow()->GetSize(); glm::mat4 projection = glm::perspective(glm::radians(45.0f), static_cast(size.Width) / static_cast(size.Height), 0.1f, 100.0f); glUniformMatrix4fv(s_Data.m_Shader->GetUniformLocation("model"), 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(s_Data.m_Shader->GetUniformLocation("view"), 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(s_Data.m_Shader->GetUniformLocation("projection"), 1, GL_FALSE, glm::value_ptr(projection)); glUniform3fv(s_Data.m_Shader->GetUniformLocation("color"), 1, glm::value_ptr(*s_Data.m_Cube->GetShaderColor())); *s_Data.m_Cube->GetModelMatrix() = glm::mat4(1.0f); s_Data.m_VAO->Bind(); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, nullptr); glBindFramebuffer(GL_FRAMEBUFFER, 0); glfwSwapBuffers(Engine::Get()->GetWindow()->GetNativeWindow()); } void Renderer::ProcessInput(GLFWwindow *window) { if(Input::IsMouseButtonPressed(ButtonRight)) { auto mousePos = Input::GetMousePosition(); if(s_FirstMouse) { s_LastX = mousePos.x; s_LastY = mousePos.y; s_FirstMouse = false; } float xOffset = mousePos.x - s_LastX; float yOffset = s_LastY - mousePos.y; s_LastX = mousePos.x; s_LastY = mousePos.y; s_Data.m_Camera->ProcessMouseMovement(xOffset, yOffset); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); } else { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } if (Input::IsKeyPressed(W)) s_Data.m_Camera->ProcessKeyboard(FORWARD, s_DeltaTime); if (Input::IsKeyPressed(S)) s_Data.m_Camera->ProcessKeyboard(BACKWARD, s_DeltaTime); if (Input::IsKeyPressed(A)) s_Data.m_Camera->ProcessKeyboard(LEFT, s_DeltaTime); if (Input::IsKeyPressed(D)) s_Data.m_Camera->ProcessKeyboard(RIGHT, s_DeltaTime); if (Input::IsKeyPressed(Q)) s_Data.m_Camera->ProcessKeyboard(DOWN, s_DeltaTime); if (Input::IsKeyPressed(E)) s_Data.m_Camera->ProcessKeyboard(UP, s_DeltaTime); } void Renderer::Shutdown() { s_Data.m_VAO->Shutdown(); s_Data.m_VBO->Shutdown(); s_Data.m_FBO->Shutdown(); s_Data.m_IBO->Shutdown(); s_Data.m_Shader->Shutdown(); }