#include "Rendering/Renderer.h" std::unordered_map Renderer::m_WindowToRenderer; Renderer::~Renderer() { delete m_PickingPass; delete m_LightCullingPass; delete m_ImGuiRenderPass; delete m_DrawFinalPass; delete m_DrawScreenQuadPass; delete m_DrawBloomPass; delete m_DrawColorCorrectionPass; delete m_SSAOPass; delete m_CubeMapPass; delete m_TextPass; } void Renderer::Initialize() { m_SSAO_Quality = m_Config->Get("SSAO.Quality", 0); m_GLOW_Quality = m_Config->Get("GLOW.Quality", 0); InitializeWindow(); InitializeRenderPasses(); glfwSwapInterval(m_VSYNC); InitializeShaders(); InitializeTextures(); m_TextPass = new TextPass(); m_TextPass->Initialize(); /* m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load(sModels/Core/UnitQuad.obj"); m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj");*/ m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker); } void Renderer::glfwWindowSizeCallback(GLFWwindow* window, int width, int height) { m_WindowToRenderer[window]->setWindowSize(Rectangle(width, height)); } void Renderer::glfwFrameBufferCallback(GLFWwindow* window, int width, int height) { m_WindowToRenderer[window]->updateFramebufferSize(); } void Renderer::SetResolution(const Rectangle& resolution) { m_Resolution = resolution; if (m_Window != nullptr) { setWindowSize(resolution); updateFramebufferSize(); } } void Renderer::InitializeWindow() { // Initialize GLFW if (!glfwInit()) { LOG_ERROR("GLFW: Initialization failed"); exit(EXIT_FAILURE); } // Create a window GLFWmonitor* monitor = nullptr; if (m_Fullscreen) { //monitor = glfwGetPrimaryMonitor(); //const GLFWvidmode* mode = glfwGetVideoMode(monitor); //glfwWindowHint(GLFW_RED_BITS, mode->redBits); //glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); //glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); //glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); glfwWindowHint(GLFW_DECORATED, false); //glfwWindowHint(GLFW_AUTO_ICONIFY, false); } //glfwWindowHint(GLFW_SAMPLES, 8); m_Window = glfwCreateWindow(m_Resolution.Width, m_Resolution.Height + 1, "daydream", monitor, nullptr); if (!m_Window) { LOG_ERROR("GLFW: Failed to create window"); exit(EXIT_FAILURE); } glfwSetWindowSizeCallback(m_Window, &glfwWindowSizeCallback); glfwSetFramebufferSizeCallback(m_Window, &glfwFrameBufferCallback); glfwMakeContextCurrent(m_Window); // GL version info glGetIntegerv(GL_MAJOR_VERSION, &m_GLVersion[0]); glGetIntegerv(GL_MINOR_VERSION, &m_GLVersion[1]); m_GLVendor = (GLchar*)glGetString(GL_VENDOR); std::stringstream ss; ss << m_GLVendor << " OpenGL " << m_GLVersion[0] << "." << m_GLVersion[1]; #ifdef DEBUG ss << " DEBUG"; #endif LOG_INFO(ss.str().c_str()); SetWindowTitle(ss.str()); // Initialize GLEW if (glewInit() != GLEW_OK) { LOG_ERROR("GLEW: Initialization failed"); exit(EXIT_FAILURE); } m_WindowToRenderer[m_Window] = this; int windowSize[2]; glfwGetFramebufferSize(m_Window, &windowSize[0], &windowSize[1]); m_ViewportSize = Rectangle(windowSize[0], windowSize[1]); } void Renderer::InitializeShaders() { m_BasicForwardProgram = ResourceManager::Load("#m_BasicForwardProgram"); m_ExplosionEffectProgram = ResourceManager::Load("#ExplosionEffectProgram"); //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ExplosionEffect.vert.glsl"))); //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); //m_ExplosionEffectProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ExplosionEffect.frag.glsl"))); //m_ExplosionEffectProgram->Compile(); //m_ExplosionEffectProgram->Link(); } void Renderer::InputUpdate(double dt) { } void Renderer::setWindowSize(Rectangle size) { m_Resolution = size; glfwSetWindowSize(m_Window, size.Width, size.Height); } void Renderer::updateFramebufferSize() { Events::ResolutionChanged e; e.OldResolution = m_ViewportSize; int width, height; glfwGetFramebufferSize(m_Window, &width, &height); glViewport(0, 0, width, height); m_ViewportSize = Rectangle(width, height); m_PickingPass->OnWindowResize(); m_DrawFinalPass->OnWindowResize(); m_LightCullingPass->OnWindowResize(); m_DrawBloomPass->OnWindowResize(); m_SSAOPass->OnWindowResize(); m_BlurHUDPass->OnWindowResize(); e.NewResolution = m_ViewportSize; m_EventBroker->Publish(e); } void Renderer::Update(double dt) { m_EventBroker->Process(); InputUpdate(dt); m_TextPass->Update(); m_ImGuiRenderPass->Update(dt); } void Renderer::Draw(RenderFrame& frame) { GLERROR("PRE"); glBindFramebuffer(GL_FRAMEBUFFER, 0); #ifdef DEBUG ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking\0Ambient Occlusion\0Combined Scene Texture\0Full Blurred Texture"); ImGui::Combo("CubeMap", &m_CubeMapTexture, "Nevada(512)\0Sky(1024)"); #endif if(m_CubeMapTexture == 0) { m_CubeMapPass->LoadTextures("Nevada"); } else if (m_CubeMapTexture == 1) { m_CubeMapPass->LoadTextures("Sky"); } #ifdef DEBUG ImGui::SliderInt("SSAO Quality", &m_SSAO_Quality, 0, 3); ImGui::SliderInt("Glow Quality", &m_GLOW_Quality, 0, 3); ImGui::SliderInt("MSAA Level", (int*)&m_MSAA_Level, 0, 16); #endif m_SSAOPass->ChangeQuality(m_SSAO_Quality); m_DrawBloomPass->ChangeQuality(m_GLOW_Quality); m_DrawFinalPass->setMSAA(m_MSAA_Level); GLERROR("SSAO Settings"); //clear buffer 0 glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear other buffers PerformanceTimer::StartTimer("Renderer-ClearBuffers"); m_PickingPass->ClearPicking(); m_DrawFinalPass->ClearBuffer(); m_DrawBloomPass->ClearBuffer(); m_SSAOPass->ClearBuffer(); m_ShadowPass->ClearBuffer(); m_BlurHUDPass->ClearBuffer(); m_ShadowPass->DebugGUI(); PerformanceTimer::StopTimer("Renderer-ClearBuffers"); GLERROR("ClearBuffers"); for (auto scene : frame.RenderScenes) { PerformanceTimer::StartTimer("Renderer-PickingPass"); m_PickingPass->Draw(*scene); GLERROR("Drawing pickingpass"); PerformanceTimer::StopTimer("Renderer-PickingPass"); } PerformanceTimer::StartTimer("Renderer-AO generation"); m_SSAOPass->Draw(*m_PickingPass->DepthBuffer(), frame.RenderScenes.front()->Camera); PerformanceTimer::StopTimer("Renderer-AO generation"); for (auto scene : frame.RenderScenes){ PerformanceTimer::StartTimer("Renderer-Depth"); SortRenderJobsByDepth(*scene); GLERROR("SortByDepth"); PerformanceTimer::StartTimerAndStopPrevious("Draw shadow maps"); m_ShadowPass->Draw(*scene); GLERROR("Draw shadow maps"); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums"); m_LightCullingPass->GenerateNewFrustum(*scene); GLERROR("Generate frustums"); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Filling Light List"); m_LightCullingPass->FillLightList(*scene); GLERROR("Filling light list"); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Light Culling"); m_LightCullingPass->CullLights(*scene); GLERROR("LightCulling"); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light"); m_DrawFinalPass->Draw(*scene, m_BlurHUDPass); GLERROR("Draw Geometry+Light"); //m_DrawScenePass->Draw(*scene); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Text"); m_TextPass->Draw(*scene, *m_DrawFinalPass->FinalPassFrameBuffer()); GLERROR("Draw Text"); PerformanceTimer::StopTimer("Renderer-Draw Text"); } PerformanceTimer::StartTimer("Renderer-Draw Bloom"); m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture()); PerformanceTimer::StopTimer("Renderer-Draw Bloom"); if (m_DebugTextureToDraw == 0) { PerformanceTimer::StartTimer("Renderer-Color Correction Pass"); GLuint test = m_DrawFinalPass->SceneTexture(); m_DrawColorCorrectionPass->Draw(test, m_DrawBloomPass->GaussianTexture(), frame.Gamma, frame.Exposure); PerformanceTimer::StopTimer("Renderer-Color Correction Pass"); } PerformanceTimer::StartTimer("Renderer-Misc Debug Draws"); if (m_DebugTextureToDraw == 1) { m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTexture()); } if (m_DebugTextureToDraw == 2) { m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTexture()); } if (m_DebugTextureToDraw == 3) { m_DrawScreenQuadPass->Draw(m_DrawBloomPass->GaussianTexture()); } if (m_DebugTextureToDraw == 4) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } if (m_DebugTextureToDraw == 5) { m_DrawScreenQuadPass->Draw(m_SSAOPass->SSAOTexture()); } if (m_DebugTextureToDraw == 6) { m_DrawScreenQuadPass->Draw(m_DrawFinalPass->CombinedSceneTexture()); } if (m_DebugTextureToDraw == 7) { m_DrawScreenQuadPass->Draw(m_DrawFinalPass->FullBlurredTexture()); } PerformanceTimer::StopTimer("Renderer-Misc Debug Draws"); PerformanceTimer::StartTimer("Renderer-ImGuiRenderPass"); m_ImGuiRenderPass->Draw(); GLERROR("Imgui draw"); PerformanceTimer::StopTimer("Renderer-ImGuiRenderPass"); PerformanceTimer::StartTimer("Renderer-SwapBuffer"); glfwSwapBuffers(m_Window); PerformanceTimer::StopTimer("Renderer-SwapBuffer"); } PickData Renderer::Pick(glm::vec2 screenCoord) { return m_PickingPass->Pick(screenCoord); } void Renderer::InitializeTextures() { m_ErrorTexture = CommonFunctions::TryLoadResource("Textures/Core/ErrorTexture.png"); m_WhiteTexture = CommonFunctions::TryLoadResource("Textures/Core/White.png"); } void Renderer::SortRenderJobsByDepth(RenderScene &scene) { //Sort all forward jobs so transparency is good. scene.Jobs.TransparentObjects.sort(Renderer::DepthSort); scene.Jobs.SpriteJob.sort(Renderer::DepthSort); scene.Jobs.Text.sort(Renderer::DepthSort); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) { glGenTextures(1, texture); glBindTexture(GL_TEXTURE_2D, *texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution GLERROR("Texture initialization failed"); } void Renderer::InitializeRenderPasses() { m_PickingPass = new PickingPass(this, m_EventBroker); m_LightCullingPass = new LightCullingPass(this); m_CubeMapPass = new CubeMapPass(this); m_SSAOPass = new SSAOPass(this, m_Config); m_ShadowPass = new ShadowPass(this); m_BlurHUDPass = new BlurHUD(this); m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass, m_SSAOPass, m_ShadowPass, m_Config); m_DrawScreenQuadPass = new DrawScreenQuadPass(this); m_DrawBloomPass = new DrawBloomPass(this, m_Config); m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this); }