Merge remote-tracking branch 'origin/master' into BoxModelCollision

This commit is contained in:
William Moberg
2016-03-10 09:57:33 +01:00
58 changed files with 15950 additions and 288 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid);
const std::string EntityWrapper::Name()
const std::string EntityWrapper::Name() const
{
return World->GetName(ID);
}
+6 -6
View File
@@ -24,7 +24,7 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
while (entity != EntityID_Invalid) {
ComponentWrapper transform = world->GetComponent(entity, "Transform");
EntityID parent = world->GetParent(entity);
position += Transform::AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"];
position += Transform::AbsoluteScale(world, parent) * (Transform::AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"]);
entity = parent;
}
@@ -89,12 +89,12 @@ glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
{
return AbsoluteTransformation(EntityWrapper(world, entity));
glm::vec3 position = Transform::AbsolutePosition(world, entity);
glm::quat orientation = Transform::AbsoluteOrientation(world, entity);
glm::vec3 scale = Transform::AbsoluteScale(world, entity);
//glm::vec3 position = Transform::AbsolutePosition(world, entity);
//glm::quat orientation = Transform::AbsoluteOrientation(world, entity);
//glm::vec3 scale = Transform::AbsoluteScale(world, entity);
glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale);
return modelMatrix;
//glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale);
//return modelMatrix;
}
glm::vec3 Transform::TransformPoint(const glm::vec3& point, const glm::mat4& matrix)
+2 -2
View File
@@ -7,7 +7,7 @@ EditorRenderSystem::EditorRenderSystem(SystemParams params, IRenderer* renderer,
{
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorRenderSystem::OnSetCamera);
auto resolution = Rectangle::Rectangle(1280, 720);
m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 5000.f);
m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.001f, 500.f);
}
void EditorRenderSystem::Update(double dt)
@@ -54,7 +54,7 @@ void EditorRenderSystem::Update(double dt)
EntityWrapper entity(m_World, cModel.EntityID);
glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World);
for (auto matGroup : model->MaterialGroups()) {
std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f, false);
std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f, false, false);
if (cModel["Transparent"]) {
scene.Jobs.TransparentObjects.push_back(modelJob);
} else {
+9 -2
View File
@@ -204,14 +204,21 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
if (m_CurrentSelection.Valid()) {
if (m_WidgetSpace == EditorGUI::WidgetSpace::Global) {
glm::quat parentOrientation;
glm::vec3 parentScale(1.f);
EntityWrapper parent = m_CurrentSelection.Parent();
if (parent.Valid()) {
parentOrientation = glm::inverse(Transform::AbsoluteOrientation(parent));
parentScale = Transform::AbsoluteScale(parent);
}
(glm::vec3&)m_CurrentSelection["Transform"]["Position"] += parentOrientation * e.Translation;
(glm::vec3&)m_CurrentSelection["Transform"]["Position"] += parentOrientation * e.Translation / parentScale;
} else if (m_WidgetSpace == EditorGUI::WidgetSpace::Local) {
glm::vec3 parentScale(1.f);
EntityWrapper parent = m_CurrentSelection.Parent();
if (parent.Valid()) {
parentScale = Transform::AbsoluteScale(parent);
}
glm::quat selectionOri = glm::quat((glm::vec3)m_CurrentSelection["Transform"]["Orientation"]);
glm::vec3 localTranslation = selectionOri * e.Translation;
glm::vec3 localTranslation = selectionOri * e.Translation / parentScale;
(glm::vec3&)m_CurrentSelection["Transform"]["Position"] += localTranslation;
}
m_EditorGUI->SetDirty(m_CurrentSelection);
+164 -38
View File
@@ -4,6 +4,8 @@ AnimationSystem::AnimationSystem(SystemParams params)
: System(params)
{
EVENT_SUBSCRIBE_MEMBER(m_EAutoAnimationBlend, &AnimationSystem::OnAutoAnimationBlend);
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &AnimationSystem::OnEntityDeleted);
EVENT_SUBSCRIBE_MEMBER(m_ESetBlendWeight, &AnimationSystem::OnSetBlendWeight);
}
void AnimationSystem::Update(double dt)
@@ -122,16 +124,16 @@ void AnimationSystem::UpdateAnimations(double dt)
}
}
void AnimationSystem::UpdateWeights(double dt)
{
for (auto& autoBlendQueue : m_AutoBlendQueues) {
if(autoBlendQueue.second.HasActiveBlendJob()) {
AutoBlendQueue::AutoBlendJob& blendJob = autoBlendQueue.second.GetActiveBlendJob();
std::shared_ptr<BlendTree> blendTree = autoBlendQueue.second.GetBlendTree();
for (auto it = m_AutoBlendQueues.begin(); it != m_AutoBlendQueues.end(); ) {
LOG_INFO("%s", it->first.Name().c_str());
it->second.PrintQueue();
if(it->second.HasActiveBlendJob()) {
AutoBlendQueue::AutoBlendJob& blendJob = it->second.GetActiveBlendJob();
LOG_INFO("%s", blendJob.RootNode.Name().c_str());
std::shared_ptr<BlendTree> blendTree = it->second.GetBlendTree();
if (blendTree != nullptr) {
if (blendJob.Duration != 0.0) {
blendJob.BlendInfo.progress = glm::clamp(blendJob.CurrentTime / blendJob.Duration, 0.0, 1.0);
@@ -140,10 +142,17 @@ void AnimationSystem::UpdateWeights(double dt)
}
blendJob.BlendInfo = blendTree->AutoBlendStep(blendJob.BlendInfo);
} else {
it = m_AutoBlendQueues.erase(it);
}
it++;
} else {
if (it->second.Empty()) {
it = m_AutoBlendQueues.erase(it);
} else {
it++;
}
}
}
}
@@ -177,46 +186,163 @@ bool AnimationSystem::OnAutoAnimationBlend(Events::AutoAnimationBlend& e)
return false;
}
EntityWrapper subTreeRoot;
EntityWrapper subTreeRoot = blendTree->GetSubTreeRoot(e.NodeName);
if (e.SingleLevelBlend) {
subTreeRoot = blendTree->GetSubTreeRoot(e.NodeName);
if (!subTreeRoot.Valid()) {
return false;
}
if (!subTreeRoot.Valid()) {
return false;
}
AutoBlendQueue::AutoBlendJob abj;
abj.AnimationEntity = e.AnimationEntity;
abj.CurrentTime = 0.0;
abj.Delay = e.Delay;
abj.Duration = e.Duration;
abj.RootNode = e.RootNode;
AutoBlendQueue::AutoBlendJob abj;
abj.AnimationEntity = e.AnimationEntity;
abj.CurrentTime = 0.0;
abj.Delay = e.Delay;
abj.Duration = e.Duration;
abj.RootNode = e.RootNode;
abj.BlendInfo.NodeName = e.NodeName;
abj.BlendInfo.progress = 0.0;
abj.BlendInfo.Start = e.Start;
abj.BlendInfo.SingleBlend = e.SingleLevelBlend;
abj.BlendInfo.Weight = e.Weight;
abj.BlendInfo.NodeName = e.NodeName;
abj.BlendInfo.progress = 0.0;
abj.BlendInfo.Start = e.Start;
abj.BlendInfo.SingleBlend = e.SingleLevelBlend;
abj.BlendInfo.Weight = e.Weight;
EntityWrapper nodeEntity = subTreeRoot.FirstChildByName(e.NodeName); // more than one
if (nodeEntity.Valid()) {
if (nodeEntity.HasComponent("Animation")) {
const Skeleton::Animation* animation = skeleton->GetAnimation(nodeEntity["Animation"]["AnimationName"]);
(bool&)nodeEntity["Animation"]["Reverse"] = e.Reverse;
std::vector<EntityWrapper> animationEntities = blendTree->GetEntitesByName(e.NodeName); // more than one
for(auto entity : animationEntities)
if (entity.Valid()) {
if (entity.HasComponent("Animation")) {
const Skeleton::Animation* animation = skeleton->GetAnimation(entity["Animation"]["AnimationName"]);
(bool&)entity["Animation"]["Reverse"] = e.Reverse;
if (e.Restart) {
if (animation != nullptr) {
if (e.Restart) {
if (e.Reverse) {
(double&)nodeEntity["Animation"]["Time"] = animation->Duration;
} else {
(double&)nodeEntity["Animation"]["Time"] = 0.0;
if (e.Restart) {
if (animation != nullptr) {
if (e.Restart) {
if (e.Reverse) {
(double&)entity["Animation"]["Time"] = animation->Duration;
} else {
(double&)entity["Animation"]["Time"] = 0.0;
}
}
}
}
}
}
m_AutoBlendQueues[subTreeRoot].Insert(abj);
} else {
std::vector<EntityWrapper> subtreeroots = blendTree->GetSingleLevelRoots(e.NodeName);
for(auto entity : subtreeroots) {
subTreeRoot = entity;
if (!subTreeRoot.Valid()) {
return false;
}
AutoBlendQueue::AutoBlendJob abj;
abj.AnimationEntity = e.AnimationEntity;
abj.CurrentTime = 0.0;
abj.Delay = e.Delay;
abj.Duration = e.Duration;
abj.RootNode = e.RootNode;
abj.BlendInfo.NodeName = e.NodeName;
abj.BlendInfo.progress = 0.0;
abj.BlendInfo.Start = e.Start;
abj.BlendInfo.SingleBlend = e.SingleLevelBlend;
abj.BlendInfo.Weight = e.Weight;
m_AutoBlendQueues[subTreeRoot].Insert(abj);
}
std::vector<EntityWrapper> animationEntities = blendTree->GetEntitesByName(e.NodeName); // more than one
for (auto entity : animationEntities)
if (entity.Valid()) {
if (entity.HasComponent("Animation")) {
const Skeleton::Animation* animation = skeleton->GetAnimation(entity["Animation"]["AnimationName"]);
(bool&)entity["Animation"]["Reverse"] = e.Reverse;
if (e.Restart) {
if (animation != nullptr) {
if (e.Restart) {
if (e.Reverse) {
(double&)entity["Animation"]["Time"] = animation->Duration;
} else {
(double&)entity["Animation"]["Time"] = 0.0;
}
}
}
}
}
}
}
m_AutoBlendQueues[subTreeRoot].Insert(abj);
return true;
}
bool AnimationSystem::OnEntityDeleted(Events::EntityDeleted& e)
{
EntityWrapper entity = EntityWrapper(m_World, e.DeletedEntity);
if (entity.HasComponent("Model")) {
Model* model;
try {
model = ResourceManager::Load<::Model, true>(entity["Model"]["Resource"]);
} catch (const std::exception&) {
return false;
}
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
if (skeleton == nullptr) {
return false;
}
if (skeleton->BlendTrees.find(entity) != skeleton->BlendTrees.end()) {
skeleton->BlendTrees.erase(entity);
}
}
}
bool AnimationSystem::OnSetBlendWeight(Events::SetBlendWeight& e)
{
if (!e.RootNode.Valid()) {
return false;
}
if (!e.RootNode.HasComponent("Model")) {
return false;
}
Model* model;
try {
model = ResourceManager::Load<::Model, true>((std::string)e.RootNode["Model"]["Resource"]);
} catch (const std::exception&) {
return false;
}
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
if (skeleton == nullptr) {
return false;
}
std::shared_ptr<BlendTree> blendTree;
if (skeleton->BlendTrees.find(e.RootNode) != skeleton->BlendTrees.end()) {
blendTree = skeleton->BlendTrees.at(e.RootNode);
} else {
return false;
}
if(e.Weight >= 0 && e.Weight <= 1) {
blendTree->SetWeightByName(e.NodeName, e.Weight);
return true;
} else {
return false;
}
}
+8 -6
View File
@@ -38,11 +38,14 @@ void AutoBlendQueue::Insert(AutoBlendJob autoBlendJob)
double animationSpeed = (double)autoBlendJob.AnimationEntity["Animation"]["Speed"];
double animationTime = (double)autoBlendJob.AnimationEntity["Animation"]["Time"];
if ((bool)autoBlendJob.AnimationEntity["Animation"]["Reverse"]) {
AnimationDuration = (animation->Duration * animationSpeed) - (animation->Duration - animationTime);
if (animationSpeed != 0) {
if ((bool)autoBlendJob.AnimationEntity["Animation"]["Reverse"]) {
AnimationDuration = (animation->Duration / animationSpeed) - (animation->Duration - animationTime);
} else {
AnimationDuration = (animation->Duration / animationSpeed) - animationTime;
}
} else {
AnimationDuration = (animation->Duration * animationSpeed) - animationTime;
return;
}
blendNode.StartTime += AnimationDuration;
@@ -75,7 +78,6 @@ void AutoBlendQueue::Insert(AutoBlendJob autoBlendJob)
}
}
m_BlendQueue.clear();
m_BlendQueue.push_back(blendNode);
}
@@ -124,7 +126,7 @@ bool AutoBlendQueue::HasActiveBlendJob()
try {
model = ResourceManager::Load<::Model, true>(blendJob.RootNode["Model"]["Resource"]);
} catch (const std::exception&) {
m_BlendQueue.pop_front();
//m_BlendQueue.pop_front();
return HasActiveBlendJob();
}
+53 -6
View File
@@ -2,11 +2,8 @@
BlendTree::BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton)
{
m_Skeleton = skeleton;
if (ModelEntity.HasComponent("Animation")) {
const Skeleton::Animation* animation = skeleton->GetAnimation(ModelEntity["Animation"]["AnimationName"]);
if (animation == nullptr) {
@@ -217,7 +214,6 @@ BlendTree::AutoBlendInfo BlendTree::AutoBlendStep(AutoBlendInfo blendInfo)
}
}
}
return blendInfo;
}
@@ -270,7 +266,7 @@ BlendTree::AutoBlendInfo BlendTree::AutoBlendStep(AutoBlendInfo blendInfo)
currentNode = currentNode->Parent;
if (blendInfo.SingleBlend) {
break;
return blendInfo;;
}
}
} else if(goalNodes.size() >= 2) {
@@ -331,9 +327,11 @@ BlendTree::AutoBlendInfo BlendTree::AutoBlendStep(AutoBlendInfo blendInfo)
lastNode = currentNode;
currentNode = currentNode->Parent;
if (blendInfo.SingleBlend) {
return blendInfo;
}
}
}
}
return blendInfo;
@@ -427,6 +425,55 @@ EntityWrapper BlendTree::GetSubTreeRoot(std::string nodeName)
return subTreeRoots.front()->Entity;
}
std::vector<EntityWrapper> BlendTree::GetSingleLevelRoots(std::string name)
{
std::vector<Node*> nodes = FindNodesByName(name);
std::vector<EntityWrapper> entities;
for (auto it = nodes.begin(); it != nodes.end(); it++) {
Node* currentNode = (*it)->Parent;
if(currentNode->Entity.Valid()) {
entities.push_back(currentNode->Entity);
}
}
return entities;
}
std::vector<EntityWrapper> BlendTree::GetEntitesByName(std::string name)
{
std::vector<Node*> nodes = FindNodesByName(name);
std::vector<EntityWrapper> entities;
for (auto it = nodes.begin(); it != nodes.end(); it++) {
Node* currentNode = (*it);
if (currentNode->Entity.Valid()) {
entities.push_back(currentNode->Entity);
}
}
return entities;
}
void BlendTree::SetWeightByName(std::string name, double weight)
{
std::vector<Node*> nodes = FindNodesByName(name);
for (auto node : nodes) {
EntityWrapper entity = node->Entity;
if(entity.HasComponent("Blend")) {
entity["Blend"]["Weight"] = weight;
node->Weight = weight;
}
}
}
void BlendTree::Blend(std::map<int, Skeleton::PoseData>& pose)
{
Node* currentNode;
+17 -2
View File
@@ -1,9 +1,10 @@
#include "Rendering/DrawFinalPass.h"
DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass, SSAOPass* ssaoPass)
DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass, SSAOPass* ssaoPass, ShadowPass* shadowPass)
: m_Renderer(renderer)
, m_LightCullingPass(lightCullingPass)
, m_CubeMapPass(cubeMapPass)
, m_SSAOPass(ssaoPass)
, m_ShadowPass(shadowPass)
{
//TODO: Make sure that uniforms are not sent into shader if not needed.
m_ShieldPixelRate = 8;
@@ -369,6 +370,13 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_SSAOPass->SSAOTexture());
glActiveTexture(GL_TEXTURE30);
if (m_ShadowPass->DepthMap() != NULL) {
glBindTexture(GL_TEXTURE_2D_ARRAY, m_ShadowPass->DepthMap());
} else {
glBindTexture(GL_TEXTURE_2D_ARRAY, m_WhiteTexture->m_Texture);
}
for (auto &job : jobs) {
auto explosionEffectJob = std::dynamic_pointer_cast<ExplosionEffectJob>(job);
if (explosionEffectJob) {
@@ -1339,6 +1347,10 @@ void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<E
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), job->FillPercentage);
GLERROR("Bind 19 uniform");
glUniform1f(glGetUniformLocation(shaderHandle, "GlowIntensity"), job->GlowIntensity);
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightP().data()));
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightV().data()));
glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->FarDistance().data());
GLERROR("END");
}
@@ -1366,8 +1378,11 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr<Model
GLint Location_Color = glGetUniformLocation(shaderHandle, "Color");
glUniform4fv(Location_Color, 1, glm::value_ptr(job->Color));
GLint Location_GlowIntensity = glGetUniformLocation(shaderHandle, "GlowIntensity");
glUniform1f(Location_GlowIntensity, job->GlowIntensity);
glUniform1f(Location_GlowIntensity, job->GlowIntensity);
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightP"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightP().data()));
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "LightV"), MAX_SPLITS, GL_FALSE, glm::value_ptr(*m_ShadowPass->LightV().data()));
glUniform1fv(glGetUniformLocation(shaderHandle, "FarDistance"), MAX_SPLITS, m_ShadowPass->FarDistance().data());
GLERROR("END");
}
+11 -1
View File
@@ -24,6 +24,13 @@ RenderBuffer::~RenderBuffer()
}
}
Texture2DArray::~Texture2DArray()
{
if (m_ResourceHandle != 0) {
glDeleteTextures(1, m_ResourceHandle);
}
}
FrameBuffer::~FrameBuffer()
{
@@ -53,12 +60,15 @@ void FrameBuffer::Generate()
case GL_TEXTURE_2D:
glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0);
GLERROR("FrameBuffer generate: glFramebufferTexture2D");
break;
case GL_RENDERBUFFER:
glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle);
GLERROR("FrameBuffer generate: glFramebufferRenderbuffer");
break;
case GL_TEXTURE_2D_ARRAY:
glFramebufferTexture(GL_FRAMEBUFFER, (*it)->m_Attachment, *(*it)->m_ResourceHandle, 0);
GLERROR("FrameBuffer generate: glFramebufferTexture2DArray");
break;
}
GLERROR("2");
+4 -2
View File
@@ -258,7 +258,8 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
m_World,
fillColor,
fillPercentage,
isShielded
isShielded,
false
));
if (m_World->HasComponent(cModel.EntityID, "Shield")){
explosionEffectJob->CalculateHash();
@@ -296,7 +297,8 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
m_World,
fillColor,
fillPercentage,
isShielded
isShielded,
(bool)cModel["Shadow"]
));
if (m_World->HasComponent(cModel.EntityID, "Shield")) {
modelJob->CalculateHash();
+7 -1
View File
@@ -146,7 +146,9 @@ void Renderer::Draw(RenderFrame& frame)
m_DrawFinalPass->ClearBuffer();
m_DrawBloomPass->ClearBuffer();
m_SSAOPass->ClearBuffer();
m_ShadowPass->ClearBuffer();
m_BlurHUDPass->ClearBuffer();
m_ShadowPass->DebugGUI();
PerformanceTimer::StopTimer("Renderer-ClearBuffers");
GLERROR("ClearBuffers");
for (auto scene : frame.RenderScenes) {
@@ -162,6 +164,9 @@ void Renderer::Draw(RenderFrame& frame)
PerformanceTimer::StartTimer("Renderer-Depth");
SortRenderJobsByDepth(*scene);
GLERROR("SortByDepth");
PerformanceTimer::StartTimerAndStopPrevious("Draw shadow maps");
m_ShadowPass->Draw(*scene);
GLERROR("Draw shadow maps");
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums");
m_LightCullingPass->GenerateNewFrustum(*scene);
GLERROR("Generate frustums");
@@ -264,8 +269,9 @@ void Renderer::InitializeRenderPasses()
m_LightCullingPass = new LightCullingPass(this);
m_CubeMapPass = new CubeMapPass(this);
m_SSAOPass = new SSAOPass(this, m_Config);
m_ShadowPass = new ShadowPass(this);
m_BlurHUDPass = new BlurHUD(this);
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass, m_SSAOPass);
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass, m_SSAOPass, m_ShadowPass);
m_DrawScreenQuadPass = new DrawScreenQuadPass(this);
m_DrawBloomPass = new DrawBloomPass(this, m_Config);
m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this);
+313
View File
@@ -0,0 +1,313 @@
#include "Rendering/ShadowPass.h"
ShadowPass::ShadowPass(IRenderer * renderer, int shadow_res_x, int shadow_res_y)
{
m_Renderer = renderer;
m_ResolutionSizeWidth = shadow_res_x;
m_ResolutionSizeHeight = shadow_res_y;
InitializeFrameBuffers();
InitializeShaderPrograms();
}
ShadowPass::ShadowPass(IRenderer * renderer)
{
m_Renderer = renderer;
InitializeFrameBuffers();
InitializeShaderPrograms();
}
ShadowPass::~ShadowPass()
{
}
void ShadowPass::DebugGUI()
{
ImGui::Checkbox("EnableShadows", &m_EnableShadows);
ImGui::DragFloat2("ShadowMapNearFar", m_NearFarPlane, 1.f, -1000.f, 1000.f);
ImGui::DragFloat("ShadowClippingWeight", &m_SplitWeight, 0.001f, 0.f, 1.f);
ImGui::Checkbox("ShadowTransparentObjects", &m_TransparentObjects);
ImGui::Checkbox("ShadowOnTextureAlphas", &m_TexturedShadows);
}
void ShadowPass::InitializeCameras(RenderScene & scene)
{
for (int i = 0; i < m_CurrentNrOfSplits; i++) {
m_shadowFrusta[i].AspectRatio = scene.Camera->AspectRatio();
m_shadowFrusta[i].FOV = scene.Camera->FOV();
}
}
// UpdateSplitDist computes the near and far distances for every frustum slice
// in camera eye space - that is, at what distance does a slice start and end
void ShadowPass::UpdateSplitDist(std::array<ShadowFrustum, MAX_SPLITS>& frusta, float near_distance, float far_distance)
{
float lambda = m_SplitWeight;
float ratio = far_distance / near_distance;
frusta[0].NearClip = near_distance;
for (int i = 1; i < m_CurrentNrOfSplits; i++) {
float si = i / static_cast<float>(m_CurrentNrOfSplits);
frusta[i].NearClip = lambda * (near_distance * powf(ratio, si)) + (1 - lambda) * (near_distance + (far_distance - near_distance) * si);
frusta[i - 1].FarClip = frusta[i].NearClip * 1.005f;
}
frusta[m_CurrentNrOfSplits - 1].FarClip = far_distance;
}
void ShadowPass::UpdateFrustumPoints(ShadowFrustum& frustum, glm::mat4 p, glm::mat4 v)
{
std::array<glm::vec4, 8> CornerPoint = {
glm::vec4(-1.f, -1.f, -1.f, 1.f),
glm::vec4(-1.f, 1.f, -1.f, 1.f),
glm::vec4(1.f, 1.f, -1.f, 1.f),
glm::vec4(1.f, -1.f, -1.f, 1.f),
glm::vec4(-1.f, -1.f, 1.f, 1.f),
glm::vec4(-1.f, 1.f, 1.f, 1.f),
glm::vec4(1.f, 1.f, 1.f, 1.f),
glm::vec4(1.f, -1.f, 1.f, 1.f)
};
for (int i = 0; i < 8; i++) {
glm::vec4 NDC = glm::inverse(p) * CornerPoint[i];
NDC = NDC / NDC.w;
frustum.CornerPoint[i] = glm::vec3(glm::inverse(v) * NDC);
}
}
// Compute the 8 corner points of the current view frustum in world space
void ShadowPass::UpdateFrustumPoints(ShadowFrustum& frustum, glm::vec3 camera_position, glm::vec3 view_dir)
{
glm::vec3 up = glm::vec3(0.f, 1.f, 0.f);
glm::vec3 right = glm::normalize(glm::cross(view_dir, up));
glm::vec3 far_center = camera_position + glm::normalize(view_dir) * frustum.FarClip;
glm::vec3 near_center = camera_position + glm::normalize(view_dir) * frustum.NearClip;
frustum.MiddlePoint = near_center + (far_center - near_center) * 0.5f;
up = glm::normalize(glm::cross(right, view_dir));
// these heights and widths are half the heights and widths of the near and far plane rectangles.
float near_height = tan(frustum.FOV / 2.f) * frustum.NearClip;
float near_width = near_height * frustum.AspectRatio;
float far_height = tan(frustum.FOV / 2.f) * frustum.FarClip;
float far_width = far_height * frustum.AspectRatio;
frustum.CornerPoint[0] = near_center - up * near_height - right * near_width;
frustum.CornerPoint[1] = near_center + up * near_height - right * near_width;
frustum.CornerPoint[2] = near_center + up * near_height + right * near_width;
frustum.CornerPoint[3] = near_center - up * near_height + right * near_width;
frustum.CornerPoint[4] = far_center - up * far_height - right * far_width;
frustum.CornerPoint[5] = far_center + up * far_height - right * far_width;
frustum.CornerPoint[6] = far_center + up * far_height + right * far_width;
frustum.CornerPoint[7] = far_center - up * far_height + right * far_width;
}
float ShadowPass::FindRadius(ShadowFrustum& frustum)
{
float radius = 0.f;
for (int i = 0; i < 8; i++) {
float distance = glm::distance(frustum.MiddlePoint, frustum.CornerPoint[i]);
if (distance > radius) {
radius = distance;
}
}
frustum.Radius = radius;
return radius;
}
void ShadowPass::InitializeFrameBuffers()
{
// Depth texture
glGenTextures(1, &m_DepthMap);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_DepthMap);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT16, m_ResolutionSizeWidth, m_ResolutionSizeHeight, m_CurrentNrOfSplits);
//glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight, m_CurrentNrOfSplits, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
m_DepthBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2DArray(&m_DepthMap, GL_DEPTH_ATTACHMENT)));
m_DepthBuffer.Generate();
GLERROR("depthMap failed END");
}
void ShadowPass::InitializeShaderPrograms()
{
m_ShadowProgram = ResourceManager::Load<ShaderProgram>("#ShadowProgram");
m_ShadowProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Shadow.vert.glsl")));
m_ShadowProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Shadow.frag.glsl")));
m_ShadowProgram->Compile();
m_ShadowProgram->BindFragDataLocation(0, "ShadowMap");
m_ShadowProgram->Link();
}
void ShadowPass::ClearBuffer()
{
m_DepthBuffer.Bind();
for (int i = 0; i < m_CurrentNrOfSplits; i++) {
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
m_DepthBuffer.Unbind();
}
void ShadowPass::PointsToLightspace(ShadowFrustum& frustum, glm::mat4 v)
{
float left = INFINITY;
float right = -INFINITY;
float bottom = INFINITY;
float top = -INFINITY;
for (int i = 0; i < 8; i++)
{
glm::vec3 tempPoint = glm::vec3(v * glm::vec4(frustum.CornerPoint[i], 1.f));
if (tempPoint.x < left) { left = tempPoint.x; }
if (tempPoint.x > right) { right = tempPoint.x; }
if (tempPoint.y < bottom) { bottom = tempPoint.y; }
if (tempPoint.y > top) { top = tempPoint.y; }
}
frustum.LRBT = { left, right, bottom, top };
}
void ShadowPass::RadiusToLightspace(ShadowFrustum& frustum)
{
float quantizationStep = 1.0f / m_ResolutionSizeHeight;
float left = -frustum.Radius;
float right = frustum.Radius;
float bottom = -frustum.Radius;
float top = frustum.Radius;
frustum.LRBT = { left, right, bottom, top };
}
void ShadowPass::Draw(RenderScene & scene)
{
if (m_EnableShadows) {
InitializeCameras(scene);
UpdateSplitDist(m_shadowFrusta, scene.Camera->NearClip(), scene.Camera->FarClip());
ShadowPassState* state = new ShadowPassState(m_DepthBuffer.GetHandle());
m_ShadowProgram->Bind();
GLuint shaderHandle = m_ShadowProgram->GetHandle();
glViewport(0, 0, m_ResolutionSizeWidth, m_ResolutionSizeHeight);
for (int i = 0; i < m_CurrentNrOfSplits; i++) {
UpdateFrustumPoints(m_shadowFrusta[i], scene.Camera->Position(), scene.Camera->Forward());
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_DepthMap, 0, i);
for (auto &job : scene.Jobs.DirectionalLight) {
auto directionalLightJob = std::dynamic_pointer_cast<DirectionalLightJob>(job);
if (directionalLightJob) {
m_LightView[i] = glm::lookAt(glm::vec3(-directionalLightJob->Direction) + m_shadowFrusta[i].MiddlePoint, m_shadowFrusta[i].MiddlePoint, glm::vec3(0.f, 1.f, 0.f));
PointsToLightspace(m_shadowFrusta[i], m_LightView[i]);
//FindRadius(m_shadowFrusta[i]);
//RadiusToLightspace(m_shadowFrusta[i]);
m_LightProjection[i] = glm::ortho(m_shadowFrusta[i].LRBT[LEFT], m_shadowFrusta[i].LRBT[RIGHT], m_shadowFrusta[i].LRBT[BOTTOM], m_shadowFrusta[i].LRBT[TOP], m_NearFarPlane[NEAR], m_NearFarPlane[FAR]);
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection[i]));
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView[i]));
GLERROR("ShadowLight ERROR");
for (auto &objectJob : scene.Jobs.OpaqueObjects) {
if (!std::dynamic_pointer_cast<ExplosionEffectJob>(objectJob)) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(objectJob);
if (!modelJob->Shadow) {
continue;
}
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), 1.f);
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
GLERROR("Shadow Draw ERROR");
}
}
if (m_TransparentObjects) {
state->CullFace(GL_BACK);
for (auto &objectJob : scene.Jobs.TransparentObjects) {
if (!std::dynamic_pointer_cast<ExplosionEffectJob>(objectJob)) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(objectJob);
if (!modelJob->Shadow) {
continue;
}
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniform1f(glGetUniformLocation(shaderHandle, "Alpha"), modelJob->Color.a);
if (m_TexturedShadows) {
switch (modelJob->Type) {
case RawModel::MaterialType::SingleTextures:
case RawModel::MaterialType::Basic:
{
glActiveTexture(GL_TEXTURE24);
if (modelJob->DiffuseTexture.size() > 0 && modelJob->DiffuseTexture[0]->Texture != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture[0]->Texture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(modelJob->DiffuseTexture[0]->UVRepeat));
}
else {
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
}
break;
}
case RawModel::MaterialType::SplatMapping:
{
glActiveTexture(GL_TEXTURE24);
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(glm::vec2(1.0f, 1.0f)));
break;
}
}
}
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
GLERROR("Shadow Draw ERROR");
}
}
state->CullFace(GL_FRONT);
}
}
}
}
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
m_DepthBuffer.Unbind();
delete state;
}
}
+19
View File
@@ -0,0 +1,19 @@
#include "Rendering/ShadowPassState.h"
ShadowPassState::ShadowPassState(GLuint frameBuffer)
{
BindFramebuffer(frameBuffer);
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
Disable(GL_BLEND);
Disable(GL_TEXTURE_2D);
CullFace(GL_FRONT);
ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f));
//Enable(GL_ALPHA_TEST);
//glAlphaFunc(GL_GREATER, 0.9f);
}
ShadowPassState::~ShadowPassState()
{
}
+2
View File
@@ -321,6 +321,8 @@ Skeleton::~Skeleton()
for (auto &kv : Bones) {
delete kv.second;
}
BlendTrees.clear();
}
const Skeleton::Animation* Skeleton::GetAnimation(std::string name)