Added a few thing , and started simplifying renderer

- Added context menu to Inspector
- Added check to see if project path exists.
- Simplifying the renderer design
This commit is contained in:
Nigel Barink 2023-05-12 22:38:10 +02:00
parent 550c1b6e5b
commit daf26c304b
9 changed files with 436 additions and 373 deletions

View File

@ -16,6 +16,10 @@ public:
AssetFinder () : EditorWindow("Assets") {} AssetFinder () : EditorWindow("Assets") {}
AssetFinder(const std::filesystem::path& projectdirectory) : EditorWindow("Assets") AssetFinder(const std::filesystem::path& projectdirectory) : EditorWindow("Assets")
{ {
assetIcon = YoggieEngine::Texture("rsc/AssetIcon.png");
spdlog::info("asset iconID: {0}", assetIcon.GetID());
for (auto& dir_entry : std::filesystem::directory_iterator(projectdirectory)) { for (auto& dir_entry : std::filesystem::directory_iterator(projectdirectory)) {
auto filepath = dir_entry.path(); auto filepath = dir_entry.path();
@ -39,7 +43,6 @@ public:
spdlog::info("Created asset: {0}", asset.GetName()); spdlog::info("Created asset: {0}", asset.GetName());
files.push_back(asset); files.push_back(asset);
assetIcon = YoggieEngine::Texture("rsc/AssetIcon.png");
} }

View File

@ -8,8 +8,6 @@ public:
Right = glm::vec3(-1.0f, 0.0f, 0.0f); Right = glm::vec3(-1.0f, 0.0f, 0.0f);
Up = glm::vec3(0.0f, 1.0f, 0.0f); Up = glm::vec3(0.0f, 1.0f, 0.0f);
projection = glm::perspective(glm::radians(65.0f), (800.0f / 600.0f), 0.001f, 100.0f);
view = glm::translate(glm::mat4(1.0f), Position) * glm::toMat4(glm::quat(Rotation)); view = glm::translate(glm::mat4(1.0f), Position) * glm::toMat4(glm::quat(Rotation));
} }
@ -19,8 +17,8 @@ public:
view = glm::translate(glm::mat4(1.0f), Position) * glm::toMat4(glm::quat(Rotation)); view = glm::translate(glm::mat4(1.0f), Position) * glm::toMat4(glm::quat(Rotation));
} }
glm::vec3 Position; glm::vec3 Position = glm::vec3(0.0f);
glm::vec3 Rotation; glm::vec3 Rotation = glm::vec3(0.0f);
private: private:

View File

@ -17,6 +17,9 @@
#include "IconsMaterialDesign.h" #include "IconsMaterialDesign.h"
#include "Project/Project.h" #include "Project/Project.h"
#include <ImGuizmo.h> #include <ImGuizmo.h>
#include "EditorCamera.h"
#include "../../YoggieEngine/src/Graphics/Memory/VertexArray.h"
#include "../../YoggieEngine/src/Graphics/Memory/Buffer.h"
using namespace YoggieEngine; using namespace YoggieEngine;
class EditorLayer : public Layer { class EditorLayer : public Layer {
@ -24,8 +27,24 @@ class EditorLayer : public Layer {
public: public:
EditorLayer() : EditorLayer() :
Layer(), Layer(),
inspector (Selected) Logo("rsc/Yoggie.png"),
inspector(Selected),
scene(),
renderer()
{ {
spdlog::info("Colour attachment id: {0}", renderer.getCurrentFrameBuffer().GetColourAttachment());
Selected = YoggieEngine::Entity((entt::entity)-1, &scene);
AssetRegistry assetManager = AssetRegistry();
// ModelLoader modelLoader = ModelLoader();
spdlog::info("{0}", project.GetProjectDirectory().string());
//auto latern = modelLoader.LoadAsset(std::filesystem::path("build/debug/Models/Latern.gltf"));
//spdlog::info("Loaded mesh: {0}", latern.GetName());
} }
void OnStartup() override { void OnStartup() override {
@ -33,27 +52,13 @@ public:
project.setProjectDirectory(path); project.setProjectDirectory(path);
assetsView = AssetFinder(project.GetProjectDirectory()); assetsView = AssetFinder(project.GetProjectDirectory());
LoadLastOrEmptyProject(); LoadLastOrEmptyProject();
cube = (ModelLoader()).LoadAsset(std::filesystem::path("build/debug/Models/cube.obj"));
AssetRegistry assetManager = AssetRegistry();
ModelLoader modelLoader = ModelLoader();
spdlog::info( "{0}", project.GetProjectDirectory().string());
auto latern = modelLoader.LoadAsset(std::filesystem::path("build/debug/Models/Latern.gltf"));
spdlog::info( "Loaded mesh: {0}" , latern.GetName() );
//Settings settings = Settings(); //Settings settings = Settings();
//Console console = Console(); //Console console = Console();
Logo = Texture("rsc/Yoggie.png", true);
Selected = YoggieEngine::Entity((entt::entity)-1, &scene);
} }
glm::vec3 cameraPosition = glm::vec3(0.0f, 0.0f, -5.0f);
glm::vec3 cameraRotation = glm::vec3(0.0f);
void OnUpdate() override { void OnUpdate() override {
scene.Update(); scene.Update();
/* /*
@ -62,12 +67,58 @@ public:
} }
*/ */
auto components = scene.getReg().view<Render3DComponent>();
for(auto component : components){
auto& renderComponent = YoggieEngine::Entity(component, &scene).GetComponent<Render3DComponent>();
renderComponent.mesh = cube;
if (renderComponent.VAO == 0 || renderComponent.IBO == 0) {
VertexArray va = VertexArray();
Buffer vertexBuffer = Buffer();
Buffer elementBuffer = Buffer();
va.Create();
va.Bind();
vertexBuffer.createBuffer();
vertexBuffer.Bind(false);
vertexBuffer.setBufferData((void*)&renderComponent.mesh.vertices[0], renderComponent.mesh.vertices.size() * sizeof(Vertex), false);
elementBuffer.createBuffer();
elementBuffer.Bind(true);
elementBuffer.setBufferData((void*)&renderComponent.mesh.elements[0], renderComponent.mesh.elements.size() * sizeof(unsigned int), true);
va.AttachAttribute(0, 3, sizeof(Vertex));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
va.Unbind();
vertexBuffer.Unbind(false);
elementBuffer.Unbind(true);
renderComponent.VAO = va.getID();
renderComponent.IBO = elementBuffer.getBufferID();
}
}
camera->view = glm::translate(glm::mat4(1.0f), cameraPosition) * glm::toMat4(glm::quat(cameraRotation));
renderer.Render(scene, *camera);
} }
void OnUI() override { void OnUI() override {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { ImGui::GetWindowWidth(), 7 }); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { ImGui::GetWindowWidth(), 7 });
ImGui::BeginMainMenuBar(); ImGui::BeginMainMenuBar();
int scaleFactor = 30; int scaleFactor = 30;
@ -216,7 +267,6 @@ public:
ImGui::SameLine(ImGui::GetWindowWidth() - 120); ImGui::SameLine(ImGui::GetWindowWidth() - 120);
/* /*
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.1f, 0.1f, 0.01f)); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.1f, 0.1f, 0.01f));
if (ImGui::Button(ICON_MD_MINIMIZE)) { spdlog::info("Minimize"); } if (ImGui::Button(ICON_MD_MINIMIZE)) { spdlog::info("Minimize"); }
@ -268,9 +318,17 @@ public:
ImGui::End(); ImGui::End();
ImGui::Begin("SceneView"); unsigned int viewportWindowFlags = ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoDecoration
| ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoCollapse;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0,0 });
ImGui::Begin("SceneView",nullptr,viewportWindowFlags);
spdlog::info( "Editor Resolution {0}x{1}", (float)ImGui::GetWindowWidth(),(float)ImGui::GetWindowHeight());
//ImGui::Image((ImTextureID)gameScreen.GetID(), gameScreen.getSize()); ImGui::Image((ImTextureID)(intptr_t)renderer.getCurrentFrameBuffer().GetColourAttachment(),
ImVec2{(float)ImGui::GetWindowWidth(),(float)ImGui::GetWindowHeight()});
ImGuizmo::Enable(true); ImGuizmo::Enable(true);
ImGuizmo::SetOrthographic(false); ImGuizmo::SetOrthographic(false);
@ -295,6 +353,15 @@ public:
*/ */
ImGui::End(); ImGui::End();
ImGui::PopStyleVar();
ImGui::Begin("EditorCamera");
ImGui::SliderFloat3("position", glm::value_ptr(cameraPosition), -50, 50);
ImGui::End();
ImGui::Begin(ICON_MD_MENU "SceneExplorer",nullptr); ImGui::Begin(ICON_MD_MENU "SceneExplorer",nullptr);
scene.getReg().each([&](entt::entity enttNumber) { scene.getReg().each([&](entt::entity enttNumber) {
@ -302,8 +369,11 @@ public:
auto id = entity.GetComponent<YoggieEngine::IdentifierComponent>(); auto id = entity.GetComponent<YoggieEngine::IdentifierComponent>();
if (ImGui::Selectable(id.name.c_str(), entity == Selected)) { if (ImGui::Selectable(id.name.c_str(), entity == Selected)) {
Selected = YoggieEngine::Entity(enttNumber, &scene); Selected = YoggieEngine::Entity(enttNumber, &scene);
} }
}); });
ImGui::End(); ImGui::End();
inspector.Update(); inspector.Update();
@ -340,7 +410,9 @@ private:
Scene scene; Scene scene;
char* path = nullptr; char* path = nullptr;
Texture Logo; Texture Logo;
Renderer renderer;
Camera* camera = new EditorCamera();
Mesh cube ;
void LoadLastOrEmptyProject() { void LoadLastOrEmptyProject() {
// Check if there is a last known loaded project and // Check if there is a last known loaded project and

View File

@ -31,6 +31,11 @@ void Project::SaveProject(std::filesystem::path path, Project& project)
void Project::LoadProject(std::filesystem::path path, Project& project) void Project::LoadProject(std::filesystem::path path, Project& project)
{ {
if (!std::filesystem::exists(path)) {
throw std::runtime_error("Couldn't find project file!");
}
std::string YAMLProject; std::string YAMLProject;
std::stringstream sstream; std::stringstream sstream;
std::ifstream projectFile; std::ifstream projectFile;
@ -47,7 +52,7 @@ void Project::LoadProject(std::filesystem::path path, Project& project)
// this is probably not perfect but it seems to work for now // this is probably not perfect but it seems to work for now
project = node.as<Project>(); project = node.as<Project>();
std::cout << "loading..." << project.Name << std::endl; spdlog::info("loaded project {0}", project.Name);

View File

@ -1,5 +1,6 @@
#include "Inspector.h" #include "Inspector.h"
#include "../TransformVec3.h" #include "../TransformVec3.h"
#include "../IconsMaterialDesign.h"
void Inspector::Draw() void Inspector::Draw()
{ {
@ -56,6 +57,28 @@ void Inspector::ShowComponents()
if (selected.HasComponent<YoggieEngine::TransformComponent>()) { if (selected.HasComponent<YoggieEngine::TransformComponent>()) {
auto& transform = selected.GetComponent<YoggieEngine::TransformComponent>(); auto& transform = selected.GetComponent<YoggieEngine::TransformComponent>();
if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{ 1.0, 1.0f, 1.0f, 0.0f });
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4{ 1.0, 1.0f, 1.0f, 0.0f });
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{ 1.0, 1.0f, 1.0f, 0.0f });
ImGui::SetCursorPosX(ImGui::GetContentRegionMax().x - 20);
ImGui::Button(ICON_MD_SETTINGS, { 20,20 });
ImGui::OpenPopupOnItemClick("##myContext", ImGuiPopupFlags_MouseButtonRight);
if (ImGui::BeginPopupContextWindow("##myContext")) {
if (ImGui::MenuItem("Reset")) {
spdlog::info("Reset component");
}
if (ImGui::MenuItem("Copy Component")) {
spdlog::info("Copy component");
}
ImGui::EndPopup();
}
ImGui::PopStyleColor(3);
/* /*
ImGui::DragFloat3("Position", glm::value_ptr(transform.Position), 0.1f); ImGui::DragFloat3("Position", glm::value_ptr(transform.Position), 0.1f);
ImGui::DragFloat3("Rotation", glm::value_ptr(transform.Rotation), 0.1f); ImGui::DragFloat3("Rotation", glm::value_ptr(transform.Rotation), 0.1f);

View File

@ -0,0 +1,27 @@
#include <YoggieEngine.h>
#include "OpenglAPI.h"
namespace YoggieEngine {
void OpenGLApi::DrawTriangles(Render3DComponent rc) {
glBindVertexArray(rc.VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rc.IBO);
glDrawElements(GL_TRIANGLES, static_cast<unsigned int> (rc.mesh.elements.size()), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
void OpenGLApi::DrawCubeMap(unsigned int VertexAttributeObject, CubeMap CubeTexture) {
glDepthMask(GL_FALSE);
glBindTexture(GL_TEXTURE_CUBE_MAP, CubeTexture.getID());
glBindVertexArray(VertexAttributeObject);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthMask(GL_TRUE);
}
}

View File

@ -0,0 +1,9 @@
#pragma once
namespace YoggieEngine {
class OpenGLApi {
public:
static void DrawTriangles(Render3DComponent rc);
static void DrawCubeMap(unsigned int VertexAttributeObject, CubeMap CubeTexture);
};
};

View File

@ -4,7 +4,6 @@
#include "../Scene/Components.h" #include "../Scene/Components.h"
#include "../Graphics/Memory/Buffer.h" #include "../Graphics/Memory/Buffer.h"
#include "../Graphics/Memory/VertexArray.h" #include "../Graphics/Memory/VertexArray.h"
#include "../Graphics/Primitives/DrawCommand.h"
namespace YoggieEngine { namespace YoggieEngine {
unsigned int quadVAO = 0; unsigned int quadVAO = 0;
@ -65,8 +64,9 @@ float skyboxVertices[]{
1.0f, -1.0f, 1.0f 1.0f, -1.0f, 1.0f
}; };
Renderer::Renderer(RendererConfig& config)
: m_framebuffer(Framebuffer(config.ScreenWidth, config.ScreenHeight)), Renderer::Renderer() :
m_framebuffer(960, 540),
gBufferShader("build/Debug/Shaders/deferred/geometry.vert", "build/Debug/Shaders/deferred/geometry.frag"), 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"), 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"), SkyboxShader("build/Debug/Shaders/Cubemaps/Skybox.vert", "build/Debug/Shaders/Cubemaps/Skybox.frag"),
@ -74,11 +74,26 @@ Renderer::Renderer(RendererConfig& config)
forwardShader("build/Debug/Shaders/forward/geometry.vert", "build/Debug/Shaders/forward/geometry.frag"), forwardShader("build/Debug/Shaders/forward/geometry.vert", "build/Debug/Shaders/forward/geometry.frag"),
postProcessingShader("build/Debug/Shaders/forward/postprocessing.vert", "build/Debug/Shaders/forward/postprocessing.frag") postProcessingShader("build/Debug/Shaders/forward/postprocessing.vert", "build/Debug/Shaders/forward/postprocessing.frag")
{ {
width = config.ScreenWidth; width = 960;
height = config.ScreenHeight; height = 540;
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
CreateGBuffer();
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"
};
skybox = CubeMap(faces);
}
void Renderer::CreateGBuffer() {
// Deferred Rendering // Deferred Rendering
glGenFramebuffers(1, &gBuffer); glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
@ -122,326 +137,16 @@ Renderer::Renderer(RendererConfig& config)
spdlog::critical("Framebuffer not complete {}{}", __FILE__, __LINE__); spdlog::critical("Framebuffer not complete {}{}", __FILE__, __LINE__);
} }
glBindFramebuffer(GL_FRAMEBUFFER, 0);
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);
#ifdef WINDOW
grassTexture = Texture("build/Debug/Texture/blending_transparent_window.png", true);
#else
grassTexture = Texture("build/Debug/Texture/grass.png", true);
#endif
} }
Renderer::~Renderer(){} Renderer::~Renderer(){}
void SubmitVegetationDemo() {
if (transparentVAO == 0) {
float transparentVertices[] = {
// positions // texture Coords (swapped y coordinates because texture is flipped upside down)
0.0f, 0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f, 1.0f,
1.0f, -0.5f, 0.0f, 1.0f, 1.0f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f,
1.0f, -0.5f, 0.0f, 1.0f, 1.0f,
1.0f, 0.5f, 0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &transparentVAO);
glGenBuffers(1, &transparentVBO);
glBindVertexArray(transparentVAO);
glBindBuffer(GL_ARRAY_BUFFER, transparentVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(transparentVertices), transparentVertices, 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(0);
}
}
void Renderer::Submit( Render3DComponent& renderComponent, TransformComponent& transform) {
if (renderComponent.mesh.elements.empty())
return;
if (renderComponent.VAO == 0 || renderComponent.IBO == 0)
{
if (renderComponent.VAO != 0)
glDeleteVertexArrays(1, &(renderComponent.VAO));
if (renderComponent.IBO != 0)
glDeleteBuffers(1, &(renderComponent.IBO));
VertexArray va = VertexArray();
Buffer vertexBuffer = Buffer();
Buffer elementBuffer = Buffer();
va.Create();
va.Bind();
vertexBuffer.createBuffer();
vertexBuffer.Bind(false);
vertexBuffer.setBufferData((void*)&renderComponent.mesh.vertices[0], renderComponent.mesh.vertices.size() * sizeof(Vertex), false);
elementBuffer.createBuffer();
elementBuffer.Bind(true);
elementBuffer.setBufferData((void*)&renderComponent.mesh.elements[0], renderComponent.mesh.elements.size() * sizeof(unsigned int), true);
va.AttachAttribute(0, 3, sizeof(Vertex));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
va.Unbind();
vertexBuffer.Unbind(false);
elementBuffer.Unbind(true);
renderComponent.VAO = va.getID();
renderComponent.IBO = elementBuffer.getBufferID();
}
DrawCommand dc = { renderComponent.isStatic , renderComponent.VAO, renderComponent.mesh.elements.size(), renderComponent.IBO, transform, renderComponent.color };
commands.push_back(dc);
}
void Renderer::GeometryPass() {
// 1.0 Geometry pass
gBufferShader.Use();
for (const DrawCommand& command : commands)
{
if (command.isDynamic == true)
continue;
glBindVertexArray(command.VAO_identifier);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, command.IBO_identifier);
gBufferShader.setUniformVec3("Color", command.color);
gBufferShader.setUniformMat4("Model", command.transform.LocalTransform);
gBufferShader.setUniformMat4("View", MainCamera.view);
gBufferShader.setUniformMat4("Projection", MainCamera.projection);
glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(command.num_elements),
GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
}
}
void Renderer::ForwardGeometryPass()
{
for (const DrawCommand& command : commands)
{
if (command.isDynamic == false)
continue;
glBindVertexArray(command.VAO_identifier);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, command.IBO_identifier);
forwardShader.Use();
forwardShader.setUniformVec3("Color", command.color);
forwardShader.setUniformMat4("M", command.transform.LocalTransform);
forwardShader.setUniformMat4("V", MainCamera.view);
forwardShader.setUniformMat4("P", MainCamera.projection);
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", MainCamera.projection);
SkyboxShader.setUniformMat4("view", glm::mat4(glm::mat3(MainCamera.view))); // 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
// configure shader
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer.GetId());
lightingPassShader.Use();
lightingPassShader.setUniformInt("gPosition", 0);
lightingPassShader.setUniformInt("gNormal", 1);
lightingPassShader.setUniformInt("gColorSpec", 2);
// 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", MainCamera.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::BlendingPass() {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Vegetation / blending test;
BlendingShader.Use();
glBindVertexArray(transparentVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, grassTexture.GetID());
BlendingShader.setUniformMat4("V", MainCamera.view);
BlendingShader.setUniformMat4("P", MainCamera.projection);
for (unsigned int i = 0; i < vegetation.size(); i++) {
auto rotation = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(0.0f, 1.0f, 0.0f));
auto translation = glm::translate(glm::mat4(1.0f), vegetation[i]);
auto transform = translation * rotation;
BlendingShader.setUniformMat4("M", transform);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
glBindVertexArray(0);
glDisable(GL_BLEND);
}
void Renderer::PostProcessing()
{
postProcessingShader.Use();
postProcessingShader.setUniformInt("screen", 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_framebuffer.GetColourAttachment());
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
}
void Renderer::CopyGBuffer() {
glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer.GetId());
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer.GetId());
}
void Renderer::Render(Scene& scene)
{
SubmitVegetationDemo();
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SkyboxPass();
GeometryPass();
lightingPass(scene);
CopyGBuffer();
ForwardGeometryPass();
BlendingPass();
//PostProcessing();
commands.clear();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Renderer::setCurrentFrameBuffer(const Framebuffer& fb) void Renderer::setCurrentFrameBuffer(const Framebuffer& fb)
{ {

View File

@ -7,8 +7,8 @@
#include "Memory/Framebuffer.h" #include "Memory/Framebuffer.h"
#include "../Scene/Components.h" #include "../Scene/Components.h"
#include"../Scene/Scene.h" #include"../Scene/Scene.h"
#include "Graphics/Primitives/DrawCommand.h"
#include "Primitives/Camera.h" #include "Primitives/Camera.h"
#include "OpenglAPI.h"
namespace YoggieEngine { namespace YoggieEngine {
@ -20,39 +20,209 @@ namespace YoggieEngine {
class Renderer { class Renderer {
public: public:
Renderer(RendererConfig& config); Renderer();
~Renderer(); ~Renderer();
void Submit(Render3DComponent& renderComponent, TransformComponent& transform); // Collects DrawCommands // Forward pass
void Render(Scene&); // Draw to screen (using drawCall structs) /*
forwardShader.Use();
forwardShader.setUniformVec3("Color", renderComponent.color);
forwardShader.setUniformMat4("M", transform.LocalTransform);
forwardShader.setUniformMat4("V", MainCamera.view);
forwardShader.setUniformMat4("P", MainCamera.projection);
OpenGLApi::DrawTriangles(renderComponent);
*/
void Render(Scene& scene, Camera MainCamera) {
MainCamera.projection = glm::perspective(glm::radians(65.0f), ((float)width/(float)height), 0.0001f, 1000.0f);
glViewport(0, 0, width, height);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Render skybox if the scene has one
SkyboxShader.Use();
SkyboxShader.setUniformMat4("projection", MainCamera.projection);
SkyboxShader.setUniformMat4("view", glm::mat4(glm::mat3(MainCamera.view)));
if (!skyboxVAO) {
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);
}
OpenGLApi::DrawCubeMap( skyboxVAO, skybox);
auto renderables = scene.getReg().view<TransformComponent, Render3DComponent>();
gBufferShader.Use();
for (auto renderable : renderables) {
auto entity = Entity(renderable, &scene);
auto& renderComponent = entity.GetComponent<Render3DComponent>();
auto& transform = entity.GetComponent<TransformComponent>();
// Geometry pass
gBufferShader.setUniformVec3("Color", renderComponent.color);
gBufferShader.setUniformMat4("Model", transform.GetTransform());
gBufferShader.setUniformMat4("View", MainCamera.view);
gBufferShader.setUniformMat4("Projection", MainCamera.projection);
OpenGLApi::DrawTriangles(renderComponent);
}
// Light pass
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer.GetId());
lightingPassShader.Use();
lightingPassShader.setUniformInt("gPosition", 0);
lightingPassShader.setUniformInt("gNormal", 1);
lightingPassShader.setUniformInt("gColorSpec", 2);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gPosition);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gNormal);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gColorSpec);
auto lights = scene.getReg().view<LightComponent, TransformComponent>();
unsigned int lightnr = 0;
for (auto light : lights) {
auto lightComponent = Entity(light, &scene).GetComponent<LightComponent>();
auto transformComponent = Entity(light, &scene).GetComponent<TransformComponent>();
auto name = "lights[" + std::to_string(lightnr) + "]";
lightingPassShader.setUniformVec3(name + ".Position",transformComponent.Position );
lightingPassShader.setUniformVec3(name + ".Color", lightComponent.Color);
const float linear = 0.7f;
const float quadratic = 1.8f;
lightingPassShader.setUniformFloat(name + ".Linear", linear);
lightingPassShader.setUniformFloat(name + ".Quadratic", quadratic);
lightnr++;
}
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,
};
unsigned int quadVBO;
// 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);
// Copy GBuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer);
glBindFramebuffer(GL_DRAW_BUFFER, m_framebuffer.GetId());
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
if (transparentVAO == 0) {
unsigned int transparentVBO;
float transparentVertices[] = {
// positions // texture Coords (swapped y coordinates because texture is flipped upside down)
0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
0.0f, -0.5f, 0.0f, 0.0f, 0.0f,
1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
1.0f, -0.5f, 0.0f, 1.0f, 0.0f,
1.0f, 0.5f, 0.0f, 1.0f, 1.0f
};
glGenVertexArrays(1, &transparentVAO);
glGenBuffers(1, &transparentVBO);
glBindVertexArray(transparentVAO);
glBindBuffer(GL_ARRAY_BUFFER, transparentVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(transparentVertices), transparentVertices, 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(0);
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
BlendingShader.Use();
glBindVertexArray(transparentVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, grassTexture.GetID());
BlendingShader.setUniformMat4("V", MainCamera.view);
BlendingShader.setUniformMat4("P", MainCamera.projection);
for (unsigned int i = 0; i < vegetation.size(); i++) {
auto translation = glm::translate(glm::mat4(1.0f), vegetation[i]) ;
BlendingShader.setUniformMat4("M", translation);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
glBindVertexArray(0);
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void setCurrentFrameBuffer(const Framebuffer& fb); void setCurrentFrameBuffer(const Framebuffer& fb);
void setClearColor(const glm::vec3& ClearColor); void setClearColor(const glm::vec3& ClearColor);
void SetMainCamera(const Camera& camera) { MainCamera = camera; }
Framebuffer& getCurrentFrameBuffer() { return m_framebuffer; } Framebuffer& getCurrentFrameBuffer() { return m_framebuffer; }
private:
void GeometryPass();
void ForwardGeometryPass();
void SkyboxPass();
void lightingPass(Scene& scene);
void BlendingPass();
void PostProcessing();
void CopyGBuffer();
private: private:
Framebuffer m_framebuffer; Framebuffer m_framebuffer;
int width, height; int width, height;
glm::vec3 m_clearColor; glm::vec3 m_clearColor;
bool m_depthTest; bool m_depthTest;
std::vector<DrawCommand> commands;
Camera MainCamera;
unsigned int skyboxVAO = 0; void CreateGBuffer();
CubeMap sky;
Shader forwardShader; Shader forwardShader;
@ -63,8 +233,59 @@ namespace YoggieEngine {
Shader SkyboxShader; Shader SkyboxShader;
Shader postProcessingShader; Shader postProcessingShader;
// blending // blending
Shader BlendingShader; Shader BlendingShader;
CubeMap skybox;
Texture grassTexture = Texture("build/Debug/Texture/grass.png");
unsigned int transparentVAO = 0;
unsigned int skyboxVAO = 0;
unsigned int quadVAO = 0;
float skyboxVertices[36*3]{
// 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
};
std::vector<glm::vec3> vegetation = {
glm::vec3(-1.5f, 0.0f, -0.48f),
glm::vec3(1.5f, 0.0f, 0.51f),
glm::vec3(0.0f, 0.0f, 0.7f),
glm::vec3(-0.3f, 0.0f, -2.3f)
};
}; };
} }