parent
c5f8ce41c7
commit
c5b8729ed6
|
@ -101,6 +101,7 @@ const int pcfRadius = 3;
|
||||||
float getShadowFromLayer(vec3 fragPosWorldSpace, vec3 normal,int layer)
|
float getShadowFromLayer(vec3 fragPosWorldSpace, vec3 normal,int layer)
|
||||||
{
|
{
|
||||||
float normalBias = 1.2*4. /** (1+pcfRadius)*/ * shadowBiases[layer]*max((1.0 - dot(normal, mainLightDirection)), 0.1)/textureSize(gShadowMap, 0).x;
|
float normalBias = 1.2*4. /** (1+pcfRadius)*/ * shadowBiases[layer]*max((1.0 - dot(normal, mainLightDirection)), 0.1)/textureSize(gShadowMap, 0).x;
|
||||||
|
normalBias = max(normalBias, 0.05);
|
||||||
vec4 fragPosLightSpace = lightSpaceMatrices[layer] * vec4(fragPosWorldSpace+normal*normalBias, 1.0);
|
vec4 fragPosLightSpace = lightSpaceMatrices[layer] * vec4(fragPosWorldSpace+normal*normalBias, 1.0);
|
||||||
// perform perspective divide
|
// perform perspective divide
|
||||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||||
|
|
|
@ -24,11 +24,13 @@
|
||||||
<ClInclude Include="src\Animator.h" />
|
<ClInclude Include="src\Animator.h" />
|
||||||
<ClInclude Include="src\Bone.h" />
|
<ClInclude Include="src\Bone.h" />
|
||||||
<ClInclude Include="src\Camera.h" />
|
<ClInclude Include="src\Camera.h" />
|
||||||
|
<ClInclude Include="src\DemoWorld.h" />
|
||||||
<ClInclude Include="src\IblUtils.h" />
|
<ClInclude Include="src\IblUtils.h" />
|
||||||
<ClInclude Include="src\Light.h" />
|
<ClInclude Include="src\Light.h" />
|
||||||
<ClInclude Include="src\MainWindow.h" />
|
<ClInclude Include="src\MainWindow.h" />
|
||||||
<ClInclude Include="src\Mesh.h" />
|
<ClInclude Include="src\Mesh.h" />
|
||||||
<ClInclude Include="src\Model.h" />
|
<ClInclude Include="src\Model.h" />
|
||||||
|
<ClInclude Include="src\Particle.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" />
|
<ClInclude Include="src\World.h" />
|
||||||
|
@ -39,6 +41,7 @@
|
||||||
<ClCompile Include="src\Animator.cpp" />
|
<ClCompile Include="src\Animator.cpp" />
|
||||||
<ClCompile Include="src\Bone.cpp" />
|
<ClCompile Include="src\Bone.cpp" />
|
||||||
<ClCompile Include="src\Camera.cpp" />
|
<ClCompile Include="src\Camera.cpp" />
|
||||||
|
<ClCompile Include="src\DemoWorld.cpp" />
|
||||||
<ClCompile Include="src\gl.c" />
|
<ClCompile Include="src\gl.c" />
|
||||||
<ClCompile Include="src\IblUtils.cpp" />
|
<ClCompile Include="src\IblUtils.cpp" />
|
||||||
<ClCompile Include="src\Light.cpp" />
|
<ClCompile Include="src\Light.cpp" />
|
||||||
|
@ -46,6 +49,7 @@
|
||||||
<ClCompile Include="src\MainWindow.cpp" />
|
<ClCompile Include="src\MainWindow.cpp" />
|
||||||
<ClCompile Include="src\Mesh.cpp" />
|
<ClCompile Include="src\Mesh.cpp" />
|
||||||
<ClCompile Include="src\Model.cpp" />
|
<ClCompile Include="src\Model.cpp" />
|
||||||
|
<ClCompile Include="src\Particle.cpp" />
|
||||||
<ClCompile Include="src\RenderPass.cpp" />
|
<ClCompile Include="src\RenderPass.cpp" />
|
||||||
<ClCompile Include="src\World.cpp" />
|
<ClCompile Include="src\World.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -163,6 +167,9 @@
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
|
|
@ -57,6 +57,12 @@
|
||||||
<ClInclude Include="src\World.h">
|
<ClInclude Include="src\World.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\Particle.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\DemoWorld.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\gl.c">
|
<ClCompile Include="src\gl.c">
|
||||||
|
@ -101,6 +107,12 @@
|
||||||
<ClCompile Include="src\World.cpp">
|
<ClCompile Include="src\World.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\Particle.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\DemoWorld.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Shaders\brdf_lut.comp">
|
<None Include="Shaders\brdf_lut.comp">
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
|
||||||
|
Actor::Actor()
|
||||||
|
: gl(MainWindow::getGLContext())
|
||||||
|
, model(gl)
|
||||||
|
, animator(gl, animation.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Actor::Actor(const std::string& path)
|
Actor::Actor(const std::string& path)
|
||||||
: gl(MainWindow::getGLContext())
|
: gl(MainWindow::getGLContext())
|
||||||
, model(gl, path)
|
, model(gl, path)
|
||||||
, danceAnimation(path, &model)
|
, animation(std::make_unique<Animation>(path, &model))
|
||||||
, animator(gl, &danceAnimation)
|
, animator(gl, animation->available() ? animation.get() : nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::tick(float deltaTime)
|
void Actor::logicalTick(float deltaTime)
|
||||||
{
|
{
|
||||||
animator.UpdateAnimation(deltaTime);
|
animator.updateAnimation(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::rendererTick(float deltaTime)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::draw(Shader& shader)
|
void Actor::draw(Shader& shader)
|
||||||
|
@ -39,6 +51,21 @@ void Actor::setRotaion(const glm::quat& rotation)
|
||||||
updateTransform();
|
updateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Actor::getPosition()
|
||||||
|
{
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Actor::getScale()
|
||||||
|
{
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat Actor::getRotation()
|
||||||
|
{
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<glm::vec3, glm::vec3> Actor::getAABB()
|
std::pair<glm::vec3, glm::vec3> Actor::getAABB()
|
||||||
{
|
{
|
||||||
return model.getAABB();
|
return model.getAABB();
|
||||||
|
|
|
@ -7,21 +7,32 @@
|
||||||
class Actor
|
class Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Actor();
|
||||||
Actor(const std::string& path);
|
Actor(const std::string& path);
|
||||||
void tick(float deltaTime);
|
virtual ~Actor() = default;
|
||||||
void draw(Shader& shader);
|
virtual void logicalTick(float deltaTime);
|
||||||
|
virtual void rendererTick(float deltaTime);
|
||||||
|
virtual void draw(Shader& shader);
|
||||||
|
|
||||||
void setPosition(const glm::vec3& position);
|
void setPosition(const glm::vec3& position);
|
||||||
void setScale(const glm::vec3& scale);
|
void setScale(const glm::vec3& scale);
|
||||||
void setRotaion(const glm::quat& rotation);
|
void setRotaion(const glm::quat& rotation);
|
||||||
|
|
||||||
|
glm::vec3 getPosition();
|
||||||
|
glm::vec3 getScale();
|
||||||
|
glm::quat getRotation();
|
||||||
|
|
||||||
std::pair<glm::vec3, glm::vec3> getAABB();
|
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GladGLContext* gl;
|
||||||
|
Model model;
|
||||||
|
std::unique_ptr<Animation> animation;
|
||||||
|
Animator animator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateTransform();
|
void updateTransform();
|
||||||
|
|
||||||
GladGLContext* gl;
|
|
||||||
Model model;
|
|
||||||
Animation danceAnimation;
|
|
||||||
Animator animator;
|
|
||||||
glm::vec3 position = glm::vec3(0);
|
glm::vec3 position = glm::vec3(0);
|
||||||
glm::vec3 scale = glm::vec3(1);
|
glm::vec3 scale = glm::vec3(1);
|
||||||
glm::quat rotation = glm::quat(1, 0, 0, 0);
|
glm::quat rotation = glm::quat(1, 0, 0, 0);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Bone.h"
|
#include "Bone.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
struct AssimpNodeData
|
struct AssimpNodeData
|
||||||
{
|
{
|
||||||
|
@ -41,16 +42,16 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool available()
|
||||||
|
{
|
||||||
|
return m_TicksPerSecond;
|
||||||
|
}
|
||||||
|
|
||||||
Bone* FindBone(const std::string& name)
|
Bone* FindBone(const std::string& name)
|
||||||
{
|
{
|
||||||
auto iter = std::find_if(m_Bones.begin(), m_Bones.end(),
|
auto iter = m_Bones.find(name);
|
||||||
[&](const Bone& Bone)
|
|
||||||
{
|
|
||||||
return Bone.GetBoneName() == name;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (iter == m_Bones.end()) return nullptr;
|
if (iter == m_Bones.end()) return nullptr;
|
||||||
else return &(*iter);
|
else return &iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +82,8 @@ private:
|
||||||
boneInfoMap[boneName].id = boneCount;
|
boneInfoMap[boneName].id = boneCount;
|
||||||
boneCount++;
|
boneCount++;
|
||||||
}
|
}
|
||||||
m_Bones.push_back(Bone(channel->mNodeName.data,
|
|
||||||
|
m_Bones.emplace(std::piecewise_construct, std::forward_as_tuple(channel->mNodeName.data), std::forward_as_tuple(channel->mNodeName.data,
|
||||||
boneInfoMap[channel->mNodeName.data].id, channel));
|
boneInfoMap[channel->mNodeName.data].id, channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +105,11 @@ private:
|
||||||
dest.children.push_back(newData);
|
dest.children.push_back(newData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float m_Duration;
|
float m_Duration = 0.f;
|
||||||
int m_TicksPerSecond;
|
int m_TicksPerSecond = 0;
|
||||||
std::vector<Bone> m_Bones;
|
std::unordered_map<std::string, Bone> m_Bones;
|
||||||
|
|
||||||
|
//std::set<Bone> m_Bones;
|
||||||
AssimpNodeData m_RootNode;
|
AssimpNodeData m_RootNode;
|
||||||
std::map<std::string, BoneInfo> m_BoneInfoMap;
|
std::map<std::string, BoneInfo> m_BoneInfoMap;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,37 +11,43 @@ class Animator
|
||||||
public:
|
public:
|
||||||
static constexpr GLint kMaxBone = 100;
|
static constexpr GLint kMaxBone = 100;
|
||||||
|
|
||||||
Animator(GladGLContext* gl, Animation* animation) : gl(gl)
|
Animator(GladGLContext* gl, Animation* animation)
|
||||||
|
: gl(gl)
|
||||||
{
|
{
|
||||||
currentTime = 0.0;
|
playAnimation(animation);
|
||||||
currentAnimation = animation;
|
|
||||||
|
|
||||||
finalBoneMatrices.reserve(100);
|
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
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 deltaTime)
|
void updateAnimation(float deltaTime)
|
||||||
{
|
{
|
||||||
if (currentAnimation)
|
if (currentAnimation)
|
||||||
{
|
{
|
||||||
currentTime += currentAnimation->GetTicksPerSecond() * deltaTime;
|
currentTime += currentAnimation->GetTicksPerSecond() * deltaTime;
|
||||||
currentTime = fmod(currentTime, currentAnimation->GetDuration());
|
currentTime = fmod(currentTime, currentAnimation->GetDuration());
|
||||||
CalculateBoneTransform(¤tAnimation->GetRootNode(), glm::mat4(1.0f));
|
calculateBoneTransform(¤tAnimation->GetRootNode(), glm::mat4(1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayAnimation(Animation* pAnimation)
|
void playAnimation(Animation* pAnimation)
|
||||||
{
|
{
|
||||||
currentAnimation = pAnimation;
|
currentAnimation = pAnimation;
|
||||||
currentTime = 0.0f;
|
currentTime = 0.0f;
|
||||||
|
|
||||||
|
if (currentAnimation)
|
||||||
|
{
|
||||||
|
finalBoneMatrices.clear();
|
||||||
|
finalBoneMatrices.reserve(kMaxBone);
|
||||||
|
for (int i = 0; i < kMaxBone; i++)
|
||||||
|
finalBoneMatrices.push_back(glm::mat4(1.0f));
|
||||||
|
|
||||||
|
if (!finalBonesMatricesUBO)
|
||||||
|
{
|
||||||
|
gl->CreateBuffers(1, &finalBonesMatricesUBO);
|
||||||
|
gl->NamedBufferData(finalBonesMatricesUBO, sizeof(glm::mat4) * Animator::kMaxBone, nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform)
|
void calculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform)
|
||||||
{
|
{
|
||||||
std::string nodeName = node->name;
|
std::string nodeName = node->name;
|
||||||
glm::mat4 nodeTransform = node->transformation;
|
glm::mat4 nodeTransform = node->transformation;
|
||||||
|
@ -56,25 +62,25 @@ public:
|
||||||
|
|
||||||
glm::mat4 globalTransformation = parentTransform * nodeTransform;
|
glm::mat4 globalTransformation = parentTransform * nodeTransform;
|
||||||
|
|
||||||
auto boneInfoMap = currentAnimation->GetBoneIDMap();
|
auto& boneInfoMap = currentAnimation->GetBoneIDMap();
|
||||||
if (boneInfoMap.find(nodeName) != boneInfoMap.end())
|
if (auto iter = boneInfoMap.find(nodeName); iter != boneInfoMap.end())
|
||||||
{
|
{
|
||||||
int index = boneInfoMap[nodeName].id;
|
auto& [index, offset] = iter->second;
|
||||||
glm::mat4 offset = boneInfoMap[nodeName].offset;
|
|
||||||
finalBoneMatrices[index] = globalTransformation * offset;
|
finalBoneMatrices[index] = globalTransformation * offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < node->childrenCount; i++)
|
for (int i = 0; i < node->childrenCount; i++)
|
||||||
CalculateBoneTransform(&node->children[i], globalTransformation);
|
calculateBoneTransform(&node->children[i], globalTransformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<glm::mat4> GetFinalBoneMatrices()
|
std::vector<glm::mat4> getFinalBoneMatrices()
|
||||||
{
|
{
|
||||||
return finalBoneMatrices;
|
return finalBoneMatrices;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint getFinalBonesMatricesUBO()
|
GLuint getFinalBonesMatricesUBO()
|
||||||
{
|
{
|
||||||
|
if (finalBonesMatricesUBO)
|
||||||
gl->NamedBufferSubData(finalBonesMatricesUBO, 0, finalBoneMatrices.size() * sizeof(finalBoneMatrices[0]), finalBoneMatrices.data());
|
gl->NamedBufferSubData(finalBonesMatricesUBO, 0, finalBoneMatrices.size() * sizeof(finalBoneMatrices[0]), finalBoneMatrices.data());
|
||||||
return finalBonesMatricesUBO;
|
return finalBonesMatricesUBO;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +88,7 @@ public:
|
||||||
private:
|
private:
|
||||||
GladGLContext* gl;
|
GladGLContext* gl;
|
||||||
std::vector<glm::mat4> finalBoneMatrices;
|
std::vector<glm::mat4> finalBoneMatrices;
|
||||||
GLuint finalBonesMatricesUBO;
|
GLuint finalBonesMatricesUBO = 0;
|
||||||
Animation* currentAnimation;
|
Animation* currentAnimation = nullptr;
|
||||||
float currentTime;
|
float currentTime;
|
||||||
};
|
};
|
||||||
|
|
|
@ -114,6 +114,10 @@ public:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator<(const Bone& e) const
|
||||||
|
{
|
||||||
|
return m_ID < e.m_ID;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "DemoWorld.h"
|
||||||
|
#include "Particle.h"
|
||||||
|
|
||||||
|
DemoWorld::DemoWorld()
|
||||||
|
{
|
||||||
|
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)));
|
||||||
|
auto actor2 = std::make_shared<Actor>(modelFilePath);
|
||||||
|
actor2->setRotaion(glm::angleAxis(glm::radians(-90.f), glm::vec3(1, 0, 0)));
|
||||||
|
actor2->setPosition({ 1,0,-1 });
|
||||||
|
auto actor3 = std::make_shared<Actor>(modelFilePath);
|
||||||
|
actor3->setRotaion(glm::angleAxis(glm::radians(-90.f), glm::vec3(1, 0, 0)));
|
||||||
|
actor3->setPosition({ -1,0,-1 });
|
||||||
|
auto sponza = std::make_shared<Actor>("Models\\Sponza\\Sponza.gltf");
|
||||||
|
sponza->setScale(glm::vec3(2));
|
||||||
|
|
||||||
|
auto particle = std::make_shared<Particle>(10);
|
||||||
|
particle->setPosition({ 4, 5, 0 });
|
||||||
|
particle->addForce(glm::vec3(0, -particle->getMass() * 9.8f, 0));
|
||||||
|
|
||||||
|
addActor(actor);
|
||||||
|
addActor(actor2);
|
||||||
|
addActor(actor3);
|
||||||
|
addActor(sponza);
|
||||||
|
addActor(particle);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
class DemoWorld : public World
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DemoWorld();
|
||||||
|
};
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include "IblUtils.h"
|
#include "IblUtils.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
#include "Particle.h"
|
||||||
|
#include "DemoWorld.h"
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: camera(glm::vec3(0.0f, 0.0f, 3.0f))
|
: camera(glm::vec3(0.0f, 0.0f, 3.0f))
|
||||||
|
@ -50,39 +52,18 @@ int MainWindow::exec()
|
||||||
gl->DepthFunc(GL_LEQUAL);
|
gl->DepthFunc(GL_LEQUAL);
|
||||||
gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||||
|
|
||||||
std::string modelFilePath;
|
std::unique_ptr<World> world = std::make_unique<DemoWorld>();
|
||||||
//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);
|
auto [minPos, maxPos] = world->getAABB();
|
||||||
actor->setRotaion(glm::angleAxis(glm::radians(-90.f), glm::vec3(1, 0, 0)));
|
|
||||||
auto actor2 = std::make_shared<Actor>(modelFilePath);
|
|
||||||
actor2->setRotaion(glm::angleAxis(glm::radians(-90.f), glm::vec3(1, 0, 0)));
|
|
||||||
actor2->setPosition({ 1,0,-1 });
|
|
||||||
auto actor3 = std::make_shared<Actor>(modelFilePath);
|
|
||||||
actor3->setRotaion(glm::angleAxis(glm::radians(-90.f), glm::vec3(1, 0, 0)));
|
|
||||||
actor3->setPosition({ -1,0,-1 });
|
|
||||||
auto sponza = std::make_shared<Actor>("Models\\Sponza\\Sponza.gltf");
|
|
||||||
sponza->setScale(glm::vec3(2));
|
|
||||||
World world;
|
|
||||||
world.addActor(actor);
|
|
||||||
world.addActor(actor2);
|
|
||||||
world.addActor(actor3);
|
|
||||||
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);
|
std::cout << std::format("{},{},{} {},{},{}\n", minPos.x, minPos.y, minPos.z, maxPos.x, maxPos.y, maxPos.z);
|
||||||
|
|
||||||
light.sceneAABB = world.getAABB();
|
light.sceneAABB = world->getAABB();
|
||||||
|
|
||||||
glm::mat4 projection, view;
|
glm::mat4 projection, view;
|
||||||
auto [skyCubemap, irradianceMap, prefilterMap, brdfLUTTexture] = IblUtils::precomputeCubemaps(gl.get());
|
auto [skyCubemap, irradianceMap, prefilterMap, brdfLUTTexture] = IblUtils::precomputeCubemaps(gl.get());
|
||||||
|
|
||||||
ShadowMapPass shadowMapPass(gl.get(), shadowFboHandle, shadowMapResolution, world, light);
|
ShadowMapPass shadowMapPass(gl.get(), shadowFboHandle, shadowMapResolution, *world, light);
|
||||||
GeometryPass geometryPass(gl.get(), frameWidth, frameHeight, fbo, world, projection, view);
|
GeometryPass geometryPass(gl.get(), frameWidth, frameHeight, fbo, *world, projection, view);
|
||||||
LightingPass lightingPass(gl.get(), frameWidth, frameHeight, view, camera, light, mainLightRadiance,
|
LightingPass lightingPass(gl.get(), frameWidth, frameHeight, view, camera, light, mainLightRadiance,
|
||||||
gbuffers, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
|
gbuffers, shadowGbuffer, irradianceMap, prefilterMap, brdfLUTTexture);
|
||||||
FinalPass finalPass(gl.get(), frameWidth, frameHeight, gbuffers, exposure);
|
FinalPass finalPass(gl.get(), frameWidth, frameHeight, gbuffers, exposure);
|
||||||
|
@ -92,14 +73,35 @@ int MainWindow::exec()
|
||||||
glfwGetFramebufferSize(window, &w, &h);
|
glfwGetFramebufferSize(window, &w, &h);
|
||||||
framebufferSizeCallback(window, w, h);
|
framebufferSizeCallback(window, w, h);
|
||||||
|
|
||||||
|
int logicalTickCount = 0;
|
||||||
|
auto logicalThread = std::jthread([&](std::stop_token stop) {
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
constexpr auto targetDuration = 1666us;
|
||||||
|
auto sleepTime = 0ns;
|
||||||
|
auto lastTick = std::chrono::high_resolution_clock::now();
|
||||||
|
while (!stop.stop_requested())
|
||||||
|
{
|
||||||
|
auto currentTick = std::chrono::high_resolution_clock::now();
|
||||||
|
auto deltaTime = currentTick - lastTick;
|
||||||
|
double deltaTime_s = std::chrono::duration<double>(deltaTime).count();
|
||||||
|
lastTick = currentTick;
|
||||||
|
processInput(window, deltaTime_s);
|
||||||
|
world->logicalTick(deltaTime_s);
|
||||||
|
logicalTickCount++;
|
||||||
|
|
||||||
|
sleepTime = targetDuration - (deltaTime - sleepTime);
|
||||||
|
std::this_thread::sleep_for(sleepTime);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
float lastFrame = glfwGetTime();
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
float currentFrame = glfwGetTime();
|
float currentFrame = glfwGetTime();
|
||||||
deltaTime = currentFrame - lastFrame;
|
float deltaTime = currentFrame - lastFrame;
|
||||||
lastFrame = currentFrame;
|
lastFrame = currentFrame;
|
||||||
processInput(window);
|
|
||||||
|
|
||||||
world.tick(deltaTime);
|
world->rendererTick(deltaTime);
|
||||||
|
|
||||||
projection = camera.getProjectionMatrix();
|
projection = camera.getProjectionMatrix();
|
||||||
view = camera.getViewMatrix();
|
view = camera.getViewMatrix();
|
||||||
|
@ -112,11 +114,24 @@ int MainWindow::exec()
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
|
static float accTime = 0, frameCnt = 0;
|
||||||
|
accTime += deltaTime;
|
||||||
|
frameCnt++;
|
||||||
|
if (accTime > 1.)
|
||||||
|
{
|
||||||
|
std::cout << std::format("{:20}\r", "");
|
||||||
|
std::cout << std::format("FPS: {:.2f} TPS: {:.2f}\r", frameCnt / accTime, logicalTickCount / accTime);
|
||||||
|
accTime = 0;
|
||||||
|
frameCnt = 0;
|
||||||
|
logicalTickCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
void MainWindow::processInput(GLFWwindow* window)
|
|
||||||
|
void MainWindow::processInput(GLFWwindow* window, float deltaTime)
|
||||||
{
|
{
|
||||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||||
glfwSetWindowShouldClose(window, true);
|
glfwSetWindowShouldClose(window, true);
|
||||||
|
|
|
@ -18,7 +18,7 @@ private:
|
||||||
void framebufferSizeCallback(GLFWwindow* window, int width, int height);
|
void framebufferSizeCallback(GLFWwindow* window, int width, int height);
|
||||||
void mouseCallback(GLFWwindow* window, double xpos, double ypos);
|
void mouseCallback(GLFWwindow* window, double xpos, double ypos);
|
||||||
void scrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
void scrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||||
void processInput(GLFWwindow* window);
|
void processInput(GLFWwindow* window, float deltaTime);
|
||||||
|
|
||||||
static constexpr int kWindowWidth = 1200;
|
static constexpr int kWindowWidth = 1200;
|
||||||
static constexpr int kWindowHeight = 675;
|
static constexpr int kWindowHeight = 675;
|
||||||
|
@ -27,11 +27,8 @@ private:
|
||||||
|
|
||||||
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 = 30.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784));
|
||||||
float exposure = 1;
|
float exposure = 0.6f;
|
||||||
|
|
||||||
float deltaTime = 0.0f;
|
|
||||||
float lastFrame = 0.0f;
|
|
||||||
|
|
||||||
std::unique_ptr<GladGLContext> gl;
|
std::unique_ptr<GladGLContext> gl;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
|
||||||
Vertex::Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVector3D& texCoords)
|
Vertex::Vertex(const glm::vec3& position, const glm::vec3& normal, const glm::vec2& texCoords)
|
||||||
: position(position.x, position.y, position.z)
|
: position(position)
|
||||||
, normal(normal.x, normal.y, normal.z)
|
, normal(normal)
|
||||||
, texCoords(texCoords.x, texCoords.y)
|
, texCoords(texCoords)
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < kMaxBoneInfluence; i++)
|
for (std::size_t i = 0; i < kMaxBoneInfluence; i++)
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,11 @@ Vertex::Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vertex::Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVector3D& texCoords)
|
||||||
|
: Vertex({position.x, position.y, position.z}, {normal.x, normal.y, normal.z}, {texCoords.x, texCoords.y})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Vertex::setBoneData(int boneID, float weight)
|
void Vertex::setBoneData(int boneID, float weight)
|
||||||
{
|
{
|
||||||
if (weight == 0) return;
|
if (weight == 0) return;
|
||||||
|
@ -43,29 +48,12 @@ void Mesh::draw(Shader& shader)
|
||||||
shader.setUniformValue("baseColor", baseColor);
|
shader.setUniformValue("baseColor", baseColor);
|
||||||
shader.setUniformValue("metallicRoughness", metallicRoughness);
|
shader.setUniformValue("metallicRoughness", metallicRoughness);
|
||||||
gl->BindVertexArray(VAO);
|
gl->BindVertexArray(VAO);
|
||||||
gl->DrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
gl->DrawElements(drawMode, indices.size(), GL_UNSIGNED_INT, 0);
|
||||||
gl->BindVertexArray(0);
|
gl->BindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::setupMesh()
|
void Mesh::setupMesh()
|
||||||
{
|
{
|
||||||
//for (auto& v : vertices)
|
|
||||||
//{
|
|
||||||
// if (v.boneIDs[0] == 6 && v.boneIDs[1] == 14 && v.boneIDs[2] == 18 && v.boneIDs[3] == 22)
|
|
||||||
// {
|
|
||||||
// v.boneIDs[0] = -1;
|
|
||||||
// v.boneIDs[1] = -1;
|
|
||||||
// v.boneIDs[2] = -1;
|
|
||||||
// v.boneIDs[3] = -1;
|
|
||||||
// }
|
|
||||||
// for (int i = 0; i < kMaxBoneInfluence; i++)
|
|
||||||
// {
|
|
||||||
// std::cout << v.boneIDs[i] << " ";
|
|
||||||
// }
|
|
||||||
// std::cout << std::endl;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
gl->GenVertexArrays(1, &VAO);
|
gl->GenVertexArrays(1, &VAO);
|
||||||
gl->GenBuffers(1, &VBO);
|
gl->GenBuffers(1, &VBO);
|
||||||
gl->GenBuffers(1, &EBO);
|
gl->GenBuffers(1, &EBO);
|
||||||
|
@ -76,7 +64,6 @@ void Mesh::setupMesh()
|
||||||
gl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
gl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||||
gl->BufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
gl->BufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
|
||||||
enum VertexAttribute : GLuint {
|
enum VertexAttribute : GLuint {
|
||||||
kPosition = 0, kNormal = 1, kTexCoords = 2, kBoneIDs = 3, kBoneWeights = 4
|
kPosition = 0, kNormal = 1, kTexCoords = 2, kBoneIDs = 3, kBoneWeights = 4
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct Vertex {
|
||||||
int boneIDs[kMaxBoneInfluence];
|
int boneIDs[kMaxBoneInfluence];
|
||||||
float boneWeights[kMaxBoneInfluence];
|
float boneWeights[kMaxBoneInfluence];
|
||||||
|
|
||||||
|
Vertex(const glm::vec3& position, const glm::vec3& normal, const glm::vec2& texCoords);
|
||||||
Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVector3D& texCoords);
|
Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVector3D& texCoords);
|
||||||
void setBoneData(int boneID, float weight);
|
void setBoneData(int boneID, float weight);
|
||||||
};
|
};
|
||||||
|
@ -25,6 +26,7 @@ public:
|
||||||
glm::mat4 model;
|
glm::mat4 model;
|
||||||
std::vector<Vertex> vertices;
|
std::vector<Vertex> vertices;
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
|
GLenum drawMode = GL_TRIANGLES;
|
||||||
GLuint textureBasecolor = 0;
|
GLuint textureBasecolor = 0;
|
||||||
GLuint textureMetallicRoughness = 0;
|
GLuint textureMetallicRoughness = 0;
|
||||||
GLuint textureNormal = 0;
|
GLuint textureNormal = 0;
|
||||||
|
@ -32,12 +34,10 @@ public:
|
||||||
glm::vec2 metallicRoughness;
|
glm::vec2 metallicRoughness;
|
||||||
unsigned int VAO;
|
unsigned int VAO;
|
||||||
|
|
||||||
Mesh(GladGLContext* gl, const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices, const glm::mat4& model);
|
Mesh(GladGLContext* gl, const std::vector<Vertex>& vertices, const std::vector<unsigned int>& indices, const glm::mat4& model = glm::mat4(1));
|
||||||
void draw(Shader& shader);
|
void draw(Shader& shader);
|
||||||
void setupMesh();
|
void setupMesh();
|
||||||
private:
|
private:
|
||||||
GladGLContext* gl;
|
GladGLContext* gl;
|
||||||
unsigned int VBO, EBO;
|
unsigned int VBO, EBO;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
|
@ -1,13 +1,76 @@
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/ext/scalar_constants.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
Model::Model(GladGLContext* gl, std::string const& path)
|
Model Model::createSphere(GladGLContext* gl, const glm::vec3& baseColor, const glm::vec2& metallicRoughness)
|
||||||
|
{
|
||||||
|
Model sphere(gl);
|
||||||
|
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<unsigned int> indices;
|
||||||
|
|
||||||
|
constexpr unsigned int kXSegments = 64;
|
||||||
|
constexpr unsigned int kYSegments = 64;
|
||||||
|
|
||||||
|
for (unsigned int x = 0; x <= kXSegments; ++x)
|
||||||
|
{
|
||||||
|
for (unsigned int y = 0; y <= kYSegments; ++y)
|
||||||
|
{
|
||||||
|
float xSegment = (float)x / (float)kXSegments;
|
||||||
|
float ySegment = (float)y / (float)kYSegments;
|
||||||
|
|
||||||
|
constexpr auto PI = glm::pi<float>();
|
||||||
|
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||||
|
float yPos = std::cos(ySegment * PI);
|
||||||
|
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||||
|
|
||||||
|
vertices.emplace_back(glm::vec3(xPos, yPos, zPos), glm::vec3(xPos, yPos, zPos), glm::vec2(xSegment, ySegment));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool oddRow = false;
|
||||||
|
for (unsigned int y = 0; y < kYSegments; ++y)
|
||||||
|
{
|
||||||
|
if (!oddRow) // even rows: y == 0, y == 2; and so on
|
||||||
|
{
|
||||||
|
for (unsigned int x = 0; x <= kXSegments; ++x)
|
||||||
|
{
|
||||||
|
indices.push_back(y * (kXSegments + 1) + x);
|
||||||
|
indices.push_back((y + 1) * (kXSegments + 1) + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int x = kXSegments; x >= 0; --x)
|
||||||
|
{
|
||||||
|
indices.push_back((y + 1) * (kXSegments + 1) + x);
|
||||||
|
indices.push_back(y * (kXSegments + 1) + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oddRow = !oddRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mesh = std::make_unique<Mesh>(gl, vertices, indices);
|
||||||
|
mesh->drawMode = GL_TRIANGLE_STRIP;
|
||||||
|
mesh->baseColor = baseColor;
|
||||||
|
mesh->metallicRoughness = metallicRoughness;
|
||||||
|
sphere.meshes.emplace_back(std::move(mesh));
|
||||||
|
|
||||||
|
return sphere;
|
||||||
|
}
|
||||||
|
|
||||||
|
Model::Model(GladGLContext* gl)
|
||||||
: gl(gl)
|
: gl(gl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Model::Model(GladGLContext* gl, std::string const& path)
|
||||||
|
: Model(gl)
|
||||||
{
|
{
|
||||||
loadModel(path);
|
loadModel(path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ public:
|
||||||
std::map<std::string, BoneInfo> boneInfoMap;
|
std::map<std::string, BoneInfo> boneInfoMap;
|
||||||
int boneCount = 0;
|
int boneCount = 0;
|
||||||
|
|
||||||
|
static Model createSphere(GladGLContext* gl, const glm::vec3& baseColor = glm::vec3(0.5, 0, 0), const glm::vec2& metallicRoughness = glm::vec2(0, 0.5));
|
||||||
|
Model(GladGLContext* gl);
|
||||||
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);
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "Particle.h"
|
||||||
|
|
||||||
|
Particle::Particle(float mass)
|
||||||
|
: Actor()
|
||||||
|
, mass(mass)
|
||||||
|
{
|
||||||
|
model = Model::createSphere(gl);
|
||||||
|
setScale(glm::vec3(0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Particle::logicalTick(float deltaTime)
|
||||||
|
{
|
||||||
|
auto pos = getPosition() + speed * deltaTime + 0.5f * resultantForce / mass * deltaTime * deltaTime;
|
||||||
|
speed += resultantForce / mass * deltaTime;
|
||||||
|
if (speed.y < 0 && pos.y < 0.5)
|
||||||
|
{
|
||||||
|
speed.y = -speed.y;
|
||||||
|
}
|
||||||
|
setPosition(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Particle::addForce(glm::vec3 force)
|
||||||
|
{
|
||||||
|
forces.push_back(force);
|
||||||
|
resultantForce += force;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Particle::getMass()
|
||||||
|
{
|
||||||
|
return mass;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Actor.h"
|
||||||
|
|
||||||
|
class Particle : public Actor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Particle(float mass);
|
||||||
|
virtual ~Particle() = default;
|
||||||
|
virtual void logicalTick(float deltaTime);
|
||||||
|
void addForce(glm::vec3 force);
|
||||||
|
float getMass();
|
||||||
|
private:
|
||||||
|
float mass;
|
||||||
|
glm::vec3 speed = glm::vec3(0.f);
|
||||||
|
std::vector<glm::vec3> forces;
|
||||||
|
glm::vec3 resultantForce = glm::vec3(0);
|
||||||
|
};
|
||||||
|
|
|
@ -73,7 +73,7 @@ void GeometryPass::dispatch()
|
||||||
glm::mat4 trans = glm::mat4(1.0f);
|
glm::mat4 trans = glm::mat4(1.0f);
|
||||||
trans = glm::translate(trans, glm::vec3(
|
trans = glm::translate(trans, glm::vec3(
|
||||||
(float)(col - (nrColumns / 2)) * spacing,
|
(float)(col - (nrColumns / 2)) * spacing,
|
||||||
(float)(row - (nrRows / 2)) * spacing,
|
(float)(row - (nrRows / 2)) * spacing + 5,
|
||||||
-2.0f
|
-2.0f
|
||||||
));
|
));
|
||||||
plainShader.setUniformValue("model", trans);
|
plainShader.setUniformValue("model", trans);
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
|
||||||
void World::tick(float deltaTime)
|
void World::logicalTick(float deltaTime)
|
||||||
{
|
{
|
||||||
for (auto& actor : actors)
|
for (auto& actor : actors)
|
||||||
actor->tick(deltaTime);
|
actor->logicalTick(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::rendererTick(float deltaTime)
|
||||||
|
{
|
||||||
|
for (auto& actor : actors)
|
||||||
|
actor->rendererTick(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::draw(Shader& shader)
|
void World::draw(Shader& shader)
|
||||||
|
|
|
@ -5,7 +5,8 @@ class World
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<std::shared_ptr<Actor>> actors;
|
std::vector<std::shared_ptr<Actor>> actors;
|
||||||
void tick(float deltaTime);
|
virtual void logicalTick(float deltaTime);
|
||||||
|
virtual void rendererTick(float deltaTime);
|
||||||
void draw(Shader& shader);
|
void draw(Shader& shader);
|
||||||
void addActor(std::shared_ptr<Actor> actor);
|
void addActor(std::shared_ptr<Actor> actor);
|
||||||
std::pair<glm::vec3, glm::vec3> getAABB();
|
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||||
|
|
Loading…
Reference in New Issue