parent
c5f8ce41c7
commit
c5b8729ed6
|
@ -101,6 +101,7 @@ const int pcfRadius = 3;
|
|||
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;
|
||||
normalBias = max(normalBias, 0.05);
|
||||
vec4 fragPosLightSpace = lightSpaceMatrices[layer] * vec4(fragPosWorldSpace+normal*normalBias, 1.0);
|
||||
// perform perspective divide
|
||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
|
|
|
@ -24,11 +24,13 @@
|
|||
<ClInclude Include="src\Animator.h" />
|
||||
<ClInclude Include="src\Bone.h" />
|
||||
<ClInclude Include="src\Camera.h" />
|
||||
<ClInclude Include="src\DemoWorld.h" />
|
||||
<ClInclude Include="src\IblUtils.h" />
|
||||
<ClInclude Include="src\Light.h" />
|
||||
<ClInclude Include="src\MainWindow.h" />
|
||||
<ClInclude Include="src\Mesh.h" />
|
||||
<ClInclude Include="src\Model.h" />
|
||||
<ClInclude Include="src\Particle.h" />
|
||||
<ClInclude Include="src\RenderPass.h" />
|
||||
<ClInclude Include="src\Shader.h" />
|
||||
<ClInclude Include="src\World.h" />
|
||||
|
@ -39,6 +41,7 @@
|
|||
<ClCompile Include="src\Animator.cpp" />
|
||||
<ClCompile Include="src\Bone.cpp" />
|
||||
<ClCompile Include="src\Camera.cpp" />
|
||||
<ClCompile Include="src\DemoWorld.cpp" />
|
||||
<ClCompile Include="src\gl.c" />
|
||||
<ClCompile Include="src\IblUtils.cpp" />
|
||||
<ClCompile Include="src\Light.cpp" />
|
||||
|
@ -46,6 +49,7 @@
|
|||
<ClCompile Include="src\MainWindow.cpp" />
|
||||
<ClCompile Include="src\Mesh.cpp" />
|
||||
<ClCompile Include="src\Model.cpp" />
|
||||
<ClCompile Include="src\Particle.cpp" />
|
||||
<ClCompile Include="src\RenderPass.cpp" />
|
||||
<ClCompile Include="src\World.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -163,6 +167,9 @@
|
|||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -57,6 +57,12 @@
|
|||
<ClInclude Include="src\World.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Particle.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\DemoWorld.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\gl.c">
|
||||
|
@ -101,6 +107,12 @@
|
|||
<ClCompile Include="src\World.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Particle.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\DemoWorld.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Shaders\brdf_lut.comp">
|
||||
|
|
|
@ -1,17 +1,29 @@
|
|||
#include "Actor.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
Actor::Actor()
|
||||
: gl(MainWindow::getGLContext())
|
||||
, model(gl)
|
||||
, animator(gl, animation.get())
|
||||
{
|
||||
}
|
||||
|
||||
Actor::Actor(const std::string& path)
|
||||
: gl(MainWindow::getGLContext())
|
||||
, model(gl, path)
|
||||
, danceAnimation(path, &model)
|
||||
, animator(gl, &danceAnimation)
|
||||
, animation(std::make_unique<Animation>(path, &model))
|
||||
, 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)
|
||||
|
@ -39,6 +51,21 @@ void Actor::setRotaion(const glm::quat& rotation)
|
|||
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()
|
||||
{
|
||||
return model.getAABB();
|
||||
|
|
|
@ -7,21 +7,32 @@
|
|||
class Actor
|
||||
{
|
||||
public:
|
||||
Actor();
|
||||
Actor(const std::string& path);
|
||||
void tick(float deltaTime);
|
||||
void draw(Shader& shader);
|
||||
virtual ~Actor() = default;
|
||||
virtual void logicalTick(float deltaTime);
|
||||
virtual void rendererTick(float deltaTime);
|
||||
virtual void draw(Shader& shader);
|
||||
|
||||
void setPosition(const glm::vec3& position);
|
||||
void setScale(const glm::vec3& scale);
|
||||
void setRotaion(const glm::quat& rotation);
|
||||
|
||||
glm::vec3 getPosition();
|
||||
glm::vec3 getScale();
|
||||
glm::quat getRotation();
|
||||
|
||||
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||
|
||||
protected:
|
||||
GladGLContext* gl;
|
||||
Model model;
|
||||
std::unique_ptr<Animation> animation;
|
||||
Animator animator;
|
||||
|
||||
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);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "Bone.h"
|
||||
#include "Model.h"
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
struct AssimpNodeData
|
||||
{
|
||||
|
@ -41,16 +42,16 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
bool available()
|
||||
{
|
||||
return m_TicksPerSecond;
|
||||
}
|
||||
|
||||
Bone* FindBone(const std::string& name)
|
||||
{
|
||||
auto iter = std::find_if(m_Bones.begin(), m_Bones.end(),
|
||||
[&](const Bone& Bone)
|
||||
{
|
||||
return Bone.GetBoneName() == name;
|
||||
}
|
||||
);
|
||||
auto iter = m_Bones.find(name);
|
||||
if (iter == m_Bones.end()) return nullptr;
|
||||
else return &(*iter);
|
||||
else return &iter->second;
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,7 +82,8 @@ private:
|
|||
boneInfoMap[boneName].id = 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));
|
||||
}
|
||||
|
||||
|
@ -103,9 +105,11 @@ private:
|
|||
dest.children.push_back(newData);
|
||||
}
|
||||
}
|
||||
float m_Duration;
|
||||
int m_TicksPerSecond;
|
||||
std::vector<Bone> m_Bones;
|
||||
float m_Duration = 0.f;
|
||||
int m_TicksPerSecond = 0;
|
||||
std::unordered_map<std::string, Bone> m_Bones;
|
||||
|
||||
//std::set<Bone> m_Bones;
|
||||
AssimpNodeData m_RootNode;
|
||||
std::map<std::string, BoneInfo> m_BoneInfoMap;
|
||||
};
|
||||
|
|
|
@ -11,37 +11,43 @@ class Animator
|
|||
public:
|
||||
static constexpr GLint kMaxBone = 100;
|
||||
|
||||
Animator(GladGLContext* gl, Animation* animation) : gl(gl)
|
||||
Animator(GladGLContext* gl, Animation* animation)
|
||||
: gl(gl)
|
||||
{
|
||||
currentTime = 0.0;
|
||||
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);
|
||||
playAnimation(animation);
|
||||
}
|
||||
|
||||
void UpdateAnimation(float deltaTime)
|
||||
void updateAnimation(float deltaTime)
|
||||
{
|
||||
if (currentAnimation)
|
||||
{
|
||||
currentTime += currentAnimation->GetTicksPerSecond() * deltaTime;
|
||||
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;
|
||||
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;
|
||||
glm::mat4 nodeTransform = node->transformation;
|
||||
|
@ -56,33 +62,33 @@ public:
|
|||
|
||||
glm::mat4 globalTransformation = parentTransform * nodeTransform;
|
||||
|
||||
auto boneInfoMap = currentAnimation->GetBoneIDMap();
|
||||
if (boneInfoMap.find(nodeName) != boneInfoMap.end())
|
||||
auto& boneInfoMap = currentAnimation->GetBoneIDMap();
|
||||
if (auto iter = boneInfoMap.find(nodeName); iter != boneInfoMap.end())
|
||||
{
|
||||
int index = boneInfoMap[nodeName].id;
|
||||
glm::mat4 offset = boneInfoMap[nodeName].offset;
|
||||
auto& [index, offset] = iter->second;
|
||||
finalBoneMatrices[index] = globalTransformation * offset;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
GLuint getFinalBonesMatricesUBO()
|
||||
{
|
||||
gl->NamedBufferSubData(finalBonesMatricesUBO, 0, finalBoneMatrices.size() * sizeof(finalBoneMatrices[0]), finalBoneMatrices.data());
|
||||
if (finalBonesMatricesUBO)
|
||||
gl->NamedBufferSubData(finalBonesMatricesUBO, 0, finalBoneMatrices.size() * sizeof(finalBoneMatrices[0]), finalBoneMatrices.data());
|
||||
return finalBonesMatricesUBO;
|
||||
}
|
||||
|
||||
private:
|
||||
GladGLContext* gl;
|
||||
std::vector<glm::mat4> finalBoneMatrices;
|
||||
GLuint finalBonesMatricesUBO;
|
||||
Animation* currentAnimation;
|
||||
GLuint finalBonesMatricesUBO = 0;
|
||||
Animation* currentAnimation = nullptr;
|
||||
float currentTime;
|
||||
};
|
||||
|
|
|
@ -114,6 +114,10 @@ public:
|
|||
assert(0);
|
||||
}
|
||||
|
||||
bool operator<(const Bone& e) const
|
||||
{
|
||||
return m_ID < e.m_ID;
|
||||
}
|
||||
|
||||
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 "RenderPass.h"
|
||||
#include "World.h"
|
||||
#include "Particle.h"
|
||||
#include "DemoWorld.h"
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: camera(glm::vec3(0.0f, 0.0f, 3.0f))
|
||||
|
@ -50,39 +52,18 @@ int MainWindow::exec()
|
|||
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 = "Models/vampire/vampire.gltf";
|
||||
//modelFilePath = "E:\\3D Objects\\cup\\cup.gltf";
|
||||
//modelFilePath = "E:\\3D Objects\\Sponza\\Sponza.gltf";
|
||||
std::unique_ptr<World> world = std::make_unique<DemoWorld>();
|
||||
|
||||
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));
|
||||
World world;
|
||||
world.addActor(actor);
|
||||
world.addActor(actor2);
|
||||
world.addActor(actor3);
|
||||
world.addActor(sponza);
|
||||
|
||||
auto [minPos, maxPos] = world.getAABB();
|
||||
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();
|
||||
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);
|
||||
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);
|
||||
|
@ -92,14 +73,35 @@ int MainWindow::exec()
|
|||
glfwGetFramebufferSize(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))
|
||||
{
|
||||
float currentFrame = glfwGetTime();
|
||||
deltaTime = currentFrame - lastFrame;
|
||||
float deltaTime = currentFrame - lastFrame;
|
||||
lastFrame = currentFrame;
|
||||
processInput(window);
|
||||
|
||||
world.tick(deltaTime);
|
||||
world->rendererTick(deltaTime);
|
||||
|
||||
projection = camera.getProjectionMatrix();
|
||||
view = camera.getViewMatrix();
|
||||
|
@ -112,11 +114,24 @@ int MainWindow::exec()
|
|||
|
||||
glfwSwapBuffers(window);
|
||||
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();
|
||||
}
|
||||
void MainWindow::processInput(GLFWwindow* window)
|
||||
|
||||
void MainWindow::processInput(GLFWwindow* window, float deltaTime)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
|
|
|
@ -18,7 +18,7 @@ private:
|
|||
void framebufferSizeCallback(GLFWwindow* window, int width, int height);
|
||||
void mouseCallback(GLFWwindow* window, double xpos, double ypos);
|
||||
void scrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
void processInput(GLFWwindow* window);
|
||||
void processInput(GLFWwindow* window, float deltaTime);
|
||||
|
||||
static constexpr int kWindowWidth = 1200;
|
||||
static constexpr int kWindowHeight = 675;
|
||||
|
@ -27,11 +27,8 @@ private:
|
|||
|
||||
Camera camera;
|
||||
Light light;
|
||||
glm::vec3 mainLightRadiance = 40.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784));
|
||||
float exposure = 1;
|
||||
|
||||
float deltaTime = 0.0f;
|
||||
float lastFrame = 0.0f;
|
||||
glm::vec3 mainLightRadiance = 30.f * glm::normalize(glm::vec3(0.7529, 0.7450, 0.6784));
|
||||
float exposure = 0.6f;
|
||||
|
||||
std::unique_ptr<GladGLContext> gl;
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "Mesh.h"
|
||||
|
||||
Vertex::Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVector3D& texCoords)
|
||||
: position(position.x, position.y, position.z)
|
||||
, normal(normal.x, normal.y, normal.z)
|
||||
, texCoords(texCoords.x, texCoords.y)
|
||||
Vertex::Vertex(const glm::vec3& position, const glm::vec3& normal, const glm::vec2& texCoords)
|
||||
: position(position)
|
||||
, normal(normal)
|
||||
, texCoords(texCoords)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (weight == 0) return;
|
||||
|
@ -43,29 +48,12 @@ void Mesh::draw(Shader& shader)
|
|||
shader.setUniformValue("baseColor", baseColor);
|
||||
shader.setUniformValue("metallicRoughness", metallicRoughness);
|
||||
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);
|
||||
}
|
||||
|
||||
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->GenBuffers(1, &VBO);
|
||||
gl->GenBuffers(1, &EBO);
|
||||
|
@ -76,7 +64,6 @@ void Mesh::setupMesh()
|
|||
gl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
gl->BufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||
|
||||
|
||||
enum VertexAttribute : GLuint {
|
||||
kPosition = 0, kNormal = 1, kTexCoords = 2, kBoneIDs = 3, kBoneWeights = 4
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ struct Vertex {
|
|||
int boneIDs[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);
|
||||
void setBoneData(int boneID, float weight);
|
||||
};
|
||||
|
@ -25,6 +26,7 @@ public:
|
|||
glm::mat4 model;
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
GLenum drawMode = GL_TRIANGLES;
|
||||
GLuint textureBasecolor = 0;
|
||||
GLuint textureMetallicRoughness = 0;
|
||||
GLuint textureNormal = 0;
|
||||
|
@ -32,12 +34,10 @@ public:
|
|||
glm::vec2 metallicRoughness;
|
||||
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 setupMesh();
|
||||
private:
|
||||
GladGLContext* gl;
|
||||
unsigned int VBO, EBO;
|
||||
|
||||
|
||||
};
|
|
@ -1,13 +1,76 @@
|
|||
#include "Model.h"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/ext/scalar_constants.hpp>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#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)
|
||||
{
|
||||
}
|
||||
|
||||
Model::Model(GladGLContext* gl, std::string const& path)
|
||||
: Model(gl)
|
||||
{
|
||||
loadModel(path);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ public:
|
|||
std::map<std::string, BoneInfo> boneInfoMap;
|
||||
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);
|
||||
void draw(Shader& shader);
|
||||
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);
|
||||
trans = glm::translate(trans, glm::vec3(
|
||||
(float)(col - (nrColumns / 2)) * spacing,
|
||||
(float)(row - (nrRows / 2)) * spacing,
|
||||
(float)(row - (nrRows / 2)) * spacing + 5,
|
||||
-2.0f
|
||||
));
|
||||
plainShader.setUniformValue("model", trans);
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
#include "World.h"
|
||||
|
||||
void World::tick(float deltaTime)
|
||||
void World::logicalTick(float deltaTime)
|
||||
{
|
||||
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)
|
||||
|
@ -28,4 +34,4 @@ std::pair<glm::vec3, glm::vec3> World::getAABB()
|
|||
maxPos = glm::max(maxPos, max);
|
||||
}
|
||||
return { minPos, maxPos };
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@ class World
|
|||
{
|
||||
public:
|
||||
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 addActor(std::shared_ptr<Actor> actor);
|
||||
std::pair<glm::vec3, glm::vec3> getAABB();
|
||||
|
|
Loading…
Reference in New Issue