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