Compare commits
5 Commits
d275db76b7
...
7ca74a245d
Author | SHA1 | Date |
---|---|---|
wuyize | 7ca74a245d | |
wuyize | e0a4c25242 | |
wuyize | 942db18774 | |
wuyize | 62369c0bf0 | |
wuyize | dbae5cb272 |
|
@ -0,0 +1,158 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="NameAndType">
|
||||
<Class Name="Animation">
|
||||
<Position X="5" Y="0.5" Width="5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAABAAGwAAAAAAAQgEAAAAQAAAAAAAQAAAAACAABMAE=</HashCode>
|
||||
<FileName>src\Animation.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Animator">
|
||||
<Position X="6.5" Y="2" Width="6" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAIAAAAAEQAABAEAAgAAAACgIAQAIAQAAgA=</HashCode>
|
||||
<FileName>src\Animator.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Particle">
|
||||
<Position X="18.75" Y="1" Width="4.75" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AMxAgQgABAAACAAAAAKAAAAABAAQAQQhCAAAAAAAAAA=</HashCode>
|
||||
<FileName>src\Particle.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Actor">
|
||||
<Position X="13.25" Y="1" Width="4.75" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>BAEAIIAAAAAIgAAEAAKAIIACAAAgAAAiQAAAAAAIAgA=</HashCode>
|
||||
<FileName>src\Actor.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="MainWindow">
|
||||
<Position X="1" Y="7.25" Width="5.75" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AIAAkAAAAAAAhAAQAAAEACAAAAJAAAAIAAAQIAAAAgA=</HashCode>
|
||||
<FileName>src\MainWindow.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="World">
|
||||
<Position X="13.25" Y="7" Width="3.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAgAAAAhQIBAAAAYIAACAAAAIAAAAgQAAAIAAAAAA=</HashCode>
|
||||
<FileName>src\World.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="RenderPass">
|
||||
<Position X="9" Y="15.5" Width="1.75" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAgA=</HashCode>
|
||||
<FileName>src\RenderPass.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="ShadowMapPass">
|
||||
<Position X="5" Y="18.25" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAEAAAAAAAAAAAoABAAIAAAAQAAAAAAAAAAAAIAAA=</HashCode>
|
||||
<FileName>src\RenderPass.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="GeometryPass">
|
||||
<Position X="7.25" Y="18.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ABAgEAAAAADAAAAAAAAAAAAAAAAAQAAgAQCAAAAIAAA=</HashCode>
|
||||
<FileName>src\RenderPass.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="LightingPass">
|
||||
<Position X="9" Y="18.25" Width="1.75" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAEwAAAEAAAACQAAAAAAIAQAAgAwAAAAAIAAA=</HashCode>
|
||||
<FileName>src\RenderPass.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="FinalPass">
|
||||
<Position X="11" Y="18.25" Width="1.75" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ACAAAAAABEAAAAAAAAAgAAIQAAAAQAAgAAAAAAAIAgA=</HashCode>
|
||||
<FileName>src\RenderPass.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="SkyboxPass">
|
||||
<Position X="13" Y="18.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ABAAAAACAAAAAAAAAgAAAAAQAAAAQAAAAQAAAAAIAAA=</HashCode>
|
||||
<FileName>src\RenderPass.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Bone">
|
||||
<Position X="0.5" Y="0.5" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EAQAAAgAAIAAAFAEEAAAIAAAAAgQAwAAAAikEIQACAA=</HashCode>
|
||||
<FileName>src\Bone.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="RenderingSystem">
|
||||
<Position X="8.25" Y="7.75" Width="3.75" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>ADBAFBBAQQRAAgBAggGQAIIQAABAQAAgAwABAABAAgI=</HashCode>
|
||||
<FileName>src\RenderingSystem.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="PhysicsManager">
|
||||
<Position X="0.5" Y="11.25" Width="6.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AABAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAQAAAAAAA=</HashCode>
|
||||
<FileName>src\PhysicsManager.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DemoWorld">
|
||||
<Position X="13.25" Y="11.5" Width="3.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAgAAAAAAIAAAAEEgAACAAAAAAAAAgAAAAIAEIBCA=</HashCode>
|
||||
<FileName>src\DemoWorld.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Struct Name="AssimpNodeData">
|
||||
<Position X="5" Y="4.75" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAAAABAAAAEAAAAAAAABAAAAAA=</HashCode>
|
||||
<FileName>src\Animation.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="Force">
|
||||
<Position X="24" Y="4.5" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAIAAA=</HashCode>
|
||||
<FileName>src\Particle.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="KeyPosition">
|
||||
<Position X="3" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AIAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>src\Bone.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="KeyRotation">
|
||||
<Position X="3" Y="2.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>src\Bone.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="KeyScale">
|
||||
<Position X="3" Y="4.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AIAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>src\Bone.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Struct Name="BinaryConstraint">
|
||||
<Position X="0.5" Y="13.25" Width="6.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAEADAAAgAAAAgAAAAA=</HashCode>
|
||||
<FileName>src\PhysicsManager.h</FileName>
|
||||
</TypeIdentifier>
|
||||
</Struct>
|
||||
<Font Name="Microsoft YaHei UI" Size="9" />
|
||||
</ClassDiagram>
|
|
@ -32,6 +32,7 @@
|
|||
<ClInclude Include="src\Model.h" />
|
||||
<ClInclude Include="src\Particle.h" />
|
||||
<ClInclude Include="src\PhysicsManager.h" />
|
||||
<ClInclude Include="src\RenderingSystem.h" />
|
||||
<ClInclude Include="src\RenderPass.h" />
|
||||
<ClInclude Include="src\RenderPassContext.h" />
|
||||
<ClInclude Include="src\Shader.h" />
|
||||
|
@ -53,11 +54,13 @@
|
|||
<ClCompile Include="src\Model.cpp" />
|
||||
<ClCompile Include="src\Particle.cpp" />
|
||||
<ClCompile Include="src\PhysicsManager.cpp" />
|
||||
<ClCompile Include="src\RenderingSystem.cpp" />
|
||||
<ClCompile Include="src\RenderPass.cpp" />
|
||||
<ClCompile Include="src\Shader.cpp" />
|
||||
<ClCompile Include="src\World.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ClassDiagram.cd" />
|
||||
<None Include="Shaders\brdf_lut.comp" />
|
||||
<None Include="Shaders\cubemap.frag" />
|
||||
<None Include="Shaders\cubemap.vert" />
|
||||
|
|
|
@ -63,6 +63,15 @@
|
|||
<ClInclude Include="src\DemoWorld.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\PhysicsManager.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\RenderPassContext.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\RenderingSystem.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\gl.c">
|
||||
|
@ -113,6 +122,15 @@
|
|||
<ClCompile Include="src\DemoWorld.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\PhysicsManager.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Shader.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\RenderingSystem.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Shaders\brdf_lut.comp">
|
||||
|
@ -166,5 +184,12 @@
|
|||
<None Include="Shaders\skybox.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="ClassDiagram.cd" />
|
||||
<None Include="Shaders\debug.frag">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="Shaders\debug.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,14 +1,14 @@
|
|||
#include "DemoWorld.h"
|
||||
#include "Particle.h"
|
||||
#include "RenderingSystem.h"
|
||||
|
||||
DemoWorld::DemoWorld()
|
||||
{
|
||||
light.lightDirection = glm::normalize(glm::vec3((cos(lightPitch) * cos(lightYaw)), (sin(lightPitch)), (cos(lightPitch) * sin(lightYaw))));
|
||||
light.radiance = 15.f * lightColor;
|
||||
|
||||
std::string modelFilePath;
|
||||
//modelFilePath = "E:\\3D Objects\\plane\\obj\\plane.obj";
|
||||
//modelFilePath = "E:\\3D Objects\\plane\\plane.gltf";
|
||||
modelFilePath = "Models/vampire/vampire.gltf";
|
||||
//modelFilePath = "E:\\3D Objects\\cup\\cup.gltf";
|
||||
//modelFilePath = "E:\\3D Objects\\Sponza\\Sponza.gltf";
|
||||
|
||||
auto actor = std::make_shared<Actor>(modelFilePath);
|
||||
actor->setRotaion(glm::angleAxis(glm::radians(-90.f), glm::vec3(1, 0, 0)));
|
||||
|
@ -95,12 +95,74 @@ void DemoWorld::logicalTick(float deltaTime)
|
|||
{
|
||||
mk2->setPosition(throwPerson->getPosition() + glm::vec3(-0.5, 2.2, 0));
|
||||
mk2->setSpeed(glm::mat3_cast(throwPerson->getRotation() * glm::rotation(glm::vec3(1, 0, 0), glm::normalize(glm::vec3(0, 0.8, 1)/*方向*/))) * glm::vec3(8.3/*速度*/, 0, 0));
|
||||
//mk2->setSpeed(glm::mat3_cast(throwPerson->getRotation() * glm::rotation(glm::vec3(1, 0, 0), glm::normalize(glm::vec3(0, 2, 1)/*方向*/))) * glm::vec3(10/*速度*/, 0, 0));
|
||||
mk2->setEnableGravity(true);
|
||||
}
|
||||
|
||||
if (mk2->getPosition().y < 7.5f && mk2->getSpeed().y < 0)
|
||||
{
|
||||
particles[3]->setSpeed(particles[3]->getSpeed() + mk2->getSpeed() / 2.f);
|
||||
mk2->setEnableGravity(false);
|
||||
mk2->setSpeed(glm::vec3(0));
|
||||
mk2->setPosition({ 0,-100,0 });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DemoWorld::rendererTick(float deltaTime)
|
||||
{
|
||||
|
||||
World::rendererTick(deltaTime);
|
||||
}
|
||||
|
||||
void DemoWorld::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_RIGHT) == GLFW_PRESS)
|
||||
camera.processMouseMovement(xoffset, yoffset);
|
||||
}
|
||||
|
||||
void DemoWorld::scrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
|
||||
lightPitch = glm::mod(lightPitch + yoffset / 100., glm::pi<double>());
|
||||
else if (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS)
|
||||
lightYaw = glm::mod(lightYaw + yoffset / 100., 2 * glm::pi<double>());
|
||||
else if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS)
|
||||
light.radiance = glm::clamp((light.radiance / lightColor).x + (float)yoffset, 0.f, 100.f) * lightColor;
|
||||
else if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
|
||||
RenderingSystem::instance().exposure = glm::clamp(RenderingSystem::instance().exposure + (float)yoffset*0.1f, 0.f, 2.f);
|
||||
else camera.processMouseScroll(yoffset);
|
||||
|
||||
light.lightDirection = glm::normalize(glm::vec3((cos(lightPitch) * cos(lightYaw)), (sin(lightPitch)), (cos(lightPitch) * sin(lightYaw))));
|
||||
}
|
||||
|
||||
void DemoWorld::processInput(GLFWwindow* window, float deltaTime)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -5,11 +5,19 @@ class DemoWorld : public World
|
|||
{
|
||||
public:
|
||||
DemoWorld();
|
||||
virtual void logicalTick(float deltaTime) override;
|
||||
virtual void rendererTick(float deltaTime) override;
|
||||
void logicalTick(float deltaTime) override;
|
||||
void rendererTick(float deltaTime) override;
|
||||
virtual void mouseCallback(GLFWwindow* window, double xpos, double ypos) override;
|
||||
virtual void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) override;
|
||||
virtual void processInput(GLFWwindow* window, float deltaTime) override;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<Particle>> particles;
|
||||
std::shared_ptr<Actor> throwPerson;
|
||||
std::shared_ptr<Particle> mk2;
|
||||
|
||||
glm::vec3 lightColor = glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784));
|
||||
float lightYaw = glm::radians(80.f);
|
||||
float lightPitch = glm::radians(105.f);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <glad/gl.h>
|
||||
#include "IblUtils.h"
|
||||
#include <array>
|
||||
#include <glm/glm.hpp>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
#include <glad/gl.h>
|
||||
#include <tuple>
|
||||
#include <glm/ext/matrix_float4x4.hpp>
|
||||
|
||||
struct GladGLContext;
|
||||
|
||||
class IblUtils
|
||||
{
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glad/gl.h>
|
||||
#include "Camera.h"
|
||||
#include "Model.h"
|
||||
|
||||
class Light
|
||||
{
|
||||
public:
|
||||
glm::vec3 lightDirection = glm::normalize(glm::vec3(0.2, 4, 0.4));
|
||||
glm::vec3 radiance = glm::vec3(0);
|
||||
|
||||
std::vector<float> shadowCascadeLevels;
|
||||
float blendRatio = 0.3;
|
||||
std::vector<float> frustumSizes;
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
#include "MainWindow.h"
|
||||
#include "IblUtils.h"
|
||||
#include "RenderPass.h"
|
||||
#include "World.h"
|
||||
#include "Particle.h"
|
||||
#include "DemoWorld.h"
|
||||
#include "RenderingSystem.h"
|
||||
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: camera(glm::vec3(0.0f, 0.0f, 3.0f))
|
||||
, light(&camera)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -21,9 +18,9 @@ int MainWindow::exec()
|
|||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
float xscale, yscale;
|
||||
glfwGetMonitorContentScale(monitor, &xscale, &yscale);
|
||||
GLFWwindow* window = glfwCreateWindow(kWindowWidth * xscale, kWindowHeight * yscale, "ToyEngine", NULL, NULL);
|
||||
window = glfwCreateWindow(kWindowWidth * xscale, kWindowHeight * yscale, "ToyEngine", NULL, NULL);
|
||||
glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height) {
|
||||
MainWindow::instance().framebufferSizeCallback(window, width, height);
|
||||
RenderingSystem::instance().framebufferSizeCallback(window, width, height);
|
||||
});
|
||||
glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos) {
|
||||
MainWindow::instance().mouseCallback(window, xpos, ypos);
|
||||
|
@ -44,38 +41,18 @@ int MainWindow::exec()
|
|||
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, 0.0f);
|
||||
gl->Enable(GL_DEPTH_TEST);
|
||||
gl->DepthFunc(GL_LEQUAL);
|
||||
gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
gl->LineWidth(5 * xscale);
|
||||
|
||||
|
||||
std::unique_ptr<World> world = std::make_unique<DemoWorld>();
|
||||
world = std::make_unique<DemoWorld>();
|
||||
|
||||
auto [minPos, maxPos] = world->getAABB();
|
||||
std::cout << std::format("{},{},{} {},{},{}\n", minPos.x, minPos.y, minPos.z, maxPos.x, maxPos.y, maxPos.z);
|
||||
|
||||
light.sceneAABB = world->getAABB();
|
||||
|
||||
glm::mat4 projection, view;
|
||||
auto [skyCubemap, irradianceMap, prefilterMap, brdfLUTTexture] = IblUtils::precomputeCubemaps(gl.get());
|
||||
|
||||
ShadowMapPass shadowMapPass(gl.get(), shadowFboHandle, shadowMapResolution, *world, light);
|
||||
GeometryPass geometryPass(gl.get(), frameWidth, frameHeight, fbo, *world, projection, view);
|
||||
LightingPass lightingPass(gl.get(), frameWidth, frameHeight, view, camera, light, mainLightRadiance,
|
||||
gbuffers, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
|
||||
FinalPass finalPass(gl.get(), frameWidth, frameHeight, gBaseColor, gDebug, exposure);
|
||||
SkyboxPass skyboxPass(gl.get(), projection, view, exposure, skyCubemap);
|
||||
RenderingSystem::instance().initialize(gl.get(), xscale, world.get());
|
||||
|
||||
int w, h;
|
||||
glfwGetFramebufferSize(window, &w, &h);
|
||||
framebufferSizeCallback(window, w, h);
|
||||
RenderingSystem::instance().framebufferSizeCallback(window, w, h);
|
||||
|
||||
int logicalTickCount = 0;
|
||||
auto logicalThread = std::jthread([&](std::stop_token stop) {
|
||||
|
@ -107,15 +84,7 @@ int MainWindow::exec()
|
|||
|
||||
world->rendererTick(deltaTime);
|
||||
|
||||
projection = camera.getProjectionMatrix();
|
||||
view = camera.getViewMatrix();
|
||||
|
||||
shadowMapPass.dispatch();
|
||||
geometryPass.dispatch();
|
||||
lightingPass.dispatch();
|
||||
finalPass.setShowDebug(showDebug);
|
||||
finalPass.dispatch();
|
||||
skyboxPass.dispatch();
|
||||
RenderingSystem::instance().tick(deltaTime);
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
|
@ -126,7 +95,7 @@ int MainWindow::exec()
|
|||
if (accTime > 1.)
|
||||
{
|
||||
std::cout << std::format("{:20}\r", "");
|
||||
std::cout << std::format("FPS: {:.2f} TPS: {:.2f} {} {} {}\r", frameCnt / accTime, logicalTickCount / accTime, camera.Position.x, camera.Position.y, camera.Position.z);
|
||||
std::cout << std::format("FPS: {:.2f} TPS: {:.2f}\r", frameCnt / accTime, logicalTickCount / accTime);
|
||||
accTime = 0;
|
||||
frameCnt = 0;
|
||||
logicalTickCount = 0;
|
||||
|
@ -141,141 +110,24 @@ void MainWindow::processInput(GLFWwindow* window, float deltaTime)
|
|||
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);
|
||||
|
||||
static glm::mat4 transform(1);
|
||||
float speed = 1;
|
||||
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
|
||||
transform = glm::translate(transform, glm::vec3(0, 0, speed));
|
||||
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
|
||||
transform = glm::translate(transform, glm::vec3(0, 0, -speed));
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
|
||||
transform = glm::translate(transform, glm::vec3(-speed, 0, 0));
|
||||
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
|
||||
transform = glm::translate(transform, glm::vec3(speed, 0, 0));
|
||||
//modelPtr->setTransform(transform);
|
||||
}
|
||||
|
||||
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->CreateTextures(GL_TEXTURE_2D, gbuffers.size(), gbuffers.data());
|
||||
gl->TextureStorage2D(gBaseColor, 1, GL_RGBA8, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gNormal, 1, GL_RGB16F, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gPosition, 1, GL_RGB32F, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gMetallicRoughness, 1, GL_RG8, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gDebug, 1, GL_RGBA8, frameWidth, frameHeight);
|
||||
|
||||
std::vector<GLenum> attachments;
|
||||
for (auto i = 0U; i < gbuffers.size(); i++)
|
||||
{
|
||||
gl->TextureParameteri(gbuffers[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
gl->TextureParameteri(gbuffers[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, gbuffers[i], 0);
|
||||
attachments.push_back(GL_COLOR_ATTACHMENT0 + i);
|
||||
}
|
||||
gl->NamedFramebufferDrawBuffers(fbo, attachments.size(), attachments.data());
|
||||
gl->CreateRenderbuffers(1, &rboDepth);
|
||||
gl->NamedRenderbufferStorage(rboDepth, GL_DEPTH_COMPONENT, frameWidth, frameHeight);
|
||||
gl->NamedFramebufferRenderbuffer(fbo, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth);
|
||||
|
||||
if (gl->CheckNamedFramebufferStatus(fbo, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
std::cerr << "Framebuffer not complete!\n";
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
world->processInput(window, deltaTime);
|
||||
}
|
||||
|
||||
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;
|
||||
static 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);
|
||||
world->mouseCallback(window, xpos, ypos);
|
||||
}
|
||||
|
||||
void MainWindow::scrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
camera.processMouseScroll(yoffset);
|
||||
world->scrollCallback(window, xoffset, yoffset);
|
||||
}
|
||||
|
||||
void MainWindow::keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_TAB && action == GLFW_PRESS)
|
||||
showDebug = !showDebug;
|
||||
RenderingSystem::instance().setShowDebug(!RenderingSystem::instance().getShowDebug());
|
||||
world->keyCallback(window, key, scancode, action, mods);
|
||||
}
|
||||
|
||||
MainWindow& MainWindow::instance()
|
||||
|
@ -287,4 +139,9 @@ MainWindow& MainWindow::instance()
|
|||
GladGLContext* MainWindow::getGLContext()
|
||||
{
|
||||
return instance().gl.get();
|
||||
}
|
||||
}
|
||||
|
||||
GLFWwindow* MainWindow::getWindow()
|
||||
{
|
||||
return window;
|
||||
}
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
#pragma once
|
||||
#include "Model.h"
|
||||
#include "Camera.h"
|
||||
#include "Light.h"
|
||||
#include <array>
|
||||
#include <glad/gl.h>
|
||||
#include <array>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "World.h"
|
||||
|
||||
|
||||
class MainWindow
|
||||
{
|
||||
public:
|
||||
static MainWindow& instance();
|
||||
static GladGLContext* getGLContext();
|
||||
GLFWwindow* getWindow();
|
||||
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 keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
|
@ -23,29 +22,9 @@ private:
|
|||
|
||||
static constexpr int kWindowWidth = 1200;
|
||||
static constexpr int kWindowHeight = 675;
|
||||
unsigned int frameWidth;
|
||||
unsigned int frameHeight;
|
||||
|
||||
Camera camera;
|
||||
Light light;
|
||||
glm::vec3 mainLightRadiance = 30.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784));
|
||||
float exposure = 0.6f;
|
||||
|
||||
|
||||
GLFWwindow* window = nullptr;
|
||||
std::unique_ptr<GladGLContext> gl;
|
||||
|
||||
GLuint fbo = 0;
|
||||
std::array<GLuint, 5> gbuffers;
|
||||
GLuint& gBaseColor = gbuffers[0];
|
||||
GLuint& gNormal = gbuffers[1];
|
||||
GLuint& gPosition = gbuffers[2];
|
||||
GLuint& gMetallicRoughness = gbuffers[3];
|
||||
GLuint& gDebug = gbuffers[4];
|
||||
GLuint rboDepth = 0;
|
||||
|
||||
GLuint shadowFboHandle = 0;
|
||||
GLuint shadowGbuffer;
|
||||
int shadowMapResolution;
|
||||
|
||||
bool showDebug = false;
|
||||
std::unique_ptr<World> world;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <glad/gl.h>
|
||||
#include "Model.h"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#pragma once
|
||||
#include <glad/gl.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
|
|
|
@ -20,7 +20,7 @@ Particle::Particle(float mass, const std::string& path)
|
|||
void Particle::logicalTick(float deltaTime)
|
||||
{
|
||||
resultantForce = glm::vec3(0);
|
||||
for (auto& force : forces)
|
||||
for (std::lock_guard<std::mutex> lk(forcesMutex); auto & force : forces)
|
||||
resultantForce += force->value;
|
||||
|
||||
if (fixed)
|
||||
|
@ -32,13 +32,8 @@ void Particle::logicalTick(float deltaTime)
|
|||
//auto pos = getPosition() + speed * deltaTime + 0.5f * resultantForce / mass * deltaTime * deltaTime;
|
||||
speed += resultantForce / mass * deltaTime;
|
||||
auto pos = getPosition() + speed * deltaTime;
|
||||
//if (speed.y < 0 && pos.y < 0.4)
|
||||
//{
|
||||
// speed.y = -speed.y;
|
||||
//}
|
||||
setPosition(pos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Particle::draw(const RenderPassContext& context, Shader& shader)
|
||||
|
@ -71,7 +66,7 @@ void Particle::draw(const RenderPassContext& context, Shader& shader)
|
|||
debugShader.setUniformValue("view", *context.view);
|
||||
glm::mat4 modelMatrix = glm::translate(glm::mat4(1), getPosition());// *glm::scale(glm::mat4(1), glm::vec3(glm::abs(resultantForce / mass)));
|
||||
gl->BindVertexArray(vao);
|
||||
for (auto& force : forces)
|
||||
for (std::lock_guard<std::mutex> lk(forcesMutex); auto & force : forces)
|
||||
{
|
||||
debugShader.setUniformValue("model", modelMatrix * glm::scale(glm::mat4(1), glm::vec3(1)) * glm::mat4_cast(glm::rotation(glm::vec3(1, 0, 0), glm::normalize(force->value))));
|
||||
debugShader.setUniformValue("color", glm::vec3(0, 1, 0));
|
||||
|
@ -85,11 +80,13 @@ void Particle::draw(const RenderPassContext& context, Shader& shader)
|
|||
|
||||
void Particle::addForce(std::shared_ptr<Force> force)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(forcesMutex);
|
||||
forces.insert(force);
|
||||
}
|
||||
|
||||
void Particle::removeForce(std::shared_ptr<Force> force)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(forcesMutex);
|
||||
forces.erase(force);
|
||||
}
|
||||
|
||||
|
@ -120,8 +117,8 @@ void Particle::setEnableGravity(bool enable)
|
|||
if (!gravity)
|
||||
{
|
||||
gravity = std::make_shared<Force>(glm::vec3(0.f, -getMass() * 9.80665f, 0.f));
|
||||
addForce(gravity);
|
||||
}
|
||||
addForce(gravity);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
virtual void draw(const RenderPassContext& context, Shader& shader);
|
||||
void addForce(std::shared_ptr<Force> force);
|
||||
void removeForce(std::shared_ptr<Force> force);
|
||||
std::mutex forcesMutex;
|
||||
float getMass();
|
||||
glm::vec3 getSpeed();
|
||||
void setSpeed(const glm::vec3& speed);
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#include <glad/gl.h>
|
||||
#include "RenderPass.h"
|
||||
#include "IblUtils.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
ShadowMapPass::ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, World& world, Light& light)
|
||||
ShadowMapPass::ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, World& world)
|
||||
: RenderPass(gl, { typeid(ShadowMapPass) })
|
||||
, modelShadowShader(gl, "Shaders/model_shadow.vert", "Shaders/model_shadow.frag", "Shaders/model_shadow.geom")
|
||||
, shadowFboHandle(shadowFboHandle)
|
||||
, shadowMapResolution(shadowMapResolution)
|
||||
, world(world)
|
||||
, light(light)
|
||||
{
|
||||
gl->CreateBuffers(1, &lightSpaceMatricesUBO);
|
||||
gl->NamedBufferData(lightSpaceMatricesUBO, sizeof(glm::mat4) * 16, nullptr, GL_STATIC_DRAW);
|
||||
|
@ -17,7 +17,7 @@ ShadowMapPass::ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& sh
|
|||
|
||||
void ShadowMapPass::dispatch()
|
||||
{
|
||||
const auto lightMatrices = light.getLightSpaceMatrices();
|
||||
const auto lightMatrices = world.light.getLightSpaceMatrices();
|
||||
|
||||
gl->NamedBufferSubData(lightSpaceMatricesUBO, 0, lightMatrices.size() * sizeof(lightMatrices[0]), lightMatrices.data());
|
||||
gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
||||
|
@ -89,7 +89,7 @@ void GeometryPass::dispatch()
|
|||
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
LightingPass::LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, glm::mat4& view, Camera& camera, Light& light, glm::vec3& mainLightRadiance, std::array<GLuint, 5>& gbuffers, GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture)
|
||||
LightingPass::LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, glm::mat4& view, Camera& camera, Light& light, std::array<GLuint, 5>& gbuffers, GLuint& shadowGbuffer, GLuint& irradianceMap, GLuint& prefilterMap, GLuint& brdfLUTTexture)
|
||||
: RenderPass(gl, { typeid(LightingPass) })
|
||||
, pbrShader(gl, "Shaders/pbr.comp")
|
||||
, frameWidth(frameWidth)
|
||||
|
@ -97,7 +97,6 @@ LightingPass::LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned
|
|||
, view(view)
|
||||
, camera(camera)
|
||||
, light(light)
|
||||
, mainLightRadiance(mainLightRadiance)
|
||||
, gbuffers(gbuffers)
|
||||
, shadowGbuffer(shadowGbuffer)
|
||||
, irradianceMap(irradianceMap)
|
||||
|
@ -126,7 +125,7 @@ void LightingPass::dispatch()
|
|||
pbrShader.setUniformValue("shadowBlendRatio", light.blendRatio);
|
||||
pbrShader.setUniformValue("camPos", camera.Position);
|
||||
pbrShader.setUniformValue("mainLightDirection", light.lightDirection);
|
||||
pbrShader.setUniformValue("mainLightRadiance", mainLightRadiance);
|
||||
pbrShader.setUniformValue("mainLightRadiance", light.radiance);
|
||||
|
||||
gl->BindTextureUnit(1, gbuffers[1]);
|
||||
gl->BindTextureUnit(2, gbuffers[2]);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#pragma once
|
||||
#include <glad/gl.h>
|
||||
#include "Shader.h"
|
||||
#include "World.h"
|
||||
#include "Light.h"
|
||||
|
@ -20,14 +19,13 @@ protected:
|
|||
class ShadowMapPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, World& world, Light& light);
|
||||
ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, World& world);
|
||||
void dispatch();
|
||||
private:
|
||||
Shader modelShadowShader;
|
||||
GLuint& shadowFboHandle;
|
||||
int& shadowMapResolution;
|
||||
World& world;
|
||||
Light& light;
|
||||
GLuint lightSpaceMatricesUBO;
|
||||
};
|
||||
|
||||
|
@ -52,7 +50,7 @@ class LightingPass : public RenderPass
|
|||
{
|
||||
public:
|
||||
LightingPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight,
|
||||
glm::mat4& view, Camera& camera, Light& light, glm::vec3& mainLightRadiance,
|
||||
glm::mat4& view, Camera& camera, Light& light,
|
||||
std::array<GLuint, 5>& gbuffers, GLuint& shadowGbuffer, GLuint& irradianceMap,
|
||||
GLuint& prefilterMap, GLuint& brdfLUTTexture);
|
||||
void dispatch();
|
||||
|
@ -63,7 +61,6 @@ private:
|
|||
glm::mat4& view;
|
||||
Camera& camera;
|
||||
Light& light;
|
||||
glm::vec3& mainLightRadiance;
|
||||
std::array<GLuint, 5>& gbuffers;
|
||||
GLuint& shadowGbuffer;
|
||||
GLuint& irradianceMap;
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
#include <glad/gl.h>
|
||||
#include "RenderingSystem.h"
|
||||
#include "IblUtils.h"
|
||||
|
||||
RenderingSystem::RenderingSystem()
|
||||
{
|
||||
}
|
||||
|
||||
void RenderingSystem::initialize(GladGLContext* gl, float pixelRatio, World* world)
|
||||
{
|
||||
world->light.sceneAABB = world->getAABB();
|
||||
|
||||
this->gl = gl;
|
||||
this->world = world;
|
||||
|
||||
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, 0.0f);
|
||||
gl->Enable(GL_DEPTH_TEST);
|
||||
gl->DepthFunc(GL_LEQUAL);
|
||||
gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
gl->LineWidth(5 * pixelRatio);
|
||||
|
||||
std::tie(skyCubemap, irradianceMap, prefilterMap, brdfLUTTexture) = IblUtils::precomputeCubemaps(gl);
|
||||
|
||||
shadowMapPass = std::make_unique<ShadowMapPass>(gl, shadowFboHandle, shadowMapResolution, *world);
|
||||
geometryPass = std::make_unique<GeometryPass>(gl, frameWidth, frameHeight, fbo, *world, projection, view);
|
||||
lightingPass = std::make_unique<LightingPass>(gl, frameWidth, frameHeight, view, world->camera, world->light,
|
||||
gbuffers, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
|
||||
finalPass = std::make_unique<FinalPass>(gl, frameWidth, frameHeight, gBaseColor, gDebug, exposure);
|
||||
skyboxPass = std::make_unique<SkyboxPass>(gl, projection, view, exposure, skyCubemap);
|
||||
}
|
||||
|
||||
void RenderingSystem::tick(float deltaTime)
|
||||
{
|
||||
projection = world->camera.getProjectionMatrix();
|
||||
view = world->camera.getViewMatrix();
|
||||
|
||||
shadowMapPass->dispatch();
|
||||
geometryPass->dispatch();
|
||||
lightingPass->dispatch();
|
||||
|
||||
finalPass->dispatch();
|
||||
skyboxPass->dispatch();
|
||||
}
|
||||
|
||||
RenderingSystem& RenderingSystem::instance()
|
||||
{
|
||||
static RenderingSystem renderingSystem;
|
||||
return renderingSystem;
|
||||
}
|
||||
|
||||
bool RenderingSystem::getShowDebug()
|
||||
{
|
||||
return finalPass->getShowDebug();
|
||||
}
|
||||
|
||||
void RenderingSystem::setShowDebug(bool showDebug)
|
||||
{
|
||||
finalPass->setShowDebug(showDebug);
|
||||
}
|
||||
|
||||
void RenderingSystem::framebufferSizeCallback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
frameWidth = width;
|
||||
frameHeight = height;
|
||||
world->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->CreateTextures(GL_TEXTURE_2D, gbuffers.size(), gbuffers.data());
|
||||
gl->TextureStorage2D(gBaseColor, 1, GL_RGBA8, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gNormal, 1, GL_RGB16F, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gPosition, 1, GL_RGB32F, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gMetallicRoughness, 1, GL_RG8, frameWidth, frameHeight);
|
||||
gl->TextureStorage2D(gDebug, 1, GL_RGBA8, frameWidth, frameHeight);
|
||||
|
||||
std::vector<GLenum> attachments;
|
||||
for (auto i = 0U; i < gbuffers.size(); i++)
|
||||
{
|
||||
gl->TextureParameteri(gbuffers[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
gl->TextureParameteri(gbuffers[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
gl->NamedFramebufferTexture(fbo, GL_COLOR_ATTACHMENT0 + i, gbuffers[i], 0);
|
||||
attachments.push_back(GL_COLOR_ATTACHMENT0 + i);
|
||||
}
|
||||
gl->NamedFramebufferDrawBuffers(fbo, attachments.size(), attachments.data());
|
||||
gl->CreateRenderbuffers(1, &rboDepth);
|
||||
gl->NamedRenderbufferStorage(rboDepth, GL_DEPTH_COMPONENT, frameWidth, frameHeight);
|
||||
gl->NamedFramebufferRenderbuffer(fbo, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth);
|
||||
|
||||
if (gl->CheckNamedFramebufferStatus(fbo, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
std::cerr << "Framebuffer not complete!\n";
|
||||
}
|
||||
|
||||
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)world->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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
#include <array>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "Model.h"
|
||||
#include "Camera.h"
|
||||
#include "Light.h"
|
||||
#include "World.h"
|
||||
#include "RenderPass.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
class RenderingSystem
|
||||
{
|
||||
public:
|
||||
static RenderingSystem& instance();
|
||||
void initialize(GladGLContext* gl, float pixelRatio, World* world);
|
||||
void tick(float deltaTime);
|
||||
void framebufferSizeCallback(GLFWwindow* window, int width, int height);
|
||||
bool getShowDebug();
|
||||
void setShowDebug(bool showDebug);
|
||||
|
||||
float exposure = 0.6f;
|
||||
|
||||
private:
|
||||
RenderingSystem();
|
||||
|
||||
unsigned int frameWidth;
|
||||
unsigned int frameHeight;
|
||||
|
||||
glm::mat4 projection, view;
|
||||
World* world;
|
||||
|
||||
GladGLContext* gl;
|
||||
|
||||
GLuint skyCubemap, irradianceMap, prefilterMap, brdfLUTTexture;
|
||||
|
||||
GLuint fbo = 0;
|
||||
std::array<GLuint, 5> gbuffers;
|
||||
GLuint& gBaseColor = gbuffers[0];
|
||||
GLuint& gNormal = gbuffers[1];
|
||||
GLuint& gPosition = gbuffers[2];
|
||||
GLuint& gMetallicRoughness = gbuffers[3];
|
||||
GLuint& gDebug = gbuffers[4];
|
||||
GLuint rboDepth = 0;
|
||||
|
||||
GLuint shadowFboHandle = 0;
|
||||
GLuint shadowGbuffer;
|
||||
int shadowMapResolution;
|
||||
|
||||
std::unique_ptr<ShadowMapPass> shadowMapPass;
|
||||
std::unique_ptr<GeometryPass> geometryPass;
|
||||
std::unique_ptr<LightingPass> lightingPass;
|
||||
std::unique_ptr<FinalPass> finalPass;
|
||||
std::unique_ptr<SkyboxPass> skyboxPass;
|
||||
};
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
#include <glad/gl.h>
|
||||
#include "Shader.h"
|
||||
|
||||
Shader::Shader(GladGLContext* gl, const char* vertexPath, const char* fragmentPath, const char* geometryPath)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
#include <glad/gl.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <string>
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#include "World.h"
|
||||
|
||||
World::World()
|
||||
: camera(glm::vec3(0.0f, 0.0f, 3.0f))
|
||||
, light(&camera)
|
||||
{
|
||||
}
|
||||
|
||||
void World::logicalTick(float deltaTime)
|
||||
{
|
||||
physicsManager.tick(deltaTime);
|
||||
|
|
|
@ -2,17 +2,29 @@
|
|||
#include "Actor.h"
|
||||
#include "RenderPassContext.h"
|
||||
#include "PhysicsManager.h"
|
||||
#include "Camera.h"
|
||||
#include "Light.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class World
|
||||
{
|
||||
public:
|
||||
Camera camera;
|
||||
Light light;
|
||||
std::vector<std::shared_ptr<Actor>> actors;
|
||||
|
||||
World();
|
||||
virtual void logicalTick(float deltaTime);
|
||||
virtual void rendererTick(float deltaTime);
|
||||
void draw(const RenderPassContext& context, Shader& shader);
|
||||
void addActor(std::shared_ptr<Actor> actor);
|
||||
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||
virtual void mouseCallback(GLFWwindow* window, double xpos, double ypos) {};
|
||||
virtual void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) {};
|
||||
virtual void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {};
|
||||
virtual void processInput(GLFWwindow* window, float deltaTime) {};
|
||||
protected:
|
||||
PhysicsManager physicsManager;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue