初步实现World和Actor
parent
6234a31673
commit
eb79d7f66c
|
@ -2,13 +2,47 @@
|
||||||
layout (location = 0) in vec3 aPos;
|
layout (location = 0) in vec3 aPos;
|
||||||
layout (location = 1) in vec3 aNormal;
|
layout (location = 1) in vec3 aNormal;
|
||||||
layout (location = 2) in vec2 aTexCoords;
|
layout (location = 2) in vec2 aTexCoords;
|
||||||
|
layout (location = 3) in ivec4 boneIds;
|
||||||
|
layout (location = 4) in vec4 weights;
|
||||||
|
|
||||||
out vec2 vTexCoords;
|
out vec2 vTexCoords;
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
|
|
||||||
|
const int MAX_BONES = 100;
|
||||||
|
const int MAX_BONE_INFLUENCE = 4;
|
||||||
|
layout (std140, binding = 1) uniform FinalBonesMatrices
|
||||||
|
{
|
||||||
|
mat4 finalBonesMatrices[MAX_BONES];
|
||||||
|
};
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
vec4 totalPosition = vec4(0.0f);
|
||||||
|
vec3 totalNormal = vec3(0);
|
||||||
|
int boneCount = 0;
|
||||||
|
for(int i = 0 ; i < MAX_BONE_INFLUENCE ; i++)
|
||||||
|
{
|
||||||
|
if(boneIds[i] == -1)
|
||||||
|
continue;
|
||||||
|
if(boneIds[i] >= MAX_BONES)
|
||||||
|
{
|
||||||
|
totalPosition = vec4(aPos,1.0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
boneCount++;
|
||||||
|
vec4 localPosition = finalBonesMatrices[boneIds[i]] * vec4(aPos,1.0f);
|
||||||
|
totalPosition += localPosition * weights[i];
|
||||||
|
vec3 localNormal = mat3(finalBonesMatrices[boneIds[i]]) * aNormal;
|
||||||
|
totalNormal += localNormal * weights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(boneCount == 0)
|
||||||
|
{
|
||||||
|
totalPosition = vec4(aPos, 1);
|
||||||
|
totalNormal = vec3(aNormal);
|
||||||
|
}
|
||||||
|
|
||||||
vTexCoords = aTexCoords;
|
vTexCoords = aTexCoords;
|
||||||
gl_Position = model * vec4(aPos, 1.0);
|
gl_Position = model * totalPosition;
|
||||||
}
|
}
|
|
@ -31,6 +31,7 @@
|
||||||
<ClInclude Include="src\Model.h" />
|
<ClInclude Include="src\Model.h" />
|
||||||
<ClInclude Include="src\RenderPass.h" />
|
<ClInclude Include="src\RenderPass.h" />
|
||||||
<ClInclude Include="src\Shader.h" />
|
<ClInclude Include="src\Shader.h" />
|
||||||
|
<ClInclude Include="src\World.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\Actor.cpp" />
|
<ClCompile Include="src\Actor.cpp" />
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
<ClCompile Include="src\Mesh.cpp" />
|
<ClCompile Include="src\Mesh.cpp" />
|
||||||
<ClCompile Include="src\Model.cpp" />
|
<ClCompile Include="src\Model.cpp" />
|
||||||
<ClCompile Include="src\RenderPass.cpp" />
|
<ClCompile Include="src\RenderPass.cpp" />
|
||||||
|
<ClCompile Include="src\World.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Shaders\brdf_lut.comp" />
|
<None Include="Shaders\brdf_lut.comp" />
|
||||||
|
@ -160,6 +162,7 @@
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
@ -176,6 +179,7 @@
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
|
|
@ -54,6 +54,9 @@
|
||||||
<ClInclude Include="src\MainWindow.h">
|
<ClInclude Include="src\MainWindow.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\World.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\gl.c">
|
<ClCompile Include="src\gl.c">
|
||||||
|
@ -95,6 +98,9 @@
|
||||||
<ClCompile Include="src\MainWindow.cpp">
|
<ClCompile Include="src\MainWindow.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\World.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Shaders\brdf_lut.comp">
|
<None Include="Shaders\brdf_lut.comp">
|
||||||
|
|
|
@ -1 +1,50 @@
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
|
#include "MainWindow.h"
|
||||||
|
|
||||||
|
Actor::Actor(const std::string& path)
|
||||||
|
: gl(MainWindow::getGLContext())
|
||||||
|
, model(gl, path)
|
||||||
|
, danceAnimation(path, &model)
|
||||||
|
, animator(gl, &danceAnimation)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::tick(float deltaTime)
|
||||||
|
{
|
||||||
|
animator.UpdateAnimation(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::draw(Shader& shader)
|
||||||
|
{
|
||||||
|
gl->BindBufferBase(GL_UNIFORM_BUFFER, 1, animator.getFinalBonesMatricesUBO());
|
||||||
|
model.draw(shader);
|
||||||
|
gl->BindBufferBase(GL_UNIFORM_BUFFER, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setPosition(const glm::vec3& position)
|
||||||
|
{
|
||||||
|
this->position = position;
|
||||||
|
updateTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setScale(const glm::vec3& scale)
|
||||||
|
{
|
||||||
|
this->scale = scale;
|
||||||
|
updateTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setRotaion(const glm::quat& rotation)
|
||||||
|
{
|
||||||
|
this->rotation = rotation;
|
||||||
|
updateTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<glm::vec3, glm::vec3> Actor::getAABB()
|
||||||
|
{
|
||||||
|
return model.getAABB();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::updateTransform()
|
||||||
|
{
|
||||||
|
model.setTransform(glm::translate(glm::mat4(1), position) * glm::scale(glm::mat4(1), scale) * glm::mat4_cast(rotation));
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
#include "Animation.h"
|
||||||
|
#include "Animator.h"
|
||||||
|
|
||||||
class Actor
|
class Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Actor(const std::string& path);
|
||||||
|
void tick(float deltaTime);
|
||||||
|
void draw(Shader& shader);
|
||||||
|
|
||||||
|
void setPosition(const glm::vec3& position);
|
||||||
|
void setScale(const glm::vec3& scale);
|
||||||
|
void setRotaion(const glm::quat& rotation);
|
||||||
|
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||||
private:
|
private:
|
||||||
|
void updateTransform();
|
||||||
|
|
||||||
|
GladGLContext* gl;
|
||||||
|
Model model;
|
||||||
|
Animation danceAnimation;
|
||||||
|
Animator animator;
|
||||||
|
glm::vec3 position = glm::vec3(0);
|
||||||
|
glm::vec3 scale = glm::vec3(1);
|
||||||
|
glm::quat rotation = glm::quat(1, 0, 0, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,32 +11,34 @@ class Animator
|
||||||
public:
|
public:
|
||||||
static constexpr GLint kMaxBone = 100;
|
static constexpr GLint kMaxBone = 100;
|
||||||
|
|
||||||
Animator(Animation* animation)
|
Animator(GladGLContext* gl, Animation* animation) : gl(gl)
|
||||||
{
|
{
|
||||||
m_CurrentTime = 0.0;
|
currentTime = 0.0;
|
||||||
m_CurrentAnimation = animation;
|
currentAnimation = animation;
|
||||||
|
|
||||||
m_FinalBoneMatrices.reserve(100);
|
finalBoneMatrices.reserve(100);
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0; i < 100; i++)
|
||||||
m_FinalBoneMatrices.push_back(glm::mat4(1.0f));
|
finalBoneMatrices.push_back(glm::mat4(1.0f));
|
||||||
|
|
||||||
|
gl->CreateBuffers(1, &finalBonesMatricesUBO);
|
||||||
|
gl->NamedBufferData(finalBonesMatricesUBO, sizeof(glm::mat4) * Animator::kMaxBone, nullptr, GL_DYNAMIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAnimation(float dt)
|
void UpdateAnimation(float deltaTime)
|
||||||
{
|
{
|
||||||
m_DeltaTime = dt;
|
if (currentAnimation)
|
||||||
if (m_CurrentAnimation)
|
|
||||||
{
|
{
|
||||||
m_CurrentTime += m_CurrentAnimation->GetTicksPerSecond() * dt;
|
currentTime += currentAnimation->GetTicksPerSecond() * deltaTime;
|
||||||
m_CurrentTime = fmod(m_CurrentTime, m_CurrentAnimation->GetDuration());
|
currentTime = fmod(currentTime, currentAnimation->GetDuration());
|
||||||
CalculateBoneTransform(&m_CurrentAnimation->GetRootNode(), glm::mat4(1.0f));
|
CalculateBoneTransform(¤tAnimation->GetRootNode(), glm::mat4(1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayAnimation(Animation* pAnimation)
|
void PlayAnimation(Animation* pAnimation)
|
||||||
{
|
{
|
||||||
m_CurrentAnimation = pAnimation;
|
currentAnimation = pAnimation;
|
||||||
m_CurrentTime = 0.0f;
|
currentTime = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform)
|
void CalculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform)
|
||||||
|
@ -44,22 +46,22 @@ public:
|
||||||
std::string nodeName = node->name;
|
std::string nodeName = node->name;
|
||||||
glm::mat4 nodeTransform = node->transformation;
|
glm::mat4 nodeTransform = node->transformation;
|
||||||
|
|
||||||
Bone* Bone = m_CurrentAnimation->FindBone(nodeName);
|
Bone* Bone = currentAnimation->FindBone(nodeName);
|
||||||
|
|
||||||
if (Bone)
|
if (Bone)
|
||||||
{
|
{
|
||||||
Bone->Update(m_CurrentTime);
|
Bone->Update(currentTime);
|
||||||
nodeTransform = Bone->GetLocalTransform();
|
nodeTransform = Bone->GetLocalTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 globalTransformation = parentTransform * nodeTransform;
|
glm::mat4 globalTransformation = parentTransform * nodeTransform;
|
||||||
|
|
||||||
auto boneInfoMap = m_CurrentAnimation->GetBoneIDMap();
|
auto boneInfoMap = currentAnimation->GetBoneIDMap();
|
||||||
if (boneInfoMap.find(nodeName) != boneInfoMap.end())
|
if (boneInfoMap.find(nodeName) != boneInfoMap.end())
|
||||||
{
|
{
|
||||||
int index = boneInfoMap[nodeName].id;
|
int index = boneInfoMap[nodeName].id;
|
||||||
glm::mat4 offset = boneInfoMap[nodeName].offset;
|
glm::mat4 offset = boneInfoMap[nodeName].offset;
|
||||||
m_FinalBoneMatrices[index] = globalTransformation * offset;
|
finalBoneMatrices[index] = globalTransformation * offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < node->childrenCount; i++)
|
for (int i = 0; i < node->childrenCount; i++)
|
||||||
|
@ -68,13 +70,19 @@ public:
|
||||||
|
|
||||||
std::vector<glm::mat4> GetFinalBoneMatrices()
|
std::vector<glm::mat4> GetFinalBoneMatrices()
|
||||||
{
|
{
|
||||||
return m_FinalBoneMatrices;
|
return finalBoneMatrices;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint getFinalBonesMatricesUBO()
|
||||||
|
{
|
||||||
|
gl->NamedBufferSubData(finalBonesMatricesUBO, 0, finalBoneMatrices.size() * sizeof(finalBoneMatrices[0]), finalBoneMatrices.data());
|
||||||
|
return finalBonesMatricesUBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<glm::mat4> m_FinalBoneMatrices;
|
GladGLContext* gl;
|
||||||
Animation* m_CurrentAnimation;
|
std::vector<glm::mat4> finalBoneMatrices;
|
||||||
float m_CurrentTime;
|
GLuint finalBonesMatricesUBO;
|
||||||
float m_DeltaTime;
|
Animation* currentAnimation;
|
||||||
|
float currentTime;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
// Default camera values
|
// Default camera values
|
||||||
static constexpr float YAW = -90.0f;
|
static constexpr float YAW = -90.0f;
|
||||||
static constexpr float PITCH = 0.0f;
|
static constexpr float PITCH = 0.0f;
|
||||||
static constexpr float SPEED = 20.f;
|
static constexpr float SPEED = 5.f;
|
||||||
static constexpr float SENSITIVITY = 0.1f;
|
static constexpr float SENSITIVITY = 0.1f;
|
||||||
static constexpr float ZOOM = 45.0f;
|
static constexpr float ZOOM = 45.0f;
|
||||||
// camera Attributes
|
// camera Attributes
|
||||||
|
@ -40,7 +40,7 @@ public:
|
||||||
float Zoom;
|
float Zoom;
|
||||||
float Ratio;
|
float Ratio;
|
||||||
float NearPlane = 0.1f;
|
float NearPlane = 0.1f;
|
||||||
float FarPlane = 1000.f;
|
float FarPlane = 100.f;
|
||||||
|
|
||||||
// constructor with vectors
|
// constructor with vectors
|
||||||
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
|
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
|
||||||
|
|
|
@ -78,39 +78,27 @@ glm::mat4 Light::getLightSpaceMatrix(const float nearPlane, const float farPlane
|
||||||
minZ = std::min(minZ, -trf.z);
|
minZ = std::min(minZ, -trf.z);
|
||||||
maxZ = std::max(maxZ, -trf.z);
|
maxZ = std::max(maxZ, -trf.z);
|
||||||
}
|
}
|
||||||
if (model != nullptr)
|
|
||||||
for (const glm::vec3& v : model->AABB)
|
std::vector<glm::vec3> aabbVertexs;
|
||||||
|
auto& [minPos, maxPos] = sceneAABB;
|
||||||
|
aabbVertexs.emplace_back(minPos.x, minPos.y, minPos.z);
|
||||||
|
aabbVertexs.emplace_back(minPos.x, minPos.y, maxPos.z);
|
||||||
|
aabbVertexs.emplace_back(minPos.x, maxPos.y, minPos.z);
|
||||||
|
aabbVertexs.emplace_back(minPos.x, maxPos.y, maxPos.z);
|
||||||
|
aabbVertexs.emplace_back(maxPos.x, minPos.y, minPos.z);
|
||||||
|
aabbVertexs.emplace_back(maxPos.x, minPos.y, maxPos.z);
|
||||||
|
aabbVertexs.emplace_back(maxPos.x, maxPos.y, minPos.z);
|
||||||
|
aabbVertexs.emplace_back(maxPos.x, maxPos.y, maxPos.z);
|
||||||
|
for (const glm::vec3& v : aabbVertexs)
|
||||||
{
|
{
|
||||||
const glm::vec4 trf = lightView * glm::vec4(v, 1);
|
const glm::vec4 trf = lightView * glm::vec4(v, 1);
|
||||||
//qDebug() << v;
|
|
||||||
//qDebug() << trf;
|
|
||||||
//minX = std::min(minX, trf.x());
|
//minX = std::min(minX, trf.x());
|
||||||
//maxX = std::max(maxX, trf.x());
|
//maxX = std::max(maxX, trf.x());
|
||||||
//minY = std::min(minY, trf.y());
|
//minY = std::min(minY, trf.y());
|
||||||
//maxY = std::max(maxY, trf.y());
|
//maxY = std::max(maxY, trf.y());
|
||||||
minZ = std::min(minZ, -trf.z);
|
minZ = std::min(minZ, -trf.z);
|
||||||
//maxZ = std::max(maxZ, trf.z());
|
//maxZ = std::max(maxZ, trf.z());
|
||||||
|
|
||||||
}
|
}
|
||||||
//qDebug() << minZ;
|
|
||||||
// Tune this parameter according to the scene
|
|
||||||
/* constexpr float zMult = 10.0f;
|
|
||||||
if (minZ < 0)
|
|
||||||
{
|
|
||||||
minZ *= zMult;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
minZ /= zMult;
|
|
||||||
}
|
|
||||||
if (maxZ < 0)
|
|
||||||
{
|
|
||||||
maxZ /= zMult;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
maxZ *= zMult;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
glm::mat4 lightProjection = glm::ortho(minX, maxX, minY, maxY, minZ, maxZ);
|
glm::mat4 lightProjection = glm::ortho(minX, maxX, minY, maxY, minZ, maxZ);
|
||||||
frustumSizes.push_back(std::max(maxX - minX, maxY - minY));
|
frustumSizes.push_back(std::max(maxX - minX, maxY - minY));
|
||||||
|
|
|
@ -11,11 +11,12 @@
|
||||||
class Light
|
class Light
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
glm::vec3 lightDirection = glm::normalize(glm::vec3(0.2, 4, 1));
|
glm::vec3 lightDirection = glm::normalize(glm::vec3(0.2, 4, 0.4));
|
||||||
std::vector<float> shadowCascadeLevels;
|
std::vector<float> shadowCascadeLevels;
|
||||||
float blendRatio = 0.3;
|
float blendRatio = 0.3;
|
||||||
std::vector<float> frustumSizes;
|
std::vector<float> frustumSizes;
|
||||||
Model* model = nullptr;
|
std::pair<glm::vec3, glm::vec3> sceneAABB;
|
||||||
|
|
||||||
Light(Camera* camera);
|
Light(Camera* camera);
|
||||||
std::vector<glm::vec4> getFrustumCornersWorldSpace(const glm::mat4& projview);
|
std::vector<glm::vec4> getFrustumCornersWorldSpace(const glm::mat4& projview);
|
||||||
std::vector<glm::vec4> getFrustumCornersWorldSpace(const glm::mat4& proj, const glm::mat4& view);
|
std::vector<glm::vec4> getFrustumCornersWorldSpace(const glm::mat4& proj, const glm::mat4& view);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "IblUtils.h"
|
#include "IblUtils.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: camera(glm::vec3(0.0f, 0.0f, 3.0f))
|
: camera(glm::vec3(0.0f, 0.0f, 3.0f))
|
||||||
|
@ -8,6 +9,105 @@ MainWindow::MainWindow()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, "ToyEngine", NULL, NULL);
|
||||||
|
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<GladGLContext>();
|
||||||
|
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";
|
||||||
|
|
||||||
|
auto actor = std::make_shared<Actor>(modelFilePath);
|
||||||
|
actor->setRotaion(glm::angleAxis(glm::radians(-90.f), glm::vec3(1, 0, 0)));
|
||||||
|
auto sponza = std::make_shared<Actor>("E:\\3D Objects\\Sponza\\Sponza.gltf");
|
||||||
|
sponza->setScale(glm::vec3(2));
|
||||||
|
World world;
|
||||||
|
world.addActor(actor);
|
||||||
|
world.addActor(sponza);
|
||||||
|
|
||||||
|
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, 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);
|
||||||
|
|
||||||
|
world.tick(deltaTime);
|
||||||
|
|
||||||
|
projection = camera.getProjectionMatrix();
|
||||||
|
view = camera.getViewMatrix();
|
||||||
|
|
||||||
|
shadowMapPass.dispatch();
|
||||||
|
geometryPass.dispatch();
|
||||||
|
lightingPass.dispatch();
|
||||||
|
finalPass.dispatch();
|
||||||
|
skyboxPass.dispatch();
|
||||||
|
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
void MainWindow::processInput(GLFWwindow* window)
|
void MainWindow::processInput(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||||
|
@ -26,16 +126,17 @@ void MainWindow::processInput(GLFWwindow* window)
|
||||||
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||||
camera.processKeyboard(DOWN, deltaTime);
|
camera.processKeyboard(DOWN, deltaTime);
|
||||||
|
|
||||||
glm::mat4 transform(1);
|
static glm::mat4 transform(1);
|
||||||
float speed = 1;
|
float speed = 1;
|
||||||
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
|
||||||
modelPtr->setTransform(glm::translate(transform, glm::vec3(0, 0, speed)));
|
transform = glm::translate(transform, glm::vec3(0, 0, speed));
|
||||||
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
|
||||||
modelPtr->setTransform(glm::translate(transform, glm::vec3(0, 0, -speed)));
|
transform = glm::translate(transform, glm::vec3(0, 0, -speed));
|
||||||
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
|
||||||
modelPtr->setTransform(glm::translate(transform, glm::vec3(-speed, 0, 0)));
|
transform = glm::translate(transform, glm::vec3(-speed, 0, 0));
|
||||||
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
|
||||||
modelPtr->setTransform(glm::translate(transform, glm::vec3(speed, 0, 0)));
|
transform = glm::translate(transform, glm::vec3(speed, 0, 0));
|
||||||
|
//modelPtr->setTransform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::framebufferSizeCallback(GLFWwindow* window, int width, int height)
|
void MainWindow::framebufferSizeCallback(GLFWwindow* window, int width, int height)
|
||||||
|
@ -145,9 +246,9 @@ void MainWindow::mouseCallback(GLFWwindow* window, double xpos, double ypos)
|
||||||
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
|
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
float speed = 0.2f;
|
float speed = 0.2f;
|
||||||
glm::mat4 rotate(1);
|
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));
|
rotate = glm::rotate(rotate, glm::radians(glm::length(glm::vec2(xoffset, yoffset)) * speed), glm::vec3(glm::vec2(-yoffset, xoffset), 0.0));
|
||||||
modelPtr->setTransform(rotate);
|
//modelPtr->setTransform(rotate);
|
||||||
}
|
}
|
||||||
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS)
|
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS)
|
||||||
camera.processMouseMovement(xoffset, yoffset);
|
camera.processMouseMovement(xoffset, yoffset);
|
||||||
|
@ -164,97 +265,7 @@ MainWindow& MainWindow::instance()
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::exec()
|
GladGLContext* MainWindow::getGLContext()
|
||||||
{
|
{
|
||||||
glfwInit();
|
return instance().gl.get();
|
||||||
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<GladGLContext>();
|
|
||||||
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();
|
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@ class MainWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static MainWindow& instance();
|
static MainWindow& instance();
|
||||||
|
static GladGLContext* getGLContext();
|
||||||
int exec();
|
int exec();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -24,7 +25,6 @@ private:
|
||||||
unsigned int frameWidth;
|
unsigned int frameWidth;
|
||||||
unsigned int frameHeight;
|
unsigned int frameHeight;
|
||||||
|
|
||||||
Model* modelPtr = nullptr;
|
|
||||||
Camera camera;
|
Camera camera;
|
||||||
Light light;
|
Light light;
|
||||||
glm::vec3 mainLightRadiance = 40.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784));
|
glm::vec3 mainLightRadiance = 40.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784));
|
||||||
|
|
|
@ -20,8 +20,17 @@ void Model::draw(Shader& shader)
|
||||||
|
|
||||||
void Model::setTransform(const glm::mat4& trans)
|
void Model::setTransform(const glm::mat4& trans)
|
||||||
{
|
{
|
||||||
|
auto inverse = glm::inverse(transform);
|
||||||
|
transform = trans;
|
||||||
for (auto& mesh : meshes)
|
for (auto& mesh : meshes)
|
||||||
mesh->model = trans * mesh->model;
|
mesh->model = transform * inverse * mesh->model;
|
||||||
|
minPos = transform * inverse * glm::vec4(minPos, 1);
|
||||||
|
maxPos = transform * inverse * glm::vec4(maxPos, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<glm::vec3, glm::vec3> Model::getAABB()
|
||||||
|
{
|
||||||
|
return { minPos, maxPos };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::loadModel(std::string const& path)
|
void Model::loadModel(std::string const& path)
|
||||||
|
@ -38,17 +47,9 @@ void Model::loadModel(std::string const& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMatrix4x4 transform;
|
aiMatrix4x4 transform;
|
||||||
aiMatrix4x4::Scaling(aiVector3D(10), transform);
|
//aiMatrix4x4::Scaling(aiVector3D(10), transform);
|
||||||
//aiMatrix4x4::Rotation(glm::radians(-90.f), { 1,0,0 }, transform);
|
//aiMatrix4x4::Rotation(glm::radians(-90.f), { 1,0,0 }, transform);
|
||||||
processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation);
|
processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation);
|
||||||
AABB.emplace_back(minPos.x, minPos.y, minPos.z);
|
|
||||||
AABB.emplace_back(minPos.x, minPos.y, maxPos.z);
|
|
||||||
AABB.emplace_back(minPos.x, maxPos.y, minPos.z);
|
|
||||||
AABB.emplace_back(minPos.x, maxPos.y, maxPos.z);
|
|
||||||
AABB.emplace_back(maxPos.x, minPos.y, minPos.z);
|
|
||||||
AABB.emplace_back(maxPos.x, minPos.y, maxPos.z);
|
|
||||||
AABB.emplace_back(maxPos.x, maxPos.y, minPos.z);
|
|
||||||
AABB.emplace_back(maxPos.x, maxPos.y, maxPos.z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
|
void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct BoneInfo
|
||||||
class Model
|
class Model
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<glm::vec3> AABB;
|
glm::mat4 transform = glm::mat4(1);
|
||||||
std::vector<std::unique_ptr<Mesh>> meshes;
|
std::vector<std::unique_ptr<Mesh>> meshes;
|
||||||
std::map<std::string, BoneInfo> boneInfoMap;
|
std::map<std::string, BoneInfo> boneInfoMap;
|
||||||
int boneCount = 0;
|
int boneCount = 0;
|
||||||
|
@ -29,6 +29,7 @@ public:
|
||||||
Model(GladGLContext* gl, std::string const& path);
|
Model(GladGLContext* gl, std::string const& path);
|
||||||
void draw(Shader& shader);
|
void draw(Shader& shader);
|
||||||
void setTransform(const glm::mat4& trans);
|
void setTransform(const glm::mat4& trans);
|
||||||
|
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||||
private:
|
private:
|
||||||
GladGLContext* gl;
|
GladGLContext* gl;
|
||||||
std::filesystem::path directory; /// 模型所在路径
|
std::filesystem::path directory; /// 模型所在路径
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
#include "IblUtils.h"
|
#include "IblUtils.h"
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
|
||||||
ShadowMapPass::ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, Model& model, Light& light)
|
ShadowMapPass::ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, World& world, Light& light)
|
||||||
: RenderPass(gl)
|
: RenderPass(gl)
|
||||||
, modelShadowShader(gl, "Shaders/model_shadow.vert", "Shaders/model_shadow.frag", "Shaders/model_shadow.geom")
|
, modelShadowShader(gl, "Shaders/model_shadow.vert", "Shaders/model_shadow.frag", "Shaders/model_shadow.geom")
|
||||||
, shadowFboHandle(shadowFboHandle)
|
, shadowFboHandle(shadowFboHandle)
|
||||||
, shadowMapResolution(shadowMapResolution)
|
, shadowMapResolution(shadowMapResolution)
|
||||||
, model(model)
|
, world(world)
|
||||||
, light(light)
|
, light(light)
|
||||||
{
|
{
|
||||||
gl->CreateBuffers(1, &lightSpaceMatricesUBO);
|
gl->CreateBuffers(1, &lightSpaceMatricesUBO);
|
||||||
|
@ -24,26 +24,22 @@ void ShadowMapPass::dispatch()
|
||||||
gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution);
|
gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution);
|
||||||
gl->Clear(GL_DEPTH_BUFFER_BIT);
|
gl->Clear(GL_DEPTH_BUFFER_BIT);
|
||||||
modelShadowShader.use();
|
modelShadowShader.use();
|
||||||
model.draw(modelShadowShader);
|
world.draw(modelShadowShader);
|
||||||
modelShadowShader.release();
|
modelShadowShader.release();
|
||||||
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
|
gl->BindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GeometryPass::GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& fbo, Model& model, glm::mat4& projection, glm::mat4& view, Animator& animator)
|
GeometryPass::GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight, GLuint& fbo, World& world, glm::mat4& projection, glm::mat4& view)
|
||||||
: RenderPass(gl)
|
: RenderPass(gl)
|
||||||
, modelShader(gl, "Shaders/model.vert", "Shaders/model.frag")
|
, modelShader(gl, "Shaders/model.vert", "Shaders/model.frag")
|
||||||
, plainShader(gl, "Shaders/plain.vert", "Shaders/plain.frag")
|
, plainShader(gl, "Shaders/plain.vert", "Shaders/plain.frag")
|
||||||
, frameWidth(frameWidth)
|
, frameWidth(frameWidth)
|
||||||
, frameHeight(frameHeight)
|
, frameHeight(frameHeight)
|
||||||
, fbo(fbo)
|
, fbo(fbo)
|
||||||
, model(model)
|
, world(world)
|
||||||
, projection(projection)
|
, projection(projection)
|
||||||
, view(view)
|
, view(view)
|
||||||
, animator(animator)
|
|
||||||
{
|
{
|
||||||
gl->CreateBuffers(1, &finalBonesMatricesUBO);
|
|
||||||
gl->NamedBufferData(finalBonesMatricesUBO, sizeof(glm::mat4) * Animator::kMaxBone, nullptr, GL_DYNAMIC_DRAW);
|
|
||||||
gl->BindBufferBase(GL_UNIFORM_BUFFER, 1, finalBonesMatricesUBO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryPass::dispatch()
|
void GeometryPass::dispatch()
|
||||||
|
@ -55,9 +51,7 @@ void GeometryPass::dispatch()
|
||||||
modelShader.use();
|
modelShader.use();
|
||||||
modelShader.setUniformValue("projection", projection);
|
modelShader.setUniformValue("projection", projection);
|
||||||
modelShader.setUniformValue("view", view);
|
modelShader.setUniformValue("view", view);
|
||||||
auto boneMatrices = animator.GetFinalBoneMatrices();
|
world.draw(modelShader);
|
||||||
gl->NamedBufferSubData(finalBonesMatricesUBO, 0, boneMatrices.size() * sizeof(boneMatrices[0]), boneMatrices.data());
|
|
||||||
model.draw(modelShader);
|
|
||||||
modelShader.release();
|
modelShader.release();
|
||||||
|
|
||||||
/// Debug Lighting
|
/// Debug Lighting
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Model.h"
|
#include "World.h"
|
||||||
#include "Light.h"
|
#include "Light.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "Animator.h"
|
#include "Animator.h"
|
||||||
|
@ -18,13 +18,13 @@ protected:
|
||||||
class ShadowMapPass : public RenderPass
|
class ShadowMapPass : public RenderPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, Model& model, Light& light);
|
ShadowMapPass(GladGLContext* gl, GLuint& shadowFboHandle, int& shadowMapResolution, World& world, Light& light);
|
||||||
void dispatch();
|
void dispatch();
|
||||||
private:
|
private:
|
||||||
Shader modelShadowShader;
|
Shader modelShadowShader;
|
||||||
GLuint& shadowFboHandle;
|
GLuint& shadowFboHandle;
|
||||||
int& shadowMapResolution;
|
int& shadowMapResolution;
|
||||||
Model& model;
|
World& world;
|
||||||
Light& light;
|
Light& light;
|
||||||
GLuint lightSpaceMatricesUBO;
|
GLuint lightSpaceMatricesUBO;
|
||||||
};
|
};
|
||||||
|
@ -33,7 +33,7 @@ class GeometryPass : public RenderPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight,
|
GeometryPass(GladGLContext* gl, unsigned int& frameWidth, unsigned int& frameHeight,
|
||||||
GLuint& fbo, Model& model, glm::mat4& projection, glm::mat4& view, Animator& animator);
|
GLuint& fbo, World& world, glm::mat4& projection, glm::mat4& view);
|
||||||
void dispatch();
|
void dispatch();
|
||||||
private:
|
private:
|
||||||
Shader modelShader;
|
Shader modelShader;
|
||||||
|
@ -42,10 +42,9 @@ private:
|
||||||
unsigned int& frameWidth;
|
unsigned int& frameWidth;
|
||||||
unsigned int& frameHeight;
|
unsigned int& frameHeight;
|
||||||
GLuint& fbo;
|
GLuint& fbo;
|
||||||
Model& model;
|
World& world;
|
||||||
glm::mat4& projection;
|
glm::mat4& projection;
|
||||||
glm::mat4& view;
|
glm::mat4& view;
|
||||||
Animator& animator;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LightingPass : public RenderPass
|
class LightingPass : public RenderPass
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
void World::tick(float deltaTime)
|
||||||
|
{
|
||||||
|
for (auto& actor : actors)
|
||||||
|
actor->tick(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::draw(Shader& shader)
|
||||||
|
{
|
||||||
|
for (auto& actor : actors)
|
||||||
|
actor->draw(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::addActor(std::shared_ptr<Actor> actor)
|
||||||
|
{
|
||||||
|
actors.push_back(actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<glm::vec3, glm::vec3> World::getAABB()
|
||||||
|
{
|
||||||
|
glm::vec3 minPos = glm::vec3(std::numeric_limits<float>::max());
|
||||||
|
glm::vec3 maxPos = glm::vec3(std::numeric_limits<float>::min());
|
||||||
|
for (auto& actor : actors)
|
||||||
|
{
|
||||||
|
auto [min, max] = actor->getAABB();
|
||||||
|
minPos = glm::min(minPos, min);
|
||||||
|
maxPos = glm::max(maxPos, max);
|
||||||
|
}
|
||||||
|
return { minPos, maxPos };
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Actor.h"
|
||||||
|
|
||||||
|
class World
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<std::shared_ptr<Actor>> actors;
|
||||||
|
void tick(float deltaTime);
|
||||||
|
void draw(Shader& shader);
|
||||||
|
void addActor(std::shared_ptr<Actor> actor);
|
||||||
|
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue