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)
This commit is contained in:
Nigel Barink 2022-12-28 22:35:23 +01:00
parent 2a5c7811e7
commit 2dcc3f1803
24 changed files with 512 additions and 70 deletions

BIN
Editor/Assets/Cube.mesh Normal file

Binary file not shown.

View File

@ -66,13 +66,9 @@ YAML::Emitter& operator<< (YAML::Emitter& emitter, glm::vec3& vector) {
emitter << YAML::Key << "Light"; emitter << YAML::Key << "Light";
emitter << YAML::Value; emitter << YAML::Value;
emitter << YAML::BeginMap; emitter << YAML::BeginMap;
emitter << YAML::Key << "strength";
emitter << YAML::Value << entity.GetComponent<LightComponent>().Strength;
emitter << YAML::Key << "Color"; emitter << YAML::Key << "Color";
emitter << YAML::Value << entity.GetComponent<LightComponent>().Color; emitter << YAML::Value << entity.GetComponent<LightComponent>().Color;
emitter << YAML::EndMap; emitter << YAML::EndMap;
} }
@ -129,7 +125,6 @@ YAML::Emitter& operator<< (YAML::Emitter& emitter, glm::vec3& vector) {
} }
if (entity["Light"]) { if (entity["Light"]) {
LightComponent lc = SE.AddComponent<LightComponent>(); LightComponent lc = SE.AddComponent<LightComponent>();
lc.Strength = entity["Light"]["strength"].as<float>();
lc.Color = glm::vec3(entity["Light"]["Color"][0].as<float>(), entity["Light"]["Color"][1].as<float>(), entity["Light"]["Color"][2].as<float>()); lc.Color = glm::vec3(entity["Light"]["Color"][0].as<float>(), entity["Light"]["Color"][1].as<float>(), entity["Light"]["Color"][2].as<float>());
} }

View File

@ -106,9 +106,10 @@ public:
switch (result) { switch (result) {
case(NFD_OKAY): case(NFD_OKAY):
// Import Model // Import Model
AssetManager::LoadFromSource( AssetManager::LoadFromSource(
path, path,
project.get()->GetProjectDirectory() / "Assets" "build/Debug/Assets"//project.get()->GetProjectDirectory() / "Assets"
); );
break; break;
case(NFD_CANCEL): case(NFD_CANCEL):

View File

@ -19,8 +19,7 @@ using namespace YoggieEngine;
auto matrix = glm::mat4(1.0f); auto matrix = glm::mat4(1.0f);
auto worldOrigin = 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) inline void ComponentView(const std::string& componentName, voidFunction func)
{ {
@ -40,7 +39,7 @@ public:
void AddComponentDropDown(Entity& selected ) 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")) if (ImGui::Button("Add Component"))
ImGui::OpenPopup("Component picker"); ImGui::OpenPopup("Component picker");
@ -82,25 +81,23 @@ public:
ImGui::ColorEdit3("Colour", glm::value_ptr(render3d.color)); ImGui::ColorEdit3("Colour", glm::value_ptr(render3d.color));
} }
} }
static bool deferred = true;
if (selected.HasComponent<LightComponent>()) { if (selected.HasComponent<LightComponent>()) {
auto& light = selected.GetComponent<LightComponent>(); auto& light = selected.GetComponent<LightComponent>();
if (ImGui::CollapsingHeader("Light", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::CollapsingHeader("Light", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::DragFloat("Strength", &light.Strength, 0.001f);
ImGui::ColorEdit3("Colour", glm::value_ptr(light.Color)); ImGui::ColorEdit3("Colour", glm::value_ptr(light.Color));
ImGui::Checkbox("Deferred", &deferred);
} }
} }
if (selected.HasComponent <CameraComponent>()) { if (selected.HasComponent <CameraComponent>()) {
auto& camera = selected.GetComponent<CameraComponent>(); auto& camera = selected.GetComponent<CameraComponent>();
static float Zoom = 90; if (ImGui::CollapsingHeader("Camera")) {
static glm::vec3 Position, Rotation = glm::vec3(0.0f); ImGui::DragFloat3("Position:",glm::value_ptr(camera.Position), 0.01f);
ComponentView("Camera", [] { ImGui::DragFloat3("Rotation:", glm::value_ptr(camera.Rotation), 0.01f);
ImGui::SliderFloat("Zoom", &Zoom, 10, 190);
ImGui::InputFloat3("Position:", &Position[0]); }
ImGui::InputFloat3("Rotation:", &Rotation[0]);
});
} }
if (selected.HasComponent<ScriptComponent>()) { if (selected.HasComponent<ScriptComponent>()) {
@ -131,7 +128,7 @@ public:
class Viewport : EditorWindow { class Viewport : EditorWindow {
public: public:
Viewport (Framebuffer& fb, Camera cam ) : EditorWindow("SceneView") Viewport (Framebuffer& fb, Camera cam) : EditorWindow("SceneView")
{ {
ImVec2 WinPos = ImGui::GetWindowPos(); ImVec2 WinPos = ImGui::GetWindowPos();
ImVec2 ContentRegionMin = ImGui::GetWindowContentRegionMin(); ImVec2 ContentRegionMin = ImGui::GetWindowContentRegionMin();
@ -149,11 +146,13 @@ public:
ImGuizmo::Enable(true); ImGuizmo::Enable(true);
ImGuizmo::SetRect(ScreenSpaceMin.x, ScreenSpaceMin.y,ContentRegionMax.x, ContentRegionMax.y); 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); 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 // 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));
} }

View File

@ -14,8 +14,6 @@
#include "SceneSerializer.h" #include "SceneSerializer.h"
#include "AssetManagement/AssetManager.h" #include "AssetManagement/AssetManager.h"
#include "UI/MainMenuBar.h" #include "UI/MainMenuBar.h"
const unsigned int MS_PER_UPDATE = 2; const unsigned int MS_PER_UPDATE = 2;
void CreateTestProject(std::unique_ptr<Project>& project, Scene& scene); void CreateTestProject(std::unique_ptr<Project>& project, Scene& scene);
@ -26,6 +24,8 @@ RendererConfig EditorSceneRendererConfig{
true // Depth testing 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 { class Editor : public Application {
public: public:
Editor() Editor()
@ -46,7 +46,9 @@ public:
viewportRenderer.Submit(renderComponent, t); viewportRenderer.Submit(renderComponent, t);
}); });
viewportRenderer.Render(); // Render scene
viewportRenderer.Render(ActiveScene);
} }
void RenderEditorGUI() { void RenderEditorGUI() {
@ -120,7 +122,6 @@ public:
Physics Physics; Physics Physics;
//Physics.Demo(); //Physics.Demo();
double previous = glfwGetTime(); double previous = glfwGetTime();
double lag = 0.0; double lag = 0.0;
while (!AppWindow.WindowShouldClose()) while (!AppWindow.WindowShouldClose())
@ -145,6 +146,8 @@ public:
lag -= MS_PER_UPDATE; lag -= MS_PER_UPDATE;
} }
RenderScene(); RenderScene();
RenderEditorGUI(); RenderEditorGUI();
@ -176,7 +179,6 @@ private:
std::unique_ptr<Project> CurrentProject; std::unique_ptr<Project> CurrentProject;
Scene ActiveScene; Scene ActiveScene;
}; };
YoggieEngine::Application* CreateApplication() { YoggieEngine::Application* CreateApplication() {
@ -211,8 +213,10 @@ void CreateTestProject(std::unique_ptr<Project>& project, Scene& scene ) {
rendercube2.mesh = *(model->renderable->mesh); rendercube2.mesh = *(model->renderable->mesh);
// create an ambient light source // create an ambient light source
auto AmbientLight = scene.AddEntity("AmbientLight"); auto light = scene.AddEntity("Light");
auto light = AmbientLight.AddComponent<LightComponent>(); auto lightComponent = light.AddComponent<LightComponent>();
light.Color = glm::vec3(1.0f); lightComponent.Color = glm::vec3(1.0f);
light.Strength = 1.0f;
} }

View File

@ -1,19 +1,24 @@
#include <YoggieEngine.h> #include <YoggieEngine.h>
#include "Camera.h" #include "Camera.h"
namespace YoggieEngine { namespace YoggieEngine {
Camera::Camera(const Camera& other)
Camera::Camera(glm::vec3 position, glm::vec3 rotation, float zoom) : Position(other.Position), Rotation(other.Rotation), Zoom(other.Zoom)
: Position(position), Rotation(rotation), Zoom(zoom) { {
}
Camera::Camera(glm::vec3 position, glm::vec3 rotation, float zoom)
: Position(position), Rotation( rotation)
{
Front = glm::vec3(-1.0f, 0.0f, 0.0f); Front = glm::vec3(-1.0f, 0.0f, 0.0f);
Right = glm::vec3(0.0f, 0.0f, 1.0f); Right = glm::vec3(0.0f, 0.0f, 1.0f);
Up = glm::vec3(0.0f, 1.0f, 0.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( ViewMatrix = glm::lookAt(
Position, Position,
glm::vec3{ rotated_position.x, rotated_position.y , rotated_position.z } + Front, Position + Front,
Up); Up);
ProjectionMatrix = glm::perspective(glm::radians(Zoom), (800.0f / 600.0f), 0.001f, 100.0f); ProjectionMatrix = glm::perspective(glm::radians(Zoom), (800.0f / 600.0f), 0.001f, 100.0f);
@ -24,13 +29,8 @@ namespace YoggieEngine {
} }
void Camera::Update() { void Camera::Update() {
ViewMatrix = glm::lookAt( ViewMatrix = glm::lookAt(Position,Position + Front,Up);
Position,
Position + Front,
Up);
} }
} }

View File

@ -2,9 +2,11 @@
namespace YoggieEngine { namespace YoggieEngine {
class Camera { class Camera {
public: public:
Camera(const Camera& other);
Camera(glm::vec3 position, glm::vec3 rotation, float zoom); Camera(glm::vec3 position, glm::vec3 rotation, float zoom);
~Camera(); ~Camera();
void Update(); void Update();
glm::vec3 Position; glm::vec3 Position;

View File

@ -0,0 +1,45 @@
#include <YoggieEngine.h>
#include "CubeMap.h"
#define STB_IMAGE_IMPLEMENTATION
#include "../stb_image.h"
YoggieEngine::CubeMap::CubeMap()
{
}
YoggieEngine::CubeMap::CubeMap(std::vector<std::string>& 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()
{
}

View File

@ -0,0 +1,19 @@
#pragma once
namespace YoggieEngine {
class CubeMap {
public:
CubeMap();
CubeMap(std::vector<std::string>& texture_faces);
~CubeMap();
unsigned int getID() { return textureID; }
private:
unsigned int textureID;
};
};

View File

@ -7,6 +7,7 @@ namespace YoggieEngine {
unsigned int IBO_identifier; unsigned int IBO_identifier;
TransformComponent& transform; TransformComponent& transform;
Shader& shader; Shader& shader;
glm::vec3& color;
// Material // Material
}; };
}; };

View File

@ -109,7 +109,7 @@ namespace YoggieEngine {
{ {
glUniform4fv(glGetUniformLocation(id, uniformName.c_str()), 1, glm::value_ptr(vector4)); 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)); glUniform3fv(glGetUniformLocation(id, uniformName.c_str()), 1, glm::value_ptr(vector3));
} }

View File

@ -2,7 +2,7 @@
#include "RenderSurface.h" #include "RenderSurface.h"
namespace YoggieEngine { namespace YoggieEngine {
RenderSurface::RenderSurface() { 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<glm::vec3>{ verts = std::vector<glm::vec3>{
{-0.5f, 0.5f, 0.0f}, // 0 {-0.5f, 0.5f, 0.0f}, // 0

View File

@ -6,24 +6,152 @@
#include "../Graphics/Memory/VertexArray.h" #include "../Graphics/Memory/VertexArray.h"
#include "../Graphics/Primitives/DrawCommand.h" #include "../Graphics/Primitives/DrawCommand.h"
#define FORWARD 1
#define DEFERRED 0
extern YoggieEngine::Camera cam;
namespace YoggieEngine { 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) 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<std::string> 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(){} Renderer::~Renderer(){}
Camera& Renderer::getCamera() { Camera& Renderer::getCamera() {
return cam; return cam;
} }
void Renderer::Submit( Render3DComponent& renderComponent, TransformComponent& transform) { void Renderer::Submit( Render3DComponent& renderComponent, TransformComponent& transform) {
if (renderComponent.VAO == 0 || renderComponent.IBO == 0) if (renderComponent.VAO == 0 || renderComponent.IBO == 0)
{ {
if (renderComponent.VAO != 0) if (renderComponent.VAO != 0)
@ -60,22 +188,151 @@ void Renderer::Submit( Render3DComponent& renderComponent, TransformComponent& t
renderComponent.IBO = elementBuffer.getBufferID(); 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); commands.push_back(dc);
} }
void Renderer::Render()
{
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer.GetId());
if (m_depthTest) { void Renderer::GeometryPass() {
glEnable(GL_DEPTH_TEST); // 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<unsigned int>(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<LightComponent, TransformComponent>();
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); glClearColor(m_clearColor.r, m_clearColor.g, m_clearColor.b, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SkyboxPass();
for (const DrawCommand& command : commands) for (const DrawCommand& command : commands)
{ {
glBindVertexArray(command.VAO_identifier); 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; 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("M", modelMatrix);
command.shader.setUniformMat4("V", cam.ViewMatrix); command.shader.setUniformMat4("V", cam.ViewMatrix);
command.shader.setUniformMat4("P", cam.ProjectionMatrix); command.shader.setUniformMat4("P", cam.ProjectionMatrix);
@ -104,22 +361,23 @@ void Renderer::Render()
} }
// Lighting pass
/* /*
* Lighting pass auto lights = scene.getReg().view<LightComponent>();
* auto lights = scene.getReg().view<LightComponent>();
lights.each([&](auto entity, LightComponent& light) { lights.each([&](auto entity, LightComponent& light) {
renderComponent.shader.setUniformVec3("lighting.color", light.Color); renderComponent.shader.setUniformVec3("lighting.color", light.Color);
renderComponent.shader.setUniformFloat("lighting.strength", light.Strength); renderComponent.shader.setUniformFloat("lighting.strength", light.Strength);
}); });
*
*/
*/
#endif
commands.clear(); commands.clear();
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
void Renderer::setCurrentFrameBuffer(const Framebuffer& fb) void Renderer::setCurrentFrameBuffer(const Framebuffer& fb)
{ {
m_framebuffer = fb; m_framebuffer = fb;
@ -130,5 +388,4 @@ void Renderer::setClearColor(const glm::vec3& ClearColor)
m_clearColor = ClearColor; m_clearColor = ClearColor;
} }
} }

View File

@ -24,17 +24,35 @@ namespace YoggieEngine {
void Submit(Render3DComponent& renderComponent, TransformComponent& transform); // Collects DrawCommands 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 setCurrentFrameBuffer(const Framebuffer& fb);
void setClearColor(const glm::vec3& ClearColor); void setClearColor(const glm::vec3& ClearColor);
Camera& getCamera(); Camera& getCamera();
private:
void GeometryPass();
void SkyboxPass();
void lightingPass(Scene& scene);
private: private:
Framebuffer m_framebuffer; Framebuffer m_framebuffer;
int width, height;
glm::vec3 m_clearColor; glm::vec3 m_clearColor;
bool m_depthTest; bool m_depthTest;
std::vector<DrawCommand> commands; std::vector<DrawCommand> commands;
unsigned int skyboxVAO = 0;
CubeMap sky;
// deferred rending parameters
unsigned int gBuffer, gPosition, gNormal, gColorSpec, gDepth;
Shader lightingPassShader;
Shader gBufferShader;
Shader SkyboxShader;
}; };
} }

View File

@ -25,14 +25,14 @@ namespace YoggieEngine {
}; };
struct LightComponent { struct LightComponent {
float Strength = 1.0f; glm::vec3 Color = glm::vec3(1.0f, .5f, .5f);
glm::vec3 Color = glm::vec3(1.0f, 1.0f, 1.0f);
}; };
struct CameraComponent { 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; Shader shader;
Render3DComponent() 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)) color(glm::vec3(1.0f, 0.0f, 0.0f))
{ {
} }

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -35,6 +35,7 @@ extern "C"
#include "Graphics/Primitives/Mesh.h" #include "Graphics/Primitives/Mesh.h"
#include "Graphics/Primitives/Shader.h" #include "Graphics/Primitives/Shader.h"
#include "Graphics/Primitives/Texture.h" #include "Graphics/Primitives/Texture.h"
#include "Graphics/Primitives/CubeMap.h"
#include "Graphics/Primitives/Camera.h" #include "Graphics/Primitives/Camera.h"
#include "Graphics/Primitives/Material.h" #include "Graphics/Primitives/Material.h"
#include "Graphics/Renderer.h" #include "Graphics/Renderer.h"