From 2dcc3f180313448ae84ad3f29eca875718aaf9a4 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Wed, 28 Dec 2022 22:35:23 +0100 Subject: [PATCH] Deferred rendering mode + Skybox - Added deferred rendering mode to the renderer - Added a skybox to the forward rendering mode - moved default imported assets directory (temporary fix) --- Editor/Assets/Cube.mesh | Bin 0 -> 891 bytes Editor/src/SceneSerializer.h | 7 +- Editor/src/UI/MainMenuBar.h | 3 +- Editor/src/UI/widgets.h | 29 +- Editor/src/app.cpp | 22 +- .../src/Graphics/Primitives/Camera.cpp | 22 +- YoggieEngine/src/Graphics/Primitives/Camera.h | 4 +- .../src/Graphics/Primitives/CubeMap.cpp | 45 +++ .../src/Graphics/Primitives/CubeMap.h | 19 ++ .../src/Graphics/Primitives/DrawCommand.h | 1 + .../src/Graphics/Primitives/Shader.cpp | 2 +- YoggieEngine/src/Graphics/RenderSurface.cpp | 2 +- YoggieEngine/src/Graphics/Renderer.cpp | 295 ++++++++++++++++-- YoggieEngine/src/Graphics/Renderer.h | 20 +- YoggieEngine/src/Scene/Components.h | 10 +- .../src/Shaders/Deferred/geometry.frag | 20 ++ .../src/Shaders/Deferred/geometry.vert | 26 ++ .../src/Shaders/Deferred/lightPass.frag | 41 +++ .../src/Shaders/Deferred/lightPass.vert | 13 + .../geometry.frag} | 0 .../{vertex.shader => Forward/geometry.vert} | 0 .../RenderSurface.frag} | 0 .../RenderSurface.vert} | 0 YoggieEngine/src/YoggieEngine.h | 1 + 24 files changed, 512 insertions(+), 70 deletions(-) create mode 100644 Editor/Assets/Cube.mesh create mode 100644 YoggieEngine/src/Graphics/Primitives/CubeMap.cpp create mode 100644 YoggieEngine/src/Graphics/Primitives/CubeMap.h create mode 100644 YoggieEngine/src/Shaders/Deferred/geometry.frag create mode 100644 YoggieEngine/src/Shaders/Deferred/geometry.vert create mode 100644 YoggieEngine/src/Shaders/Deferred/lightPass.frag create mode 100644 YoggieEngine/src/Shaders/Deferred/lightPass.vert rename YoggieEngine/src/Shaders/{fragment.shader => Forward/geometry.frag} (100%) rename YoggieEngine/src/Shaders/{vertex.shader => Forward/geometry.vert} (100%) rename YoggieEngine/src/Shaders/{RenderSurfaceFrag.shader => RenderSurface/RenderSurface.frag} (100%) rename YoggieEngine/src/Shaders/{RenderSurfaceVert.shader => RenderSurface/RenderSurface.vert} (100%) diff --git a/Editor/Assets/Cube.mesh b/Editor/Assets/Cube.mesh new file mode 100644 index 0000000000000000000000000000000000000000..939f1b1f766652e32f4f8090b8075a94944aab0d GIT binary patch literal 891 zcmZ{jM-Ia<3-nsJUFIyC=&& zU&s?==5cZ^+KX1oc|=2B$oS`FZeH>I^D@^mO_^6SGzX37wan{hu1~b4Nxjm0B+qo} zmop*S>vaWh==sLEPAfBy3@yt`^x?N6 z+ETB2^dvX*=^nR3?m<))x+>J54h?8R3);|uF7%)e0~o>x#xQ{?%s_sb1uS6&YuLaR RcCd#79N`3KxWE-|@B^Bjif{k` literal 0 HcmV?d00001 diff --git a/Editor/src/SceneSerializer.h b/Editor/src/SceneSerializer.h index 55816b9..ea8d115 100644 --- a/Editor/src/SceneSerializer.h +++ b/Editor/src/SceneSerializer.h @@ -66,13 +66,9 @@ YAML::Emitter& operator<< (YAML::Emitter& emitter, glm::vec3& vector) { emitter << YAML::Key << "Light"; emitter << YAML::Value; emitter << YAML::BeginMap; - emitter << YAML::Key << "strength"; - emitter << YAML::Value << entity.GetComponent().Strength; - emitter << YAML::Key << "Color"; emitter << YAML::Value << entity.GetComponent().Color; - emitter << YAML::EndMap; - + emitter << YAML::EndMap; } @@ -129,7 +125,6 @@ YAML::Emitter& operator<< (YAML::Emitter& emitter, glm::vec3& vector) { } if (entity["Light"]) { LightComponent lc = SE.AddComponent(); - lc.Strength = entity["Light"]["strength"].as(); lc.Color = glm::vec3(entity["Light"]["Color"][0].as(), entity["Light"]["Color"][1].as(), entity["Light"]["Color"][2].as()); } diff --git a/Editor/src/UI/MainMenuBar.h b/Editor/src/UI/MainMenuBar.h index 20d0602..0c8a32a 100644 --- a/Editor/src/UI/MainMenuBar.h +++ b/Editor/src/UI/MainMenuBar.h @@ -106,9 +106,10 @@ public: switch (result) { case(NFD_OKAY): // Import Model + AssetManager::LoadFromSource( path, - project.get()->GetProjectDirectory() / "Assets" + "build/Debug/Assets"//project.get()->GetProjectDirectory() / "Assets" ); break; case(NFD_CANCEL): diff --git a/Editor/src/UI/widgets.h b/Editor/src/UI/widgets.h index 6dec587..e7ccddc 100644 --- a/Editor/src/UI/widgets.h +++ b/Editor/src/UI/widgets.h @@ -19,8 +19,7 @@ using namespace YoggieEngine; auto matrix = glm::mat4(1.0f); auto worldOrigin = glm::mat4(1.0f); -auto projection = glm::perspective(45.0f, 0.89f, 0.001f, 1.0f); -auto view = glm::mat4(1.0f); + inline void ComponentView(const std::string& componentName, voidFunction func) { @@ -40,7 +39,7 @@ public: void AddComponentDropDown(Entity& selected ) { - static char* names[] = { "Script Component", "Camera Component" }; + static char* names[] = { "Script Component", "Camera Component", "Light Component"}; if (ImGui::Button("Add Component")) ImGui::OpenPopup("Component picker"); @@ -82,25 +81,23 @@ public: ImGui::ColorEdit3("Colour", glm::value_ptr(render3d.color)); } } - + static bool deferred = true; if (selected.HasComponent()) { auto& light = selected.GetComponent(); if (ImGui::CollapsingHeader("Light", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::DragFloat("Strength", &light.Strength, 0.001f); ImGui::ColorEdit3("Colour", glm::value_ptr(light.Color)); + ImGui::Checkbox("Deferred", &deferred); } } if (selected.HasComponent ()) { auto& camera = selected.GetComponent(); - static float Zoom = 90; - static glm::vec3 Position, Rotation = glm::vec3(0.0f); - ComponentView("Camera", [] { - ImGui::SliderFloat("Zoom", &Zoom, 10, 190); - ImGui::InputFloat3("Position:", &Position[0]); - ImGui::InputFloat3("Rotation:", &Rotation[0]); - }); + if (ImGui::CollapsingHeader("Camera")) { + ImGui::DragFloat3("Position:",glm::value_ptr(camera.Position), 0.01f); + ImGui::DragFloat3("Rotation:", glm::value_ptr(camera.Rotation), 0.01f); + + } } if (selected.HasComponent()) { @@ -131,7 +128,7 @@ public: class Viewport : EditorWindow { public: - Viewport (Framebuffer& fb, Camera cam ) : EditorWindow("SceneView") + Viewport (Framebuffer& fb, Camera cam) : EditorWindow("SceneView") { ImVec2 WinPos = ImGui::GetWindowPos(); ImVec2 ContentRegionMin = ImGui::GetWindowContentRegionMin(); @@ -149,11 +146,13 @@ public: ImGuizmo::Enable(true); ImGuizmo::SetRect(ScreenSpaceMin.x, ScreenSpaceMin.y,ContentRegionMax.x, ContentRegionMax.y); - ImGuizmo::ViewManipulate(glm::value_ptr(cam.ViewMatrix), 1, { ScreenSpaceMin.x,ScreenSpaceMin.y }, { 90,90 }, 0x22CCCCCC); + glm::mat4 transposed_view = glm::transpose(cam.ViewMatrix); + + ImGuizmo::ViewManipulate(glm::value_ptr(transposed_view), 1, { ScreenSpaceMin.x,ScreenSpaceMin.y }, { 90,90 }, 0x22CCCCCC); ImGuizmo::DrawGrid(glm::value_ptr(cam.ViewMatrix), glm::value_ptr(cam.ProjectionMatrix), glm::value_ptr(worldOrigin), 100.0f); // Matrix is the model matrix we would want to manipulate - ImGuizmo::Manipulate(glm::value_ptr(cam.ViewMatrix), glm::value_ptr(cam.ProjectionMatrix), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(matrix)); + //ImGuizmo::Manipulate(glm::value_ptr(cam.ViewMatrix), glm::value_ptr(cam.ProjectionMatrix), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(cam.ViewMatrix)); } diff --git a/Editor/src/app.cpp b/Editor/src/app.cpp index 0c9cc34..8f3d60e 100644 --- a/Editor/src/app.cpp +++ b/Editor/src/app.cpp @@ -14,8 +14,6 @@ #include "SceneSerializer.h" #include "AssetManagement/AssetManager.h" #include "UI/MainMenuBar.h" - - const unsigned int MS_PER_UPDATE = 2; void CreateTestProject(std::unique_ptr& project, Scene& scene); @@ -26,6 +24,8 @@ RendererConfig EditorSceneRendererConfig{ true // Depth testing }; +glm::vec3 temp = glm::vec3(0); +Camera cam = Camera(glm::vec3(12.0f, 1.0f, 0.0f), glm::vec3(45.0f, 0.0f, 0.0f), 90); class Editor : public Application { public: Editor() @@ -46,7 +46,9 @@ public: viewportRenderer.Submit(renderComponent, t); }); - viewportRenderer.Render(); + // Render scene + viewportRenderer.Render(ActiveScene); + } void RenderEditorGUI() { @@ -120,7 +122,6 @@ public: Physics Physics; //Physics.Demo(); - double previous = glfwGetTime(); double lag = 0.0; while (!AppWindow.WindowShouldClose()) @@ -145,6 +146,8 @@ public: lag -= MS_PER_UPDATE; } + + RenderScene(); RenderEditorGUI(); @@ -176,7 +179,6 @@ private: std::unique_ptr CurrentProject; Scene ActiveScene; - }; YoggieEngine::Application* CreateApplication() { @@ -211,8 +213,10 @@ void CreateTestProject(std::unique_ptr& project, Scene& scene ) { rendercube2.mesh = *(model->renderable->mesh); // create an ambient light source - auto AmbientLight = scene.AddEntity("AmbientLight"); - auto light = AmbientLight.AddComponent(); - light.Color = glm::vec3(1.0f); - light.Strength = 1.0f; + auto light = scene.AddEntity("Light"); + auto lightComponent = light.AddComponent(); + lightComponent.Color = glm::vec3(1.0f); + + + } diff --git a/YoggieEngine/src/Graphics/Primitives/Camera.cpp b/YoggieEngine/src/Graphics/Primitives/Camera.cpp index 2b3e86a..9f2d311 100644 --- a/YoggieEngine/src/Graphics/Primitives/Camera.cpp +++ b/YoggieEngine/src/Graphics/Primitives/Camera.cpp @@ -1,19 +1,24 @@ #include #include "Camera.h" namespace YoggieEngine { - - Camera::Camera(glm::vec3 position, glm::vec3 rotation, float zoom) - : Position(position), Rotation(rotation), Zoom(zoom) { + Camera::Camera(const Camera& other) + : Position(other.Position), Rotation(other.Rotation), Zoom(other.Zoom) + { + + } + Camera::Camera(glm::vec3 position, glm::vec3 rotation, float zoom) + : Position(position), Rotation( rotation) + { Front = glm::vec3(-1.0f, 0.0f, 0.0f); Right = glm::vec3(0.0f, 0.0f, 1.0f); Up = glm::vec3(0.0f, 1.0f, 0.0f); + Zoom = zoom; - auto rotated_position = glm::rotate(glm::mat4(1.0f), Rotation.x, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::vec4(Position, 1.0f); ViewMatrix = glm::lookAt( Position, - glm::vec3{ rotated_position.x, rotated_position.y , rotated_position.z } + Front, + Position + Front, Up); ProjectionMatrix = glm::perspective(glm::radians(Zoom), (800.0f / 600.0f), 0.001f, 100.0f); @@ -24,13 +29,8 @@ namespace YoggieEngine { } - - void Camera::Update() { - ViewMatrix = glm::lookAt( - Position, - Position + Front, - Up); + ViewMatrix = glm::lookAt(Position,Position + Front,Up); } } diff --git a/YoggieEngine/src/Graphics/Primitives/Camera.h b/YoggieEngine/src/Graphics/Primitives/Camera.h index bf8ae9f..a1018ea 100644 --- a/YoggieEngine/src/Graphics/Primitives/Camera.h +++ b/YoggieEngine/src/Graphics/Primitives/Camera.h @@ -2,9 +2,11 @@ namespace YoggieEngine { class Camera { public: + + Camera(const Camera& other); Camera(glm::vec3 position, glm::vec3 rotation, float zoom); ~Camera(); - + void Update(); glm::vec3 Position; diff --git a/YoggieEngine/src/Graphics/Primitives/CubeMap.cpp b/YoggieEngine/src/Graphics/Primitives/CubeMap.cpp new file mode 100644 index 0000000..48d8bff --- /dev/null +++ b/YoggieEngine/src/Graphics/Primitives/CubeMap.cpp @@ -0,0 +1,45 @@ +#include +#include "CubeMap.h" +#define STB_IMAGE_IMPLEMENTATION +#include "../stb_image.h" + + +YoggieEngine::CubeMap::CubeMap() +{ +} + +YoggieEngine::CubeMap::CubeMap(std::vector& texture_faces) +{ + glGenTextures(1, &textureID); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); + + stbi_set_flip_vertically_on_load(false); + + int width, height, nrChannels; + unsigned char* data; + for (unsigned int i = 0; i < texture_faces.size(); i++) + { + data = stbi_load(texture_faces[i].c_str(), &width, &height, &nrChannels, 0); + if (data) { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + } + else { + spdlog::debug("Loading image {} failed!", texture_faces[i]); + stbi_image_free(data); + } + } + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + stbi_set_flip_vertically_on_load(true); + +} + +YoggieEngine::CubeMap::~CubeMap() +{ +} diff --git a/YoggieEngine/src/Graphics/Primitives/CubeMap.h b/YoggieEngine/src/Graphics/Primitives/CubeMap.h new file mode 100644 index 0000000..0e3cbd5 --- /dev/null +++ b/YoggieEngine/src/Graphics/Primitives/CubeMap.h @@ -0,0 +1,19 @@ +#pragma once + + +namespace YoggieEngine { + class CubeMap { + public: + CubeMap(); + CubeMap(std::vector& texture_faces); + ~CubeMap(); + + unsigned int getID() { return textureID; } + + private: + unsigned int textureID; + + + + }; +}; \ No newline at end of file diff --git a/YoggieEngine/src/Graphics/Primitives/DrawCommand.h b/YoggieEngine/src/Graphics/Primitives/DrawCommand.h index 4a50b58..920a80a 100644 --- a/YoggieEngine/src/Graphics/Primitives/DrawCommand.h +++ b/YoggieEngine/src/Graphics/Primitives/DrawCommand.h @@ -7,6 +7,7 @@ namespace YoggieEngine { unsigned int IBO_identifier; TransformComponent& transform; Shader& shader; + glm::vec3& color; // Material }; }; diff --git a/YoggieEngine/src/Graphics/Primitives/Shader.cpp b/YoggieEngine/src/Graphics/Primitives/Shader.cpp index 5871578..8429130 100644 --- a/YoggieEngine/src/Graphics/Primitives/Shader.cpp +++ b/YoggieEngine/src/Graphics/Primitives/Shader.cpp @@ -109,7 +109,7 @@ namespace YoggieEngine { { glUniform4fv(glGetUniformLocation(id, uniformName.c_str()), 1, glm::value_ptr(vector4)); } - void Shader::setUniformVec3(std::string uniformName, const glm::vec3& vector3) const + void Shader::setUniformVec3(std::string uniformName, const glm::vec3& vector3) const { glUniform3fv(glGetUniformLocation(id, uniformName.c_str()), 1, glm::value_ptr(vector3)); } diff --git a/YoggieEngine/src/Graphics/RenderSurface.cpp b/YoggieEngine/src/Graphics/RenderSurface.cpp index f1bb3d5..c2e6c83 100644 --- a/YoggieEngine/src/Graphics/RenderSurface.cpp +++ b/YoggieEngine/src/Graphics/RenderSurface.cpp @@ -2,7 +2,7 @@ #include "RenderSurface.h" namespace YoggieEngine { RenderSurface::RenderSurface() { - shader = new Shader("build/SandboxAppliction/Debug/renderSuface.vs", "build/SandboxApplication/Debug/renderSurface.fs"); + shader = new Shader("build/SandboxAppliction/Debug/Shaders/forward/geometry.vert", "build/SandboxApplication/Debug/Shaders/forward/geometry.frag"); verts = std::vector{ {-0.5f, 0.5f, 0.0f}, // 0 diff --git a/YoggieEngine/src/Graphics/Renderer.cpp b/YoggieEngine/src/Graphics/Renderer.cpp index 69cc3b8..63f7422 100644 --- a/YoggieEngine/src/Graphics/Renderer.cpp +++ b/YoggieEngine/src/Graphics/Renderer.cpp @@ -6,24 +6,152 @@ #include "../Graphics/Memory/VertexArray.h" #include "../Graphics/Primitives/DrawCommand.h" +#define FORWARD 1 +#define DEFERRED 0 + +extern YoggieEngine::Camera cam; namespace YoggieEngine { -Camera cam = Camera(glm::vec3(12.0f, 0.0f, 0.0f), glm::vec3(45.0f, 0.0f, 0.0f), 90.0f); +unsigned int quadVAO = 0; +unsigned int quadVBO = 0; + + +float skyboxVertices[]{ + // positions + -1.0f, 1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + 1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, + + -1.0f, -1.0f, 1.0f, + -1.0f, -1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 1.0f, + + 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + + -1.0f, -1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 1.0f, + -1.0f, -1.0f, 1.0f, + + -1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, -1.0f, + + -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, 1.0f, + 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, 1.0f, + 1.0f, -1.0f, 1.0f +}; Renderer::Renderer(RendererConfig& config) - : m_framebuffer(Framebuffer(config.ScreenWidth, config.ScreenHeight)) + : m_framebuffer(Framebuffer(config.ScreenWidth, config.ScreenHeight)), + gBufferShader("build/Debug/Shaders/deferred/geometry.vert", "build/Debug/Shaders/deferred/geometry.frag"), + lightingPassShader("build/Debug/Shaders/deferred/lightPass.vert", "build/Debug/Shaders/deferred/lightPass.frag"), + SkyboxShader("build/Debug/Shaders/Cubemaps/Skybox.vert", "build/Debug/Shaders/Cubemaps/Skybox.frag") { + width = config.ScreenWidth; + height = config.ScreenHeight; + + glEnable(GL_DEPTH_TEST); + +#if DEFERRED + // Deferred Rendering + glGenFramebuffers(1, &gBuffer); + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + + // - Position Color Buffer ; + glGenTextures(1, &gPosition); + glBindTexture(GL_TEXTURE_2D, gPosition); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0); + + // - normal color buffer ; + glGenTextures(1, &gNormal); + glBindTexture(GL_TEXTURE_2D, gNormal); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0); + + // - Color + Specular buffer ; + glGenTextures(1, &gColorSpec); + glBindTexture(GL_TEXTURE_2D, gColorSpec); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gColorSpec, 0); + + + unsigned int attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 }; + glDrawBuffers(3, attachments); + + // Create and attach a depth buffer + glGenRenderbuffers(1, &gDepth); + glBindRenderbuffer(GL_RENDERBUFFER, gDepth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gDepth); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + spdlog::critical("Framebuffer not complete {}{}", __FILE__, __LINE__); + } + + +#endif + + std::vector faces{ + "build/Debug/skybox/Open_Water/right.jpg", + "build/Debug/skybox/Open_Water/left.jpg", + "build/Debug/skybox/Open_Water/top.jpg", + "build/Debug/skybox/Open_Water/bottom.jpg", + "build/Debug/skybox/Open_Water/front.jpg", + "build/Debug/skybox/Open_Water/back.jpg" + }; + + sky = CubeMap(faces); + + // Create a skybox vao + unsigned int VBO; + glGenVertexArrays(1, &skyboxVAO); + glGenBuffers(1, &VBO); + glBindVertexArray(skyboxVAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + + + + } Renderer::~Renderer(){} - Camera& Renderer::getCamera() { return cam; } void Renderer::Submit( Render3DComponent& renderComponent, TransformComponent& transform) { - if (renderComponent.VAO == 0 || renderComponent.IBO == 0) { if (renderComponent.VAO != 0) @@ -60,22 +188,151 @@ void Renderer::Submit( Render3DComponent& renderComponent, TransformComponent& t renderComponent.IBO = elementBuffer.getBufferID(); } - DrawCommand dc = { renderComponent.VAO, renderComponent.mesh.elements.size(), renderComponent.IBO, transform, renderComponent.shader }; + DrawCommand dc = { renderComponent.VAO, renderComponent.mesh.elements.size(), renderComponent.IBO, transform, renderComponent.shader, renderComponent.color }; commands.push_back(dc); } -void Renderer::Render() -{ - glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer.GetId()); - if (m_depthTest) { - glEnable(GL_DEPTH_TEST); +void Renderer::GeometryPass() { + // 1.0 Geometry pass + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gBufferShader.Use(); + + for (const DrawCommand& command : commands) + { + glBindVertexArray(command.VAO_identifier); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, command.IBO_identifier); + + glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), command.transform.Rotation.x, glm::vec3(1.0f, 0.0f, 0.0f)); + rotation *= glm::rotate(glm::mat4(1.0f), command.transform.Rotation.y, glm::vec3(0.0f, 1.0f, 0.0f)); + rotation *= glm::rotate(glm::mat4(1.0f), command.transform.Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)); + + glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), command.transform.Position) * glm::scale(glm::mat4(1.0f), command.transform.Scale) * rotation; + + + gBufferShader.setUniformVec3("Color", command.color); + gBufferShader.setUniformMat4("Model", modelMatrix); + gBufferShader.setUniformMat4("View", cam.ViewMatrix); + gBufferShader.setUniformMat4("Projection", cam.ProjectionMatrix); + + glDrawElements(GL_TRIANGLES, static_cast(command.num_elements), + GL_UNSIGNED_INT, NULL); + + glBindVertexArray(0); } + +} + + +void Renderer::SkyboxPass() { + // Render skybox + glDepthMask(GL_FALSE); + SkyboxShader.Use(); + SkyboxShader.setUniformMat4("projection", cam.ProjectionMatrix); + SkyboxShader.setUniformMat4("view", glm::mat4(glm::mat3(cam.ViewMatrix))); // remove rotation from the view matrix + glBindVertexArray(skyboxVAO); + glBindTexture(GL_TEXTURE_CUBE_MAP, sky.getID()); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + + glDepthMask(GL_TRUE); + +} + +void Renderer::lightingPass(Scene& scene){ + + // 2.0 Lighting Pass + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer.GetId()); + lightingPassShader.Use(); + + // Bind all Gbuffer textures + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gPosition); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gNormal); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, gColorSpec); + + // send relevant Lighting Uniforms + auto lights = scene.getReg().view(); + unsigned int lightnr = 0; + lights.each([&](auto entity, LightComponent& light, TransformComponent& transform) { + lightingPassShader.setUniformVec3("lights[" + std::to_string(lightnr) + "].Position", transform.Position); + lightingPassShader.setUniformVec3("lights[" + std::to_string(lightnr) + "].Color", light.Color); + + // Attenuation + const float linear = 0.7f; + const float quadratic = 1.8f; + lightingPassShader.setUniformFloat("lights[" + std::to_string(lightnr) + "].Linear", linear); + lightingPassShader.setUniformFloat("lights[" + std::to_string(lightnr) + "].Quadratic", quadratic); + + + lightnr++; + }); + + lightingPassShader.setUniformVec3("viewPos", getCamera().Position); + + // render to quad + if (quadVAO == 0) + { + float quadVertices[] = { + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + }; + // setup plane VAO ; + glGenVertexArrays(1, &quadVAO); + glGenBuffers(1, &quadVBO); + glBindVertexArray(quadVAO); + glBindBuffer(GL_ARRAY_BUFFER, quadVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + } + + + glBindVertexArray(quadVAO); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); +} + +void Renderer::Render(Scene& scene) +{ +#if DEFERRED + // configure shader + lightingPassShader.Use(); + lightingPassShader.setUniformInt("gPosition", 0); + lightingPassShader.setUniformInt("gNormal", 1); + lightingPassShader.setUniformInt("gColorSpec", 2); + + GeometryPass(); + + lightingPass(scene); + + + + +#endif + +#if FORWARD + // Forward rendering approach + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer.GetId()); + glClearColor(m_clearColor.r, m_clearColor.g, m_clearColor.b, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + + + + SkyboxPass(); + + for (const DrawCommand& command : commands) { glBindVertexArray(command.VAO_identifier); @@ -91,7 +348,7 @@ void Renderer::Render() glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), command.transform.Position) * glm::scale(glm::mat4(1.0f), command.transform.Scale) * rotation; - command.shader.setUniformVec3("Color", glm::vec3(0.3f, 0.3f, 0.3f)); + command.shader.setUniformVec3("Color", command.color); command.shader.setUniformMat4("M", modelMatrix); command.shader.setUniformMat4("V", cam.ViewMatrix); command.shader.setUniformMat4("P", cam.ProjectionMatrix); @@ -104,22 +361,23 @@ void Renderer::Render() } + + // Lighting pass /* - * Lighting pass - * auto lights = scene.getReg().view(); + auto lights = scene.getReg().view(); lights.each([&](auto entity, LightComponent& light) { renderComponent.shader.setUniformVec3("lighting.color", light.Color); renderComponent.shader.setUniformFloat("lighting.strength", light.Strength); }); - * - */ + */ + +#endif + commands.clear(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } - - void Renderer::setCurrentFrameBuffer(const Framebuffer& fb) { m_framebuffer = fb; @@ -130,5 +388,4 @@ void Renderer::setClearColor(const glm::vec3& ClearColor) m_clearColor = ClearColor; } - } \ No newline at end of file diff --git a/YoggieEngine/src/Graphics/Renderer.h b/YoggieEngine/src/Graphics/Renderer.h index 7a53d64..c1ced62 100644 --- a/YoggieEngine/src/Graphics/Renderer.h +++ b/YoggieEngine/src/Graphics/Renderer.h @@ -24,17 +24,35 @@ namespace YoggieEngine { void Submit(Render3DComponent& renderComponent, TransformComponent& transform); // Collects DrawCommands - void Render(); // Draw to screen (using drawCall structs) + void Render(Scene&); // Draw to screen (using drawCall structs) void setCurrentFrameBuffer(const Framebuffer& fb); void setClearColor(const glm::vec3& ClearColor); Camera& getCamera(); + + private: + void GeometryPass(); + void SkyboxPass(); + void lightingPass(Scene& scene); + private: Framebuffer m_framebuffer; + int width, height; glm::vec3 m_clearColor; bool m_depthTest; std::vector commands; + + + unsigned int skyboxVAO = 0; + CubeMap sky; + + // deferred rending parameters + unsigned int gBuffer, gPosition, gNormal, gColorSpec, gDepth; + Shader lightingPassShader; + Shader gBufferShader; + Shader SkyboxShader; + }; } diff --git a/YoggieEngine/src/Scene/Components.h b/YoggieEngine/src/Scene/Components.h index 6ee6813..8a1eb5b 100644 --- a/YoggieEngine/src/Scene/Components.h +++ b/YoggieEngine/src/Scene/Components.h @@ -25,14 +25,14 @@ namespace YoggieEngine { }; struct LightComponent { - float Strength = 1.0f; - glm::vec3 Color = glm::vec3(1.0f, 1.0f, 1.0f); + glm::vec3 Color = glm::vec3(1.0f, .5f, .5f); }; struct CameraComponent { - glm::mat4 view; - + glm::vec3 Position = glm::vec3(0); + glm::vec3 Rotation = glm::vec3(0); + float Zoom ; }; @@ -49,7 +49,7 @@ namespace YoggieEngine { Shader shader; Render3DComponent() - : shader(Shader("build/Debug/test.vs", "build/Debug/test.fs")), + : shader(Shader("build/Debug/Shaders/forward/geometry.vert", "build/Debug/Shaders/forward/geometry.frag")), color(glm::vec3(1.0f, 0.0f, 0.0f)) { } diff --git a/YoggieEngine/src/Shaders/Deferred/geometry.frag b/YoggieEngine/src/Shaders/Deferred/geometry.frag new file mode 100644 index 0000000..96698e6 --- /dev/null +++ b/YoggieEngine/src/Shaders/Deferred/geometry.frag @@ -0,0 +1,20 @@ +#version 440 core +layout (location = 0) out vec3 gPosition; +layout (location = 1) out vec3 gNormal; +layout (location = 2) out vec4 gColorSpec; + + +in vec2 TexCoords; +in vec3 FragPos; +in vec3 Normal; + +uniform sampler2D texture_diffuse1; +uniform smapler2D texture_specular1; + +void main(){ + gPosition = FragPos; + gNormal = normalize(Normal); + gColorSpec.rgb = texture(texture_diffuse1, TexCoords).rgb; + gColorSpec.a = texture(texture_specular1, TexCoords).r; + +} \ No newline at end of file diff --git a/YoggieEngine/src/Shaders/Deferred/geometry.vert b/YoggieEngine/src/Shaders/Deferred/geometry.vert new file mode 100644 index 0000000..9fe0283 --- /dev/null +++ b/YoggieEngine/src/Shaders/Deferred/geometry.vert @@ -0,0 +1,26 @@ +#version 440 core +in layout(location=0) vec3 aPos; +in layout(location=1) vec3 aNormal; +in layout(location=2) vec2 aTexCoords; + +out vec3 FragPos; +out vec2 TexCoords; +out vec3 Normal; + + +uniform mat4 Model; +uniform mat4 View; +uniform mat4 Projection; + + + +void main() { + vec4 worldPos = model * vec4(aPos, 1.0f); + FragPos = worldPos.xyz; + TexCoords = aTexCoords; + + mat3 normalMatrix = transpose(inverse(mat3(model))); + Normal = normalMatrix * aNormal; + + gl_Position = Projection * View * worldPos; +} \ No newline at end of file diff --git a/YoggieEngine/src/Shaders/Deferred/lightPass.frag b/YoggieEngine/src/Shaders/Deferred/lightPass.frag new file mode 100644 index 0000000..666616b --- /dev/null +++ b/YoggieEngine/src/Shaders/Deferred/lightPass.frag @@ -0,0 +1,41 @@ +#version 440 core +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D gPosition; +uniform sampler2D gNormal; +uniform sampler2D gColorSpec; + + +struct Light { + vec3 Position; + vec3 Color; +}; +const int NR_LIGHTS = 32; +uniform Light lights[NR_LIGHTS]; +uniform vec3 viewPos; + +void main() +{ + // retrieve data from G-buffer + vec3 FragPos = texture(gPosition, TexCoords).rgb; + vec3 Normal = texture(gNormal, TexCoords).rgb; + vec3 Albedo = texture(gColorSpec, TexCoords).rgb; + float Specular = texture(gColorSpec, TexCoords).a; + + // calculate lighting as usual + vec3 lighting = Albedo * 0.1; // Hard-coded ambient light + vec3 viewDir = normalize(viewPos - FragPos); + for( int i = 0; i < NR_LIGHTS; ++i) + { + // diffuse + vec3 lightDir = normalize(lights[i].Position - FragPos); + vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Albedo * lights[i].Color; + lighting += diffuse; + } + + FragColor = vec4(lighting, 1.0f); + + +} \ No newline at end of file diff --git a/YoggieEngine/src/Shaders/Deferred/lightPass.vert b/YoggieEngine/src/Shaders/Deferred/lightPass.vert new file mode 100644 index 0000000..5fb4a1b --- /dev/null +++ b/YoggieEngine/src/Shaders/Deferred/lightPass.vert @@ -0,0 +1,13 @@ +#version 440 core +layout (location=0) in vec3 aPos; +layout (location=1) in vec2 aTexCoords; + +out vec2 TexCoords; + + +void main() +{ + TexCoords = aTexCoords; + gl_Position = vec4(aPos, 1.0f); + +} \ No newline at end of file diff --git a/YoggieEngine/src/Shaders/fragment.shader b/YoggieEngine/src/Shaders/Forward/geometry.frag similarity index 100% rename from YoggieEngine/src/Shaders/fragment.shader rename to YoggieEngine/src/Shaders/Forward/geometry.frag diff --git a/YoggieEngine/src/Shaders/vertex.shader b/YoggieEngine/src/Shaders/Forward/geometry.vert similarity index 100% rename from YoggieEngine/src/Shaders/vertex.shader rename to YoggieEngine/src/Shaders/Forward/geometry.vert diff --git a/YoggieEngine/src/Shaders/RenderSurfaceFrag.shader b/YoggieEngine/src/Shaders/RenderSurface/RenderSurface.frag similarity index 100% rename from YoggieEngine/src/Shaders/RenderSurfaceFrag.shader rename to YoggieEngine/src/Shaders/RenderSurface/RenderSurface.frag diff --git a/YoggieEngine/src/Shaders/RenderSurfaceVert.shader b/YoggieEngine/src/Shaders/RenderSurface/RenderSurface.vert similarity index 100% rename from YoggieEngine/src/Shaders/RenderSurfaceVert.shader rename to YoggieEngine/src/Shaders/RenderSurface/RenderSurface.vert diff --git a/YoggieEngine/src/YoggieEngine.h b/YoggieEngine/src/YoggieEngine.h index 6e6b940..0eb2c33 100644 --- a/YoggieEngine/src/YoggieEngine.h +++ b/YoggieEngine/src/YoggieEngine.h @@ -35,6 +35,7 @@ extern "C" #include "Graphics/Primitives/Mesh.h" #include "Graphics/Primitives/Shader.h" #include "Graphics/Primitives/Texture.h" +#include "Graphics/Primitives/CubeMap.h" #include "Graphics/Primitives/Camera.h" #include "Graphics/Primitives/Material.h" #include "Graphics/Renderer.h"