From 6234a31673aa2e6a1d9be503c0f8c690238a9680 Mon Sep 17 00:00:00 2001 From: wuyize Date: Sun, 16 Apr 2023 18:34:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0MainWIndow=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ToyEngine/ToyEngine.vcxproj | 2 + ToyEngine/ToyEngine.vcxproj.filters | 6 + ToyEngine/src/MainWindow.cpp | 260 +++++++++++++++++++++++++ ToyEngine/src/MainWindow.h | 45 +++++ ToyEngine/src/main.cpp | 291 +--------------------------- 5 files changed, 315 insertions(+), 289 deletions(-) create mode 100644 ToyEngine/src/MainWindow.cpp create mode 100644 ToyEngine/src/MainWindow.h diff --git a/ToyEngine/ToyEngine.vcxproj b/ToyEngine/ToyEngine.vcxproj index fd9d2e4..fd95a7c 100644 --- a/ToyEngine/ToyEngine.vcxproj +++ b/ToyEngine/ToyEngine.vcxproj @@ -26,6 +26,7 @@ + @@ -41,6 +42,7 @@ + diff --git a/ToyEngine/ToyEngine.vcxproj.filters b/ToyEngine/ToyEngine.vcxproj.filters index f9db082..1eef953 100644 --- a/ToyEngine/ToyEngine.vcxproj.filters +++ b/ToyEngine/ToyEngine.vcxproj.filters @@ -51,6 +51,9 @@ 头文件 + + 头文件 + @@ -89,6 +92,9 @@ 源文件 + + 源文件 + diff --git a/ToyEngine/src/MainWindow.cpp b/ToyEngine/src/MainWindow.cpp new file mode 100644 index 0000000..31a9f38 --- /dev/null +++ b/ToyEngine/src/MainWindow.cpp @@ -0,0 +1,260 @@ +#include "MainWindow.h" +#include "IblUtils.h" +#include "RenderPass.h" + +MainWindow::MainWindow() + : camera(glm::vec3(0.0f, 0.0f, 3.0f)) + , light(&camera) +{ +} + +void MainWindow::processInput(GLFWwindow* window) +{ + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, true); + + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) + camera.processKeyboard(FORWARD, deltaTime); + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) + camera.processKeyboard(BACKWARD, deltaTime); + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + camera.processKeyboard(LEFT, deltaTime); + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + camera.processKeyboard(RIGHT, deltaTime); + if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) + camera.processKeyboard(UP, deltaTime); + if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) + camera.processKeyboard(DOWN, deltaTime); + + glm::mat4 transform(1); + float speed = 1; + if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) + modelPtr->setTransform(glm::translate(transform, glm::vec3(0, 0, speed))); + if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) + modelPtr->setTransform(glm::translate(transform, glm::vec3(0, 0, -speed))); + if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) + modelPtr->setTransform(glm::translate(transform, glm::vec3(-speed, 0, 0))); + if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) + modelPtr->setTransform(glm::translate(transform, glm::vec3(speed, 0, 0))); +} + +void MainWindow::framebufferSizeCallback(GLFWwindow* window, int width, int height) +{ + frameWidth = width; + frameHeight = height; + camera.Ratio = (float)frameWidth / (float)frameHeight; + if (fbo) + { + gl->DeleteRenderbuffers(1, &rboDepth); + gl->DeleteTextures(gbuffers.size(), gbuffers.data()); + gl->DeleteFramebuffers(1, &fbo); + } + + gl->CreateFramebuffers(1, &fbo); + gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); + { + gl->GenTextures(gbuffers.size(), gbuffers.data()); + //BaseColor + gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]); + gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, frameWidth, frameHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gbuffers[0], 0); + //Normal + gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]); + gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gbuffers[1], 0); + //Position + gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]); + gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0); + //MetallicRoughness + gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]); + gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0); + + std::array attachments = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; + gl->DrawBuffers(attachments.size(), attachments.data()); + gl->GenRenderbuffers(1, &rboDepth); + gl->BindRenderbuffer(GL_RENDERBUFFER, rboDepth); + gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, frameWidth, frameHeight); + gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth); + if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + std::cerr << "Framebuffer not complete!\n"; + + gl->BindFramebuffer(GL_FRAMEBUFFER, 0); + } + + if (shadowFboHandle != 0) + { + gl->DeleteTextures(1, &shadowGbuffer); + gl->DeleteFramebuffers(1, &shadowFboHandle); + } + + shadowMapResolution = 2048; + gl->GenFramebuffers(1, &shadowFboHandle); + { + gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle); + gl->GenTextures(1, &shadowGbuffer); + //Depth + gl->BindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); + gl->TexImage3D( + GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, shadowMapResolution, shadowMapResolution, (int)light.shadowCascadeLevels.size(), + 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); + + gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + gl->TexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f })); + gl->FramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowGbuffer, 0); + gl->DrawBuffer(GL_NONE); + gl->ReadBuffer(GL_NONE); + + if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + std::cerr << "ShadowFramebuffer not complete!\n"; + gl->BindFramebuffer(GL_FRAMEBUFFER, 0); + } + +} + +void MainWindow::mouseCallback(GLFWwindow* window, double xpos, double ypos) +{ + static bool firstMouse = true; + static float lastX; + static float lastY; + + float xoffset = xpos - lastX; + float yoffset = lastY - ypos; + + lastX = xpos; + lastY = ypos; + + if (firstMouse) + { + firstMouse = false; + return; + } + + if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) + { + float speed = 0.2f; + glm::mat4 rotate(1); + rotate = glm::rotate(rotate, glm::radians(glm::length(glm::vec2(xoffset, yoffset)) * speed), glm::vec3(glm::vec2(-yoffset, xoffset), 0.0)); + modelPtr->setTransform(rotate); + } + if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) + camera.processMouseMovement(xoffset, yoffset); +} + +void MainWindow::scrollCallback(GLFWwindow* window, double xoffset, double yoffset) +{ + camera.processMouseScroll(yoffset); +} + +MainWindow& MainWindow::instance() +{ + static MainWindow window; + return window; +} + +int MainWindow::exec() +{ + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + float xscale, yscale; + glfwGetMonitorContentScale(monitor, &xscale, &yscale); + GLFWwindow* window = glfwCreateWindow(kWindowWidth * xscale, kWindowHeight * yscale, "RenderModel", NULL, NULL); + MainWindow& m = *this; + glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height) { + MainWindow::instance().framebufferSizeCallback(window, width, height); + }); + glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos) { + MainWindow::instance().mouseCallback(window, xpos, ypos); + }); + glfwSetScrollCallback(window, [](GLFWwindow* window, double xoffset, double yoffset) { + MainWindow::instance().scrollCallback(window, xoffset, yoffset); + }); + int xpos, ypos, width, height; + glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height); + glfwSetWindowPos(window, xpos + (width - (kWindowWidth * xscale)) / 2, ypos + (height - kWindowHeight * yscale) / 2); + glfwMakeContextCurrent(window); + gl = std::make_unique(); + if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)glfwGetProcAddress(name); })) + { + std::cout << "Failed to initialize GLAD" << std::endl; + return -1; + } + gl->Enable(GL_DEBUG_OUTPUT); + //gl->Enable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + gl->DebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) { + if (type == GL_DEBUG_TYPE_ERROR) + std::cerr << std::format("GL_ERROR: type = {:#x}, severity = {:#x}, message = {}", type, severity, message); + }, 0); + gl->ClearColor(0.0f, 0.0f, 0.0f, 1.0f); + gl->Enable(GL_DEPTH_TEST); + gl->DepthFunc(GL_LEQUAL); + gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + + std::string modelFilePath; + //modelFilePath = "E:\\3D Objects\\plane\\obj\\plane.obj"; + //modelFilePath = "E:\\3D Objects\\plane\\plane.gltf"; + modelFilePath = "E:\\3D Objects\\vampire/gltf/vampire.gltf"; + //modelFilePath = "E:\\3D Objects\\cup\\cup.gltf"; + //modelFilePath = "E:\\3D Objects\\Sponza\\Sponza.gltf"; + + Model model(gl.get(), modelFilePath); + modelPtr = &model; + light.model = &model; + + Animation danceAnimation(modelFilePath, &model); + Animator animator(&danceAnimation); + + glm::mat4 projection, view; + auto [skyCubemap, irradianceMap, prefilterMap, brdfLUTTexture] = IblUtils::precomputeCubemaps(gl.get()); + + ShadowMapPass shadowMapPass(gl.get(), shadowFboHandle, shadowMapResolution, model, light); + GeometryPass geometryPass(gl.get(), frameWidth, frameHeight, fbo, model, projection, view, animator); + LightingPass lightingPass(gl.get(), frameWidth, frameHeight, view, camera, light, mainLightRadiance, + gbuffers, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture); + FinalPass finalPass(gl.get(), frameWidth, frameHeight, gbuffers, exposure); + SkyboxPass skyboxPass(gl.get(), projection, view, exposure, skyCubemap); + + int w, h; + glfwGetFramebufferSize(window, &w, &h); + framebufferSizeCallback(window, w, h); + + while (!glfwWindowShouldClose(window)) + { + float currentFrame = glfwGetTime(); + deltaTime = currentFrame - lastFrame; + lastFrame = currentFrame; + processInput(window); + + animator.UpdateAnimation(deltaTime); + + projection = camera.getProjectionMatrix(); + view = camera.getViewMatrix(); + + shadowMapPass.dispatch(); + geometryPass.dispatch(); + lightingPass.dispatch(); + finalPass.dispatch(); + skyboxPass.dispatch(); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwTerminate(); +} diff --git a/ToyEngine/src/MainWindow.h b/ToyEngine/src/MainWindow.h new file mode 100644 index 0000000..1bf9b2d --- /dev/null +++ b/ToyEngine/src/MainWindow.h @@ -0,0 +1,45 @@ +#pragma once +#include "Model.h" +#include "Camera.h" +#include "Light.h" +#include +#include +#include + +class MainWindow +{ +public: + static MainWindow& instance(); + int exec(); + +private: + MainWindow(); + void framebufferSizeCallback(GLFWwindow* window, int width, int height); + void mouseCallback(GLFWwindow* window, double xpos, double ypos); + void scrollCallback(GLFWwindow* window, double xoffset, double yoffset); + void processInput(GLFWwindow* window); + + static constexpr int kWindowWidth = 1200; + static constexpr int kWindowHeight = 675; + unsigned int frameWidth; + unsigned int frameHeight; + + Model* modelPtr = nullptr; + Camera camera; + Light light; + glm::vec3 mainLightRadiance = 40.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784)); + float exposure = 1; + + float deltaTime = 0.0f; + float lastFrame = 0.0f; + + std::unique_ptr gl; + + GLuint fbo = 0; + std::array gbuffers; + GLuint rboDepth = 0; + GLuint shadowFboHandle = 0; + GLuint shadowGbuffer; + int shadowMapResolution; +}; + diff --git a/ToyEngine/src/main.cpp b/ToyEngine/src/main.cpp index 6f1bb92..30105f8 100644 --- a/ToyEngine/src/main.cpp +++ b/ToyEngine/src/main.cpp @@ -1,299 +1,12 @@ #define STB_IMAGE_IMPLEMENTATION #include -#include -#include -#include -#include -#include -#include "Shader.h" -#include "camera.h" -#include "Model.h" -#include "IblUtils.h" -#include "Light.h" -#include "RenderPass.h" -#include -#include -#include -#include "Animation.h" -#include "Animator.h" +#include "MainWindow.h" extern "C" { _declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; } -void framebufferSizeCallback(GLFWwindow* window, int width, int height); -void mouseCallback(GLFWwindow* window, double xpos, double ypos); -void scrollCallback(GLFWwindow* window, double xoffset, double yoffset); -void processInput(GLFWwindow* window); - -constexpr int windowWidth = 1200; -constexpr int windowHeight = 675; -unsigned int frameWidth; -unsigned int frameHeight; - -Model* modelPtr = nullptr; -Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); -Light light(&camera); -glm::vec3 mainLightRadiance = 40.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784)); -float exposure = 1; - -float deltaTime = 0.0f; -float lastFrame = 0.0f; - -std::unique_ptr gl; - -GLuint fbo = 0; -std::array gbuffers; -GLuint rboDepth = 0; -GLuint shadowFboHandle = 0; -GLuint shadowGbuffer; -int shadowMapResolution; - -void GLAPIENTRY messageCallback(GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam) -{ - if (type == GL_DEBUG_TYPE_ERROR) - std::cerr << std::format("GL_ERROR: type = {:#x}, severity = {:#x}, message = {}", - type, severity, message); -} - int main() { - glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - float xscale, yscale; - glfwGetMonitorContentScale(monitor, &xscale, &yscale); - GLFWwindow* window = glfwCreateWindow(windowWidth * xscale, windowHeight * yscale, "RenderModel", NULL, NULL); - glfwSetFramebufferSizeCallback(window, framebufferSizeCallback); - glfwSetCursorPosCallback(window, mouseCallback); - glfwSetScrollCallback(window, scrollCallback); - int xpos, ypos, width, height; - glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height); - glfwSetWindowPos(window, xpos + (width - (windowWidth * xscale)) / 2, ypos + (height - windowHeight * yscale) / 2); - glfwMakeContextCurrent(window); - gl = std::make_unique(); - if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)glfwGetProcAddress(name); })) - { - std::cout << "Failed to initialize GLAD" << std::endl; - return -1; - } - gl->Enable(GL_DEBUG_OUTPUT); - //gl->Enable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - gl->DebugMessageCallback(messageCallback, 0); - gl->ClearColor(0.0f, 0.0f, 0.0f, 1.0f); - gl->Enable(GL_DEPTH_TEST); - gl->DepthFunc(GL_LEQUAL); - gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - - std::string modelFilePath; - //modelFilePath = "E:\\3D Objects\\plane\\obj\\plane.obj"; - //modelFilePath = "E:\\3D Objects\\plane\\plane.gltf"; - modelFilePath = "E:\\3D Objects\\vampire/gltf/vampire.gltf"; - //modelFilePath = "E:\\3D Objects\\cup\\cup.gltf"; - //modelFilePath = "E:\\3D Objects\\Sponza\\Sponza.gltf"; - - Model model(gl.get(), modelFilePath); - modelPtr = &model; - light.model = &model; - - Animation danceAnimation(modelFilePath, &model); - Animator animator(&danceAnimation); - - glm::mat4 projection, view; - auto [skyCubemap, irradianceMap, prefilterMap, brdfLUTTexture] = IblUtils::precomputeCubemaps(gl.get()); - - ShadowMapPass shadowMapPass(gl.get(), shadowFboHandle, shadowMapResolution, model, light); - GeometryPass geometryPass(gl.get(), frameWidth, frameHeight, fbo, model, projection, view, animator); - LightingPass lightingPass(gl.get(), frameWidth, frameHeight, view, camera, light, mainLightRadiance, - gbuffers, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture); - FinalPass finalPass(gl.get(), frameWidth, frameHeight, gbuffers, exposure); - SkyboxPass skyboxPass(gl.get(), projection, view, exposure, skyCubemap); - - int w, h; - glfwGetFramebufferSize(window, &w, &h); - framebufferSizeCallback(window, w, h); - - while (!glfwWindowShouldClose(window)) - { - float currentFrame = glfwGetTime(); - deltaTime = currentFrame - lastFrame; - lastFrame = currentFrame; - processInput(window); - - animator.UpdateAnimation(deltaTime); - - projection = camera.getProjectionMatrix(); - view = camera.getViewMatrix(); - - shadowMapPass.dispatch(); - geometryPass.dispatch(); - lightingPass.dispatch(); - finalPass.dispatch(); - skyboxPass.dispatch(); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - glfwTerminate(); - return 0; -} - -void processInput(GLFWwindow* window) -{ - if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) - glfwSetWindowShouldClose(window, true); - - if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) - camera.processKeyboard(FORWARD, deltaTime); - if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) - camera.processKeyboard(BACKWARD, deltaTime); - if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) - camera.processKeyboard(LEFT, deltaTime); - if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) - camera.processKeyboard(RIGHT, deltaTime); - if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) - camera.processKeyboard(UP, deltaTime); - if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) - camera.processKeyboard(DOWN, deltaTime); - - glm::mat4 transform(1); - float speed = 1; - if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) - modelPtr->setTransform(glm::translate(transform, glm::vec3(0, 0, speed))); - if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) - modelPtr->setTransform(glm::translate(transform, glm::vec3(0, 0, -speed))); - if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) - modelPtr->setTransform(glm::translate(transform, glm::vec3(-speed, 0, 0))); - if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) - modelPtr->setTransform(glm::translate(transform, glm::vec3(speed, 0, 0))); -} - -void framebufferSizeCallback(GLFWwindow* window, int width, int height) -{ - frameWidth = width; - frameHeight = height; - camera.Ratio = (float)frameWidth / (float)frameHeight; - if (fbo) - { - gl->DeleteRenderbuffers(1, &rboDepth); - gl->DeleteTextures(gbuffers.size(), gbuffers.data()); - gl->DeleteFramebuffers(1, &fbo); - } - - gl->CreateFramebuffers(1, &fbo); - gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); - { - gl->GenTextures(gbuffers.size(), gbuffers.data()); - //BaseColor - gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]); - gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, frameWidth, frameHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gbuffers[0], 0); - //Normal - gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]); - gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gbuffers[1], 0); - //Position - gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]); - gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0); - //MetallicRoughness - gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]); - gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0); - - std::array attachments = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; - gl->DrawBuffers(attachments.size(), attachments.data()); - gl->GenRenderbuffers(1, &rboDepth); - gl->BindRenderbuffer(GL_RENDERBUFFER, rboDepth); - gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, frameWidth, frameHeight); - gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth); - if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - std::cerr << "Framebuffer not complete!\n"; - - gl->BindFramebuffer(GL_FRAMEBUFFER, 0); - } - - if (shadowFboHandle != 0) - { - gl->DeleteTextures(1, &shadowGbuffer); - gl->DeleteFramebuffers(1, &shadowFboHandle); - } - - shadowMapResolution = 2048; - gl->GenFramebuffers(1, &shadowFboHandle); - { - gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle); - gl->GenTextures(1, &shadowGbuffer); - //Depth - gl->BindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); - gl->TexImage3D( - GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, shadowMapResolution, shadowMapResolution, (int)light.shadowCascadeLevels.size(), - 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); - - gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - gl->TexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - gl->TexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f })); - gl->FramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowGbuffer, 0); - gl->DrawBuffer(GL_NONE); - gl->ReadBuffer(GL_NONE); - - if (gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - std::cerr << "ShadowFramebuffer not complete!\n"; - gl->BindFramebuffer(GL_FRAMEBUFFER, 0); - } - -} - -void mouseCallback(GLFWwindow* window, double xpos, double ypos) -{ - static bool firstMouse = true; - static float lastX; - static float lastY; - - float xoffset = xpos - lastX; - float yoffset = lastY - ypos; - - lastX = xpos; - lastY = ypos; - - if (firstMouse) - { - firstMouse = false; - return; - } - - if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) - { - float speed = 0.2f; - glm::mat4 rotate(1); - rotate = glm::rotate(rotate, glm::radians(glm::length(glm::vec2(xoffset, yoffset)) * speed), glm::vec3(glm::vec2(-yoffset, xoffset), 0.0)); - modelPtr->setTransform(rotate); - } - if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) - camera.processMouseMovement(xoffset, yoffset); -} - -void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) -{ - camera.processMouseScroll(yoffset); + return MainWindow::instance().exec(); } \ No newline at end of file