Merge remote-tracking branch 'origin/master' into Dirtybit
# Conflicts: # src/Engine/Collision/CollisionSystem.cpp # src/Engine/Core/Transform.cpp # src/Engine/Editor/EditorSystem.cpp # src/Engine/Rendering/AnimationSystem.cpp # src/Engine/Rendering/BoneAttachmentSystem.cpp # src/Game/Systems/CapturePointSystem.cpp # src/Game/Systems/ExplosionEffectSystem.cpp # src/Game/Systems/PlayerMovementSystem.cpp
This commit is contained in:
@@ -360,7 +360,14 @@ constexpr bool FaceIsGround(float faceNormalY)
|
||||
//An array containing 3 int pairs { 0, 2 }, { 0, 1 }, { 1, 2 }
|
||||
constexpr std::array<std::pair<int, int>, 3> dimensionPairs({ std::pair<int, int>(0, 2), std::pair<int, int>(0, 1), std::pair<int, int>(1, 2) });
|
||||
|
||||
bool AABBvsTriangle(const AABB& box,
|
||||
enum class BoxTriRes
|
||||
{
|
||||
Front,
|
||||
Behind,
|
||||
Intersect
|
||||
};
|
||||
|
||||
BoxTriRes AABBvsTriangle(const AABB& box,
|
||||
const std::array<glm::vec3, 3>& triPos,
|
||||
const glm::vec3& originalBoxVelocity,
|
||||
float verticalStepHeight,
|
||||
@@ -374,7 +381,7 @@ bool AABBvsTriangle(const AABB& box,
|
||||
//Less checks, and we should be able to walk out from models if we are trapped inside.
|
||||
glm::vec3 triNormal = glm::cross(triPos[1] - triPos[0], triPos[2] - triPos[0]);
|
||||
if (!vectorHasLength(triNormal) || (glm::dot(triNormal, originalBoxVelocity) > 0)) {
|
||||
return false;
|
||||
return BoxTriRes::Behind;
|
||||
}
|
||||
triNormal = glm::normalize(triNormal);
|
||||
|
||||
@@ -409,6 +416,9 @@ bool AABBvsTriangle(const AABB& box,
|
||||
const glm::vec3& min = box.MinCorner();
|
||||
const glm::vec3& max = box.MaxCorner();
|
||||
|
||||
// If there is no intersection, whether the box center is in front of or behind the triangle.
|
||||
BoxTriRes noIntersection = glm::dot(triNormal, origin - triPos[0]) > 0 ? BoxTriRes::Front : BoxTriRes::Behind;
|
||||
|
||||
//For each projection in xy-, xz-, and yx-planes.
|
||||
for (std::pair<int, int> dim : dimensionPairs) {
|
||||
//2D Triangle.
|
||||
@@ -426,7 +436,7 @@ bool AABBvsTriangle(const AABB& box,
|
||||
bool pushedFromTriangleLine;
|
||||
//if projections don't overlap, return false.
|
||||
if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist, pushedFromTriangleLine)) {
|
||||
return false;
|
||||
return noIntersection;
|
||||
} else if (resolveCollision) {
|
||||
//Overwrite the smallest resolution if this is smaller.
|
||||
if (resolutionDist < resolveShortest.DistanceSq) {
|
||||
@@ -462,14 +472,15 @@ bool AABBvsTriangle(const AABB& box,
|
||||
float t = glm::dot(triNormal, triPos[0] - origin) / glm::dot(triNormal, diagonal);
|
||||
//If intersection point between plane and diagonal is within the box.
|
||||
if (glm::abs(t) > 1) {
|
||||
return false;
|
||||
return noIntersection;
|
||||
}
|
||||
|
||||
if (!resolveCollision) {
|
||||
return true;
|
||||
return BoxTriRes::Intersect;
|
||||
}
|
||||
|
||||
glm::vec3 cornerResolution = (1+t) * diagonal;
|
||||
cornerResolution = glm::dot(cornerResolution, triNormal) * triNormal;
|
||||
//Overwrite the smallest resolution if cornerResolution is smaller.
|
||||
float lenSq = glm::length2(cornerResolution);
|
||||
if (lenSq < resolveShortest.DistanceSq) {
|
||||
@@ -498,7 +509,7 @@ bool AABBvsTriangle(const AABB& box,
|
||||
case ResolveDimZ:
|
||||
//If we get here, the resolution is along one coordinate axis.
|
||||
//set velocity to 0 in y if it is along y-axis.
|
||||
return true;
|
||||
return BoxTriRes::Intersect;
|
||||
case Line:
|
||||
projNorm = glm::normalize(outResolution);
|
||||
break;
|
||||
@@ -533,10 +544,10 @@ bool AABBvsTriangle(const AABB& box,
|
||||
boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return BoxTriRes::Intersect;
|
||||
}
|
||||
|
||||
bool AABBvsTriangles(const AABB& box,
|
||||
Output AABBvsTriangles(const AABB& box,
|
||||
const RawModel::Vertex* modelVertices,
|
||||
const std::vector<unsigned int>& modelIndices,
|
||||
const glm::mat4& modelMatrix,
|
||||
@@ -546,8 +557,8 @@ bool AABBvsTriangles(const AABB& box,
|
||||
glm::vec3& outResolutionVector,
|
||||
bool resolveCollision)
|
||||
{
|
||||
bool hit = false;
|
||||
|
||||
bool intersect = false;
|
||||
Output out = Output::OutContained;
|
||||
bool everHitTheGround = false;
|
||||
AABB newBox = box;
|
||||
outResolutionVector = glm::vec3(0.f);
|
||||
@@ -560,20 +571,27 @@ bool AABBvsTriangles(const AABB& box,
|
||||
};
|
||||
glm::vec3 outVec;
|
||||
bool collideWithGround = isOnGround;
|
||||
if (AABBvsTriangle(newBox, triVertices, originalBoxVelocity, verticalStepHeight, collideWithGround, boxVelocity, outVec, resolveCollision)) {
|
||||
hit = true;
|
||||
switch (AABBvsTriangle(newBox, triVertices, originalBoxVelocity, verticalStepHeight, collideWithGround, boxVelocity, outVec, resolveCollision)) {
|
||||
case Collision::BoxTriRes::Front:
|
||||
out = Output::OutSeparated;
|
||||
break;
|
||||
case Collision::BoxTriRes::Intersect:
|
||||
intersect = true;
|
||||
outResolutionVector += outVec;
|
||||
newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size());
|
||||
if (collideWithGround) {
|
||||
everHitTheGround = isOnGround = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!everHitTheGround) {
|
||||
isOnGround = false;
|
||||
}
|
||||
return hit;
|
||||
return intersect ? Output::OutIntersecting : out;
|
||||
}
|
||||
|
||||
bool AABBvsTriangles(const AABB& box,
|
||||
@@ -593,13 +611,31 @@ bool AABBvsTriangles(const AABB& box,
|
||||
verticalStepHeight,
|
||||
isOnGround,
|
||||
outResolutionVector,
|
||||
true);
|
||||
true) == Output::OutIntersecting;
|
||||
}
|
||||
|
||||
bool AABBvsTriangles(const AABB& box,
|
||||
const RawModel::Vertex* modelVertices,
|
||||
const std::vector<unsigned int>& modelIndices,
|
||||
const glm::mat4& modelMatrix)
|
||||
{
|
||||
glm::vec3 vel, outres;
|
||||
bool g;
|
||||
return AABBvsTriangles(box,
|
||||
modelVertices,
|
||||
modelIndices,
|
||||
modelMatrix,
|
||||
vel,
|
||||
0.f,
|
||||
g,
|
||||
outres,
|
||||
false) == Output::OutIntersecting;
|
||||
}
|
||||
|
||||
Output AABBvsTrianglesWContainment(const AABB& box,
|
||||
const RawModel::Vertex* modelVertices,
|
||||
const std::vector<unsigned int>& modelIndices,
|
||||
const glm::mat4& modelMatrix)
|
||||
{
|
||||
glm::vec3 vel, outres;
|
||||
bool g;
|
||||
|
||||
@@ -37,6 +37,10 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
bool hit;
|
||||
float dist;
|
||||
if (boxB.Entity.HasComponent("Model")) {
|
||||
if (!((bool)boxB.Entity["Model"]["Visible"])) {
|
||||
// Don't collide against invisible models.
|
||||
continue;
|
||||
}
|
||||
RawModel* model;
|
||||
std::string res = (std::string)boxB.Entity["Model"]["Resource"];
|
||||
try {
|
||||
@@ -77,7 +81,11 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
}
|
||||
|
||||
if (boxB.Entity.HasComponent("Model") && Collision::AABBVsAABB(boxA, boxB)) {
|
||||
//Here we know boxB is a entity with Collideable, AABB, and Model.
|
||||
// Here we know boxB is a entity with Collideable, AABB, and Model.
|
||||
if (!((const bool&)boxB.Entity["Model"]["Visible"])) {
|
||||
// Don't collide against invisible models.
|
||||
continue;
|
||||
}
|
||||
RawModel* model;
|
||||
try {
|
||||
model = ResourceManager::Load<RawModel, true>(boxB.Entity["Model"]["Resource"]);
|
||||
@@ -88,12 +96,11 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity);
|
||||
|
||||
glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"];
|
||||
bool notMovingxz = glm::all(glm::lessThan(glm::abs(glm::vec2(inOutVelocity.x, inOutVelocity.z)), glm::vec2(0.01f))) && prevPosIt != m_PrevPositions.end();
|
||||
bool isOnGround = (bool)cPhysics["IsOnGround"];
|
||||
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
|
||||
if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
|
||||
//Move the position to previous position if it is not moving in the xz-plane, else resolve with the resolution vector.
|
||||
(Field<glm::vec3>)cTransform["Position"] += notMovingxz ? prevPosIt->second - boxA.Origin() : resolutionVector;
|
||||
(Field<glm::vec3>)cTransform["Position"] += resolutionVector;
|
||||
boxA = *Collision::EntityAbsoluteAABB(entity);
|
||||
cPhysics["Velocity"] = inOutVelocity;
|
||||
if (isOnGround) {
|
||||
|
||||
@@ -10,6 +10,16 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapp
|
||||
return;
|
||||
}
|
||||
|
||||
RawModel* triggerModel = nullptr;
|
||||
glm::mat4 triggerModelMat;
|
||||
if (triggerEntity.HasComponent("Model")) {
|
||||
try {
|
||||
triggerModel = ResourceManager::Load<RawModel, true>(triggerEntity["Model"]["Resource"]);
|
||||
triggerModelMat = Transform::ModelMatrix(triggerEntity);
|
||||
} catch (const std::exception&) {
|
||||
}
|
||||
}
|
||||
|
||||
m_OctreeOut.clear();
|
||||
m_Octree->ObjectsInSameRegion(*triggerBox, m_OctreeOut);
|
||||
|
||||
@@ -22,7 +32,17 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapp
|
||||
if (colliderFitsInTrigger) {
|
||||
completelyInsideBox = AABB::FromOriginSize((*triggerBox).Origin(), (*triggerBox).Size() - 2.0f * colliderBox.Size());
|
||||
}
|
||||
if (colliderFitsInTrigger && Collision::AABBVsAABB(completelyInsideBox, colliderBox)) {
|
||||
|
||||
// We know the entity is inside the trigger box, but perhaps not the model yet.
|
||||
Collision::Output out = triggerModel == nullptr
|
||||
? Collision::Output::OutContained
|
||||
: Collision::AABBvsTrianglesWContainment(
|
||||
colliderBox,
|
||||
triggerModel->Vertices(),
|
||||
triggerModel->m_Indices,
|
||||
triggerModelMat);
|
||||
|
||||
if (colliderFitsInTrigger && Collision::AABBVsAABB(completelyInsideBox, colliderBox) && out == Collision::Output::OutContained) {
|
||||
// Entity is completely inside the trigger.
|
||||
// If it was only touching before, it is erased.
|
||||
m_EntitiesTouchingTrigger[triggerEntity].erase(colliderEntity);
|
||||
@@ -32,7 +52,8 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapp
|
||||
completeSet.insert(colliderEntity);
|
||||
publish<Events::TriggerEnter>(colliderEntity, triggerEntity);
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
} else if (out != Collision::Output::OutSeparated) {
|
||||
// Entity is only touching the trigger.
|
||||
auto& touchSet = m_EntitiesTouchingTrigger[triggerEntity];
|
||||
auto& completeSet = m_EntitiesCompletelyInTrigger[triggerEntity];
|
||||
@@ -47,17 +68,17 @@ void TriggerSystem::UpdateComponent(EntityWrapper& triggerEntity, ComponentWrapp
|
||||
touchSet.insert(colliderEntity);
|
||||
}
|
||||
// Else, it was touching the trigger last frame too and nothing is done.
|
||||
}
|
||||
} else {
|
||||
// Entity is not touching the trigger,
|
||||
// Throw event if it was previously.
|
||||
if (throwLeaveIfWasInTrigger(m_EntitiesTouchingTrigger[triggerEntity], colliderEntity, triggerEntity)) {
|
||||
continue;
|
||||
}
|
||||
// This only occurs if the entity was completely inside the trigger one frame,
|
||||
// then completely outside the trigger, e.g. when dying and respawning.
|
||||
throwLeaveIfWasInTrigger(m_EntitiesCompletelyInTrigger[triggerEntity], colliderEntity, triggerEntity);
|
||||
}
|
||||
// Only get here if entity is not touching the trigger,
|
||||
// throw event if it was touching previously.
|
||||
if (throwLeaveIfWasInTrigger(m_EntitiesTouchingTrigger[triggerEntity], colliderEntity, triggerEntity)) {
|
||||
continue;
|
||||
}
|
||||
// This only occurs if the entity was completely inside the trigger one frame,
|
||||
// then completely outside the trigger, e.g. when dying and respawning.
|
||||
throwLeaveIfWasInTrigger(m_EntitiesCompletelyInTrigger[triggerEntity], colliderEntity, triggerEntity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -86,7 +86,7 @@ bool EditorRenderSystem::OnSetCamera(Events::SetCamera& e)
|
||||
{
|
||||
ComponentWrapper cTransform = e.CameraEntity["Transform"];
|
||||
ComponentWrapper cCamera = e.CameraEntity["Camera"];
|
||||
m_EditorCamera->SetFOV(static_cast<float>((double)cCamera["FOV"]));
|
||||
m_EditorCamera->SetFOV(glm::radians(static_cast<float>((double)cCamera["FOV"])));
|
||||
m_EditorCamera->SetNearClip(static_cast<float>((double)cCamera["NearClip"]));
|
||||
m_EditorCamera->SetFarClip(static_cast<float>((double)cCamera["FarClip"]));
|
||||
m_EditorCamera->SetPosition(cTransform["Position"]);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "Editor/EditorWidgetSystem.h"
|
||||
#include "Core/EntityFile.h"
|
||||
|
||||
EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame)
|
||||
EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame)
|
||||
: System(params)
|
||||
, m_Renderer(renderer)
|
||||
, m_RenderFrame(renderFrame)
|
||||
@@ -14,7 +14,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame
|
||||
m_EditorWorldSystemPipeline->AddSystem<UniformScaleSystem>(0);
|
||||
m_EditorWorldSystemPipeline->AddSystem<EditorWidgetSystem>(0, m_Renderer);
|
||||
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
||||
|
||||
|
||||
m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
|
||||
m_ActualCamera = m_EditorCamera;
|
||||
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform");
|
||||
@@ -47,6 +47,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame
|
||||
Enable();
|
||||
} else {
|
||||
Disable();
|
||||
m_EventBroker->Publish(Events::UnlockMouse());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,14 +72,16 @@ void EditorSystem::Update(double dt)
|
||||
m_EditorStats->Draw(actualDelta);
|
||||
|
||||
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
|
||||
m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection);
|
||||
if (isAnyParentMissingTransform(m_CurrentSelection.ID)) {
|
||||
return;
|
||||
}
|
||||
(Field<glm::vec3>)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection);
|
||||
if (m_WidgetSpace == EditorGUI::WidgetSpace::Local) {
|
||||
m_Widget["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(m_CurrentSelection);
|
||||
} else {
|
||||
m_Widget["Transform"]["Orientation"] = glm::vec3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_EditorWorldSystemPipeline->Update(actualDelta);
|
||||
|
||||
ComponentWrapper& cameraTransform = m_EditorCamera["Transform"];
|
||||
@@ -202,16 +205,26 @@ bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
||||
bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
|
||||
{
|
||||
if (m_CurrentSelection.Valid()) {
|
||||
if (isAnyParentMissingTransform(m_CurrentSelection.ID)) {
|
||||
return false;
|
||||
}
|
||||
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);
|
||||
}
|
||||
(Field<glm::vec3>)m_CurrentSelection["Transform"]["Position"] += parentOrientation * e.Translation;
|
||||
(Field<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;
|
||||
(Field<glm::vec3>)m_CurrentSelection["Transform"]["Position"] += localTranslation;
|
||||
}
|
||||
m_EditorGUI->SetDirty(m_CurrentSelection);
|
||||
@@ -301,3 +314,15 @@ void EditorSystem::setWidgetMode(EditorGUI::WidgetMode mode)
|
||||
|
||||
m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
|
||||
}
|
||||
|
||||
bool EditorSystem::isAnyParentMissingTransform(EntityID entityID)
|
||||
{
|
||||
EntityWrapper entity(m_World, entityID);
|
||||
while (entity.Parent().Valid()) {
|
||||
if (!entity.HasComponent("Transform")) {
|
||||
return true;
|
||||
}
|
||||
entity = entity.Parent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ bool ButtonSystem::OnMousePress(const Events::MousePress& e)
|
||||
//You have clicked on a button entity, send pressed event.
|
||||
if (m_World->HasComponent(m_PickData.Entity, "InputCmdButton")) {
|
||||
Events::InputCommand eInputCmd;
|
||||
eInputCmd.PlayerID = LocalPlayer.ID;
|
||||
eInputCmd.PlayerID = -1;
|
||||
eInputCmd.Player = LocalPlayer;
|
||||
EntityWrapper button = EntityWrapper(m_World, m_PickData.Entity);
|
||||
eInputCmd.Command = (std::string)button["InputCmdButton"]["Command"];
|
||||
@@ -68,7 +68,7 @@ bool ButtonSystem::OnMouseRelease(const Events::MouseRelease& e)
|
||||
|
||||
if (m_World->HasComponent(m_PickData.Entity, "InputCmdButton")) {
|
||||
Events::InputCommand eInputCmd;
|
||||
eInputCmd.PlayerID = LocalPlayer.ID;
|
||||
eInputCmd.PlayerID = -1;
|
||||
eInputCmd.Player = LocalPlayer;
|
||||
EntityWrapper button = EntityWrapper(m_World, m_PickData.Entity);
|
||||
eInputCmd.Command = (std::string)button["InputCmdButton"]["Command"];
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#include "GUI/MainMenuSystem.h"
|
||||
|
||||
MainMenuSystem::MainMenuSystem(SystemParams params, IRenderer* renderer)
|
||||
: System(params)
|
||||
, ImpureSystem()
|
||||
, m_Renderer(renderer)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPressed, &MainMenuSystem::OnButtonPress);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EReleased, &MainMenuSystem::OnButtonRelease);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EClicked, &MainMenuSystem::OnButtonClick);
|
||||
}
|
||||
|
||||
void MainMenuSystem::Update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool MainMenuSystem::OnButtonClick(const Events::ButtonClicked& e)
|
||||
{
|
||||
if(e.EntityName == "Play") {
|
||||
//Run play code
|
||||
} else if(e.EntityName == "Connect") {
|
||||
//Run connect code
|
||||
} else if(e.EntityName == "Host") {
|
||||
//Run host code
|
||||
} else if(e.EntityName == "Quit") {
|
||||
printf("No, you stay");
|
||||
} else if (e.EntityName == "Res1080") {
|
||||
glfwSetWindowSize(m_Renderer->Window(), 1920, 1080);
|
||||
printf("\n1080");
|
||||
} else if (e.EntityName == "Res720") {
|
||||
glfwSetWindowSize(m_Renderer->Window(), 1280, 720);
|
||||
glViewport(0, 0, 1280, 720);
|
||||
printf("\n720");
|
||||
} else if (e.EntityName == "Res480") {
|
||||
glfwSetWindowSize(m_Renderer->Window(), 854, 480);
|
||||
glViewport(0, 0, 854, 480);
|
||||
printf("\n480");
|
||||
} else if (e.EntityName == "FullScreen") {
|
||||
printf("No fullscreen for now");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainMenuSystem::OnButtonRelease(const Events::ButtonReleased& e)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainMenuSystem::OnButtonPress(const Events::ButtonPressed& e)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ void InputProxy::Update(double dt)
|
||||
}
|
||||
}
|
||||
|
||||
void InputProxy::Process()
|
||||
void InputProxy::Process(bool suppressNewEvents /*= false*/)
|
||||
{
|
||||
for (auto& pair : m_CommandHandlers) {
|
||||
const std::string& command = pair.first;
|
||||
@@ -62,8 +62,10 @@ void InputProxy::Process()
|
||||
e.PlayerID = -1;
|
||||
e.Command = command;
|
||||
e.Value = currentValue;
|
||||
m_EventBroker->Publish(e);
|
||||
//LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
if (!suppressNewEvents || e.Value == 0) {
|
||||
m_EventBroker->Publish(e);
|
||||
//LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
}
|
||||
m_LastCommandValues[command] = currentValue;
|
||||
}
|
||||
}
|
||||
@@ -78,8 +80,10 @@ void InputProxy::Process()
|
||||
e.Value += value;
|
||||
}
|
||||
//e.Value = std::max(-1.f, std::min(e.Value, 1.f));
|
||||
m_EventBroker->Publish(e);
|
||||
//LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
if (!suppressNewEvents || e.Value == 0) {
|
||||
m_EventBroker->Publish(e);
|
||||
//LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
}
|
||||
}
|
||||
m_CommandQueue.clear();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Network/Client.h"
|
||||
#include "Network/EPlayerDisconnected.h"
|
||||
using namespace boost::asio::ip;
|
||||
|
||||
Client::Client(World* world, EventBroker* eventBroker)
|
||||
@@ -35,6 +36,7 @@ void Client::Connect(std::string address, int port)
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &Client::OnDoubleJump);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &Client::OnDashAbility);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EConnectRequest, &Client::OnConnectRequest);
|
||||
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
m_Address = address;
|
||||
if (address.empty()) {
|
||||
@@ -49,16 +51,19 @@ void Client::Connect(std::string address, int port)
|
||||
void Client::Update()
|
||||
{
|
||||
m_EventBroker->Process<Client>();
|
||||
//while (m_Unreliable.IsSocketAvailable()) {
|
||||
// // Packet will get real data in receive
|
||||
// Packet packet(MessageType::Invalid);
|
||||
// m_Unreliable.Receive(packet);
|
||||
// if (packet.GetMessageType() == MessageType::Connect) {
|
||||
// parseUDPConnect(packet);
|
||||
// } else {
|
||||
// parseMessageType(packet);
|
||||
// }
|
||||
//}
|
||||
while (m_Unreliable.IsSocketAvailable()) {
|
||||
m_Unreliable.ReceivePackets();
|
||||
}
|
||||
// Packet will get real data in GetNextPacket()
|
||||
Packet parsedPacket(MessageType::Invalid);
|
||||
while (m_Unreliable.GetNextPacket(parsedPacket)) {
|
||||
if (parsedPacket.GetMessageType() == MessageType::Connect) {
|
||||
parseUDPConnect(parsedPacket);
|
||||
} else {
|
||||
parseMessageType(parsedPacket);
|
||||
}
|
||||
}
|
||||
|
||||
while (m_Reliable.IsSocketAvailable()) {
|
||||
// Packet will get real data in receive
|
||||
Packet packet(MessageType::Invalid);
|
||||
@@ -82,7 +87,10 @@ void Client::Update()
|
||||
if (m_SearchingForServers) {
|
||||
if (m_SearchingTime < (1000* (std::clock() - m_StartSearchTime) / (double)CLOCKS_PER_SEC)) {
|
||||
m_SearchingForServers = false;
|
||||
displayServerlist();
|
||||
//displayServerlist();
|
||||
Events::DisplayServerlist e;
|
||||
e.Serverlist = m_Serverlist;
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +110,9 @@ void Client::Update()
|
||||
|
||||
void Client::parseMessageType(Packet& packet)
|
||||
{
|
||||
// Pop packetSize
|
||||
packet.ReadPrimitive<int>();
|
||||
// Pop packetSize, sequenceNumber and packetsInSequence.
|
||||
popNetworkSegmentOfHeader(packet);
|
||||
|
||||
int messageType = packet.ReadPrimitive<int>();
|
||||
if (messageType == -1)
|
||||
return;
|
||||
@@ -158,27 +167,30 @@ void Client::parseMessageType(Packet& packet)
|
||||
void Client::parseUDPConnect(Packet& packet)
|
||||
{
|
||||
// Map ServerEntityID and your PlayerID
|
||||
// TODO: If this is not received send a new connect message.
|
||||
LOG_INFO("I be connected PogChamp");
|
||||
}
|
||||
|
||||
void Client::parseTCPConnect(Packet& packet)
|
||||
{
|
||||
LOG_INFO("Received TCP connect from server");
|
||||
// Pop size of message int
|
||||
packet.ReadPrimitive<int>();
|
||||
// Pop packetSize, group, groupIndex and groupSize.
|
||||
popNetworkSegmentOfHeader(packet);
|
||||
|
||||
int messageType = packet.ReadPrimitive<int>();
|
||||
// Read packet ID
|
||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||
// parse player id and other stuff
|
||||
m_PlayerID = packet.ReadPrimitive<int>();
|
||||
m_PlayerID = packet.ReadPrimitive<int>();
|
||||
LOG_INFO("A Player connected");
|
||||
// TODO: If this is not received send a new connect message.
|
||||
Packet UnreliablePacket(MessageType::Connect, m_SendPacketID);
|
||||
// Add player id and other stuff
|
||||
packet.WritePrimitive(m_PlayerID);
|
||||
// m_Unreliable.Send(packet);
|
||||
// LOG_INFO("Sent UDP Connect Server");
|
||||
m_Unreliable.Send(packet);
|
||||
|
||||
// LOG_INFO("Sent UDP Connect Server");
|
||||
}
|
||||
|
||||
void Client::parsePlayerConnected(Packet & packet)
|
||||
@@ -204,10 +216,11 @@ void Client::parsePing()
|
||||
|
||||
void Client::parseServerlist(Packet& packet)
|
||||
{
|
||||
// Pop size, message type, and ID
|
||||
packet.ReadPrimitive<int>();
|
||||
// Pop packetSize, group, groupIndex and groupSize.
|
||||
popNetworkSegmentOfHeader(packet);
|
||||
packet.ReadPrimitive<int>();
|
||||
packet.ReadPrimitive<int>();
|
||||
|
||||
std::string address = packet.ReadString();
|
||||
int port = packet.ReadPrimitive<int>();
|
||||
std::string serverName = packet.ReadString();
|
||||
@@ -220,7 +233,7 @@ void Client::parseServerlist(Packet& packet)
|
||||
void Client::parseKick()
|
||||
{
|
||||
LOG_WARNING("You have been kicked from the server.");
|
||||
m_IsConnected = false;
|
||||
disconnect();
|
||||
}
|
||||
|
||||
void Client::parseSpawnEvents()
|
||||
@@ -453,22 +466,23 @@ void Client::parseSnapshot(Packet& packet)
|
||||
|
||||
void Client::disconnect()
|
||||
{
|
||||
removeWorld();
|
||||
m_IsConnected = false;
|
||||
m_PreviousPacketID = 0;
|
||||
m_PacketID = 0;
|
||||
Packet packet(MessageType::Disconnect, m_SendPacketID);
|
||||
m_Reliable.Send(packet);
|
||||
m_Unreliable.Disconnect();
|
||||
m_Reliable.Disconnect();
|
||||
Events::PlayerDisconnected e;
|
||||
e.Entity = m_LocalPlayer.ID;
|
||||
e.PlayerID = -1;
|
||||
m_EventBroker->Publish(e);
|
||||
createMainMenu();
|
||||
}
|
||||
|
||||
bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||
{
|
||||
// TEMP
|
||||
if (e.Command == "SearchForServers" && e.Value > 0) {
|
||||
Events::SearchForServers e;
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
if (e.PlayerID != -1) {
|
||||
return false;
|
||||
}
|
||||
@@ -476,7 +490,7 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||
if (e.Command == "ConnectToServer") { // Connect for now
|
||||
if (e.Value > 0) {
|
||||
m_Reliable.Connect(m_PlayerName, m_Address, m_Port);
|
||||
// m_Unreliable.Connect(m_PlayerName, m_Address, m_Port);
|
||||
m_Unreliable.Connect(m_PlayerName, m_Address, m_Port);
|
||||
}
|
||||
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
return true;
|
||||
@@ -548,12 +562,29 @@ bool Client::OnDashAbility(const Events::DashAbility& e)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Client::OnConnectRequest(const Events::ConnectRequest& e)
|
||||
{
|
||||
removeWorld();
|
||||
if (m_Reliable.Connect(m_PlayerName, e.IP, e.Port)) {
|
||||
m_Unreliable.Connect(m_PlayerName, e.IP, e.Port);
|
||||
// The client sent a successful connect message
|
||||
return true;
|
||||
|
||||
} else {
|
||||
// The client could not send a successful connect message
|
||||
createMainMenu();
|
||||
// Load the main menu again ?
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Client::OnSearchForServers(const Events::SearchForServers& e)
|
||||
{
|
||||
m_SearchingForServers = true;
|
||||
m_StartSearchTime = std::clock();
|
||||
m_Serverlist.clear();
|
||||
LOG_INFO("Searching for LAN servers...\n");
|
||||
Packet packet(MessageType::ServerlistRequest);
|
||||
m_ServerlistRequest.Broadcast(packet, 13); // TODO: Config
|
||||
return true;
|
||||
@@ -613,7 +644,7 @@ void Client::sendLocalPlayerTransform()
|
||||
packet.WritePrimitive((int)cAssaultWeapon["Ammo"]);
|
||||
}
|
||||
|
||||
m_Reliable.Send(packet);
|
||||
m_Unreliable.Send(packet);
|
||||
}
|
||||
|
||||
void Client::identifyPacketLoss()
|
||||
@@ -675,6 +706,25 @@ void Client::displayServerlist()
|
||||
}
|
||||
}
|
||||
|
||||
void Client::removeWorld()
|
||||
{
|
||||
std::vector<EntityID> childrenToBeDeleted;
|
||||
auto rootEntites = m_World->GetDirectChildren(EntityID_Invalid);
|
||||
for (auto it = rootEntites.first; it != rootEntites.second; it++) {
|
||||
childrenToBeDeleted.push_back(it->second);
|
||||
}
|
||||
for (int i = 0; i < childrenToBeDeleted.size(); ++i) {
|
||||
m_World->DeleteEntity(childrenToBeDeleted[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Client::createMainMenu()
|
||||
{
|
||||
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/StartMenu.xml");
|
||||
entityFile->MergeInto(m_World);
|
||||
}
|
||||
|
||||
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
||||
{
|
||||
if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) {
|
||||
|
||||
@@ -83,3 +83,12 @@ void Network::updateNetworkData()
|
||||
m_NetworkData.DataReceivedThisInterval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Network::popNetworkSegmentOfHeader(Packet & packet)
|
||||
{
|
||||
// Pop packetSize, group, groupIndex and groupSize.
|
||||
packet.ReadPrimitive<int>();
|
||||
packet.ReadPrimitive<int>();
|
||||
packet.ReadPrimitive<int>();
|
||||
packet.ReadPrimitive<int>();
|
||||
}
|
||||
|
||||
@@ -3,16 +3,22 @@
|
||||
Packet::Packet(MessageType type, unsigned int& packetID)
|
||||
{
|
||||
m_Data = new char[m_MaxPacketSize];
|
||||
Init(type, packetID);
|
||||
Init(type, packetID, 1, 1, -1);
|
||||
}
|
||||
|
||||
// Create message
|
||||
Packet::Packet(char* data, const size_t sizeOfPacket)
|
||||
{
|
||||
// Create message header
|
||||
// allocate memory for size of packet, sequenceNumber and totalPacketesInSequence
|
||||
m_ReturnDataOffset = 0;
|
||||
m_Offset = 0;
|
||||
// Resize message
|
||||
m_MaxPacketSize = sizeOfPacket;
|
||||
// Copy data newly allocated memory
|
||||
m_Data = new char[sizeOfPacket];
|
||||
unsigned int dummy = 0;
|
||||
Init(MessageType::Invalid, dummy, 0, 0, 0);
|
||||
memcpy(m_Data, data, sizeOfPacket);
|
||||
m_Offset = sizeOfPacket;
|
||||
}
|
||||
@@ -21,7 +27,7 @@ Packet::Packet(MessageType type)
|
||||
{
|
||||
m_Data = new char[m_MaxPacketSize];
|
||||
unsigned int dummy = 0;
|
||||
Init(type, dummy);
|
||||
Init(type, dummy, 1, 1, -1);
|
||||
}
|
||||
|
||||
Packet::~Packet()
|
||||
@@ -29,16 +35,30 @@ Packet::~Packet()
|
||||
delete[] m_Data;
|
||||
}
|
||||
|
||||
void Packet::Init(MessageType type, unsigned int & packetID)
|
||||
void Packet::Init(MessageType type, unsigned int & packetID,
|
||||
int groupIndex, int groupSize, int group)
|
||||
{
|
||||
m_ReturnDataOffset = 0;
|
||||
m_Offset = 0;
|
||||
// Create message header
|
||||
// allocate memory for size of packet(only used in tcp)
|
||||
// allocate memory for size of packet, sequenceNumber and totalPacketesInSequence
|
||||
packetSizeOffset = m_Offset;
|
||||
WritePrimitive<int>(0);
|
||||
// packetGroup is the group the packet is in
|
||||
groupOffset = m_Offset;
|
||||
WritePrimitive<int>(group);
|
||||
// What index the packet has in the packetGroup
|
||||
groupIndexOffset = m_Offset;
|
||||
WritePrimitive(groupIndex);
|
||||
// The total amount of packets in a packetGroup
|
||||
groupSizeOffset = m_Offset;
|
||||
WritePrimitive(groupSize);
|
||||
// Add message type
|
||||
int messageType = static_cast<int>(type);
|
||||
messageTypeOffset = m_Offset;
|
||||
WritePrimitive<int>(messageType);
|
||||
// Packet ID
|
||||
packetIDOffset = m_Offset;
|
||||
WritePrimitive<int>(packetID);
|
||||
packetID++;
|
||||
m_HeaderSize = m_Offset;
|
||||
@@ -50,7 +70,7 @@ void Packet::WriteString(const std::string& str)
|
||||
size_t sizeOfString = str.size() + 1;
|
||||
if (m_Offset + sizeOfString > m_MaxPacketSize) {
|
||||
if (m_MaxPacketSize >= 32000) {
|
||||
LOG_WARNING("Package::WriteString(): New size is huge %i bytes\n", m_MaxPacketSize*2);
|
||||
//LOG_WARNING("Package::WriteString(): New size is huge %i bytes\n", m_MaxPacketSize*2);
|
||||
}
|
||||
resizeData();
|
||||
}
|
||||
@@ -65,7 +85,7 @@ void Packet::WriteData(char * data, int sizeOfData)
|
||||
|
||||
if (m_Offset + sizeOfData > m_MaxPacketSize) {
|
||||
if (m_MaxPacketSize >= 32000) {
|
||||
LOG_WARNING("Package::WriteData(): New size is huge %i bytes\n", m_MaxPacketSize*2);
|
||||
//LOG_WARNING("Package::WriteData(): New size is huge %i bytes\n", m_MaxPacketSize*2);
|
||||
}
|
||||
while (m_Offset + sizeOfData > m_MaxPacketSize) {
|
||||
resizeData();
|
||||
@@ -104,8 +124,7 @@ void Packet::ReconstructFromData(char * data, size_t sizeOfData)
|
||||
|
||||
void Packet::UpdateSize()
|
||||
{
|
||||
int whatisoffset = m_Offset;
|
||||
memcpy(m_Data, &m_Offset, sizeof(int));
|
||||
memcpy(m_Data + packetSizeOffset, &m_Offset, sizeof(int));
|
||||
}
|
||||
|
||||
char * Packet::ReadData(int sizeOfData)
|
||||
@@ -123,14 +142,47 @@ void Packet::ChangePacketID(unsigned int & packetID)
|
||||
{
|
||||
packetID = packetID + 1;
|
||||
// Overwrite old PacketID
|
||||
memcpy(m_Data + 2*sizeof(int), &packetID, sizeof(int));
|
||||
memcpy(m_Data + packetIDOffset, &packetID, sizeof(int));
|
||||
}
|
||||
|
||||
void Packet::ChangeGroupIndex(int groupIndex)
|
||||
{
|
||||
memcpy(m_Data + groupIndexOffset, &groupIndex, sizeof(int));
|
||||
}
|
||||
|
||||
void Packet::ChangeGroupSize(int groupSize)
|
||||
{
|
||||
memcpy(m_Data + groupSizeOffset, &groupSize, sizeof(int));
|
||||
}
|
||||
|
||||
void Packet::ChangeGroup(int group)
|
||||
{
|
||||
memcpy(m_Data + groupOffset, &group, sizeof(int));
|
||||
}
|
||||
|
||||
MessageType Packet::GetMessageType()
|
||||
{
|
||||
MessageType messagType;
|
||||
memcpy(&messagType, m_Data + sizeof(int), sizeof(int));
|
||||
return messagType;
|
||||
return *reinterpret_cast<MessageType*>(m_Data + messageTypeOffset);
|
||||
}
|
||||
|
||||
size_t Packet::Group()
|
||||
{
|
||||
return *reinterpret_cast<size_t*>(m_Data + groupOffset);
|
||||
}
|
||||
|
||||
size_t Packet::GroupIndex()
|
||||
{
|
||||
return *reinterpret_cast<size_t*>(m_Data + groupIndexOffset);
|
||||
}
|
||||
|
||||
size_t Packet::GroupSize()
|
||||
{
|
||||
return *reinterpret_cast<size_t*>(m_Data + groupSizeOffset);
|
||||
}
|
||||
|
||||
size_t Packet::PacketID()
|
||||
{
|
||||
return *reinterpret_cast<size_t*>(m_Data + packetIDOffset);
|
||||
}
|
||||
|
||||
void Packet::resizeData()
|
||||
|
||||
@@ -7,6 +7,8 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
|
||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
|
||||
pingIntervalMs = config->Get<float>("Networking.PingIntervalMs", 1000);
|
||||
m_ServerName = config->Get<std::string>("Networking.Name", "Unnamed");
|
||||
|
||||
// Subscribe to events
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
|
||||
@@ -47,19 +49,19 @@ void Server::Update()
|
||||
}
|
||||
}
|
||||
|
||||
//PlayerDefinition pd;
|
||||
//while (m_Unreliable.IsSocketAvailable()) {
|
||||
// // Packet will get real data in receive
|
||||
// Packet packet(MessageType::Invalid);
|
||||
// m_Unreliable.Receive(packet, pd);
|
||||
// m_Address = pd.Endpoint.address();
|
||||
// m_Port = pd.Endpoint.port();
|
||||
// if (packet.GetMessageType() == MessageType::Connect) {
|
||||
// parseUDPConnect(packet);
|
||||
// } else {
|
||||
// parseMessageType(packet);
|
||||
// }
|
||||
//}
|
||||
PlayerDefinition pd;
|
||||
while (m_Unreliable.IsSocketAvailable()) {
|
||||
// Packet will get real data in receive
|
||||
Packet packet(MessageType::Invalid);
|
||||
m_Unreliable.Receive(packet, pd);
|
||||
m_Address = pd.Endpoint.address();
|
||||
m_Port = pd.Endpoint.port();
|
||||
if (packet.GetMessageType() == MessageType::Connect) {
|
||||
parseUDPConnect(packet);
|
||||
} else {
|
||||
parseMessageType(packet);
|
||||
}
|
||||
}
|
||||
|
||||
while (m_ServerlistRequest.IsSocketAvailable()) {
|
||||
Packet packet(MessageType::Invalid);
|
||||
@@ -67,9 +69,11 @@ void Server::Update()
|
||||
localArea.Endpoint = boost::asio::ip::udp::endpoint();
|
||||
m_ServerlistRequest.Receive(packet, localArea);
|
||||
if (packet.GetMessageType() == MessageType::ServerlistRequest) {
|
||||
packet.ReadPrimitive<int>(); // Pop size
|
||||
packet.ReadPrimitive<int>(); // Pop MsgType
|
||||
packet.ReadPrimitive<int>(); // Pop packet ID
|
||||
// Pop header
|
||||
popNetworkSegmentOfHeader(packet);
|
||||
packet.ReadPrimitive<int>();
|
||||
packet.ReadPrimitive<int>();
|
||||
|
||||
int port = packet.ReadPrimitive<int>();
|
||||
std::string address = localArea.Endpoint.address().to_string();
|
||||
parseServerlistRequest(boost::asio::ip::udp::endpoint(boost::asio::ip::address().from_string(address), port));
|
||||
@@ -107,9 +111,9 @@ void Server::Update()
|
||||
|
||||
void Server::parseMessageType(Packet& packet)
|
||||
{
|
||||
// Pop packetSize which is used by TCP Client to
|
||||
// Pop packetSize, sequenceNumber and packetsInSequence.
|
||||
// create a packet of the correct size
|
||||
packet.ReadPrimitive<int>();
|
||||
popNetworkSegmentOfHeader(packet);
|
||||
|
||||
int messageType = packet.ReadPrimitive<int>(); // Read what type off message was sent from server
|
||||
// Read packet ID
|
||||
@@ -160,10 +164,7 @@ void Server::reliableBroadcast(Packet& packet)
|
||||
|
||||
void Server::unreliableBroadcast(Packet& packet)
|
||||
{
|
||||
for (auto& kv : m_ConnectedPlayers) {
|
||||
packet.ChangePacketID(kv.second.PacketID);
|
||||
// m_Unreliable.Send(packet, kv.second);
|
||||
}
|
||||
m_Unreliable.SendToConnectedPlayers(packet, m_ConnectedPlayers);
|
||||
}
|
||||
|
||||
// Send snapshot fields
|
||||
@@ -172,7 +173,8 @@ void Server::sendSnapshot()
|
||||
Packet packet(MessageType::Snapshot);
|
||||
addInputCommandsToPacket(packet);
|
||||
addPlayersToPacket(packet, EntityID_Invalid);
|
||||
reliableBroadcast(packet);
|
||||
//addChildrenToPacket(packet, EntityID_Invalid);
|
||||
unreliableBroadcast(packet);
|
||||
}
|
||||
|
||||
void Server::addInputCommandsToPacket(Packet& packet)
|
||||
@@ -297,8 +299,6 @@ void Server::sendPing()
|
||||
reliableBroadcast(packet);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Server::checkForTimeOuts()
|
||||
{
|
||||
double startPing = 1000 * m_StartPingTime
|
||||
@@ -315,38 +315,35 @@ void Server::checkForTimeOuts()
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < playersToRemove.size(); i++) {
|
||||
for (int i = playersToRemove.size() - 1; i >= 0; i--) {
|
||||
disconnect(playersToRemove.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
//void Server::parseUDPConnect(Packet & packet)
|
||||
//{
|
||||
// // Pop size of message int
|
||||
// packet.ReadPrimitive<int>();
|
||||
// int messageType = packet.ReadPrimitive<int>();
|
||||
// // Read packet ID
|
||||
// m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||
// m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||
// // parse player id and other stuff
|
||||
// PlayerID playerID = packet.ReadPrimitive<int>();
|
||||
// if (!EntityWrapper(m_World, playerID).Valid()) {
|
||||
//
|
||||
// }
|
||||
// // Do something here?
|
||||
// boost::asio::ip::udp::endpoint endpoint(m_Address, m_Port);
|
||||
// m_ConnectedPlayers.at(playerID).Endpoint = endpoint;
|
||||
// LOG_INFO("parseUDPConnect: Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), m_ConnectedPlayers.at(playerID).Endpoint.address().to_string().c_str());
|
||||
// // Send a message to the player that connected
|
||||
// Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID);
|
||||
// m_Unreliable.Send(connnectPacket);
|
||||
// LOG_INFO("UDP Connect sent to client");
|
||||
//}
|
||||
void Server::parseUDPConnect(Packet & packet)
|
||||
{
|
||||
//Pop packetSize, sequenceNumber and packetsInSequence.
|
||||
popNetworkSegmentOfHeader(packet);
|
||||
int messageType = packet.ReadPrimitive<int>();
|
||||
// Read packet ID
|
||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||
// parse player id and other stuff
|
||||
PlayerID playerID = packet.ReadPrimitive<int>();
|
||||
boost::asio::ip::udp::endpoint endpoint(m_Address, m_Port);
|
||||
m_ConnectedPlayers.at(playerID).Endpoint = endpoint;
|
||||
LOG_INFO("parseUDPConnect: Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), m_ConnectedPlayers.at(playerID).Endpoint.address().to_string().c_str());
|
||||
// Send a message to the player that connected
|
||||
Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID);
|
||||
m_Unreliable.Send(connnectPacket);
|
||||
LOG_INFO("UDP Connect sent to client");
|
||||
}
|
||||
|
||||
void Server::parseTCPConnect(Packet & packet)
|
||||
{
|
||||
// Pop size of message int
|
||||
packet.ReadPrimitive<int>();
|
||||
// Pop packetSize, sequenceNumber and packetsInSequence.
|
||||
popNetworkSegmentOfHeader(packet);
|
||||
|
||||
int messageType = packet.ReadPrimitive<int>();
|
||||
// Read packet ID
|
||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||
@@ -354,9 +351,9 @@ void Server::parseTCPConnect(Packet & packet)
|
||||
|
||||
LOG_INFO("Parsing connections");
|
||||
// Check if player is already connected
|
||||
// Ska vara till lagd i TCPServer receive
|
||||
PlayerID playerID = getPlayerIDFromEndpoint();
|
||||
if (playerID == -1) {
|
||||
LOG_INFO("Server::parseTCPConnect: Not connected");
|
||||
return;
|
||||
}
|
||||
// Create a new player
|
||||
@@ -379,7 +376,7 @@ void Server::parseTCPConnect(Packet & packet)
|
||||
Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID);
|
||||
// Write playerID to packet
|
||||
connnectPacket.WritePrimitive(playerID);
|
||||
m_Reliable.Send(connnectPacket);
|
||||
m_Reliable.Send(connnectPacket, m_ConnectedPlayers.at(playerID));
|
||||
|
||||
Packet firstSnapshot(MessageType::Snapshot);
|
||||
addInputCommandsToPacket(firstSnapshot);
|
||||
@@ -410,7 +407,7 @@ void Server::parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint)
|
||||
Packet packet(MessageType::ServerlistRequest);
|
||||
packet.WriteString(m_Reliable.Address());
|
||||
packet.WritePrimitive<int>(m_Reliable.Port());
|
||||
packet.WriteString("SERVERNAME");
|
||||
packet.WriteString(m_ServerName);
|
||||
packet.WritePrimitive<int>(m_ConnectedPlayers.size());
|
||||
m_ServerlistRequest.Send(packet);
|
||||
}
|
||||
@@ -641,22 +638,7 @@ void Server::parsePlayerTransform(Packet& packet)
|
||||
|
||||
bool Server::shouldSendToClient(EntityWrapper childEntity)
|
||||
{
|
||||
auto children = m_World->GetDirectChildren(childEntity.ID);
|
||||
for (auto it = children.first; it != children.second; it++) {
|
||||
EntityWrapper child(m_World, it->second);
|
||||
if (child.HasComponent("CapturePoint") || child.HasComponent("HealthPickup")
|
||||
|| child.HasComponent("AmmoPickup")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return childEntity.HasComponent("Player")
|
||||
|| childEntity.FirstParentWithComponent("Player").Valid()
|
||||
|| childEntity.HasComponent("CapturePoint")
|
||||
|| childEntity.HasComponent("HealthPickup")
|
||||
|| childEntity.HasComponent("AmmoPickup")
|
||||
|| childEntity.HasComponent("ScoreScreen")
|
||||
|| childEntity.FirstParentWithComponent("ScoreScreen").Valid()
|
||||
|| childEntity.FirstParentWithComponent("CapturePoint").Valid();
|
||||
return childEntity.HasComponent("NetworkComponent") || childEntity.FirstParentWithComponent("NetworkComponent").Valid();
|
||||
}
|
||||
|
||||
PlayerID Server::getPlayerIDFromEndpoint()
|
||||
@@ -681,4 +663,4 @@ PlayerID Server::getPlayerIDFromEntityID(EntityID entityID)
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -3,24 +3,14 @@
|
||||
using namespace boost::asio::ip;
|
||||
|
||||
TCPClient::TCPClient()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
TCPClient::~TCPClient()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
void TCPClient::Connect(std::string playerName, std::string address, int port)
|
||||
bool TCPClient::Connect(std::string playerName, std::string address, int port)
|
||||
{
|
||||
if (m_Socket) {
|
||||
if (m_IsConnected) {
|
||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||
packet.WriteString(playerName);
|
||||
Send(packet);
|
||||
LOG_INFO("Connect message sent again!");
|
||||
}
|
||||
}
|
||||
else if (!m_IsConnected) {
|
||||
if (!m_Socket) {
|
||||
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||
m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||
m_Socket = std::unique_ptr<tcp::socket>(new tcp::socket(m_IOService));
|
||||
@@ -34,24 +24,20 @@ void TCPClient::Connect(std::string playerName, std::string address, int port)
|
||||
packet.WriteString(playerName);
|
||||
Send(packet);
|
||||
LOG_INFO("Connect message sent!");
|
||||
}
|
||||
// If error
|
||||
else {
|
||||
return true;
|
||||
} else { // If error
|
||||
m_Socket->close();
|
||||
m_Socket = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TCPClient::Disconnect()
|
||||
{
|
||||
if (!m_IsConnected) {
|
||||
return;
|
||||
}
|
||||
{
|
||||
m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
m_Socket->close();
|
||||
m_Socket = nullptr;
|
||||
m_IsConnected = false;
|
||||
}
|
||||
|
||||
void TCPClient::Receive(Packet& packet)
|
||||
@@ -63,7 +49,7 @@ void TCPClient::Receive(Packet& packet)
|
||||
}
|
||||
|
||||
size_t TCPClient::readBuffer()
|
||||
{
|
||||
{
|
||||
if (!m_Socket) {
|
||||
return 0;
|
||||
}
|
||||
@@ -89,7 +75,7 @@ size_t TCPClient::readBuffer()
|
||||
while (sizeOfPacket > bytesReceived) {
|
||||
// Read the rest of the message
|
||||
bytesReceived += m_Socket->read_some(boost
|
||||
::asio::buffer((void*)(m_ReadBuffer), sizeOfPacket - bytesReceived),
|
||||
::asio::buffer((void*)(m_ReadBuffer + bytesReceived), sizeOfPacket - bytesReceived),
|
||||
error);
|
||||
if (error) {
|
||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||
|
||||
@@ -48,6 +48,7 @@ void TCPServer::Send(Packet & packet, PlayerDefinition & playerDefinition)
|
||||
{
|
||||
packet.UpdateSize();
|
||||
try {
|
||||
// Crashed once TCPSocket was NULL
|
||||
int bytesSent = playerDefinition.TCPSocket->send(
|
||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||
0);
|
||||
|
||||
@@ -1,38 +1,51 @@
|
||||
#include "Network/UDPClient.h"
|
||||
#include "boost/asio/basic_datagram_socket.hpp"
|
||||
|
||||
using namespace boost::asio::ip;
|
||||
|
||||
UDPClient::UDPClient()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
UDPClient::~UDPClient()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
void UDPClient::Connect(std::string playerName, std::string address, int port)
|
||||
bool UDPClient::Connect(std::string playerName, std::string address, int port)
|
||||
{
|
||||
if (m_Socket) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address().from_string(address), port);
|
||||
m_Socket = boost::shared_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService));
|
||||
m_Socket->open(boost::asio::ip::udp::v4());
|
||||
boost::asio::socket_base::receive_buffer_size option(m_SizeOfSocketBuffer);
|
||||
m_Socket->set_option(option);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UDPClient::Disconnect()
|
||||
{
|
||||
m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
m_Socket->close();
|
||||
m_Socket = nullptr;
|
||||
|
||||
m_LastReceivedSnapshotGroup = 0;
|
||||
m_PacketSegmentMap.clear();
|
||||
PacketID m_SendPacketID = 0;
|
||||
}
|
||||
|
||||
void UDPClient::Receive(Packet& packet)
|
||||
{
|
||||
int bytesRead = readBuffer();
|
||||
if (bytesRead > 0) {
|
||||
if (bytesRead > 0) {
|
||||
packet.ReconstructFromData(m_ReadBuffer, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
void UDPClient::ReceivePackets()
|
||||
{
|
||||
readPartOfPacket();
|
||||
}
|
||||
|
||||
int UDPClient::readBuffer()
|
||||
{
|
||||
if (!m_Socket) {
|
||||
@@ -40,9 +53,9 @@ int UDPClient::readBuffer()
|
||||
}
|
||||
boost::system::error_code error;
|
||||
// Read size of packet
|
||||
m_Socket->receive(boost
|
||||
m_Socket->receive(boost
|
||||
::asio::buffer((void*)m_ReadBuffer, sizeof(int)),
|
||||
boost::asio::ip::udp::socket::message_peek, error);
|
||||
boost::asio::ip::udp::socket::message_peek, error);
|
||||
int sizeOfPacket = 0;
|
||||
memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int));
|
||||
if (sizeOfPacket > m_Socket->available()) {
|
||||
@@ -71,6 +84,72 @@ int UDPClient::readBuffer()
|
||||
return bytesReceived;
|
||||
}
|
||||
|
||||
void UDPClient::readPartOfPacket()
|
||||
{
|
||||
if (!m_Socket) {
|
||||
return;
|
||||
}
|
||||
boost::system::error_code error;
|
||||
// Peek header
|
||||
m_Socket->receive(boost
|
||||
::asio::buffer((void*)m_ReadBuffer, 5 * sizeof(int)),
|
||||
boost::asio::ip::udp::socket::message_peek, error);
|
||||
|
||||
int sizeOfPacket = 0;
|
||||
memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int));
|
||||
if (sizeOfPacket == 0) {
|
||||
return;
|
||||
}
|
||||
int packetGroup = *reinterpret_cast<int*>(m_ReadBuffer + sizeof(int));
|
||||
int packetGroupIndex = *reinterpret_cast<int*>(m_ReadBuffer + 2 * sizeof(int));
|
||||
int packetGroupSize = *reinterpret_cast<int*>(m_ReadBuffer + 3 * sizeof(int));
|
||||
//LOG_INFO("Packet group: %i. Group index: %i. Group size: %i. Packet size: %i.", packetGroup, packetGroupIndex, packetGroupSize, sizeOfPacket);
|
||||
if (sizeOfPacket > m_Socket->available()) {
|
||||
LOG_WARNING("UDPClient::readBuffer(): We haven't got the whole packet yet.");
|
||||
// return;
|
||||
}
|
||||
// if the buffer is to small increase the size of it
|
||||
boost::shared_ptr<char> packetData(new char[sizeOfPacket]);
|
||||
|
||||
// Read the message
|
||||
size_t bytesReceived = m_Socket->receive_from(boost
|
||||
::asio::buffer((void*)(packetData.get()),
|
||||
sizeOfPacket),
|
||||
m_ReceiverEndpoint, 0, error);
|
||||
if (error) {
|
||||
LOG_ERROR("UDPClient::readPartOfPacket: %s", error.message().c_str());
|
||||
}
|
||||
// Might want to do this earlier when i figure out a good way to
|
||||
// remove data from network buffer.
|
||||
if (hasReceivedPacket(packetGroup, packetGroupIndex)) {
|
||||
return;
|
||||
}
|
||||
// If group exists
|
||||
PacketMap::iterator it;
|
||||
it = m_PacketSegmentMap.find(packetGroup);
|
||||
if (it != m_PacketSegmentMap.end()) {
|
||||
it->second.push_back(std::make_pair(packetGroupIndex, std::move(packetData)));
|
||||
} else { // Create group and add element
|
||||
m_PacketSegmentMap[packetGroup].push_back(std::make_pair(packetGroupIndex, std::move(packetData)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool UDPClient::hasReceivedPacket(int packetGroup, int groupIndex)
|
||||
{
|
||||
PacketMap::iterator it;
|
||||
it = m_PacketSegmentMap.find(packetGroup);
|
||||
if (it != m_PacketSegmentMap.end()) {
|
||||
const std::vector<std::pair<int, boost::shared_ptr<char>>>& loopPacketGroup = it->second;
|
||||
for (size_t i = 0; i < loopPacketGroup.size(); i++) {
|
||||
if (loopPacketGroup.at(i).first == groupIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UDPClient::Send(Packet& packet)
|
||||
{
|
||||
packet.UpdateSize();
|
||||
@@ -78,7 +157,7 @@ void UDPClient::Send(Packet& packet)
|
||||
packet.Data(),
|
||||
packet.Size()),
|
||||
m_ReceiverEndpoint, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UDPClient::Broadcast(Packet& packet, int port)
|
||||
{
|
||||
@@ -94,8 +173,55 @@ void UDPClient::Broadcast(Packet& packet, int port)
|
||||
|
||||
bool UDPClient::IsSocketAvailable()
|
||||
{
|
||||
if (!m_Socket) {
|
||||
if (!m_Socket) {
|
||||
return false;
|
||||
}
|
||||
return m_Socket->available();
|
||||
}
|
||||
}
|
||||
|
||||
bool UDPClient::GetNextPacket(Packet & packet)
|
||||
{
|
||||
// A duplicate packet should not be present in the vector!
|
||||
// Soo we will assume that this is true and only look if size
|
||||
// of vector is correct.
|
||||
PacketMap::iterator it = m_PacketSegmentMap.begin();
|
||||
while (it != m_PacketSegmentMap.end()) {
|
||||
// pair(Group index, packetData)
|
||||
std::vector<std::pair<int, boost::shared_ptr<char>>>& currentVector = it->second;
|
||||
Packet headerInfoPacket(currentVector.at(0).second.get(), packet.HeaderSize());
|
||||
int groupSize = headerInfoPacket.GroupSize();
|
||||
//LOG_INFO("UDPClient::GetNextPacket: Packet group : %i.Group index : %i.Group size : %i. lastReceivedSnapshotGroup: %i. MessageType(Ples 4): %i", headerInfoPacket.Group(), headerInfoPacket.GroupIndex(), groupSize, lastReceivedSnapshotGroup, headerInfoPacket.GetMessageType());
|
||||
//LOG_INFO("UDPClient::GetNextPacket: Packet group : %i.lastReceivedSnapshotGroup: %i. MessageType(Ples 4): %i", headerInfoPacket.Group(), lastReceivedSnapshotGroup, headerInfoPacket.GetMessageType());
|
||||
int mapSize = m_PacketSegmentMap.size();
|
||||
if (mapSize > 5) {
|
||||
it = m_PacketSegmentMap.erase(it);
|
||||
LOG_INFO("The map is increasing in size, size is %i", mapSize);
|
||||
continue;
|
||||
}
|
||||
if (headerInfoPacket.GetMessageType() == MessageType::Snapshot && m_LastReceivedSnapshotGroup > headerInfoPacket.Group()) {
|
||||
it = m_PacketSegmentMap.erase(it);
|
||||
continue;
|
||||
//LOG_INFO("Deleted old entry");
|
||||
}
|
||||
if (currentVector.size() == groupSize) {
|
||||
std::sort(currentVector.begin(), currentVector.end());
|
||||
// Add the first packet in vector
|
||||
packet.ReconstructFromData(currentVector.at(0).second.get(), packet.HeaderSize());
|
||||
// Add the rest of the packets.
|
||||
int sizeOfData = 0;
|
||||
for (auto& packetSegment : currentVector) {
|
||||
memcpy(&sizeOfData, packetSegment.second.get(), sizeof(int));
|
||||
packet.WriteData(packetSegment.second.get() + packet.HeaderSize(), sizeOfData - packet.HeaderSize());
|
||||
}
|
||||
if (headerInfoPacket.GetMessageType() == MessageType::Snapshot) {
|
||||
m_LastReceivedSnapshotGroup = packet.Group();
|
||||
}
|
||||
// No need to get next it as we are returning.
|
||||
m_PacketSegmentMap.erase(it);
|
||||
return true;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,34 +12,110 @@ UDPServer::UDPServer(int port)
|
||||
|
||||
UDPServer::~UDPServer()
|
||||
{ }
|
||||
|
||||
void UDPServer::Send(Packet& packet, PlayerDefinition & playerDefinition)
|
||||
// TODO: Fix correct groups
|
||||
void UDPServer::Send(Packet& packet, PlayerDefinition& playerDefinition)
|
||||
{
|
||||
packet.UpdateSize();
|
||||
try {
|
||||
int bytesSent = m_Socket->send_to(
|
||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||
playerDefinition.Endpoint,
|
||||
0);
|
||||
LOG_INFO("Size of packet is %i", bytesSent);
|
||||
// Remove header from packet.
|
||||
packet.ReadData(packet.HeaderSize());
|
||||
int totalBytesSent = 0;
|
||||
int groupIndex = 1;
|
||||
int groupSize = std::ceil((float)packet.Size() / MAXPACKETSIZE);
|
||||
int packetDataSent = 0;
|
||||
int packetDataSize = packet.Size() - packet.HeaderSize();
|
||||
|
||||
while (packetDataSize > packetDataSent) {
|
||||
Packet splitPacket(packet.GetMessageType(), playerDefinition.PacketID);
|
||||
splitPacket.ChangeGroupIndex(groupIndex);
|
||||
splitPacket.ChangeGroupSize(groupSize);
|
||||
splitPacket.ChangeGroup(playerDefinition.PacketGroup);
|
||||
int amountToSend = packetDataSize - packetDataSent;
|
||||
if (amountToSend > MAXPACKETSIZE) {
|
||||
amountToSend = MAXPACKETSIZE;
|
||||
}
|
||||
splitPacket.WriteData(packet.ReadData(amountToSend), amountToSend);
|
||||
splitPacket.UpdateSize();
|
||||
// Remove header size from bytes sent soo that we only
|
||||
// count data in the packet
|
||||
int bytesSent = 0;
|
||||
bytesSent = m_Socket->send_to(
|
||||
boost::asio::buffer(splitPacket.Data(), splitPacket.Size()),
|
||||
playerDefinition.Endpoint,
|
||||
0);
|
||||
packetDataSent += bytesSent - splitPacket.HeaderSize();
|
||||
totalBytesSent += bytesSent;
|
||||
//LOG_INFO("bytesSent size %i, groupIndex: %i. Number of packets: %i", bytesSent, sequenceNumber, totalMessages);
|
||||
++groupIndex;
|
||||
}
|
||||
playerDefinition.PacketGroup++;
|
||||
} catch (const boost::system::system_error& e) {
|
||||
LOG_INFO(e.what());
|
||||
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UDPServer::SendToConnectedPlayers(Packet& packet, std::map<PlayerID, PlayerDefinition>& playersTosendTo)
|
||||
{
|
||||
packet.UpdateSize();
|
||||
// Remove header from packet.
|
||||
packet.ReadData(packet.HeaderSize());
|
||||
int totalBytesSent = 0;
|
||||
int groupIndex = 1;
|
||||
int groupSize = std::ceil((float)packet.Size() / MAXPACKETSIZE);
|
||||
int packetDataSent = 0;
|
||||
int packetDataSize = packet.Size() - packet.HeaderSize();
|
||||
|
||||
while (packetDataSize > packetDataSent) {
|
||||
Packet splitPacket(packet.GetMessageType());
|
||||
splitPacket.ChangeGroupIndex(groupIndex);
|
||||
splitPacket.ChangeGroupSize(groupSize);
|
||||
int amountToSend = packetDataSize - packetDataSent;
|
||||
if (amountToSend > MAXPACKETSIZE) {
|
||||
amountToSend = MAXPACKETSIZE;
|
||||
}
|
||||
splitPacket.WriteData(packet.ReadData(amountToSend), amountToSend);
|
||||
splitPacket.UpdateSize();
|
||||
// Remove header size from bytes sent soo that we only
|
||||
// count data in the packet
|
||||
int bytesSent = 0;
|
||||
for (auto& kv : playersTosendTo) {
|
||||
try {
|
||||
splitPacket.ChangeGroup(kv.second.PacketGroup);
|
||||
bytesSent = m_Socket->send_to(
|
||||
boost::asio::buffer(splitPacket.Data(), splitPacket.Size()),
|
||||
kv.second.Endpoint,
|
||||
0);
|
||||
// LOG_INFO("bytesSent: %i", bytesSent);
|
||||
} catch (const boost::system::system_error& e) {
|
||||
LOG_INFO("UDPServer::SendToConnectedPlayers: Disconnected client. %s", e.what());
|
||||
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||
kv.second.Endpoint = boost::asio::ip::udp::endpoint();
|
||||
}
|
||||
}
|
||||
packetDataSent += splitPacket.Size() - splitPacket.HeaderSize();
|
||||
totalBytesSent += splitPacket.Size();
|
||||
|
||||
//LOG_INFO("bytesSent size %i, groupIndex: %i. Number of packets: %i", bytesSent, sequenceNumber, totalMessages);
|
||||
++groupIndex;
|
||||
}
|
||||
for (auto& kv : playersTosendTo) {
|
||||
kv.second.PacketGroup++;
|
||||
}
|
||||
}
|
||||
|
||||
// Send back to endpoint of received packet
|
||||
void UDPServer::Send(Packet & packet)
|
||||
{
|
||||
packet.UpdateSize();
|
||||
size_t bytesSent = m_Socket->send_to(
|
||||
size_t bytesSent = m_Socket->send_to(
|
||||
boost::asio::buffer(
|
||||
packet.Data(),
|
||||
packet.Size()),
|
||||
m_ReceiverEndpoint,
|
||||
0);
|
||||
LOG_INFO("Size of packet is %i", bytesSent);
|
||||
//LOG_INFO("Size of packet is %i", bytesSent);
|
||||
}
|
||||
|
||||
// Broadcasting respond specific logic
|
||||
@@ -52,7 +128,7 @@ void UDPServer::Send(Packet & packet, boost::asio::ip::udp::endpoint endpoint)
|
||||
packet.Size()),
|
||||
endpoint,
|
||||
0);
|
||||
LOG_INFO("Size of packet is %i", bytesSent);
|
||||
//LOG_INFO("Size of packet is %i", bytesSent);
|
||||
}
|
||||
|
||||
// Broadcasting
|
||||
@@ -64,7 +140,7 @@ void UDPServer::Broadcast(Packet & packet, int port)
|
||||
boost::asio::buffer(
|
||||
packet.Data(),
|
||||
packet.Size()),
|
||||
boost::asio::ip::udp::endpoint(boost::asio::ip::address_v4().broadcast(),port),
|
||||
boost::asio::ip::udp::endpoint(boost::asio::ip::address_v4().broadcast(), port),
|
||||
0);
|
||||
m_Socket->set_option(boost::asio::socket_base::broadcast(false));
|
||||
}
|
||||
@@ -91,7 +167,7 @@ int UDPServer::readBuffer()
|
||||
int addasdasd = m_Socket->available();
|
||||
boost::system::error_code error;
|
||||
// Read size of packet
|
||||
m_Socket->receive_from(boost
|
||||
m_Socket->receive_from(boost
|
||||
::asio::buffer((void*)m_ReadBuffer, sizeof(int)),
|
||||
m_ReceiverEndpoint, boost::asio::ip::udp::socket::message_peek, error);
|
||||
unsigned int sizeOfPacket = 0;
|
||||
@@ -114,13 +190,13 @@ int UDPServer::readBuffer()
|
||||
::asio::buffer((void*)(m_ReadBuffer),
|
||||
sizeOfPacket),
|
||||
m_ReceiverEndpoint, 0, error);
|
||||
if (error) {
|
||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||
}
|
||||
if (sizeOfPacket > 1000000)
|
||||
LOG_WARNING("The packets received are bigger than 1MB");
|
||||
if (error) {
|
||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||
}
|
||||
if (sizeOfPacket > 1000000)
|
||||
LOG_WARNING("The packets received are bigger than 1MB");
|
||||
|
||||
return bytesReceived;
|
||||
return bytesReceived;
|
||||
}
|
||||
|
||||
void UDPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers)
|
||||
|
||||
@@ -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)
|
||||
@@ -123,16 +125,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);
|
||||
@@ -141,10 +143,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++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,46 +187,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"]);
|
||||
(Field<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"]);
|
||||
(Field<bool>)entity["Animation"]["Reverse"] = e.Reverse;
|
||||
|
||||
if (e.Restart) {
|
||||
if (animation != nullptr) {
|
||||
if (e.Restart) {
|
||||
if (e.Reverse) {
|
||||
(Field<double>)nodeEntity["Animation"]["Time"] = animation->Duration;
|
||||
} else {
|
||||
(Field<double>)nodeEntity["Animation"]["Time"] = 0.0;
|
||||
if (e.Restart) {
|
||||
if (animation != nullptr) {
|
||||
if (e.Restart) {
|
||||
if (e.Reverse) {
|
||||
(Field<double>)entity["Animation"]["Time"] = animation->Duration;
|
||||
} else {
|
||||
(Field<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"]);
|
||||
entity["Animation"]["Reverse"] = e.Reverse;
|
||||
|
||||
if (e.Restart) {
|
||||
if (animation != nullptr) {
|
||||
if (e.Restart) {
|
||||
if (e.Reverse) {
|
||||
entity["Animation"]["Time"] = animation->Duration;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
#include "Rendering/BlurHUD.h"
|
||||
|
||||
BlurHUD::BlurHUD(IRenderer* renderer)
|
||||
: m_Renderer(renderer)
|
||||
{
|
||||
InitializeShaderPrograms();
|
||||
InitializeBuffers();
|
||||
InitializeTextures();
|
||||
}
|
||||
|
||||
void BlurHUD::InitializeTextures()
|
||||
{
|
||||
m_BlackTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/Black.png");
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||
}
|
||||
|
||||
void BlurHUD::InitializeShaderPrograms()
|
||||
{
|
||||
m_GaussianProgram_horiz = ResourceManager::Load<ShaderProgram>("##GaussianProgramHoriz");
|
||||
if (m_GaussianProgram_horiz->GetHandle() == 0) {
|
||||
m_GaussianProgram_horiz->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Gaussian_horiz.vert.glsl")));
|
||||
m_GaussianProgram_horiz->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Gaussian_horiz.frag.glsl")));
|
||||
m_GaussianProgram_horiz->Compile();
|
||||
m_GaussianProgram_horiz->BindFragDataLocation(0, "fragmentColor");
|
||||
m_GaussianProgram_horiz->Link();
|
||||
}
|
||||
|
||||
m_GaussianProgram_vert = ResourceManager::Load<ShaderProgram>("##GaussianProgramVert");
|
||||
if (m_GaussianProgram_vert->GetHandle() == 0) {
|
||||
m_GaussianProgram_vert->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Gaussian_vert.vert.glsl")));
|
||||
m_GaussianProgram_vert->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Gaussian_vert.frag.glsl")));
|
||||
m_GaussianProgram_vert->Compile();
|
||||
m_GaussianProgram_vert->BindFragDataLocation(0, "fragmentColor");
|
||||
m_GaussianProgram_vert->Link();
|
||||
}
|
||||
m_FillDepthStencilProgram = ResourceManager::Load<ShaderProgram>("#FillDepthStencilProgram");
|
||||
if (m_FillDepthStencilProgram->GetHandle() == 0) {
|
||||
m_FillDepthStencilProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/FillDepthBuffer.vert.glsl")));
|
||||
m_FillDepthStencilProgram->Compile();
|
||||
m_FillDepthStencilProgram->Link();
|
||||
}
|
||||
m_CombineTexturesProgram = ResourceManager::Load<ShaderProgram>("#CombineTexturesProgram");
|
||||
if (m_CombineTexturesProgram->GetHandle() == 0) {
|
||||
m_CombineTexturesProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/CombineTexture.vert.glsl")));
|
||||
m_CombineTexturesProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/CombineTexture.frag.glsl")));
|
||||
m_CombineTexturesProgram->Compile();
|
||||
m_CombineTexturesProgram->BindFragDataLocation(0, "sceneColor");
|
||||
m_CombineTexturesProgram->BindFragDataLocation(1, "bloomColor");
|
||||
m_CombineTexturesProgram->Link();
|
||||
}
|
||||
GLERROR("Creating DepthFill program");
|
||||
}
|
||||
|
||||
void BlurHUD::InitializeBuffers()
|
||||
{
|
||||
glm::vec2 res = glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glm::vec2 res2 = glm::vec2(m_Renderer->GetViewportSize().Width/m_BlurQuality, m_Renderer->GetViewportSize().Height/m_BlurQuality);
|
||||
|
||||
|
||||
CommonFunctions::GenerateTexture(&m_DepthStencil_horiz, GL_CLAMP_TO_BORDER, GL_NEAREST,
|
||||
res2, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_NEAREST,
|
||||
res2, GL_RGBA16F, GL_RGBA, GL_FLOAT);
|
||||
|
||||
if (m_GaussianFrameBuffer_horiz.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_DepthStencil_horiz, GL_DEPTH_STENCIL_ATTACHMENT)));
|
||||
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_horiz.Generate();
|
||||
|
||||
CommonFunctions::GenerateTexture(&m_DepthStencil_vert, GL_CLAMP_TO_BORDER, GL_NEAREST,
|
||||
res2, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_NEAREST,
|
||||
res2, GL_RGBA16F, GL_RGBA, GL_FLOAT);
|
||||
|
||||
if (m_GaussianFrameBuffer_vert.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_DepthStencil_vert, GL_DEPTH_STENCIL_ATTACHMENT)));
|
||||
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_vert.Generate();
|
||||
|
||||
CommonFunctions::GenerateTexture(&m_CombinedTexture, GL_CLAMP_TO_BORDER, GL_NEAREST,
|
||||
res, GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
|
||||
if (m_CombinedTextureBuffer.GetHandle() == 0) {
|
||||
m_CombinedTextureBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_CombinedTexture, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_CombinedTextureBuffer.Generate();
|
||||
}
|
||||
|
||||
|
||||
void BlurHUD::ClearBuffer()
|
||||
{
|
||||
GLERROR("PRE");
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClearStencil(0x00);
|
||||
glStencilMask(~0);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClearStencil(0x00);
|
||||
glStencilMask(~0);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
|
||||
m_CombinedTextureBuffer.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_CombinedTextureBuffer.Unbind();
|
||||
GLERROR("END");
|
||||
}
|
||||
|
||||
//Returns the finished blurred texture
|
||||
GLuint BlurHUD::Draw(GLuint texture, RenderScene& scene)
|
||||
{
|
||||
GLERROR("DrawBloomPass::Draw: Pre");
|
||||
|
||||
FillStencil(scene);
|
||||
|
||||
RenderState state;
|
||||
state.Disable(GL_BLEND);
|
||||
state.Disable(GL_DEPTH_TEST);
|
||||
state.Disable(GL_CULL_FACE);
|
||||
|
||||
state.Enable(GL_STENCIL_TEST);
|
||||
state.StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
state.StencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
state.StencilMask(0x00);
|
||||
state.DepthMask(GL_FALSE);
|
||||
state.Enable(GL_SCISSOR_TEST);
|
||||
|
||||
GLuint shaderHandle_horiz = m_GaussianProgram_horiz->GetHandle();
|
||||
GLuint shaderHandle_vert = m_GaussianProgram_vert->GetHandle();
|
||||
|
||||
//Horizontal pass, first use the given texture then save it to the horizontal framebuffer.
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
|
||||
glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_BlurQuality, m_Renderer->GetViewportSize().Height/m_BlurQuality);
|
||||
glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
|
||||
m_GaussianProgram_vert->Bind();
|
||||
glUniform1i(glGetUniformLocation(shaderHandle_vert, "Lod"), 0);
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
glUniform1i(glGetUniformLocation(shaderHandle_horiz, "Lod"), 0);
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
//Iterate some times to make it more gaussian.
|
||||
for (int i = 1; i < m_Iterations; i++) {
|
||||
//Vertical pass
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
|
||||
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
//horizontal pass
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_vert);
|
||||
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
}
|
||||
|
||||
//final vertical gaussian after the iterations are done
|
||||
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
|
||||
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
|
||||
GLERROR("DrawBloomPass::Draw: END");
|
||||
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
|
||||
|
||||
return m_GaussianTexture_vert;
|
||||
}
|
||||
|
||||
|
||||
void BlurHUD::OnWindowResize()
|
||||
{
|
||||
InitializeBuffers();
|
||||
}
|
||||
|
||||
void BlurHUD::FillStencil(RenderScene& scene)
|
||||
{
|
||||
RenderState state;
|
||||
|
||||
state.BindFramebuffer(m_GaussianFrameBuffer_horiz.GetHandle());
|
||||
state.Enable(GL_DEPTH_TEST);
|
||||
state.Enable(GL_CULL_FACE);
|
||||
state.Enable(GL_STENCIL_TEST);
|
||||
state.StencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
state.StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
state.StencilMask(0xFF);
|
||||
|
||||
state.AlphaFunc(GL_GEQUAL, 0.95f);
|
||||
state.Enable(GL_ALPHA_TEST);
|
||||
|
||||
glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_BlurQuality, m_Renderer->GetViewportSize().Height/m_BlurQuality);
|
||||
|
||||
m_FillDepthStencilProgram->Bind();
|
||||
|
||||
GLuint shaderHandle = m_FillDepthStencilProgram->GetHandle();
|
||||
glm::mat4 VP = scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix();
|
||||
|
||||
for (auto& job : scene.Jobs.SpriteJob) {
|
||||
auto spriteJob = std::dynamic_pointer_cast<SpriteJob>(job);
|
||||
if (!spriteJob) {
|
||||
continue;
|
||||
}
|
||||
if (!spriteJob->BlurBackground) {
|
||||
continue;
|
||||
}
|
||||
|
||||
glm::mat4 MVP = VP * spriteJob->Matrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(MVP));
|
||||
|
||||
|
||||
glBindVertexArray(spriteJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, spriteJob->Model->ElementBuffer);
|
||||
glDrawElements(GL_TRIANGLES, spriteJob->EndIndex - spriteJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(spriteJob->StartIndex*sizeof(unsigned int)));
|
||||
}
|
||||
|
||||
state.BindFramebuffer(m_GaussianFrameBuffer_vert.GetHandle());
|
||||
for (auto& job : scene.Jobs.SpriteJob) {
|
||||
auto spriteJob = std::dynamic_pointer_cast<SpriteJob>(job);
|
||||
if (!spriteJob) {
|
||||
continue;
|
||||
}
|
||||
if(!spriteJob->BlurBackground) {
|
||||
continue;
|
||||
}
|
||||
glm::mat4 MVP = VP * spriteJob->Matrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(MVP));
|
||||
|
||||
glBindVertexArray(spriteJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, spriteJob->Model->ElementBuffer);
|
||||
glDrawElements(GL_TRIANGLES, spriteJob->EndIndex - spriteJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(spriteJob->StartIndex*sizeof(unsigned int)));
|
||||
}
|
||||
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
}
|
||||
|
||||
//Texture 1 will be used if texture 2 is black at that texel, else texture 2 is used.
|
||||
GLuint BlurHUD::CombineTextures(GLuint texture1, GLuint texture2)
|
||||
{
|
||||
//RenderState state;
|
||||
//state.BindFramebuffer(m_CombinedTextureBuffer.GetHandle());
|
||||
//state.Disable(GL_DEPTH_TEST);
|
||||
//state.Disable(GL_STENCIL_TEST);
|
||||
|
||||
m_CombineTexturesProgram->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||
glBindTexture(GL_TEXTURE_2D, texture2);
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
|
||||
return m_CombinedTexture;
|
||||
}
|
||||
@@ -50,13 +50,15 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
glm::vec4 perspective;
|
||||
glm::decompose(boneTransform, scale, rotation, translation, skew, perspective);
|
||||
|
||||
glm::vec3 angles = glm::vec3(-glm::pitch(rotation), -glm::yaw(rotation), -glm::roll(rotation));
|
||||
rotation = glm::quat((glm::vec3)entity["BoneAttachment"]["OrientationOffset"]) * rotation;
|
||||
rotation = glm::inverse(rotation);
|
||||
glm::vec3 angles = glm::eulerAngles(rotation);
|
||||
|
||||
if ((bool)entity["BoneAttachment"]["InheritPosition"]) {
|
||||
entity["Transform"]["Position"] = translation + (glm::vec3)entity["BoneAttachment"]["PositionOffset"];
|
||||
}
|
||||
if ((bool)entity["BoneAttachment"]["InheritOrientation"]) {
|
||||
entity["Transform"]["Orientation"] = angles + (glm::vec3)entity["BoneAttachment"]["OrientationOffset"];
|
||||
entity["Transform"]["Orientation"] = angles;
|
||||
}
|
||||
if ((bool)entity["BoneAttachment"]["InheritScale"]) {
|
||||
entity["Transform"]["Scale"] = scale * (glm::vec3)entity["BoneAttachment"]["ScaleOffset"];
|
||||
|
||||
@@ -9,9 +9,15 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer, ConfigFile* config)
|
||||
ChangeQuality(m_Config->Get<int>("GLOW.Quality", 2));
|
||||
}
|
||||
|
||||
DrawBloomPass::~DrawBloomPass() {
|
||||
CommonFunctions::DeleteTexture(&m_GaussianTexture_horiz);
|
||||
CommonFunctions::DeleteTexture(&m_GaussianTexture_vert);
|
||||
CommonFunctions::DeleteTexture(&m_FinalGaussianTexture);
|
||||
}
|
||||
|
||||
void DrawBloomPass::InitializeTextures()
|
||||
{
|
||||
m_BlackTexture = CommonFunctions::LoadTexture("Textures/Core/Black.png", false);
|
||||
m_BlackTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/Black.png");
|
||||
}
|
||||
|
||||
void DrawBloomPass::ChangeQuality(int quality)
|
||||
@@ -25,9 +31,8 @@ void DrawBloomPass::ChangeQuality(int quality)
|
||||
|
||||
if (m_Quality == 0) {
|
||||
CommonFunctions::DeleteTexture(&m_GaussianTexture_horiz);
|
||||
CommonFunctions::DeleteTexture(&m_GaussianTexture_vert);
|
||||
m_GaussianTexture_horiz = 0;
|
||||
m_GaussianTexture_vert = 0;
|
||||
CommonFunctions::DeleteTexture(&m_GaussianTexture_vert);
|
||||
CommonFunctions::DeleteTexture(&m_FinalGaussianTexture);
|
||||
return;
|
||||
}
|
||||
InitializeTextures();
|
||||
@@ -57,22 +62,50 @@ void DrawBloomPass::InitializeShaderPrograms()
|
||||
m_GaussianProgram_vert->BindFragDataLocation(0, "fragmentColor");
|
||||
m_GaussianProgram_vert->Link();
|
||||
}
|
||||
|
||||
m_GaussianCombineProgram = ResourceManager::Load<ShaderProgram>("#GaussianCombineProgram");
|
||||
if (m_GaussianCombineProgram->GetHandle() == 0) {
|
||||
m_GaussianCombineProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/CombineGaussianTexture.vert.glsl")));
|
||||
m_GaussianCombineProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/CombineGaussianTexture.frag.glsl")));
|
||||
m_GaussianCombineProgram->Compile();
|
||||
m_GaussianCombineProgram->BindFragDataLocation(0, "fragmentColor");
|
||||
m_GaussianCombineProgram->Link();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBloomPass::InitializeBuffers()
|
||||
{
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateMipMapTexture(
|
||||
&m_GaussianTexture_horiz, GL_CLAMP_TO_BORDER, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height)
|
||||
, GL_RGB, GL_FLOAT, m_BloomLod);
|
||||
CommonFunctions::GenerateMipMapTexture(
|
||||
&m_GaussianTexture_vert, GL_CLAMP_TO_BORDER, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height)
|
||||
, GL_RGB, GL_FLOAT, m_BloomLod);
|
||||
CommonFunctions::GenerateTexture(&m_FinalGaussianTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
|
||||
if (m_GaussianFrameBuffer_horiz.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_horiz.Generate();
|
||||
if (m_GaussianCombineBuffer.GetHandle() == 0) {
|
||||
m_GaussianCombineBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_FinalGaussianTexture, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianCombineBuffer.Generate();
|
||||
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
if (m_GaussianFrameBuffer_vert.GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0)));
|
||||
}
|
||||
m_GaussianFrameBuffer_vert.Generate();
|
||||
if(m_GaussianFrameBuffer_horiz == nullptr) {
|
||||
m_GaussianFrameBuffer_horiz = new FrameBuffer[m_BloomLod];
|
||||
}
|
||||
if (m_GaussianFrameBuffer_vert == nullptr) {
|
||||
m_GaussianFrameBuffer_vert = new FrameBuffer[m_BloomLod];
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_BloomLod; i++) {
|
||||
if(m_GaussianFrameBuffer_horiz[i].GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_horiz[i].AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0, i)));
|
||||
}
|
||||
m_GaussianFrameBuffer_horiz[i].Generate();
|
||||
|
||||
if (m_GaussianFrameBuffer_vert[i].GetHandle() == 0) {
|
||||
m_GaussianFrameBuffer_vert[i].AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0, i)));
|
||||
}
|
||||
m_GaussianFrameBuffer_vert[i].Generate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,33 +115,64 @@ void DrawBloomPass::ClearBuffer()
|
||||
return;
|
||||
}
|
||||
GLERROR("PRE");
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
for (int i = 0; i < m_BloomLod; i++) {
|
||||
m_GaussianFrameBuffer_horiz[i].Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_horiz[i].Unbind();
|
||||
m_GaussianFrameBuffer_vert[i].Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_vert[i].Unbind();
|
||||
|
||||
}
|
||||
m_GaussianCombineBuffer.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
m_GaussianCombineBuffer.Unbind();
|
||||
GLERROR("END");
|
||||
}
|
||||
|
||||
void DrawBloomPass::Draw(GLuint texture)
|
||||
{
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_BloomLod; i++) {
|
||||
GaussianLodPass(i, texture);
|
||||
}
|
||||
CombineGaussianBlur();
|
||||
}
|
||||
|
||||
|
||||
void DrawBloomPass::OnWindowResize()
|
||||
{
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
GLERROR("DrawBloomPass::Draw: Pre");
|
||||
InitializeBuffers();
|
||||
}
|
||||
|
||||
void DrawBloomPass::GaussianLodPass(GLuint mipMap, GLuint texture)
|
||||
{
|
||||
GLERROR("DrawBloomPass::Draw: Pre");
|
||||
glViewport(0, 0, m_Renderer->GetViewportSize().Width/(glm::pow(2, mipMap)), m_Renderer->GetViewportSize().Height/(glm::pow(2, mipMap)));
|
||||
DrawBloomPassState state;
|
||||
|
||||
GLuint shaderHandle_horiz = m_GaussianProgram_horiz->GetHandle();
|
||||
GLuint shaderHandle_vert = m_GaussianProgram_vert->GetHandle();
|
||||
|
||||
m_GaussianProgram_vert->Bind();
|
||||
glUniform1i(glGetUniformLocation(shaderHandle_vert, "Lod"), mipMap);
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
glUniform1i(glGetUniformLocation(shaderHandle_horiz, "Lod"), mipMap);
|
||||
|
||||
|
||||
//Horizontal pass, first use the given texture then save it to the horizontal framebuffer.
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
m_GaussianFrameBuffer_horiz[mipMap].Bind();
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
@@ -118,55 +182,56 @@ void DrawBloomPass::Draw(GLuint texture)
|
||||
//Iterate some times to make it more gaussian.
|
||||
for (int i = 1; i < m_Iterations; i++) {
|
||||
//Vertical pass
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianFrameBuffer_vert[mipMap].Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
//horizontal pass
|
||||
m_GaussianFrameBuffer_vert.Unbind();
|
||||
m_GaussianFrameBuffer_vert[mipMap].Unbind();
|
||||
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
m_GaussianFrameBuffer_horiz[mipMap].Bind();
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_vert);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
m_GaussianFrameBuffer_horiz[mipMap].Unbind();
|
||||
}
|
||||
|
||||
//final vertical gaussian after the iterations are done
|
||||
|
||||
m_GaussianFrameBuffer_vert.Bind();
|
||||
m_GaussianFrameBuffer_vert[mipMap].Bind();
|
||||
m_GaussianProgram_vert->Bind();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz);
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
|
||||
GLERROR("DrawBloomPass::Draw: END");
|
||||
glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
m_GaussianFrameBuffer_vert[mipMap].Unbind();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DrawBloomPass::OnWindowResize()
|
||||
void DrawBloomPass::CombineGaussianBlur()
|
||||
{
|
||||
if (m_Quality == 0) {
|
||||
return;
|
||||
}
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
m_GaussianFrameBuffer_vert.Generate();
|
||||
CommonFunctions::GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
m_GaussianFrameBuffer_horiz.Generate();
|
||||
m_GaussianCombineBuffer.Bind();
|
||||
m_GaussianCombineProgram->Bind();
|
||||
glUniform1i(glGetUniformLocation(m_GaussianCombineProgram->GetHandle(), "MaxMipMap"), m_BloomLod);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_vert);
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -12,20 +13,28 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCulling
|
||||
InitializeFrameBuffers();
|
||||
}
|
||||
|
||||
DrawFinalPass::~DrawFinalPass(){
|
||||
CommonFunctions::DeleteTexture(&m_BloomTexture);
|
||||
CommonFunctions::DeleteTexture(&m_SceneTexture);
|
||||
CommonFunctions::DeleteTexture(&m_DepthBuffer);
|
||||
CommonFunctions::DeleteTexture(&m_ShieldBuffer);
|
||||
CommonFunctions::DeleteTexture(&m_CubeMapTexture);
|
||||
}
|
||||
|
||||
void DrawFinalPass::InitializeTextures()
|
||||
{
|
||||
m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false);
|
||||
m_BlackTexture = CommonFunctions::LoadTexture("Textures/Core/Black.png", false);
|
||||
m_NeutralNormalTexture = CommonFunctions::LoadTexture("Textures/Core/NeutralNormalMap.png", false);
|
||||
m_GreyTexture = CommonFunctions::LoadTexture("Textures/Core/Grey.png", false);
|
||||
m_ErrorTexture = CommonFunctions::LoadTexture("Textures/Core/ErrorTexture.png", false);
|
||||
m_WhiteTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/White.png");
|
||||
m_BlackTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/Black.png");
|
||||
m_NeutralNormalTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/NeutralNormalMap.png");
|
||||
m_GreyTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/Grey.png");
|
||||
m_ErrorTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/ErrorTexture.png");
|
||||
}
|
||||
|
||||
void DrawFinalPass::InitializeFrameBuffers()
|
||||
{
|
||||
CommonFunctions::GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
//GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
//GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4);
|
||||
//GenerateTexture(&m_StencilTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_STENCIL, GL_STENCIL_INDEX8, GL_INT);
|
||||
|
||||
@@ -233,7 +242,7 @@ void DrawFinalPass::InitializeShaderPrograms()
|
||||
|
||||
}
|
||||
|
||||
void DrawFinalPass::Draw(RenderScene& scene)
|
||||
void DrawFinalPass::Draw(RenderScene& scene, BlurHUD* blurHUDPass)
|
||||
{
|
||||
GLERROR("Pre");
|
||||
DrawFinalPassState* stateDethp = new DrawFinalPassState(m_ShieldDepthFrameBuffer.GetHandle());
|
||||
@@ -280,16 +289,34 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
||||
DrawModelRenderQueuesWithShieldCheck(scene.Jobs.TransparentObjects, scene); //might need changing
|
||||
GLERROR("Shielded Transparent objects");
|
||||
|
||||
//Generate blur texture.
|
||||
delete state;
|
||||
if (scene.ShouldBlur) {
|
||||
//This needs to be drawn only when the full scene is being renderd, and then let be, otherwise sprite and other shit will show on it.
|
||||
m_FullBlurredTexture = blurHUDPass->Draw(m_SceneTexture, scene);
|
||||
}
|
||||
|
||||
DrawFinalPassState* stateSprite = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle());
|
||||
if(scene.ShouldBlur) {
|
||||
//Combine nonblur and blur texture
|
||||
stateSprite->Disable(GL_DEPTH_TEST);
|
||||
stateSprite->Disable(GL_STENCIL_TEST);
|
||||
m_CombinedTexture = blurHUDPass->CombineTextures(m_SceneTexture, m_FullBlurredTexture);
|
||||
|
||||
}
|
||||
//Draw Transparen objects
|
||||
//state->BlendFunc(GL_ONE, GL_ONE);
|
||||
//state->StencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
//DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene);
|
||||
GLERROR("TransparentObjects");
|
||||
//state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
stateSprite->Enable(GL_DEPTH_TEST);
|
||||
//stateSprite->AlphaFunc(GL_GEQUAL, 0.05f);
|
||||
//stateSprite->Enable(GL_ALPHA_TEST);
|
||||
DrawSprites(scene.Jobs.SpriteJob, scene);
|
||||
GLERROR("SpriteJobs");
|
||||
|
||||
delete state;
|
||||
delete stateSprite;
|
||||
GLERROR("END");
|
||||
|
||||
}
|
||||
@@ -318,8 +345,8 @@ void DrawFinalPass::OnWindowResize()
|
||||
//InitializeFrameBuffers();
|
||||
CommonFunctions::GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST,
|
||||
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
|
||||
CommonFunctions::GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
CommonFunctions::GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT);
|
||||
m_FinalPassFrameBuffer.Generate();
|
||||
|
||||
GLERROR("Error changing texture resolutions");
|
||||
@@ -335,6 +362,8 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
GLuint explosionSkinnedHandle = m_ExplosionEffectSkinnedProgram->GetHandle();
|
||||
GLuint explosionSplatMapSkinnedHandle = m_ExplosionEffectSplatMapSkinnedProgram->GetHandle();
|
||||
GLuint forwardSplatMapSkinnedHandle = m_ForwardPlusSplatMapSkinnedProgram->GetHandle();
|
||||
GLuint lastShader = 0;
|
||||
unsigned int lastModel = 0;
|
||||
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO());
|
||||
@@ -343,6 +372,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) {
|
||||
@@ -351,9 +387,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
case RawModel::MaterialType::SingleTextures:
|
||||
{
|
||||
if (explosionEffectJob->Model->IsSkinned()) {
|
||||
|
||||
m_ExplosionEffectSkinnedProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSkinned program");
|
||||
if (lastShader != m_ExplosionEffectSkinnedProgram->GetHandle()) {
|
||||
m_ExplosionEffectSkinnedProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSkinned program");
|
||||
glUniform1i(glGetUniformLocation(explosionSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSkinned Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -373,8 +417,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
|
||||
}
|
||||
else {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffect program");
|
||||
if (lastShader != m_ExplosionEffectProgram->GetHandle()) {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
lastShader = m_ExplosionEffectProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffect program");
|
||||
glUniform1i(glGetUniformLocation(explosionHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffect Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -388,8 +441,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
case RawModel::MaterialType::SplatMapping:
|
||||
{
|
||||
if (explosionEffectJob->Model->IsSkinned()) {
|
||||
m_ExplosionEffectSplatMapSkinnedProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSplatMapSkinned program");
|
||||
if (lastShader != m_ExplosionEffectSplatMapSkinnedProgram->GetHandle()) {
|
||||
m_ExplosionEffectSplatMapSkinnedProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSplatMapSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSplatMapSkinned program");
|
||||
glUniform1i(glGetUniformLocation(explosionSplatMapSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSplatMapSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSplatMapSkinned Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -405,9 +467,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
|
||||
}
|
||||
else {
|
||||
m_ExplosionEffectSplatMapProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSplatMap program");
|
||||
//bind uniforms
|
||||
if (lastShader != m_ExplosionEffectSplatMapProgram->GetHandle()) {
|
||||
m_ExplosionEffectSplatMapProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSplatMapProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSplatMap program");
|
||||
glUniform1i(glGetUniformLocation(explosionSplatMapHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSplatMapHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSplatMapHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -420,8 +490,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
//draw
|
||||
glBindVertexArray(explosionEffectJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer);
|
||||
if (lastModel != explosionEffectJob->ModelID) {
|
||||
glBindVertexArray(explosionEffectJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer);
|
||||
lastModel = explosionEffectJob->ModelID;
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int)));
|
||||
glEnable(GL_CULL_FACE);
|
||||
GLERROR("explosion effect end");
|
||||
@@ -435,8 +508,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
case RawModel::MaterialType::SingleTextures:
|
||||
{
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_ForwardPlusSkinnedProgram->Bind();
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram");
|
||||
if (lastShader != m_ForwardPlusSkinnedProgram->GetHandle()) {
|
||||
m_ForwardPlusSkinnedProgram->Bind();
|
||||
lastShader = m_ForwardPlusSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram program");
|
||||
glUniform1i(glGetUniformLocation(forwardSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSkinnedHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -454,8 +536,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
}
|
||||
else {
|
||||
m_ForwardPlusProgram->Bind();
|
||||
GLERROR("Bind ForwardPlusProgram");
|
||||
if (lastShader != m_ForwardPlusProgram->GetHandle()) {
|
||||
m_ForwardPlusProgram->Bind();
|
||||
lastShader = m_ForwardPlusProgram->GetHandle();
|
||||
GLERROR("Bind ForwardPlusProgram program");
|
||||
glUniform1i(glGetUniformLocation(forwardHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ForwardPlusProgram Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -469,8 +560,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
case RawModel::MaterialType::SplatMapping:
|
||||
{
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_ForwardPlusSplatMapSkinnedProgram->Bind();
|
||||
GLERROR("Bind SplatMap program");
|
||||
if (lastShader != m_ForwardPlusSplatMapSkinnedProgram->GetHandle()) {
|
||||
m_ForwardPlusSplatMapSkinnedProgram->Bind();
|
||||
lastShader = m_ForwardPlusSplatMapSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind SkinnedSplatMapProgram program");
|
||||
glUniform1i(glGetUniformLocation(forwardSplatMapSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSplatMapSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind SkinnedSplatMapProgram Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -486,8 +586,17 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
|
||||
}
|
||||
else {
|
||||
m_ForwardPlusSplatMapProgram->Bind();
|
||||
GLERROR("Bind SplatMap program");
|
||||
if (lastShader != m_ForwardPlusSplatMapProgram->GetHandle()) {
|
||||
m_ForwardPlusSplatMapProgram->Bind();
|
||||
lastShader = m_ForwardPlusSplatMapProgram->GetHandle();
|
||||
GLERROR("Bind SplatMap program");
|
||||
glUniform1i(glGetUniformLocation(forwardSplatMapHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSplatMapHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSplatMapHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind SplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSplatMapHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -498,8 +607,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
}
|
||||
}
|
||||
//draw
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
if (lastModel != modelJob->ModelID) {
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
lastModel = modelJob->ModelID;
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int)));
|
||||
if (GLERROR("models end")) {
|
||||
continue;
|
||||
@@ -528,6 +640,8 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
GLuint explosionSkinnedShieldCheckHandle = m_ExplosionEffectSkinnedShieldCheckProgram->GetHandle();
|
||||
GLuint explosionSplatMapSkinnedShieldCheckHandle = m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->GetHandle();
|
||||
GLuint forwardSplatMapSkinnedShieldCheckHandle = m_ForwardPlusSplatMapSkinnedShieldCheckProgram->GetHandle();
|
||||
GLuint lastShader = 0;
|
||||
unsigned int lastModel = 0;
|
||||
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO());
|
||||
@@ -548,9 +662,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SingleTextures:
|
||||
{
|
||||
if (explosionEffectJob->Model->IsSkinned()) {
|
||||
|
||||
m_ExplosionEffectSkinnedShieldCheckProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSkinned program");
|
||||
if (lastShader != m_ExplosionEffectSkinnedShieldCheckProgram->GetHandle()) {
|
||||
m_ExplosionEffectSkinnedShieldCheckProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSkinnedShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSkinned program");
|
||||
glUniform1i(glGetUniformLocation(explosionSkinnedShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSkinnedShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSkinnedShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSkinned Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSkinnedShieldCheckHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -569,8 +691,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
|
||||
}
|
||||
else {
|
||||
m_ExplosionEffectShieldCheckProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffect program");
|
||||
if (lastShader != m_ExplosionEffectShieldCheckProgram->GetHandle()) {
|
||||
m_ExplosionEffectShieldCheckProgram->Bind();
|
||||
lastShader = m_ExplosionEffectShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffect program");
|
||||
glUniform1i(glGetUniformLocation(explosionShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffect Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionShieldCheckHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -585,8 +716,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SplatMapping:
|
||||
{
|
||||
if (explosionEffectJob->Model->IsSkinned()) {
|
||||
m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSplatMapSkinned program");
|
||||
if (lastShader != m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->GetHandle()) {
|
||||
m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSplatMapSkinned program");
|
||||
glUniform1i(glGetUniformLocation(explosionSplatMapSkinnedShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSplatMapSkinnedShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSplatMapSkinnedShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSplatMapSkinned Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSplatMapSkinnedShieldCheckHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -603,9 +743,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
|
||||
}
|
||||
else {
|
||||
m_ExplosionEffectSplatMapShieldCheckProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSplatMap program");
|
||||
//bind uniforms
|
||||
if (lastShader != m_ExplosionEffectSplatMapShieldCheckProgram->GetHandle()) {
|
||||
m_ExplosionEffectSplatMapShieldCheckProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSplatMapShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSplatMap program");
|
||||
glUniform1i(glGetUniformLocation(explosionSplatMapShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSplatMapShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSplatMapShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSplatMapShieldCheckHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -621,9 +769,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SingleTextures:
|
||||
{
|
||||
if (explosionEffectJob->Model->IsSkinned()) {
|
||||
|
||||
m_ExplosionEffectSkinnedProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSkinned program");
|
||||
if (lastShader != m_ExplosionEffectSkinnedProgram->GetHandle()) {
|
||||
m_ExplosionEffectSkinnedProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSkinned program");
|
||||
glUniform1i(glGetUniformLocation(explosionSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSkinned Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -641,8 +797,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
}
|
||||
else {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffect program");
|
||||
if (lastShader != m_ExplosionEffectProgram->GetHandle()) {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
lastShader = m_ExplosionEffectProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffect program");
|
||||
glUniform1i(glGetUniformLocation(explosionHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffect Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -656,8 +821,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SplatMapping:
|
||||
{
|
||||
if (explosionEffectJob->Model->IsSkinned()) {
|
||||
m_ExplosionEffectSplatMapSkinnedProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSplatMapSkinned program");
|
||||
if (lastShader != m_ExplosionEffectSplatMapSkinnedProgram->GetHandle()) {
|
||||
m_ExplosionEffectSplatMapSkinnedProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSplatMapSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSkinnedSplatMap program");
|
||||
glUniform1i(glGetUniformLocation(explosionSplatMapSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSplatMapSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSkinnedSplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -673,9 +847,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
|
||||
}
|
||||
else {
|
||||
m_ExplosionEffectSplatMapProgram->Bind();
|
||||
GLERROR("Bind ExplosionEffectSplatMap program");
|
||||
//bind uniforms
|
||||
if (lastShader != m_ExplosionEffectSplatMapProgram->GetHandle()) {
|
||||
m_ExplosionEffectSplatMapProgram->Bind();
|
||||
lastShader = m_ExplosionEffectSplatMapProgram->GetHandle();
|
||||
GLERROR("Bind ExplosionEffectSplatMap program");
|
||||
glUniform1i(glGetUniformLocation(explosionSplatMapHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(explosionSplatMapHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(explosionSplatMapHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ExplosionEffectSplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene);
|
||||
//bind textures
|
||||
@@ -689,8 +871,11 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
//draw
|
||||
glBindVertexArray(explosionEffectJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer);
|
||||
if (lastModel != explosionEffectJob->ModelID) {
|
||||
glBindVertexArray(explosionEffectJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer);
|
||||
lastModel = explosionEffectJob->ModelID;
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int)));
|
||||
glEnable(GL_CULL_FACE);
|
||||
GLERROR("explosion effect end");
|
||||
@@ -705,8 +890,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SingleTextures:
|
||||
{
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_ForwardPlusSkinnedShieldCheckProgram->Bind();
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram");
|
||||
if (lastShader != m_ForwardPlusSkinnedShieldCheckProgram->GetHandle()) {
|
||||
m_ForwardPlusSkinnedShieldCheckProgram->Bind();
|
||||
lastShader = m_ForwardPlusSkinnedShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram program");
|
||||
glUniform1i(glGetUniformLocation(forwardSkinnedShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSkinnedShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSkinnedShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSkinnedShieldCheckHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -725,8 +919,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
|
||||
}
|
||||
else {
|
||||
m_ForwardPlusShieldCheckProgram->Bind();
|
||||
GLERROR("Bind ForwardPlusProgram");
|
||||
if (lastShader != m_ForwardPlusShieldCheckProgram->GetHandle()) {
|
||||
m_ForwardPlusShieldCheckProgram->Bind();
|
||||
lastShader = m_ForwardPlusShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind ForwardPlusProgram program");
|
||||
glUniform1i(glGetUniformLocation(forwardShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ForwardPlusProgram Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardShieldCheckHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -740,8 +943,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SplatMapping:
|
||||
{
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_ForwardPlusSplatMapSkinnedShieldCheckProgram->Bind();
|
||||
GLERROR("Bind SplatMap program");
|
||||
if (lastShader != m_ForwardPlusSplatMapSkinnedShieldCheckProgram->GetHandle()) {
|
||||
m_ForwardPlusSplatMapSkinnedShieldCheckProgram->Bind();
|
||||
lastShader = m_ForwardPlusSplatMapSkinnedShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind ForwardPlusProgramSplatMapSkinned program");
|
||||
glUniform1i(glGetUniformLocation(forwardSplatMapSkinnedShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSplatMapSkinnedShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSplatMapSkinnedShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ForwardPlusProgramSplatMapSkinned Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSplatMapSkinnedShieldCheckHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -757,8 +969,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedShieldCheckHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
}
|
||||
else {
|
||||
m_ForwardPlusSplatMapShieldCheckProgram->Bind();
|
||||
GLERROR("Bind SplatMap program");
|
||||
if (lastShader != m_ForwardPlusSplatMapShieldCheckProgram->GetHandle()) {
|
||||
m_ForwardPlusSplatMapShieldCheckProgram->Bind();
|
||||
lastShader = m_ForwardPlusSplatMapShieldCheckProgram->GetHandle();
|
||||
GLERROR("Bind SplatMap program");
|
||||
glUniform1i(glGetUniformLocation(forwardSplatShieldCheckHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatShieldCheckHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatShieldCheckHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSplatShieldCheckHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSplatShieldCheckHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind SplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSplatShieldCheckHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -774,8 +995,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SingleTextures:
|
||||
{
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_ForwardPlusSkinnedProgram->Bind();
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram");
|
||||
if (lastShader != m_ForwardPlusSkinnedProgram->GetHandle()) {
|
||||
m_ForwardPlusSkinnedProgram->Bind();
|
||||
lastShader = m_ForwardPlusSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram program");
|
||||
glUniform1i(glGetUniformLocation(forwardSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ForwardPlusSkinnedProgram Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSkinnedHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -794,8 +1024,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
|
||||
}
|
||||
else {
|
||||
m_ForwardPlusProgram->Bind();
|
||||
GLERROR("Bind ForwardPlusProgram");
|
||||
if (lastShader != m_ForwardPlusProgram->GetHandle()) {
|
||||
m_ForwardPlusProgram->Bind();
|
||||
lastShader = m_ForwardPlusProgram->GetHandle();
|
||||
GLERROR("Bind ForwardPlusProgram program");
|
||||
glUniform1i(glGetUniformLocation(forwardHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind ForwardPlusProgram Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -809,8 +1048,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
case RawModel::MaterialType::SplatMapping:
|
||||
{
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_ForwardPlusSplatMapSkinnedProgram->Bind();
|
||||
GLERROR("Bind SplatMap program");
|
||||
if (lastShader != m_ForwardPlusSplatMapSkinnedProgram->GetHandle()) {
|
||||
m_ForwardPlusSplatMapSkinnedProgram->Bind();
|
||||
lastShader = m_ForwardPlusSplatMapSkinnedProgram->GetHandle();
|
||||
GLERROR("Bind SplatMap program");
|
||||
glUniform1i(glGetUniformLocation(forwardSplatMapSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSplatMapSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind SplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -826,8 +1074,17 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
}
|
||||
else {
|
||||
m_ForwardPlusSplatMapProgram->Bind();
|
||||
GLERROR("Bind SplatMap program");
|
||||
if (lastShader != m_ForwardPlusSplatMapProgram->GetHandle()) {
|
||||
m_ForwardPlusSplatMapProgram->Bind();
|
||||
lastShader = m_ForwardPlusSplatMapProgram->GetHandle();
|
||||
GLERROR("Bind SplatMap program");
|
||||
glUniform1i(glGetUniformLocation(forwardSplatMapHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(forwardSplatMapHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(forwardSplatMapHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind SplatMap Uniforms");
|
||||
}
|
||||
//bind uniforms
|
||||
BindModelUniforms(forwardSplatMapHandle, modelJob, scene);
|
||||
//bind textures
|
||||
@@ -839,8 +1096,11 @@ void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list<std::shared_p
|
||||
}
|
||||
}
|
||||
//draw
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
if (lastModel != modelJob->ModelID) {
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
lastModel = modelJob->ModelID;
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int)));
|
||||
if (GLERROR("models end")) {
|
||||
continue;
|
||||
@@ -945,17 +1205,26 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
|
||||
void DrawFinalPass::DrawToDepthStencilBuffer(std::list<std::shared_ptr<RenderJob>>& jobs, RenderScene& scene)
|
||||
{
|
||||
|
||||
|
||||
GLuint shaderSkinnedHandle = m_FillDepthStencilBufferSkinnedProgram->GetHandle();
|
||||
GLuint shaderHandle = m_FillDepthStencilBufferProgram->GetHandle();
|
||||
GLuint lastShader = 0;
|
||||
for (auto &job : jobs) {
|
||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||
|
||||
if(modelJob->Model->IsSkinned()) {
|
||||
m_FillDepthStencilBufferSkinnedProgram->Bind();
|
||||
GLuint shaderHandle = m_FillDepthStencilBufferSkinnedProgram->GetHandle();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
if (lastShader != m_FillDepthStencilBufferSkinnedProgram->GetHandle()) {
|
||||
m_FillDepthStencilBufferSkinnedProgram->Bind();
|
||||
lastShader = m_FillDepthStencilBufferSkinnedProgram->GetHandle();
|
||||
glUniform1i(glGetUniformLocation(shaderSkinnedHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(shaderSkinnedHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(shaderSkinnedHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind Uniforms 1");
|
||||
}
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * modelJob->Matrix));
|
||||
GLERROR("Bind PVM uniform");
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->BlendTree != nullptr) {
|
||||
@@ -966,11 +1235,19 @@ void DrawFinalPass::DrawToDepthStencilBuffer(std::list<std::shared_ptr<RenderJob
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
m_FillDepthStencilBufferProgram->Bind();
|
||||
GLuint shaderHandle = m_FillDepthStencilBufferProgram->GetHandle();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
if (lastShader != m_FillDepthStencilBufferProgram->GetHandle()) {
|
||||
m_FillDepthStencilBufferProgram->Bind();
|
||||
lastShader = m_FillDepthStencilBufferProgram->GetHandle();
|
||||
glUniform1i(glGetUniformLocation(shaderHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind Uniforms 2");
|
||||
}
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * modelJob->Matrix));
|
||||
GLERROR("Bind PVM uniform");
|
||||
}
|
||||
|
||||
|
||||
@@ -992,25 +1269,36 @@ void DrawFinalPass::DrawSprites(std::list<std::shared_ptr<RenderJob>>&jobs, Rend
|
||||
|
||||
GLuint shaderHandle = m_SpriteProgram->GetHandle();
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform3fv(glGetUniformLocation(shaderHandle, "CameraPos"), 1, glm::value_ptr(scene.Camera->Position()));
|
||||
RenderState* jobState = new RenderState();
|
||||
|
||||
|
||||
for(auto& job : jobs) {
|
||||
auto spriteJob = std::dynamic_pointer_cast<SpriteJob>(job);
|
||||
RenderState jobState;
|
||||
|
||||
if (spriteJob) {
|
||||
if(spriteJob->Depth == 0) {
|
||||
jobState.Disable(GL_DEPTH_TEST);
|
||||
jobState->Disable(GL_DEPTH_TEST);
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(spriteJob->Matrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform3fv(glGetUniformLocation(shaderHandle, "CameraPos"), 1, glm::value_ptr(scene.Camera->Position()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * spriteJob->Matrix));
|
||||
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(spriteJob->Color));
|
||||
glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(spriteJob->FillColor));
|
||||
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), spriteJob->FillPercentage);
|
||||
glUniform1f(glGetUniformLocation(shaderHandle, "ScaleX"), spriteJob->ScaleX);
|
||||
glUniform1f(glGetUniformLocation(shaderHandle, "ScaleY"), spriteJob->ScaleY);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
if (spriteJob->DiffuseTexture != nullptr) {
|
||||
glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture->m_Texture);
|
||||
if (spriteJob->Linear) {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, m_ErrorTexture->m_Texture);
|
||||
}
|
||||
@@ -1028,22 +1316,20 @@ void DrawFinalPass::DrawSprites(std::list<std::shared_ptr<RenderJob>>&jobs, Rend
|
||||
glDrawElements(GL_TRIANGLES, spriteJob->EndIndex - spriteJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(spriteJob->StartIndex*sizeof(unsigned int)));
|
||||
}
|
||||
}
|
||||
delete jobState;
|
||||
// m_SpriteProgram->Unbind();
|
||||
}
|
||||
|
||||
void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<ExplosionEffectJob>& job, RenderScene& scene)
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(shaderHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
GLERROR("Bind 1 uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix));
|
||||
GLERROR("Bind 2 uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
GLERROR("Bind 3 uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
GLERROR("Bind 4 uniform");
|
||||
|
||||
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
GLERROR("Bind 5 uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * job->Matrix));
|
||||
GLERROR("Bind PVM uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "VM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix() * job->Matrix));
|
||||
GLERROR("Bind VM uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "TIM"), 1, GL_FALSE, glm::value_ptr(glm::transpose(glm::inverse(job->Matrix))));
|
||||
GLERROR("Bind TIM uniform");
|
||||
|
||||
glUniform3fv(glGetUniformLocation(shaderHandle, "ExplosionOrigin"), 1, glm::value_ptr(job->ExplosionOrigin));
|
||||
GLERROR("Bind 6 uniform");
|
||||
@@ -1074,29 +1360,25 @@ void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr<E
|
||||
GLERROR("Bind 18 uniform");
|
||||
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), job->FillPercentage);
|
||||
GLERROR("Bind 19 uniform");
|
||||
glUniform4fv(glGetUniformLocation(shaderHandle, "AmbientColor"), 1, glm::value_ptr(scene.AmbientColor));
|
||||
GLERROR("Bind 20 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");
|
||||
}
|
||||
|
||||
void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr<ModelJob>& job, RenderScene& scene)
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(shaderHandle, "SSAOQuality"), m_SSAOPass->TextureQuality());
|
||||
GLERROR("Bind 1 uniform");
|
||||
GLint Location_M = glGetUniformLocation(shaderHandle, "M");
|
||||
glUniformMatrix4fv(Location_M, 1, GL_FALSE, glm::value_ptr(job->Matrix));
|
||||
GLERROR("Bind 2 uniform");
|
||||
GLint Location_V = glGetUniformLocation(shaderHandle, "V");
|
||||
glUniformMatrix4fv(Location_V, 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
GLERROR("Bind 3 uniform");
|
||||
GLint Location_P = glGetUniformLocation(shaderHandle, "P");
|
||||
glUniformMatrix4fv(Location_P, 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
GLERROR("Bind 4 uniform");
|
||||
|
||||
GLint Location_ScreenDimensions = glGetUniformLocation(shaderHandle, "ScreenDimensions");
|
||||
glUniform2f(Location_ScreenDimensions, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
|
||||
GLERROR("Bind 5 uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * job->Matrix));
|
||||
GLERROR("Bind PVM uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "VM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix() * job->Matrix));
|
||||
GLERROR("Bind VM uniform");
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "TIM"), 1, GL_FALSE, glm::value_ptr(glm::transpose(glm::inverse(job->Matrix))));
|
||||
GLERROR("Bind TIM uniform");
|
||||
|
||||
GLint Location_FillPercentage = glGetUniformLocation(shaderHandle, "FillPercentage");
|
||||
glUniform1f(Location_FillPercentage, job->FillPercentage);
|
||||
@@ -1109,14 +1391,12 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr<Model
|
||||
GLERROR("Bind 8 uniform");
|
||||
GLint Location_Color = glGetUniformLocation(shaderHandle, "Color");
|
||||
glUniform4fv(Location_Color, 1, glm::value_ptr(job->Color));
|
||||
GLERROR("Bind 9 uniform");
|
||||
GLint Location_AmbientColor = glGetUniformLocation(shaderHandle, "AmbientColor");
|
||||
glUniform4fv(Location_AmbientColor, 1, glm::value_ptr(scene.AmbientColor));
|
||||
|
||||
GLERROR("Bind 10 uniform");
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer)
|
||||
Enable(GL_DEPTH_TEST);
|
||||
DepthMask(GL_TRUE);
|
||||
Enable(GL_CULL_FACE);
|
||||
Enable(GL_ALPHA_TEST);
|
||||
AlphaFunc(GL_GEQUAL, 0.05f);
|
||||
// Enable(GL_STENCIL_TEST);
|
||||
// StencilFunc(GL_NOTEQUAL, 1, 0xFF);
|
||||
// StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
#include "Rendering/FrameBuffer.h"
|
||||
|
||||
|
||||
BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment)
|
||||
BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment, GLuint mipMapLod)
|
||||
{
|
||||
m_ResourceHandle = resourceHandle;
|
||||
m_ResourceType = resourceType;
|
||||
m_Attachment = attachment;
|
||||
m_MipMapLod = mipMapLod;
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
@@ -24,6 +25,13 @@ RenderBuffer::~RenderBuffer()
|
||||
}
|
||||
}
|
||||
|
||||
Texture2DArray::~Texture2DArray()
|
||||
{
|
||||
if (m_ResourceHandle != 0) {
|
||||
glDeleteTextures(1, m_ResourceHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
@@ -51,14 +59,17 @@ void FrameBuffer::Generate()
|
||||
for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) {
|
||||
switch ((*it)->m_ResourceType) {
|
||||
case GL_TEXTURE_2D:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, (*it)->m_Attachment, *(*it)->m_ResourceHandle, (*it)->m_MipMapLod);
|
||||
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");
|
||||
|
||||
|
||||
@@ -42,6 +42,15 @@ void LightCullingPass::SetSSBOSizes()
|
||||
{
|
||||
m_NumberOfTiles = (int)(m_Renderer->GetViewportSize().Width/TILE_SIZE) * (int)(m_Renderer->GetViewportSize().Height/TILE_SIZE);
|
||||
|
||||
if (m_Frustums != nullptr) {
|
||||
delete[] m_Frustums;
|
||||
}
|
||||
if (m_LightGrid != nullptr) {
|
||||
delete[] m_LightGrid;
|
||||
}
|
||||
if (m_LightIndex != nullptr) {
|
||||
delete[] m_LightIndex;
|
||||
}
|
||||
m_Frustums = new Frustum[m_NumberOfTiles];
|
||||
m_LightGrid = new LightGrid[m_NumberOfTiles];
|
||||
m_LightIndex = new float[m_NumberOfTiles*MAX_LIGHTS_PER_TILE];
|
||||
|
||||
@@ -10,31 +10,31 @@ Model::Model(std::string fileName)
|
||||
case RawModel::MaterialType::SingleTextures:
|
||||
{
|
||||
RawModel::MaterialSingleTextures* materialSingleTexture = static_cast<RawModel::MaterialSingleTextures*>(materialProperty.material);
|
||||
materialSingleTexture->ColorMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->ColorMap.TexturePath, false);
|
||||
materialSingleTexture->NormalMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->NormalMap.TexturePath, false);
|
||||
materialSingleTexture->SpecularMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->SpecularMap.TexturePath, false);
|
||||
materialSingleTexture->IncandescenceMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->IncandescenceMap.TexturePath, false);
|
||||
materialSingleTexture->ColorMap.Texture = CommonFunctions::TryLoadResource<Texture, false>(materialSingleTexture->ColorMap.TexturePath);
|
||||
materialSingleTexture->NormalMap.Texture = CommonFunctions::TryLoadResource<Texture, false>(materialSingleTexture->NormalMap.TexturePath);
|
||||
materialSingleTexture->SpecularMap.Texture = CommonFunctions::TryLoadResource<Texture, false>(materialSingleTexture->SpecularMap.TexturePath);
|
||||
materialSingleTexture->IncandescenceMap.Texture = CommonFunctions::TryLoadResource<Texture, false>(materialSingleTexture->IncandescenceMap.TexturePath);
|
||||
}
|
||||
break;
|
||||
case RawModel::MaterialType::SplatMapping:
|
||||
{
|
||||
RawModel::MaterialSplatMapping* materialSplatMapping = static_cast<RawModel::MaterialSplatMapping*>(materialProperty.material);
|
||||
materialSplatMapping->SplatMap.Texture = CommonFunctions::LoadTexture(materialSplatMapping->SplatMap.TexturePath, false);
|
||||
materialSplatMapping->SplatMap.Texture = CommonFunctions::TryLoadResource<Texture, false>(materialSplatMapping->SplatMap.TexturePath);
|
||||
for (auto& texture : materialSplatMapping->ColorMaps)
|
||||
{
|
||||
texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false);
|
||||
texture.Texture = CommonFunctions::TryLoadResource<Texture, false>(texture.TexturePath);
|
||||
}
|
||||
for (auto& texture : materialSplatMapping->NormalMaps)
|
||||
{
|
||||
texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false);
|
||||
texture.Texture = CommonFunctions::TryLoadResource<Texture, false>(texture.TexturePath);
|
||||
}
|
||||
for (auto& texture : materialSplatMapping->SpecularMaps)
|
||||
{
|
||||
texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false);
|
||||
texture.Texture = CommonFunctions::TryLoadResource<Texture, false>(texture.TexturePath);
|
||||
}
|
||||
for (auto& texture : materialSplatMapping->IncandescenceMaps)
|
||||
{
|
||||
texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false);
|
||||
texture.Texture = CommonFunctions::TryLoadResource<Texture, false>(texture.TexturePath);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -12,7 +12,8 @@ PickingPass::PickingPass(IRenderer* renderer, EventBroker* eb)
|
||||
|
||||
PickingPass::~PickingPass()
|
||||
{
|
||||
|
||||
CommonFunctions::DeleteTexture(&m_PickingTexture);
|
||||
CommonFunctions::DeleteTexture(&m_DepthBuffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +24,7 @@ void PickingPass::InitializeTextures()
|
||||
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
|
||||
|
||||
CommonFunctions::GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST,
|
||||
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
|
||||
glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
|
||||
}
|
||||
|
||||
void PickingPass::InitializeFrameBuffers()
|
||||
@@ -61,8 +62,9 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
//TODO: Render: Add code for more jobs than modeljobs.
|
||||
GLuint shaderHandle = m_PickingProgram->GetHandle();
|
||||
GLuint shaderSkinnedHandle = m_PickingSkinnedProgram->GetHandle();
|
||||
GLuint lastShader = 0;
|
||||
unsigned int lastModel = 0;
|
||||
m_PickingProgram->Bind();
|
||||
|
||||
if (scene.ClearDepth) {
|
||||
//glClear(GL_DEPTH_BUFFER_BIT);
|
||||
state->Disable(GL_DEPTH_TEST);
|
||||
@@ -98,10 +100,11 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
||||
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_PickingSkinnedProgram->Bind();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
if (lastShader != m_PickingSkinnedProgram->GetHandle()) {
|
||||
m_PickingSkinnedProgram->Bind();
|
||||
lastShader = m_PickingSkinnedProgram->GetHandle();
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * modelJob->Matrix));
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
@@ -114,15 +117,19 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
|
||||
|
||||
} else {
|
||||
m_PickingProgram->Bind();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
if (lastShader != m_PickingProgram->GetHandle()) {
|
||||
m_PickingProgram->Bind();
|
||||
lastShader = m_PickingProgram->GetHandle();
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * modelJob->Matrix));
|
||||
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
}
|
||||
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
if (lastModel != modelJob->ModelID) {
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
lastModel = modelJob->ModelID;
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
||||
}
|
||||
}
|
||||
@@ -208,10 +215,11 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
||||
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_PickingSkinnedProgram->Bind();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
if (lastShader != m_PickingSkinnedProgram->GetHandle()) {
|
||||
m_PickingSkinnedProgram->Bind();
|
||||
lastShader = m_PickingSkinnedProgram->GetHandle();
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * modelJob->Matrix));
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
@@ -224,19 +232,24 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
m_PickingProgram->Bind();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
if (lastShader != m_PickingProgram->GetHandle()) {
|
||||
m_PickingProgram->Bind();
|
||||
lastShader = m_PickingProgram->GetHandle();
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * modelJob->Matrix));
|
||||
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
}
|
||||
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
if (lastModel != modelJob->ModelID) {
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
lastModel = modelJob->ModelID;
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
||||
}
|
||||
}
|
||||
|
||||
m_PickingProgram->Bind();
|
||||
for (auto& job : scene.Jobs.SpriteJob) {
|
||||
auto spriteJob = std::dynamic_pointer_cast<SpriteJob>(job);
|
||||
if (!spriteJob->Pickable) {
|
||||
@@ -271,14 +284,11 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
|
||||
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
||||
|
||||
m_PickingProgram->Bind();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(spriteJob->Matrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "PVM"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix() * scene.Camera->ViewMatrix() * spriteJob->Matrix));
|
||||
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
glBindVertexArray(spriteJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, spriteJob->Model->ElementBuffer);
|
||||
glBindVertexArray(spriteJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, spriteJob->Model->ElementBuffer);
|
||||
glDrawElements(GL_TRIANGLES, spriteJob->EndIndex - spriteJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(spriteJob->StartIndex * sizeof(unsigned int)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,14 +148,29 @@ void RawModelCustom::ReadMaterialSingle(std::size_t& offset, char* fileData, con
|
||||
case MaterialType::Basic:
|
||||
newMaterialProperty.material = new MaterialBasic();
|
||||
ReadMaterialBasic(newMaterialProperty.material, offset, fileData, fileByteSize);
|
||||
if(hasSkin){
|
||||
newMaterialProperty.ShaderID = ResourceManager::Load<ShaderProgram>("#ForwardPlusSkinnedProgram")->ResourceID;
|
||||
} else {
|
||||
newMaterialProperty.ShaderID = ResourceManager::Load<ShaderProgram>("#ForwardPlusProgram")->ResourceID;
|
||||
}
|
||||
break;
|
||||
case MaterialType::SplatMapping:
|
||||
newMaterialProperty.material = new MaterialSplatMapping();
|
||||
ReadMaterialSplatMapping(static_cast<MaterialSplatMapping*>(newMaterialProperty.material), offset, fileData, fileByteSize);
|
||||
if (hasSkin){
|
||||
newMaterialProperty.ShaderID = ResourceManager::Load<ShaderProgram>("#ForwardPlusSplatMapSkinnedProgram")->ResourceID;
|
||||
} else {
|
||||
newMaterialProperty.ShaderID = ResourceManager::Load<ShaderProgram>("#ForwardPlusSplatMapProgram")->ResourceID;
|
||||
}
|
||||
break;
|
||||
case MaterialType::SingleTextures:
|
||||
newMaterialProperty.material = new MaterialSingleTextures();
|
||||
ReadMaterialSingleTexture(static_cast<MaterialSingleTextures*>(newMaterialProperty.material), offset, fileData, fileByteSize);
|
||||
if (hasSkin){
|
||||
newMaterialProperty.ShaderID = ResourceManager::Load<ShaderProgram>("#ForwardPlusSkinnedProgram")->ResourceID;
|
||||
} else {
|
||||
newMaterialProperty.ShaderID = ResourceManager::Load<ShaderProgram>("#ForwardPlusProgram")->ResourceID;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Resource::FailedLoadingException("Material contains an unknown MaterialType");
|
||||
|
||||
@@ -9,10 +9,11 @@ RenderSystem::RenderSystem(SystemParams params, const IRenderer* renderer, Rende
|
||||
, m_Octree(frustumCullOctree)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EResolutionChanged, &RenderSystem::OnResolutionChanged);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned);
|
||||
|
||||
m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);
|
||||
m_Camera = new Camera((float)m_Renderer->GetViewportSize().Width / m_Renderer->GetViewportSize().Height, glm::radians(45.f), 0.01f, 5000.f);
|
||||
}
|
||||
|
||||
RenderSystem::~RenderSystem()
|
||||
@@ -20,11 +21,18 @@ RenderSystem::~RenderSystem()
|
||||
delete m_Camera;
|
||||
}
|
||||
|
||||
bool RenderSystem::OnResolutionChanged(Events::ResolutionChanged& e)
|
||||
{
|
||||
// Update camera aspect ration on resolution change
|
||||
m_Camera->SetAspectRatio((float)e.NewResolution.Width / e.NewResolution.Height);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderSystem::OnSetCamera(Events::SetCamera& e)
|
||||
{
|
||||
ComponentWrapper cTransform = e.CameraEntity["Transform"];
|
||||
ComponentWrapper cCamera = e.CameraEntity["Camera"];
|
||||
m_Camera->SetFOV((double)cCamera["FOV"]);
|
||||
m_Camera->SetFOV(glm::radians((double)cCamera["FOV"]));
|
||||
m_Camera->SetNearClip((double)cCamera["NearClip"]);
|
||||
m_Camera->SetFarClip((double)cCamera["FarClip"]);
|
||||
m_Camera->SetPosition(cTransform["Position"]);
|
||||
@@ -170,6 +178,7 @@ void RenderSystem::fillSprites(std::list<std::shared_ptr<RenderJob>>& jobs, Worl
|
||||
|
||||
bool RenderSystem::isEntityVisible(EntityWrapper& entity)
|
||||
{
|
||||
return true;
|
||||
// Only render children of a camera if that camera is currently active
|
||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||
return false;
|
||||
@@ -258,7 +267,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 +306,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();
|
||||
@@ -435,6 +446,7 @@ void RenderSystem::Update(double dt)
|
||||
}
|
||||
|
||||
RenderScene scene;
|
||||
scene.ShouldBlur = true;
|
||||
scene.Camera = m_Camera;
|
||||
scene.Viewport = Rectangle(1280, 720);
|
||||
|
||||
@@ -448,7 +460,7 @@ void RenderSystem::Update(double dt)
|
||||
fillModels(scene.Jobs);
|
||||
fillPointLights(scene.Jobs.PointLight, m_World);
|
||||
//TODO: Make sure all objects needed are also sorted.
|
||||
scene.Jobs.OpaqueObjects.sort();
|
||||
scene.Jobs.OpaqueObjects.sort([](auto& a, auto& b) {return *a < *b; });
|
||||
fillSprites(scene.Jobs.SpriteJob, m_World);
|
||||
fillDirectionalLights(scene.Jobs.DirectionalLight, m_World);
|
||||
fillText(scene.Jobs.Text, m_World);
|
||||
|
||||
@@ -2,6 +2,19 @@
|
||||
|
||||
std::unordered_map<GLFWwindow*, Renderer*> Renderer::m_WindowToRenderer;
|
||||
|
||||
Renderer::~Renderer() {
|
||||
delete m_PickingPass;
|
||||
delete m_LightCullingPass;
|
||||
delete m_ImGuiRenderPass;
|
||||
delete m_DrawFinalPass;
|
||||
delete m_DrawScreenQuadPass;
|
||||
delete m_DrawBloomPass;
|
||||
delete m_DrawColorCorrectionPass;
|
||||
delete m_SSAOPass;
|
||||
delete m_CubeMapPass;
|
||||
delete m_TextPass;
|
||||
}
|
||||
|
||||
void Renderer::Initialize()
|
||||
{
|
||||
m_SSAO_Quality = m_Config->Get<int>("SSAO.Quality", 0);
|
||||
@@ -23,16 +36,24 @@ void Renderer::Initialize()
|
||||
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
|
||||
}
|
||||
|
||||
void Renderer::glfwWindowSizeCallback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
m_WindowToRenderer[window]->setWindowSize(Rectangle(width, height));
|
||||
}
|
||||
|
||||
void Renderer::glfwFrameBufferCallback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
Renderer* currentRenderer = m_WindowToRenderer[window];
|
||||
currentRenderer->m_ViewportSize = Rectangle(width, height);
|
||||
currentRenderer->m_PickingPass->OnWindowResize();
|
||||
currentRenderer->m_DrawFinalPass->OnWindowResize();
|
||||
currentRenderer->m_LightCullingPass->OnWindowResize();
|
||||
currentRenderer->m_DrawBloomPass->OnWindowResize();
|
||||
currentRenderer->m_SSAOPass->OnWindowResize();
|
||||
m_WindowToRenderer[window]->updateFramebufferSize();
|
||||
}
|
||||
|
||||
void Renderer::SetResolution(const Rectangle& resolution)
|
||||
{
|
||||
m_Resolution = resolution;
|
||||
|
||||
if (m_Window != nullptr) {
|
||||
setWindowSize(resolution);
|
||||
updateFramebufferSize();
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::InitializeWindow()
|
||||
@@ -54,6 +75,7 @@ void Renderer::InitializeWindow()
|
||||
LOG_ERROR("GLFW: Failed to create window");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
glfwSetWindowSizeCallback(m_Window, &glfwWindowSizeCallback);
|
||||
glfwSetFramebufferSizeCallback(m_Window, &glfwFrameBufferCallback);
|
||||
glfwMakeContextCurrent(m_Window);
|
||||
|
||||
@@ -98,6 +120,32 @@ void Renderer::InputUpdate(double dt)
|
||||
|
||||
}
|
||||
|
||||
void Renderer::setWindowSize(Rectangle size)
|
||||
{
|
||||
m_Resolution = size;
|
||||
glfwSetWindowSize(m_Window, size.Width, size.Height);
|
||||
}
|
||||
|
||||
void Renderer::updateFramebufferSize()
|
||||
{
|
||||
Events::ResolutionChanged e;
|
||||
e.OldResolution = m_ViewportSize;
|
||||
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(m_Window, &width, &height);
|
||||
glViewport(0, 0, width, height);
|
||||
m_ViewportSize = Rectangle(width, height);
|
||||
m_PickingPass->OnWindowResize();
|
||||
m_DrawFinalPass->OnWindowResize();
|
||||
m_LightCullingPass->OnWindowResize();
|
||||
m_DrawBloomPass->OnWindowResize();
|
||||
m_SSAOPass->OnWindowResize();
|
||||
m_BlurHUDPass->OnWindowResize();
|
||||
|
||||
e.NewResolution = m_ViewportSize;
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
void Renderer::Update(double dt)
|
||||
{
|
||||
m_EventBroker->Process<Renderer>();
|
||||
@@ -110,7 +158,7 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
{
|
||||
GLERROR("PRE");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking\0Ambient Occlusion");
|
||||
ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking\0Ambient Occlusion\0Combined Scene Texture\0Full Blurred Texture");
|
||||
ImGui::Combo("CubeMap", &m_CubeMapTexture, "Nevada(512)\0Sky(1024)");
|
||||
if(m_CubeMapTexture == 0) {
|
||||
m_CubeMapPass->LoadTextures("Nevada");
|
||||
@@ -133,6 +181,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) {
|
||||
@@ -148,6 +199,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");
|
||||
@@ -158,7 +212,7 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
m_LightCullingPass->CullLights(*scene);
|
||||
GLERROR("LightCulling");
|
||||
PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light");
|
||||
m_DrawFinalPass->Draw(*scene);
|
||||
m_DrawFinalPass->Draw(*scene, m_BlurHUDPass);
|
||||
GLERROR("Draw Geometry+Light");
|
||||
//m_DrawScenePass->Draw(*scene);
|
||||
|
||||
@@ -194,6 +248,12 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
if (m_DebugTextureToDraw == 5) {
|
||||
m_DrawScreenQuadPass->Draw(m_SSAOPass->SSAOTexture());
|
||||
}
|
||||
if (m_DebugTextureToDraw == 6) {
|
||||
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->CombinedSceneTexture());
|
||||
}
|
||||
if (m_DebugTextureToDraw == 7) {
|
||||
m_DrawScreenQuadPass->Draw(m_DrawFinalPass->FullBlurredTexture());
|
||||
}
|
||||
PerformanceTimer::StopTimer("Renderer-Misc Debug Draws");
|
||||
|
||||
PerformanceTimer::StartTimer("Renderer-ImGuiRenderPass");
|
||||
@@ -213,8 +273,8 @@ PickData Renderer::Pick(glm::vec2 screenCoord)
|
||||
|
||||
void Renderer::InitializeTextures()
|
||||
{
|
||||
m_ErrorTexture = CommonFunctions::LoadTexture("Textures/Core/ErrorTexture.png", false);
|
||||
m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false);
|
||||
m_ErrorTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/ErrorTexture.png");
|
||||
m_WhiteTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/White.png");
|
||||
}
|
||||
|
||||
|
||||
@@ -238,15 +298,18 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin
|
||||
GLERROR("Texture initialization failed");
|
||||
}
|
||||
|
||||
|
||||
void Renderer::InitializeRenderPasses()
|
||||
{
|
||||
m_PickingPass = new PickingPass(this, m_EventBroker);
|
||||
m_LightCullingPass = new LightCullingPass(this);
|
||||
m_CubeMapPass = new CubeMapPass(this);
|
||||
m_SSAOPass = new SSAOPass(this, m_Config);
|
||||
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass, m_SSAOPass);
|
||||
m_ShadowPass = new ShadowPass(this);
|
||||
m_BlurHUDPass = new BlurHUD(this);
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
@@ -4,12 +4,19 @@ SSAOPass::SSAOPass(IRenderer* renderer, ConfigFile* config)
|
||||
: m_Renderer(renderer)
|
||||
, m_Config(config)
|
||||
{
|
||||
m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false);
|
||||
m_WhiteTexture = CommonFunctions::TryLoadResource<Texture, false>("Textures/Core/White.png");
|
||||
|
||||
ChangeQuality(m_Config->Get<int>("SSAO.Quality", 0));
|
||||
|
||||
}
|
||||
|
||||
SSAOPass::~SSAOPass() {
|
||||
CommonFunctions::DeleteTexture(&m_SSAOTexture);
|
||||
CommonFunctions::DeleteTexture(&m_SSAOViewSpaceZTexture);
|
||||
CommonFunctions::DeleteTexture(&m_Gaussian_horiz);
|
||||
CommonFunctions::DeleteTexture(&m_Gaussian_vert);
|
||||
}
|
||||
|
||||
void SSAOPass::ChangeQuality(int quality)
|
||||
{
|
||||
if (m_Quality == quality) {
|
||||
@@ -226,6 +233,11 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
GLuint shaderHandle_horiz = m_GaussianProgram_horiz->GetHandle();
|
||||
GLuint shaderHandle_vert = m_GaussianProgram_vert->GetHandle();
|
||||
|
||||
m_GaussianProgram_vert->Bind();
|
||||
glUniform1i(glGetUniformLocation(shaderHandle_vert, "Lod"), 0);
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
glUniform1i(glGetUniformLocation(shaderHandle_horiz, "Lod"), 0);
|
||||
|
||||
m_GaussianFrameBuffer_horiz.Bind();
|
||||
m_GaussianProgram_horiz->Bind();
|
||||
|
||||
@@ -245,8 +257,6 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_Gaussian_horiz);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
//horizontal pass
|
||||
@@ -258,8 +268,6 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_Gaussian_vert);
|
||||
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
m_GaussianFrameBuffer_horiz.Unbind();
|
||||
@@ -272,8 +280,7 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera)
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_Gaussian_horiz);
|
||||
glBindVertexArray(m_ScreenQuad->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1
|
||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex);
|
||||
|
||||
|
||||
@@ -4,22 +4,32 @@ GLuint Shader::CompileShader(GLenum shaderType, std::string fileName)
|
||||
{
|
||||
LOG_INFO("Compiling shader \"%s\"", fileName.c_str());
|
||||
|
||||
std::string shaderFile;
|
||||
std::ifstream in(fileName, std::ios::in);
|
||||
if (!in) {
|
||||
LOG_ERROR("Error: Failed to open shader file \"%s\"", fileName.c_str());
|
||||
return 0;
|
||||
}
|
||||
in.seekg(0, std::ios::end);
|
||||
shaderFile.resize((int)in.tellg());
|
||||
in.seekg(0, std::ios::beg);
|
||||
in.read(&shaderFile[0], shaderFile.size());
|
||||
in.close();
|
||||
std::string shaderFile = ReadFile(fileName);
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
if (GLERROR("glCreateShader"))
|
||||
return 0;
|
||||
|
||||
std::size_t startPos = 0;
|
||||
std::size_t SEofNewFile[2];
|
||||
std::string key = "#include";
|
||||
while((startPos = shaderFile.find(key, startPos)) != std::string::npos)
|
||||
{
|
||||
SEofNewFile[0] = shaderFile.find('"', startPos+key.length())+1;
|
||||
SEofNewFile[1] = shaderFile.find('"', SEofNewFile[0]);
|
||||
if (SEofNewFile[0] == std::string::npos || SEofNewFile[1] == std::string::npos)
|
||||
return 0;
|
||||
|
||||
std::string replacementFileName = shaderFile.substr(SEofNewFile[0], SEofNewFile[1] - SEofNewFile[0]);
|
||||
std::string replacementString = ReadFile(replacementFileName);
|
||||
size_t firstof = replacementString.find_first_of((char)0);
|
||||
replacementString.erase(firstof, replacementString.size() - firstof);
|
||||
if (replacementString.length() <= 0)
|
||||
return 0;
|
||||
shaderFile.replace(startPos, SEofNewFile[1]+2 - startPos, replacementString + "\n");
|
||||
startPos += replacementString.length(); //This might not be wanted.
|
||||
}
|
||||
|
||||
const GLchar* shaderFiles = shaderFile.c_str();
|
||||
const GLint length = static_cast<GLint>(shaderFile.length());
|
||||
glShaderSource(shader, 1, &shaderFiles, &length);
|
||||
@@ -46,6 +56,24 @@ GLuint Shader::CompileShader(GLenum shaderType, std::string fileName)
|
||||
return shader;
|
||||
}
|
||||
|
||||
std::string Shader::ReadFile(std::string fileName)
|
||||
{
|
||||
std::string shaderFile;
|
||||
std::ifstream in(fileName, std::ios::in);
|
||||
if (!in) {
|
||||
LOG_ERROR("Error: Failed to open shader file \"%s\"", fileName.c_str());
|
||||
return "";
|
||||
}
|
||||
|
||||
in.seekg(0, std::ios::end);
|
||||
shaderFile.resize((int)in.tellg());
|
||||
in.seekg(0, std::ios::beg);
|
||||
in.read(&shaderFile[0], shaderFile.size());
|
||||
in.close();
|
||||
return shaderFile;
|
||||
}
|
||||
|
||||
|
||||
Shader::Shader(GLenum shaderType, std::string fileName) : m_ShaderType(shaderType), m_FileName(fileName)
|
||||
{
|
||||
m_ShaderHandle = 0;
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
#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();
|
||||
|
||||
m_ShadowProgramSkinned = ResourceManager::Load<ShaderProgram>("#ShadowProgramSkinned");
|
||||
m_ShadowProgramSkinned->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/ShadowSkinned.vert.glsl")));
|
||||
m_ShadowProgramSkinned->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Shadow.frag.glsl")));
|
||||
m_ShadowProgramSkinned->Compile();
|
||||
m_ShadowProgramSkinned->BindFragDataLocation(0, "ShadowMap");
|
||||
m_ShadowProgramSkinned->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());
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
GLuint shaderHandle;
|
||||
|
||||
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]);
|
||||
|
||||
|
||||
m_ShadowProgram->Bind();
|
||||
shaderHandle = m_ShadowProgram->GetHandle();
|
||||
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]));
|
||||
|
||||
m_ShadowProgramSkinned->Bind();
|
||||
shaderHandle = m_ShadowProgramSkinned->GetHandle();
|
||||
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;
|
||||
}
|
||||
|
||||
if(modelJob->Model->IsSkinned()) {
|
||||
m_ShadowProgramSkinned->Bind();
|
||||
shaderHandle = m_ShadowProgramSkinned->GetHandle();
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->BlendTree != nullptr) {
|
||||
frameBones = modelJob->BlendTree->GetFinalPose();
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetTPose();
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
m_ShadowProgram->Bind();
|
||||
shaderHandle = m_ShadowProgram->GetHandle();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (modelJob->Model->IsSkinned()) {
|
||||
m_ShadowProgramSkinned->Bind();
|
||||
shaderHandle = m_ShadowProgramSkinned->GetHandle();
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->BlendTree != nullptr) {
|
||||
frameBones = modelJob->BlendTree->GetFinalPose();
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetTPose();
|
||||
}
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
m_ShadowProgram->Bind();
|
||||
shaderHandle = m_ShadowProgram->GetHandle();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -321,6 +321,8 @@ Skeleton::~Skeleton()
|
||||
for (auto &kv : Bones) {
|
||||
delete kv.second;
|
||||
}
|
||||
|
||||
BlendTrees.clear();
|
||||
}
|
||||
|
||||
const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
|
||||
@@ -7,23 +7,23 @@ TextPass::TextPass()
|
||||
|
||||
void TextPass::Initialize()
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
m_TextProgram = ResourceManager::Load<ShaderProgram>("#TextProgram");
|
||||
m_TextProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Text.vert.glsl")));
|
||||
m_TextProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Text.frag.glsl")));
|
||||
m_TextProgram->Compile();
|
||||
m_TextProgram->BindFragDataLocation(0, "sceneColor");
|
||||
m_TextProgram->BindFragDataLocation(1, "bloomColor");
|
||||
m_TextProgram->Link();
|
||||
m_TextProgram = ResourceManager::Load<ShaderProgram>("#TextProgram");
|
||||
m_TextProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Text.vert.glsl")));
|
||||
m_TextProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Text.frag.glsl")));
|
||||
m_TextProgram->Compile();
|
||||
m_TextProgram->BindFragDataLocation(0, "sceneColor");
|
||||
m_TextProgram->BindFragDataLocation(1, "bloomColor");
|
||||
m_TextProgram->Link();
|
||||
}
|
||||
|
||||
void TextPass::Update()
|
||||
@@ -33,81 +33,180 @@ void TextPass::Update()
|
||||
|
||||
void TextPass::Draw(RenderScene& scene, FrameBuffer& frameBuffer)
|
||||
{
|
||||
GLERROR("Derp1");
|
||||
TextPassState* state = new TextPassState(frameBuffer.GetHandle());
|
||||
for (auto &job : scene.Jobs.Text) {
|
||||
auto textJob = std::dynamic_pointer_cast<TextJob>(job);
|
||||
if (textJob) {
|
||||
GLERROR("Derp1");
|
||||
TextPassState* state = new TextPassState(frameBuffer.GetHandle());
|
||||
for (auto &job : scene.Jobs.Text) {
|
||||
auto textJob = std::dynamic_pointer_cast<TextJob>(job);
|
||||
if (textJob) {
|
||||
|
||||
renderText(textJob->Content, textJob->Resource, textJob->Alignment, textJob->Color, textJob->Matrix, scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix());
|
||||
}
|
||||
}
|
||||
GLERROR("Derp2");
|
||||
delete state;
|
||||
renderText(textJob->Content, textJob->Resource, textJob->Alignment, textJob->Color, textJob->Matrix, scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix());
|
||||
}
|
||||
}
|
||||
GLERROR("Derp2");
|
||||
delete state;
|
||||
}
|
||||
|
||||
std::string TextPass::parseColors(std::string text, std::map<int, glm::vec4>& colorChanges, glm::vec4 originalColor)
|
||||
{
|
||||
std::string parsedString = text;
|
||||
glm::vec4 newColor = originalColor;
|
||||
bool colorChange = false;
|
||||
|
||||
for (std::string::const_iterator c = parsedString.begin(); c != parsedString.end(); c++) {
|
||||
if (*c == char(92)) { // Backlash
|
||||
if ((c + 1) != parsedString.end()) {
|
||||
if (*(c + 1) == char('C')) { // C for Color
|
||||
if ((c + 7) != parsedString.end()) {
|
||||
bool hasCorrectFormat = true;
|
||||
|
||||
for (std::string::const_iterator colorC = c + 2; colorC != c + 8; colorC++) {
|
||||
if (*colorC < '0' || *colorC > 'F') {
|
||||
hasCorrectFormat = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasCorrectFormat == true) {
|
||||
colorChange = true;
|
||||
|
||||
std::array<int, 3> hexToInt = {
|
||||
std::stoi(std::string(c + 2, c + 4), 0, 16),
|
||||
std::stoi(std::string(c + 4, c + 6), 0, 16),
|
||||
std::stoi(std::string(c + 6, c + 8), 0, 16)
|
||||
};
|
||||
|
||||
newColor = glm::vec4(
|
||||
float(hexToInt[0]) / 255.f,
|
||||
float(hexToInt[1]) / 255.f,
|
||||
float(hexToInt[2]) / 255.f,
|
||||
newColor.a);
|
||||
|
||||
parsedString.erase(c, (c + 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*(c + 1) == char('A')) { // A for Alpha
|
||||
if ((c + 3) != parsedString.end()) {
|
||||
bool hasCorrectFormat = true;
|
||||
|
||||
for (std::string::const_iterator colorC = c + 2; colorC != c + 4; colorC++) {
|
||||
if (*colorC < '0' || *colorC > 'F') {
|
||||
hasCorrectFormat = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasCorrectFormat == true) {
|
||||
colorChange = true;
|
||||
|
||||
int hexToInt = std::stoi(std::string(c + 2, c + 4), 0, 16);
|
||||
|
||||
newColor = glm::vec4(
|
||||
newColor.r,
|
||||
newColor.g,
|
||||
newColor.b,
|
||||
float(hexToInt) / 255.f);
|
||||
|
||||
parsedString.erase(c, (c + 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((*(c + 1) >= '1' && *(c + 1) <= '9') || *(c + 1) == 'B' || *(c + 1) == 'E' || *(c + 1) == 'F') { // Icons
|
||||
if (*(c + 1) >= '1' && *(c + 1) <= '9') {
|
||||
parsedString.replace(c, (c + 2), 1, (*(c + 1) - 48));
|
||||
}
|
||||
else {
|
||||
parsedString.replace(c, (c + 2), 1, (*(c + 1) - 55));
|
||||
}
|
||||
}
|
||||
|
||||
if (colorChange) {
|
||||
colorChanges[c - parsedString.begin()] = newColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return parsedString;
|
||||
}
|
||||
|
||||
void TextPass::renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix)
|
||||
{
|
||||
GLfloat penX = 0;
|
||||
GLfloat penY = 0;
|
||||
GLfloat scale = 1.0/font->FontSize;
|
||||
GLfloat penX = 0;
|
||||
GLfloat penY = 0;
|
||||
GLfloat scale = 1.0 / font->FontSize;
|
||||
|
||||
GLfloat stringWidth = 0.f;
|
||||
GLfloat stringWidth = 0.f;
|
||||
|
||||
for (std::string::const_iterator c = text.begin(); c != text.end(); c++) {
|
||||
Font::Character ch = font->m_Characters[*c];
|
||||
stringWidth += (ch.Advance >> 6) * scale;
|
||||
}
|
||||
std::map<int, glm::vec4> colorChanges;
|
||||
std::string parsedText = parseColors(text, colorChanges, color);
|
||||
|
||||
if(alignment == TextJob::AlignmentEnum::Center) {
|
||||
penX = -stringWidth/2.f;
|
||||
} else if (alignment == TextJob::AlignmentEnum::Right) {
|
||||
penX = -stringWidth;
|
||||
} else {
|
||||
penX = 0;
|
||||
}
|
||||
|
||||
|
||||
for (std::string::const_iterator c = parsedText.begin(); c != parsedText.end(); c++) {
|
||||
Font::Character ch = font->m_Characters[*c];
|
||||
stringWidth += (ch.Advance >> 6) * scale;
|
||||
}
|
||||
|
||||
m_TextProgram->Bind();
|
||||
glUniform4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), 1, glm::value_ptr(color));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindVertexArray(VAO);
|
||||
if (alignment == TextJob::AlignmentEnum::Center) {
|
||||
penX = -stringWidth / 2.f;
|
||||
}
|
||||
else if (alignment == TextJob::AlignmentEnum::Right) {
|
||||
penX = -stringWidth;
|
||||
}
|
||||
else {
|
||||
penX = 0;
|
||||
}
|
||||
|
||||
|
||||
for (std::string::const_iterator c = text.begin(); c != text.end(); c++) {
|
||||
Font::Character ch = font->m_Characters[*c];
|
||||
|
||||
GLfloat xpos = penX + ch.Bearing.x * scale;
|
||||
GLfloat ypos = penY - (ch.Size.y - ch.Bearing.y) * scale;
|
||||
m_TextProgram->Bind();
|
||||
glUniform4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), 1, glm::value_ptr(color));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
GLfloat w = ch.Size.x * scale;
|
||||
GLfloat h = ch.Size.y * scale;
|
||||
|
||||
GLfloat vertices[6][4] = {
|
||||
{ xpos, ypos + h, 0.0, 0.0 },
|
||||
{ xpos, ypos, 0.0, 1.0 },
|
||||
{ xpos + w, ypos, 1.0, 1.0 },
|
||||
for (std::string::const_iterator c = parsedText.begin(); c != parsedText.end(); c++) {
|
||||
|
||||
{ xpos, ypos + h, 0.0, 0.0 },
|
||||
{ xpos + w, ypos, 1.0, 1.0 },
|
||||
{ xpos + w, ypos + h, 1.0, 0.0 }
|
||||
};
|
||||
auto it = colorChanges.find(c - parsedText.begin());
|
||||
if (it != colorChanges.end()) {
|
||||
glUniform4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), 1, glm::value_ptr(it->second));
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
|
||||
Font::Character ch = font->m_Characters[*c];
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
penX += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
GLfloat xpos = penX + ch.Bearing.x * scale;
|
||||
GLfloat ypos = penY - (ch.Size.y - ch.Bearing.y) * scale;
|
||||
|
||||
GLERROR("Text rendering Error");
|
||||
GLfloat w = ch.Size.x * scale;
|
||||
GLfloat h = ch.Size.y * scale;
|
||||
|
||||
GLfloat vertices[6][4] = {
|
||||
{ xpos, ypos + h, 0.0, 0.0 },
|
||||
{ xpos, ypos, 0.0, 1.0 },
|
||||
{ xpos + w, ypos, 1.0, 1.0 },
|
||||
|
||||
{ xpos, ypos + h, 0.0, 0.0 },
|
||||
{ xpos + w, ypos, 1.0, 1.0 },
|
||||
{ xpos + w, ypos + h, 1.0, 0.0 }
|
||||
};
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
penX += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
GLERROR("Text rendering Error");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,18 +4,6 @@ Texture::Texture(std::string path)
|
||||
{
|
||||
PNG* img = ResourceManager::Load<PNG, true>(path); //TODO: Make this threaded. Catch exeptions in all other load places.
|
||||
|
||||
//PNG image(path);
|
||||
|
||||
//if (img->Width == 0 && img->Height == 0 || img->Format == Image::ImageFormat::Unknown) {
|
||||
// //image = PNG("Textures/Core/ErrorTexture.png");
|
||||
// //return; // Temporary fix to remove crash
|
||||
|
||||
// if (img->Width == 0 && img->Height == 0 || img->Format == Image::ImageFormat::Unknown) {
|
||||
// LOG_ERROR("Couldn't even load the error texture. This is a dark day indeed.");
|
||||
// return;
|
||||
// }
|
||||
//}
|
||||
|
||||
this->Width = img->Width;
|
||||
this->Height = img->Height;
|
||||
this->Data = img->Data;
|
||||
@@ -29,9 +17,9 @@ Texture::Texture(std::string path)
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Construct the OpenGL texture
|
||||
|
||||
glGenTextures(1, &m_Texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_Texture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "Rendering/TextureSprite.h"
|
||||
|
||||
TextureSprite::TextureSprite(std::string path)
|
||||
:Texture(path)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
GLERROR("Texture load");
|
||||
}
|
||||
@@ -1,23 +1,5 @@
|
||||
#include "Rendering/Util/CommonFunctions.h"
|
||||
|
||||
Texture* CommonFunctions::LoadTexture(std::string path, bool threaded)
|
||||
{
|
||||
Texture* img;
|
||||
try {
|
||||
if(threaded) {
|
||||
img = ResourceManager::Load<Texture, true>(path);
|
||||
} else {
|
||||
img = ResourceManager::Load<Texture, false>(path);
|
||||
}
|
||||
} catch (const Resource::StillLoadingException&) {
|
||||
img = ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png");
|
||||
} catch (const std::exception&) {
|
||||
img = nullptr;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void CommonFunctions::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
||||
{
|
||||
glDeleteTextures(1, texture);
|
||||
@@ -43,10 +25,12 @@ void CommonFunctions::GenerateMultiSampleTexture(GLuint* texture, int numSamples
|
||||
|
||||
void CommonFunctions::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps)
|
||||
{
|
||||
glDeleteTextures(1, texture);
|
||||
glGenTextures(1, texture);
|
||||
glBindTexture(GL_TEXTURE_2D, *texture);
|
||||
glTexStorage2D(GL_TEXTURE_2D, numMipMaps, GL_RGBA8, dimensions.x, dimensions.y);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dimensions.x, dimensions.y, format, type, texture);
|
||||
//glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dimensions.x, dimensions.y, format, type, NULL);
|
||||
GLERROR("MipMap Texture glTexSubImage2D failed");
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
|
||||
|
||||
@@ -36,10 +36,6 @@ ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer*
|
||||
unsigned char pdata[3];
|
||||
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pdata);
|
||||
GLERROR("glReadPixels(pdata) Error");
|
||||
PickDataBuffer->Unbind();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
||||
GLERROR("glBindFramebuffer(DepthBuffer) Error");
|
||||
float depthData;
|
||||
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData);
|
||||
GLERROR("glReadPixels(depthData) Error");
|
||||
|
||||
+10
-2
@@ -35,8 +35,12 @@
|
||||
#include "Game/Systems/BoostSystem.h"
|
||||
#include "Game/Systems/BoostIconsHUDSystem.h"
|
||||
#include "Game/Systems/ScoreScreenSystem.h"
|
||||
#include "Game/Systems/SpectatorCameraSystem.h"
|
||||
#include "GUI/ButtonSystem.h"
|
||||
#include "GUI/MainMenuSystem.h"
|
||||
#include "Game/Systems/MainMenuSystem.h"
|
||||
#include "Game/Systems/ServerListSystem.h"
|
||||
#include "Game/Systems/StartSystem.h"
|
||||
#include "Rendering/TextureSprite.h"
|
||||
|
||||
|
||||
Game::Game(int argc, char* argv[])
|
||||
@@ -48,6 +52,7 @@ Game::Game(int argc, char* argv[])
|
||||
ResourceManager::RegisterType<Model>("Model");
|
||||
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||
ResourceManager::RegisterType<Texture>("Texture");
|
||||
ResourceManager::RegisterType<TextureSprite>("TextureSprite");
|
||||
ResourceManager::RegisterType<PNG>("Png");
|
||||
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
|
||||
ResourceManager::RegisterType<EntityFile>("EntityFile");
|
||||
@@ -149,6 +154,9 @@ Game::Game(int argc, char* argv[])
|
||||
m_SystemPipeline->AddSystem<MainMenuSystem>(updateOrderLevel, m_Renderer);
|
||||
m_SystemPipeline->AddSystem<BoostIconsHUDSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<ScoreScreenSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<SpectatorCameraSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<ServerListSystem>(updateOrderLevel, m_Renderer);
|
||||
m_SystemPipeline->AddSystem<StartSystem>(updateOrderLevel);
|
||||
// Populate Octree with collidables
|
||||
++updateOrderLevel;
|
||||
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
|
||||
@@ -211,7 +219,7 @@ void Game::Tick()
|
||||
PerformanceTimer::StartTimerAndStopPrevious("InputProxy");
|
||||
m_InputProxy->Update(dt);
|
||||
m_EventBroker->Swap();
|
||||
m_InputProxy->Process();
|
||||
m_InputProxy->Process(ImGui::GetIO().WantCaptureKeyboard || ImGui::GetIO().WantCaptureMouse);
|
||||
m_EventBroker->Swap();
|
||||
|
||||
PerformanceTimer::StartTimerAndStopPrevious("SoundManager");
|
||||
|
||||
@@ -15,7 +15,9 @@ bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComp
|
||||
|| component.Info.Name == "AssaultWeapon"
|
||||
|| component.Info.Name == "DefenderWeapon"
|
||||
|| component.Info.Name == "Animation"
|
||||
|| component.Info.Name == "AnimationOffset"
|
||||
|| component.Info.Name == "Blend"
|
||||
|| component.Info.Name == "BlendAdditive"
|
||||
|| component.Info.Name == "BlendOverride"
|
||||
|| entity.Name() == "PlayerName"
|
||||
) {
|
||||
return false;
|
||||
|
||||
@@ -37,8 +37,7 @@ void AmmoPickupSystem::Update(double dt)
|
||||
|
||||
//erase the current element (somePickup)
|
||||
it = m_ETriggerTouchVector.erase(it);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
@@ -48,7 +47,7 @@ void AmmoPickupSystem::Update(double dt)
|
||||
m_PickupAtMaximum.erase(it);
|
||||
break;
|
||||
}
|
||||
if ((int)it->player["AssaultWeapon"]["Ammo"] < (int)it->player["AssaultWeapon"]["MaxAmmo"]) {
|
||||
if (!DoesPlayerHaveMaxAmmo(it->player)) {
|
||||
DoPickup(it->player, it->trigger);
|
||||
m_PickupAtMaximum.erase(it);
|
||||
break;
|
||||
@@ -56,6 +55,58 @@ void AmmoPickupSystem::Update(double dt)
|
||||
}
|
||||
}
|
||||
}
|
||||
bool AmmoPickupSystem::DoesPlayerHaveMaxAmmo(EntityWrapper &player) {
|
||||
PlayerClass playerClass = DetermineClass(player);
|
||||
if (playerClass == PlayerClass::Defender) {
|
||||
return !((int)player["DefenderWeapon"]["Ammo"] < (int)player["DefenderWeapon"]["MaxAmmo"]);
|
||||
} else if (playerClass == PlayerClass::Sniper) {
|
||||
return !((int)player["SniperWeapon"]["Ammo"] < (int)player["SniperWeapon"]["MaxAmmo"]);
|
||||
} else if (playerClass == PlayerClass::Assault) {
|
||||
return !((int)player["AssaultWeapon"]["Ammo"] < (int)player["AssaultWeapon"]["MaxAmmo"]);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void AmmoPickupSystem::SetPlayerAmmo(EntityWrapper &player, int ammoGain) {
|
||||
int maxWeaponAmmo = GetPlayerMaxAmmo(player);
|
||||
|
||||
PlayerClass playerClass = DetermineClass(player);
|
||||
if (playerClass == PlayerClass::Defender) {
|
||||
(Field<int>)player["DefenderWeapon"]["Ammo"] = std::min((int)player["DefenderWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
||||
} else if (playerClass == PlayerClass::Sniper) {
|
||||
(Field<int>)player["SniperWeapon"]["Ammo"] = std::min((int)player["SniperWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
||||
} else if (playerClass == PlayerClass::Assault) {
|
||||
(Field<int>)player["AssaultWeapon"]["Ammo"] = std::min((int)player["AssaultWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
||||
} else {
|
||||
//unknown class - ignore
|
||||
}
|
||||
}
|
||||
int AmmoPickupSystem::GetPlayerMaxAmmo(EntityWrapper &player) {
|
||||
PlayerClass playerClass = DetermineClass(player);
|
||||
if (playerClass == PlayerClass::Defender) {
|
||||
return (int)player["DefenderWeapon"]["MaxAmmo"];
|
||||
} else if (playerClass == PlayerClass::Sniper) {
|
||||
return (int)player["SniperWeapon"]["MaxAmmo"];
|
||||
} else if (playerClass == PlayerClass::Assault) {
|
||||
return (int)player["AssaultWeapon"]["MaxAmmo"];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
AmmoPickupSystem::PlayerClass AmmoPickupSystem::DetermineClass(EntityWrapper &player)
|
||||
{
|
||||
//determine the class based on what component the inflictor-player has
|
||||
if (m_World->HasComponent(player.ID, "DashAbility")) {
|
||||
return PlayerClass::Assault;
|
||||
}
|
||||
if (m_World->HasComponent(player.ID, "ShieldAbility")) {
|
||||
return PlayerClass::Defender;
|
||||
}
|
||||
if (m_World->HasComponent(player.ID, "SprintAbility")) {
|
||||
return PlayerClass::Sniper;
|
||||
}
|
||||
return PlayerClass::None;
|
||||
}
|
||||
|
||||
bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||
{
|
||||
@@ -63,7 +114,7 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||
return false;
|
||||
}
|
||||
//TODO: add other weapontypes
|
||||
if (!e.Entity.HasComponent("AssaultWeapon")) {
|
||||
if (DetermineClass(e.Entity) == PlayerClass::None) {
|
||||
return false;
|
||||
}
|
||||
if (!e.Trigger.HasComponent("AmmoPickup")) {
|
||||
@@ -71,7 +122,7 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||
}
|
||||
|
||||
//if at maxammo, save the trigger-touch to a vector since standing inside it will not re-trigger the trigger
|
||||
if ((int)e.Entity["AssaultWeapon"]["Ammo"] >= (int)e.Entity["AssaultWeapon"]["MaxAmmo"]) {
|
||||
if (DoesPlayerHaveMaxAmmo(e.Entity)) {
|
||||
m_PickupAtMaximum.push_back({ e.Entity, e.Trigger });
|
||||
return false;
|
||||
}
|
||||
@@ -85,19 +136,16 @@ bool AmmoPickupSystem::OnAmmoPickup(Events::AmmoPickup & e)
|
||||
return false;
|
||||
}
|
||||
//TODO: add other weapontypes
|
||||
if (!e.Player.HasComponent("AssaultWeapon")) {
|
||||
if (DetermineClass(e.Player) == PlayerClass::None) {
|
||||
return false;
|
||||
}
|
||||
int maxWeaponAmmo = (int)e.Player["AssaultWeapon"]["MaxAmmo"];
|
||||
int& currentAmmo = (int)e.Player["AssaultWeapon"]["Ammo"];
|
||||
//cant pick up ammopacks if you are already at MaxAmmo
|
||||
if (currentAmmo >= maxWeaponAmmo) {
|
||||
if (DoesPlayerHaveMaxAmmo(e.Player)) {
|
||||
return false;
|
||||
}
|
||||
SetPlayerAmmo(e.Player, e.AmmoGain);
|
||||
|
||||
currentAmmo = std::min(currentAmmo + e.AmmoGain, maxWeaponAmmo);
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AmmoPickupSystem::OnTriggerLeave(Events::TriggerLeave& e) {
|
||||
@@ -119,7 +167,7 @@ void AmmoPickupSystem::DoPickup(EntityWrapper &player, EntityWrapper &trigger) {
|
||||
if (!trigger.Valid()) {
|
||||
return;
|
||||
}
|
||||
int maxWeaponAmmo = (int)player["AssaultWeapon"]["MaxAmmo"];
|
||||
int maxWeaponAmmo = GetPlayerMaxAmmo(player);
|
||||
int ammoGiven = 0.01*(double)trigger["AmmoPickup"]["AmmoGain"] * maxWeaponAmmo;
|
||||
|
||||
Events::AmmoPickup ePlayerAmmoPickup;
|
||||
|
||||
@@ -108,10 +108,10 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
|
||||
//change what model is displaying (change all in case 2 capturepoints has been captured on the same frame)
|
||||
for (int i = 0; i < m_NumberOfCapturePoints; i++) {
|
||||
auto owner = (int)m_CapturePointNumberToEntityMap[i]["Team"]["Team"];
|
||||
if (m_CapturePointNumberToEntityMap[i].FirstChildByName("Red").ID != EntityID_Invalid) {
|
||||
m_CapturePointNumberToEntityMap[i].FirstChildByName("Red")["Model"]["Visible"] = owner == redTeam ? true : false;
|
||||
m_CapturePointNumberToEntityMap[i].FirstChildByName("Blue")["Model"]["Visible"] = owner == blueTeam ? true : false;
|
||||
m_CapturePointNumberToEntityMap[i].FirstChildByName("Spectator")["Model"]["Visible"] = owner == spectatorTeam ? true : false;
|
||||
if (m_CapturePointNumberToEntityMap[i].FirstChildByName("Red").Valid()) {
|
||||
ChangeCapturePointModelsVisibility(m_CapturePointNumberToEntityMap[i].FirstChildByName("Red"), owner == redTeam);
|
||||
ChangeCapturePointModelsVisibility(m_CapturePointNumberToEntityMap[i].FirstChildByName("Blue"), owner == blueTeam);
|
||||
ChangeCapturePointModelsVisibility(m_CapturePointNumberToEntityMap[i].FirstChildByName("Spectator"), owner == spectatorTeam);
|
||||
}
|
||||
}
|
||||
//save the next cap points and publish the captured event
|
||||
@@ -232,6 +232,19 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
|
||||
|
||||
}
|
||||
|
||||
void CapturePointSystem::ChangeCapturePointModelsVisibility(EntityWrapper &capturePointModels, bool isOwner) {
|
||||
(Field<bool>)capturePointModels["Model"]["Visible"] = isOwner;
|
||||
for (auto& capModel : capturePointModels.ChildrenWithComponent("Transform"))
|
||||
{
|
||||
if (capModel.HasComponent("Model")) {
|
||||
(Field<bool>)capModel["Model"]["Visible"] = isOwner;
|
||||
}
|
||||
if (capModel.HasComponent("PointLight")) {
|
||||
(Field<bool>)capModel["PointLight"]["Visible"] = isOwner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e)
|
||||
{
|
||||
//personEntered = e.Entity, thingEntered = e.Trigger
|
||||
|
||||
@@ -8,12 +8,13 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params)
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &DamageIndicatorSystem::OnSetCamera);
|
||||
|
||||
//load texture to cache
|
||||
auto texture = CommonFunctions::LoadTexture("Textures/DamageIndicator.png", false);
|
||||
auto texture = CommonFunctions::TryLoadResource<Texture, false>("Textures/DamageIndicator.png");
|
||||
auto entityFile = ResourceManager::Load<EntityXMLFile>("Schema/Entities/DamageIndicator.xml");
|
||||
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
|
||||
}
|
||||
|
||||
void DamageIndicatorSystem::Update(double dt) {
|
||||
if (!IsServer && LocalPlayer.Valid()) {
|
||||
if ((!IsServer || !m_NetworkEnabled) && LocalPlayer.Valid()) {
|
||||
for (auto& iter = updateDamageIndicatorVector.begin(); iter != updateDamageIndicatorVector.end(); iter++) {
|
||||
if (!iter->spriteEntity.Valid()) {
|
||||
updateDamageIndicatorVector.erase(iter);
|
||||
@@ -40,10 +41,15 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
|
||||
return false;
|
||||
}
|
||||
|
||||
//friendly fire - return
|
||||
if (e.Damage < 0.1f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
glm::vec3 inflictorPos = e.Inflictor["Transform"]["Position"];
|
||||
//if testing
|
||||
#ifdef INDICATOR_TEST
|
||||
inflictorPos = DamageIndicatorTest(e.Victim);
|
||||
inflictorPos = DamageIndicatorTest(e.Victim);
|
||||
#endif
|
||||
|
||||
float angleBetweenVectors = CalculateAngle(e.Victim, inflictorPos);
|
||||
@@ -55,7 +61,7 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
|
||||
//simply set the rotation z-wise to the angleBetweenVectors
|
||||
sprite["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors);
|
||||
|
||||
if (!IsServer) {
|
||||
if (!IsServer || !m_NetworkEnabled) {
|
||||
updateDamageIndicatorVector.emplace_back(sprite, inflictorPos);
|
||||
}
|
||||
|
||||
@@ -122,7 +128,7 @@ glm::vec3 DamageIndicatorSystem::DamageIndicatorTest(EntityWrapper player) {
|
||||
}
|
||||
m_TestVar++;
|
||||
|
||||
auto inflictorPos = glm::vec3(currentPos.x + testVar*6.0f, currentPos.y, currentPos.z + testVar2*6.0f);
|
||||
auto inflictorPos = glm::vec3(currentPos.x + testVar*6.0f, currentPos.y, currentPos.z + testVar2*6.0f);
|
||||
|
||||
//load the explosioneffect XML
|
||||
auto deathEffect = ResourceManager::Load<EntityXMLFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
|
||||
void ExplosionEffectSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||
{
|
||||
Field<double> timeSinceDeath = component["TimeSinceDeath"];
|
||||
if (timeSinceDeath > (double)component["ExplosionDuration"]) {
|
||||
timeSinceDeath = 0.f;
|
||||
Field<double> delay = component["Delay"];
|
||||
if (delay > 0) {
|
||||
delay = std::max(0.0, delay - dt);
|
||||
}
|
||||
timeSinceDeath += dt;
|
||||
|
||||
//if ((bool)Component["Gravity"] == true) {
|
||||
// (bool)Component["ExponentialAccelaration"] = false;
|
||||
//}
|
||||
if (delay <= 0) {
|
||||
Field<double> timeSinceDeath = component["TimeSinceDeath"];
|
||||
timeSinceDeath += (Field<double>)component["Speed"] * dt;
|
||||
if (timeSinceDeath < 0 || timeSinceDeath > (const double&)component["ExplosionDuration"]) {
|
||||
timeSinceDeath = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "../Game/Systems/MainMenuSystem.h"
|
||||
|
||||
MainMenuSystem::MainMenuSystem(SystemParams params, IRenderer* renderer)
|
||||
: System(params)
|
||||
, ImpureSystem()
|
||||
, m_Renderer(renderer)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPressed, &MainMenuSystem::OnButtonPress);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EReleased, &MainMenuSystem::OnButtonRelease);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EClicked, &MainMenuSystem::OnButtonClick);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &MainMenuSystem::OnInputCommand);
|
||||
}
|
||||
|
||||
void MainMenuSystem::Update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MainMenuSystem::OpenSubMenu(const Events::InputCommand& e)
|
||||
{
|
||||
auto menus = m_World->GetComponents("Menu");
|
||||
if (menus == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_OpenSubMenu == EntityWrapper::Invalid) {
|
||||
//No submenu is open, open one.
|
||||
for (auto& menu : *menus) {
|
||||
EntityWrapper menuEntity = EntityWrapper(m_World, menu.EntityID);
|
||||
auto serverListSpawner = menuEntity.FirstChildByName(e.Command + "Spawner");
|
||||
if (!serverListSpawner.HasComponent("Spawner")) {
|
||||
return;
|
||||
}
|
||||
m_OpenSubMenu = SpawnerSystem::Spawn(serverListSpawner, serverListSpawner);
|
||||
Events::SearchForServers event;
|
||||
m_EventBroker->Publish(event);
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (m_OpenSubMenu.Name().compare(e.Command) != 0) {
|
||||
//Menu is open, but not the right one, delete the old one and open a new one.
|
||||
m_World->DeleteEntity(m_OpenSubMenu.ID);
|
||||
m_OpenSubMenu = EntityWrapper::Invalid;
|
||||
|
||||
for (auto& menu : *menus) {
|
||||
EntityWrapper menuEntity = EntityWrapper(m_World, menu.EntityID);
|
||||
auto serverListSpawner = menuEntity.FirstChildByName(e.Command + "Spawner");
|
||||
if (!serverListSpawner.HasComponent("Spawner")) {
|
||||
return;
|
||||
}
|
||||
m_OpenSubMenu = SpawnerSystem::Spawn(serverListSpawner, serverListSpawner);
|
||||
Events::SearchForServers event;
|
||||
m_EventBroker->Publish(event);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//Serverlist submenu is open, close it.
|
||||
m_World->DeleteEntity(m_OpenSubMenu.ID);
|
||||
m_OpenSubMenu = EntityWrapper::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
bool MainMenuSystem::OnButtonClick(const Events::ButtonClicked& e)
|
||||
{
|
||||
EntityWrapper entity = e.Entity;
|
||||
if (entity.Name() == "ServerIdentityConnect") {
|
||||
EntityWrapper serverIdentityEntity = entity.FirstParentWithComponent("ServerIdentity");
|
||||
if(serverIdentityEntity.Valid()) {
|
||||
Events::ConnectRequest event;
|
||||
event.IP = (std::string)serverIdentityEntity["ServerIdentity"]["IP"];
|
||||
event.Port = (int)serverIdentityEntity["ServerIdentity"]["Port"];
|
||||
printf("\n ----Request Server Connect----\nIP: %s\nPort: %i\n ------------------------------", event.IP, event.Port);
|
||||
m_EventBroker->Publish(event);
|
||||
}
|
||||
} else if (entity.HasComponent("ConfigBtnResolution")) {
|
||||
|
||||
m_Renderer->SetResolution(Rectangle((int)entity["ConfigBtnResolution"]["Width"], (int)entity["ConfigBtnResolution"]["Height"]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainMenuSystem::OnButtonRelease(const Events::ButtonReleased& e)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainMenuSystem::OnButtonPress(const Events::ButtonPressed& e)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainMenuSystem::OnInputCommand(const Events::InputCommand& e)
|
||||
{
|
||||
if(e.Command == "Play" && e.Value == 1) {
|
||||
OpenSubMenu(e);
|
||||
} else if (e.Command == "RefreshServerList" && e.Value == 1){
|
||||
Events::SearchForServers event;
|
||||
m_EventBroker->Publish(event);
|
||||
} else if (e.Command == "Options" && e.Value == 1) {
|
||||
OpenSubMenu(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "Systems/PlayerDeathSystem.h"
|
||||
#include "Core/ELockMouse.h"
|
||||
|
||||
PlayerDeathSystem::PlayerDeathSystem(SystemParams params)
|
||||
: System(params)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &PlayerDeathSystem::OnEntityDeleted);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &PlayerDeathSystem::OnInputCommand);
|
||||
}
|
||||
|
||||
void PlayerDeathSystem::Update(double dt)
|
||||
@@ -33,10 +35,10 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
|
||||
|
||||
//components that we need from player
|
||||
auto playerModel = player.FirstChildByName("PlayerModel");
|
||||
if (!playerModel.Valid()) {
|
||||
return;
|
||||
}
|
||||
if (!playerModel.HasComponent("Model") || !playerModel.HasComponent("Animation")) {
|
||||
if (player == LocalPlayer) {
|
||||
setSpectatorCamera();
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto playerEntityModel = playerModel["Model"];
|
||||
@@ -68,14 +70,35 @@ bool PlayerDeathSystem::OnEntityDeleted(Events::EntityDeleted& e)
|
||||
if (m_LocalPlayerDeathEffect.ID != e.DeletedEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// If the player hasn't spawned already, activate the spectator camera.
|
||||
if (!LocalPlayer.Valid()) {
|
||||
setSpectatorCamera();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlayerDeathSystem::setSpectatorCamera()
|
||||
{
|
||||
// Look for the spectator camera entity in the level.
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName("SpectatorCamera");
|
||||
if (!spectatorCam.Valid() || !spectatorCam.HasComponent("Camera") || LocalPlayer.Valid()) {
|
||||
return false;
|
||||
if (!spectatorCam.HasComponent("Camera")) {
|
||||
return;
|
||||
}
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
return true;
|
||||
Events::UnlockMouse unlock;
|
||||
m_EventBroker->Publish(unlock);
|
||||
}
|
||||
|
||||
bool PlayerDeathSystem::OnInputCommand(Events::InputCommand& e)
|
||||
{
|
||||
if (e.Value == 0 || e.Command != "SwapToTeamPick" && e.Command != "SwapToClassPick") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure that we don't set spectator camera if the player deliberately changes to class/team pick.
|
||||
m_LocalPlayerDeathEffect = EntityWrapper::Invalid;
|
||||
return true;
|
||||
}
|
||||
@@ -81,27 +81,18 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
||||
cameraOrientation.x(cameraOrientation.x() + controller->Rotation().x);
|
||||
// Limit camera pitch so we don't break our necks
|
||||
cameraOrientation.x(glm::clamp(cameraOrientation.x(), -glm::half_pi<float>(), glm::half_pi<float>()));
|
||||
|
||||
// Set third person model aim pitch
|
||||
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
|
||||
|
||||
//Third-person aim
|
||||
if (playerModel.Valid()) {
|
||||
EntityWrapper aimPrimaryEntity = playerModel.FirstChildByName("AimPrimary");
|
||||
EntityWrapper aimPrimaryEntity = playerModel.FirstChildByName("Aim");
|
||||
if(aimPrimaryEntity.Valid()){
|
||||
if(aimPrimaryEntity.HasComponent("Animation")) {
|
||||
float pitch = cameraOrientation.x() + 0.2f;
|
||||
double time = (pitch + glm::half_pi<float>()) / glm::pi<float>();
|
||||
float pitch = cameraOrientation.x();
|
||||
double time = ((pitch + glm::half_pi<float>()) / glm::pi<float>());
|
||||
(Field<double>)aimPrimaryEntity["Animation"]["Time"] = time;
|
||||
}
|
||||
}
|
||||
EntityWrapper aimSecondaryEntity = playerModel.FirstChildByName("AimSecondary");
|
||||
if (aimSecondaryEntity.Valid()) {
|
||||
if (aimSecondaryEntity.HasComponent("Animation")) {
|
||||
float pitch = cameraOrientation.x() + 0.2f;
|
||||
double time = (pitch + glm::half_pi<float>()) / glm::pi<float>();
|
||||
(Field<double>)aimSecondaryEntity["Animation"]["Time"] = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +205,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.25;
|
||||
aeb.NodeName = "StandCrouchBlend";
|
||||
aeb.NodeName = "MovementBlend";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Start = true;
|
||||
aeb.Restart = false;
|
||||
@@ -245,11 +236,11 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.25;
|
||||
aeb.NodeName = "StandCrouchBlend";
|
||||
aeb.NodeName = "MovementBlend";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Start = true;
|
||||
aeb.Restart = false;
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("Jump");
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("BlendTreeLower").FirstChildByName("Jump");
|
||||
m_EventBroker->Publish(aeb);
|
||||
}
|
||||
}
|
||||
@@ -274,6 +265,12 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
||||
size = glm::vec3(1.f, 1.f, 1.f);
|
||||
} else {
|
||||
size = glm::vec3(1.f, 1.6f, 1.f);
|
||||
if (controller->CrouchingLastFrame() && isOnGround) {
|
||||
// The collision should resolve this anyway, but
|
||||
// this is more reliable, since the box gets larger.
|
||||
Field<glm::vec3> pos = cTransform["Position"];
|
||||
pos.y(pos.y() + 0.3f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,12 +375,12 @@ void PlayerMovementSystem::spawnHexagon(EntityWrapper target)
|
||||
bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
{
|
||||
EntityWrapper player(m_World, e.Player);
|
||||
if (!player.Valid() || !IsClient){// || player.ID == LocalPlayer.ID) {
|
||||
if (!player.Valid()){// || !IsClient || player.ID == LocalPlayer.ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DashEffect.xml");
|
||||
EntityWrapper dashEffect = entityFile->MergeInto(m_World);
|
||||
// auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DashEffect.xml");
|
||||
// EntityWrapper dashEffect = entityFile->MergeInto(m_World);
|
||||
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
|
||||
|
||||
for (auto& kv : m_PlayerInputControllers) {
|
||||
@@ -401,7 +398,7 @@ bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
if (controller->Movement().x > 0) {
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.Duration = 0.1;
|
||||
aeb.NodeName = "DashRight";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Restart = true;
|
||||
@@ -410,19 +407,18 @@ bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
}
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.NodeName = "StandCrouchBlend";
|
||||
aeb.Duration = 0.2;
|
||||
aeb.NodeName = "MovementBlend";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Delay = -0.3;
|
||||
aeb.Start = true;
|
||||
aeb.Restart = false;
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("DashForward");
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("DashRight");
|
||||
m_EventBroker->Publish(aeb);
|
||||
}
|
||||
} else {
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.Duration = 0.1;
|
||||
aeb.NodeName = "DashLeft";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Restart = true;
|
||||
@@ -431,13 +427,12 @@ bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
}
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.NodeName = "StandCrouchBlend";
|
||||
aeb.Duration = 0.2;
|
||||
aeb.NodeName = "MovementBlend";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Delay = -0.3;
|
||||
aeb.Start = true;
|
||||
aeb.Restart = false;
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("DashForward");
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("DashLeft");
|
||||
m_EventBroker->Publish(aeb);
|
||||
}
|
||||
}
|
||||
@@ -445,7 +440,7 @@ bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
if (controller->Movement().z < 0) {
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.Duration = 0.1;
|
||||
aeb.NodeName = "DashForward";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Restart = true;
|
||||
@@ -454,10 +449,9 @@ bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
}
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.NodeName = "StandCrouchBlend";
|
||||
aeb.Duration = 0.2;
|
||||
aeb.NodeName = "MovementBlend";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Delay = -0.3;
|
||||
aeb.Start = true;
|
||||
aeb.Restart = false;
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("DashForward");
|
||||
@@ -466,7 +460,7 @@ bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
} else {
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.Duration = 0.1;
|
||||
aeb.NodeName = "DashBackward";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Restart = true;
|
||||
@@ -475,32 +469,41 @@ bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e)
|
||||
}
|
||||
{
|
||||
Events::AutoAnimationBlend aeb;
|
||||
aeb.Duration = 0.3;
|
||||
aeb.NodeName = "StandCrouchBlend";
|
||||
aeb.Duration = 0.2;
|
||||
aeb.NodeName = "MovementBlend";
|
||||
aeb.RootNode = playerModel;
|
||||
aeb.Delay = -0.3;
|
||||
aeb.Start = true;
|
||||
aeb.Restart = false;
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("DashForward");
|
||||
aeb.AnimationEntity = playerModel.FirstChildByName("DashBackward");
|
||||
m_EventBroker->Publish(aeb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
auto playerEntityAnimation = playerModel["Animation"];
|
||||
|
||||
playerEntityModel.Copy(dashEffect["Model"]);
|
||||
playerEntityAnimation.Copy(dashEffect["Animation"]);
|
||||
dashEffect["ExplosionEffect"]["EndColor"] = (glm::vec4)playerEntityModel["Color"];
|
||||
((Field<glm::vec4>)dashEffect["ExplosionEffect"]["EndColor"]).w = 0.f;
|
||||
*/
|
||||
EntityWrapper dashEffectModel;
|
||||
dashEffectModel = playerModel.Clone();
|
||||
player["Transform"].Copy(dashEffectModel["Transform"]);
|
||||
|
||||
|
||||
dashEffectModel.AttachComponent("ExplosionEffect");
|
||||
dashEffectModel["ExplosionEffect"]["EndColor"] = (glm::vec4)playerModel["Model"]["Color"];
|
||||
((Field<glm::vec4>)dashEffectModel["ExplosionEffect"]["EndColor"]).w = 0.f;
|
||||
(Field<double>)dashEffectModel["ExplosionEffect"]["ExplosionDuration"] = dashEffect["Lifetime"]["Lifetime"];
|
||||
(Field<glm::vec3>)dashEffectModel["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 1, 0) + (0.2f * controller->Movement());
|
||||
|
||||
|
||||
|
||||
|
||||
auto animationChildren = dashEffectModel.ChildrenWithComponent("Animation");
|
||||
|
||||
for (auto animationEntity : animationChildren) {
|
||||
(Field<bool>)animationEntity["Animation"]["Play"] = false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Systems/PlayerSpawnSystem.h"
|
||||
#include "Core/ELockMouse.h"
|
||||
|
||||
PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params)
|
||||
: System(params)
|
||||
@@ -59,7 +60,15 @@ void PlayerSpawnSystem::Update(double dt)
|
||||
}
|
||||
|
||||
int numSpawnedPlayers = 0;
|
||||
for (auto& req : m_SpawnRequests) {
|
||||
int playersSpectating = 0;
|
||||
const int numRequestsToHandle = (int)m_SpawnRequests.size();
|
||||
for (auto it = m_SpawnRequests.begin(); it != m_SpawnRequests.end(); ++it) {
|
||||
// It is valid if they didn't pick class yet
|
||||
// but don't spawn anything, goto next spawnrequest.
|
||||
if (it->Class == PlayerClass::None) {
|
||||
++playersSpectating;
|
||||
continue;
|
||||
}
|
||||
for (auto& cPlayerSpawn : *playerSpawns) {
|
||||
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
|
||||
if (!spawner.HasComponent("Spawner")) {
|
||||
@@ -69,43 +78,49 @@ void PlayerSpawnSystem::Update(double dt)
|
||||
// If the spawner has a team affiliation, check it
|
||||
if (spawner.HasComponent("Team")) {
|
||||
auto cSpawnerTeam = spawner["Team"];
|
||||
if ((int)cSpawnerTeam["Team"] != req.Team) {
|
||||
// Increase num spawned players if someone picks spectator, since it is valid to pick spectator
|
||||
// but don't spawn anything, goto next spawnrequest.
|
||||
if (req.Team == (int)cSpawnerTeam["Team"].Enum("Spectator")) {
|
||||
++numSpawnedPlayers;
|
||||
if ((int)cSpawnerTeam["Team"] != it->Team) {
|
||||
// If they somehow has a valid class as spectator, don't spawn them.
|
||||
if (it->Team == cSpawnerTeam["Team"].Enum("Spectator")) {
|
||||
++playersSpectating;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Choose a different spawner depending on class picked?
|
||||
|
||||
// Spawn the player!
|
||||
EntityWrapper player = SpawnerSystem::Spawn(spawner, EntityWrapper::Invalid, "Player");
|
||||
// Set the player team affiliation
|
||||
player["Team"]["Team"] = req.Team;
|
||||
player["Team"]["Team"] = it->Team;
|
||||
|
||||
// Publish a PlayerSpawned event
|
||||
Events::PlayerSpawned e;
|
||||
e.PlayerID = req.PlayerID;
|
||||
e.PlayerID = it->PlayerID;
|
||||
e.Player = player;
|
||||
e.Spawner = spawner;
|
||||
m_EventBroker->Publish(e);
|
||||
++numSpawnedPlayers;
|
||||
it = m_SpawnRequests.erase(it);
|
||||
break;
|
||||
}
|
||||
if (it == m_SpawnRequests.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (numSpawnedPlayers != (int)m_SpawnRequests.size()) {
|
||||
LOG_DEBUG("%i players were supposed to be spawned or set as spectator, but only %i was handled.", (int)m_SpawnRequests.size(), numSpawnedPlayers);
|
||||
if (numSpawnedPlayers != numRequestsToHandle - playersSpectating) {
|
||||
LOG_DEBUG("%i players were supposed to be spawned, but only %i was successfully.", numRequestsToHandle - playersSpectating, numSpawnedPlayers);
|
||||
} else {
|
||||
LOG_DEBUG("%i players were spawned or set as spectator.", numSpawnedPlayers);
|
||||
std::string dbg = numSpawnedPlayers != 0 ? std::to_string(numSpawnedPlayers) + " players were spawned. " : "";
|
||||
dbg += playersSpectating != 0 ? std::to_string(playersSpectating) + " players are spectating/picking class. " : "";
|
||||
LOG_DEBUG(dbg.c_str());
|
||||
}
|
||||
m_SpawnRequests.clear();
|
||||
}
|
||||
|
||||
bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
|
||||
{
|
||||
if (e.Command != "PickTeam" && e.Command != "SwapToClassPick") {
|
||||
if (e.Command != "PickTeam" && e.Command != "PickClass" && e.Command != "SwapToTeamPick" && e.Command != "SwapToClassPick") {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -113,19 +128,6 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
|
||||
return false;
|
||||
}
|
||||
|
||||
// A dead client should be able to swap to the overwatch camera.
|
||||
if (IsClient && !LocalPlayer.Valid()) {
|
||||
// Set the camera as active, if it exists.
|
||||
// Find the respawn camera or class pick camera.
|
||||
std::string camName = e.Command == "SwapToClassPick" ? "PickClassCamera" : "SpectatorCamera";
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName(camName);
|
||||
if (spectatorCam.Valid() && spectatorCam.HasComponent("Camera")) {
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
}
|
||||
}
|
||||
|
||||
// Team picks should be processed ONLY server-side!
|
||||
// Don't make a spawn request if we're the client.
|
||||
if (!IsServer && m_NetworkEnabled) {
|
||||
@@ -136,27 +138,38 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
|
||||
auto iter = m_SpawnRequests.begin();
|
||||
for (; iter != m_SpawnRequests.end(); ++iter) {
|
||||
if (iter->PlayerID == e.PlayerID) {
|
||||
// If player wants to switch class, remove their spawn request.
|
||||
if (e.Command == "SwapToClassPick") {
|
||||
m_SpawnRequests.erase(iter);
|
||||
// If player wants to switch team or class , remove their selected class so they don't spawn.
|
||||
if (e.Command == "SwapToTeamPick" || e.Command == "SwapToClassPick") {
|
||||
iter->Class = PlayerClass::None;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (e.Command == "SwapToClassPick") {
|
||||
return true;
|
||||
}
|
||||
//If we get here we got a PickTeam or PickClass, so add or alter a spawn request.
|
||||
|
||||
if (iter != m_SpawnRequests.end()) {
|
||||
// If player is in queue to spawn, then change their team affiliation in the request.
|
||||
iter->Team = (ComponentInfo::EnumType)e.Value;
|
||||
// If player is in queue to spawn, then change their team affiliation or class in the request.
|
||||
if (e.Command == "PickTeam") {
|
||||
iter->Team = (ComponentInfo::EnumType)e.Value;
|
||||
} else {
|
||||
iter->Class = static_cast<PlayerClass>((int)e.Value);
|
||||
}
|
||||
} else if (m_PlayerEntities.count(e.PlayerID) == 0 || !m_PlayerEntities[e.PlayerID].Valid()) {
|
||||
// If player is not in queue to spawn, then create a spawn request,
|
||||
// but only if they are spectating and/or just connected.
|
||||
SpawnRequest req;
|
||||
req.PlayerID = e.PlayerID;
|
||||
req.Team = (ComponentInfo::EnumType)e.Value;
|
||||
if (e.Command == "PickTeam") {
|
||||
req.Team = (ComponentInfo::EnumType)e.Value;
|
||||
req.Class = PlayerClass::None;
|
||||
} else {
|
||||
// Should never get here, since you should have picked a team before you ever get a chance to pick class.
|
||||
LOG_WARNING("Sequence error: Should not be able to pick class before team");
|
||||
req.Team = 1; // TODO: 1 Signifies spectator, should probably have real enum here later.
|
||||
req.Class = static_cast<PlayerClass>((int)e.Value);
|
||||
}
|
||||
m_SpawnRequests.push_back(req);
|
||||
} else {
|
||||
return false;
|
||||
@@ -191,18 +204,8 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||
Events::SetCamera e;
|
||||
e.CameraEntity = cameraEntity;
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
// HACK: Set the player model color to team color
|
||||
EntityWrapper playerModel = e.Player.FirstChildByName("PlayerModel");
|
||||
if (playerModel.Valid() && e.Player.HasComponent("Team")) {
|
||||
ComponentWrapper cTeam = e.Player["Team"];
|
||||
ComponentWrapper cModel = playerModel["Model"];
|
||||
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Red")) {
|
||||
cModel["Color"] = glm::vec3(1.f, 0.f, 0.f);
|
||||
} else if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Blue")) {
|
||||
cModel["Color"] = glm::vec3(0.f, 0.25f, 1.f);
|
||||
}
|
||||
Events::LockMouse lock;
|
||||
m_EventBroker->Publish(lock);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -210,7 +213,7 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||
|
||||
bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||
{
|
||||
//Only spawn request if network is disabled or we are server.
|
||||
// Only spawn request if network is disabled or we are server.
|
||||
if (!IsServer && m_NetworkEnabled) {
|
||||
return false;
|
||||
}
|
||||
@@ -218,10 +221,6 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||
return false;
|
||||
}
|
||||
ComponentWrapper cTeam = e.Player["Team"];
|
||||
//A spectator can't die anyway
|
||||
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_PlayerIDs.count(e.Player.ID) == 0) {
|
||||
return false;
|
||||
@@ -230,6 +229,16 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||
SpawnRequest req;
|
||||
req.PlayerID = m_PlayerIDs.at(e.Player.ID);
|
||||
req.Team = cTeam["Team"];
|
||||
// TODO: Something better than temp class state code, if we ever add class enums in .xml
|
||||
if (e.Player.HasComponent("DashAbility")) {
|
||||
req.Class = PlayerClass::Assault;
|
||||
} else if (e.Player.HasComponent("SprintAbility")) {
|
||||
req.Class = PlayerClass::Sniper;
|
||||
} else if (e.Player.HasComponent("ShieldAbility")) {
|
||||
req.Class = PlayerClass::Defender;
|
||||
} else {
|
||||
req.Class = PlayerClass::None;
|
||||
}
|
||||
m_SpawnRequests.push_back(req);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "../Game/Systems/ServerListSystem.h"
|
||||
|
||||
ServerListSystem::ServerListSystem(SystemParams params, IRenderer* renderer)
|
||||
: System(params)
|
||||
, PureSystem("ServerList")
|
||||
, m_Renderer(renderer)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EServerListRecieved, &ServerListSystem::OnServerListRecieved);
|
||||
}
|
||||
|
||||
void ServerListSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cServerList, double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ServerListSystem::RefreshList()
|
||||
{
|
||||
Events::SearchForServers event;
|
||||
m_EventBroker->Publish(event);
|
||||
}
|
||||
|
||||
|
||||
bool ServerListSystem::OnServerListRecieved(const Events::DisplayServerlist& e)
|
||||
{
|
||||
if (e.Serverlist.size() == 0) {
|
||||
return 1;
|
||||
}
|
||||
auto serverLists = m_World->GetComponents("ServerList");
|
||||
if (serverLists == nullptr)
|
||||
return 1;
|
||||
for (auto& cServerList : *serverLists) {
|
||||
EntityWrapper serverListEntity = EntityWrapper(m_World, cServerList.EntityID);
|
||||
EntityWrapper identitySpawner = serverListEntity.FirstChildByName("ServerIdentitySpawner");
|
||||
identitySpawner.DeleteChildren();
|
||||
|
||||
(Field<int>)cServerList["TotalIdentities"] = (int)e.Serverlist.size();
|
||||
for (int i = 0; i < e.Serverlist.size(); i++) {
|
||||
//Create Identities for each server and place them on the right position.
|
||||
EntityWrapper newIdentity = SpawnerSystem::Spawn(identitySpawner, identitySpawner);
|
||||
EntityWrapper serverIdentityEntity = newIdentity.FirstChildByName("ServerIdentity");
|
||||
|
||||
glm::vec3 offset = (glm::vec3)serverListEntity["ServerList"]["Offset"];
|
||||
(Field<glm::vec3>)serverIdentityEntity["Transform"]["Position"] = offset * (float)i;
|
||||
|
||||
auto& cIdentity = serverIdentityEntity["ServerIdentity"];
|
||||
(Field<std::string>)cIdentity["IP"] = e.Serverlist[i].Address;
|
||||
(Field<std::string>)cIdentity["ServerName"] = e.Serverlist[i].Name;
|
||||
(Field<int>)cIdentity["Port"] = e.Serverlist[i].Port;
|
||||
(Field<int>)cIdentity["PlayersConnected"] = e.Serverlist[i].PlayersConnected;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "Systems/SpectatorCameraSystem.h"
|
||||
#include "Rendering/ESetCamera.h"
|
||||
#include "Core/ELockMouse.h"
|
||||
|
||||
SpectatorCameraSystem::SpectatorCameraSystem(SystemParams params)
|
||||
: System(params)
|
||||
, m_CamSetToTeamPick(false)
|
||||
, m_PickedTeam(-1)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SpectatorCameraSystem::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EDisconnect, &SpectatorCameraSystem::OnDisconnect);
|
||||
}
|
||||
|
||||
void SpectatorCameraSystem::Update(double dt)
|
||||
{
|
||||
if (!m_CamSetToTeamPick && IsClient) {
|
||||
// Find the class pick camera and set them to it, since they need to pick a team before they can leave the screen.
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName("PickTeamCamera");
|
||||
if (spectatorCam.HasComponent("Camera")) {
|
||||
m_CamSetToTeamPick = true;
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
Events::UnlockMouse unlock;
|
||||
m_EventBroker->Publish(unlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SpectatorCameraSystem::OnInputCommand(const Events::InputCommand& e)
|
||||
{
|
||||
// Only the client should do this, and only if player is not spawned.
|
||||
if (!IsClient || LocalPlayer.Valid()) {
|
||||
return false;
|
||||
}
|
||||
bool swapToClass = e.Command == "PickTeam" || e.Command == "SwapToClassPick";
|
||||
if (e.Value == 0 || !swapToClass && e.Command != "SwapToTeamPick" && e.Command != "PickClass") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.Command == "PickTeam") {
|
||||
m_PickedTeam = e.Value;
|
||||
}
|
||||
|
||||
// If a team has not been picked, they may not exit the pick team screen.
|
||||
if (m_PickedTeam == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A dead client should be able to swap to and between the overwatch cameras.
|
||||
std::string camName;
|
||||
// TODO: 1 Signifies spectator, should probably have real enum here later.
|
||||
// Spectators should never end up at the class select, instead put them at the SpectatorCamera.
|
||||
if (swapToClass && m_PickedTeam != 1) {
|
||||
camName = "PickClassCamera";
|
||||
} else if (e.Command == "SwapToTeamPick") {
|
||||
camName = "PickTeamCamera";
|
||||
} else {
|
||||
camName = "SpectatorCamera";
|
||||
}
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName(camName);
|
||||
// Set the camera as active, if it exists.
|
||||
if (spectatorCam.HasComponent("Camera")) {
|
||||
// Set the class pick button visible if a blue or red team is picked, else invisible.
|
||||
EntityWrapper HUD;
|
||||
if (camName == "SpectatorCamera") {
|
||||
HUD = spectatorCam.FirstChildByName("SpectatorHUD");
|
||||
} else if (camName == "PickTeamCamera") {
|
||||
HUD = spectatorCam.FirstChildByName("PickTeamHUD");
|
||||
}
|
||||
// If we are at the class pick already, or if HUD is invalid for any other reason, do nothing.
|
||||
if (HUD.Valid()) {
|
||||
EntityWrapper toClassButton = spectatorCam.FirstChildByName("ToClassPick");
|
||||
if (toClassButton.Valid()) {
|
||||
// Set ClassButton as invisible if spectator, else visible.
|
||||
bool visible = m_PickedTeam != 1; // TODO: 1 Signifies spectator.
|
||||
toClassButton["Sprite"]["Visible"] = visible;
|
||||
for (auto& child : toClassButton.ChildrenWithComponent("Text")) {
|
||||
child["Text"]["Visible"] = visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
Events::UnlockMouse unlock;
|
||||
m_EventBroker->Publish(unlock);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpectatorCameraSystem::OnDisconnect(const Events::PlayerDisconnected& e)
|
||||
{
|
||||
// If local player gets disconnected, they should be set to
|
||||
// the spectator camera next time a map loads that has one.
|
||||
if (e.Entity == LocalPlayer.ID) {
|
||||
m_CamSetToTeamPick = false;
|
||||
// They will also be set to menu, so unlock mouse just in case they were in game with locked mouse.
|
||||
Events::UnlockMouse unlock;
|
||||
m_EventBroker->Publish(unlock);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "../Game/Systems/StartSystem.h"
|
||||
|
||||
StartSystem::StartSystem(SystemParams params)
|
||||
: System(params)
|
||||
, ImpureSystem()
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ECameraActivated, &StartSystem::OnCameraActivated);
|
||||
}
|
||||
|
||||
void StartSystem::Update(double dt)
|
||||
{
|
||||
auto cameras = m_World->GetComponents("Camera");
|
||||
if(cameras == nullptr) {
|
||||
return;
|
||||
}
|
||||
for(auto& cCamera: *cameras) {
|
||||
EntityWrapper cameraEntity = EntityWrapper(m_World, cCamera.EntityID);
|
||||
if(cameraEntity == m_ActiveCamera){
|
||||
return;
|
||||
}
|
||||
if(cameraEntity.Name() == "Overview_Camera_Start_Menu") {
|
||||
Events::SetCamera event;
|
||||
event.CameraEntity = cameraEntity;
|
||||
m_EventBroker->Publish(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool StartSystem::OnCameraActivated(const Events::SetCamera& e)
|
||||
{
|
||||
m_ActiveCamera = e.CameraEntity;
|
||||
return 1;
|
||||
}
|
||||
@@ -7,17 +7,21 @@ void TextFieldReader::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
}
|
||||
|
||||
// Find the entity to read from
|
||||
const std::string& parentEntityName = cAmmunitionHUD["ParentEntityName"];
|
||||
const std::string& entityName = cAmmunitionHUD["ParentEntityName"];
|
||||
const std::string& componentType = cAmmunitionHUD["ComponentType"];
|
||||
EntityWrapper readEntity = entity;
|
||||
if (!parentEntityName.empty()) {
|
||||
readEntity = entity.FirstParentByName(parentEntityName);
|
||||
if (!readEntity.Valid()) {
|
||||
return;
|
||||
if (entityName.empty()) {
|
||||
if (!readEntity.HasComponent(componentType)) {
|
||||
readEntity = readEntity.FirstParentWithComponent(componentType);
|
||||
}
|
||||
} else {
|
||||
readEntity = entity.FirstParentByName(entityName);
|
||||
}
|
||||
if (!readEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the component to read from
|
||||
const std::string& componentType = cAmmunitionHUD["ComponentType"];
|
||||
if (componentType.empty() || !readEntity.HasComponent(componentType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -40,12 +40,16 @@ void AssaultWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo&
|
||||
magAmmo = glm::min(*magSize, *ammo);
|
||||
isReloading = false;
|
||||
if (wi.FirstPersonEntity.Valid()) {
|
||||
wi.FirstPersonEntity["Model"]["Visible"] = true;
|
||||
wi.FirstPersonEntity.FirstChildByName("ViewModel")["Model"]["Visible"] = true;
|
||||
}
|
||||
if (wi.ThirdPersonEntity.Valid()) {
|
||||
wi.ThirdPersonEntity["Model"]["Visible"] = true;
|
||||
}
|
||||
}
|
||||
double reloadTime = cWeapon["ReloadTime"];
|
||||
if (isReloading && reloadTimer <= reloadTime / 2) {
|
||||
|
||||
}
|
||||
|
||||
// Restore view angle
|
||||
if (IsClient) {
|
||||
@@ -68,7 +72,7 @@ void AssaultWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo&
|
||||
const float& movementSpeed = cPlayer["MovementSpeed"];
|
||||
float speed = glm::length((const glm::vec3&)cPhysics["Velocity"]);
|
||||
float animationWeight = glm::min(speed, movementSpeed) / movementSpeed;
|
||||
EntityWrapper rootNode = wi.FirstPersonEntity.FirstParentWithComponent("Model");
|
||||
EntityWrapper rootNode = wi.FirstPersonEntity;
|
||||
if (rootNode.Valid()) {
|
||||
EntityWrapper blend = rootNode.FirstChildByName("MovementBlend");
|
||||
if (blend.Valid()) {
|
||||
@@ -121,19 +125,35 @@ void AssaultWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
reloadTimer = reloadTime;
|
||||
|
||||
// Play animation
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "BlendTreeAssaultWeapon", "Reload");
|
||||
if (IsClient) {
|
||||
// Spawn explosion effect
|
||||
EntityWrapper reloadEffectSpawner = wi.FirstPersonEntity.FirstChildByName("FirstPersonReloadSpawner");
|
||||
if (reloadEffectSpawner.Valid()) {
|
||||
SpawnerSystem::Spawn(reloadEffectSpawner, reloadEffectSpawner);
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "ActionBlend", "Reload");
|
||||
// Third person anim
|
||||
Events::AutoAnimationBlend b1;
|
||||
b1.RootNode = wi.ThirdPersonPlayerModel;
|
||||
b1.NodeName = "Reload";
|
||||
b1.Restart = true;
|
||||
b1.Start = true;
|
||||
m_EventBroker->Publish(b1);
|
||||
|
||||
// Spawn explosion effect
|
||||
if (wi.FirstPersonEntity.Valid()) {
|
||||
if (IsClient) {
|
||||
EntityWrapper reloadEffectSpawner = wi.FirstPersonEntity.FirstChildByName("ReloadSpawner");
|
||||
if (reloadEffectSpawner.Valid()) {
|
||||
reloadEffectSpawner.DeleteChildren();
|
||||
SpawnerSystem::Spawn(reloadEffectSpawner, reloadEffectSpawner);
|
||||
}
|
||||
}
|
||||
if (wi.FirstPersonEntity.Valid()) {
|
||||
wi.FirstPersonEntity["Model"]["Visible"] = false;
|
||||
}
|
||||
if (wi.ThirdPersonEntity.Valid()) {
|
||||
wi.ThirdPersonEntity["Model"]["Visible"] = false;
|
||||
wi.FirstPersonEntity.FirstChildByName("ViewModel")["Model"]["Visible"] = false;
|
||||
}
|
||||
if (wi.ThirdPersonEntity.Valid()) {
|
||||
if (IsServer) {
|
||||
EntityWrapper reloadEffectSpawner = wi.ThirdPersonEntity.FirstChildByName("ReloadSpawner");
|
||||
if (reloadEffectSpawner.Valid()) {
|
||||
reloadEffectSpawner.DeleteChildren();
|
||||
SpawnerSystem::Spawn(reloadEffectSpawner, reloadEffectSpawner);
|
||||
}
|
||||
}
|
||||
wi.ThirdPersonEntity["Model"]["Visible"] = false;
|
||||
}
|
||||
|
||||
// Sound
|
||||
@@ -190,7 +210,7 @@ void AssaultWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
}
|
||||
|
||||
// Get weapon model based on current person
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponModelEntity(wi);
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponEntity(wi);
|
||||
if (!weaponModelEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
@@ -221,7 +241,15 @@ void AssaultWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
}
|
||||
|
||||
// Play animation
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "BlendTreeAssaultWeapon", "Fire");
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "ActionBlend", "Fire");
|
||||
|
||||
// Third person anim
|
||||
Events::AutoAnimationBlend b1;
|
||||
b1.RootNode = wi.ThirdPersonPlayerModel;
|
||||
b1.NodeName = "Fire";
|
||||
b1.Restart = true;
|
||||
b1.Start = true;
|
||||
m_EventBroker->Publish(b1);
|
||||
|
||||
// Sound
|
||||
Events::PlaySoundOnEntity e;
|
||||
|
||||
@@ -36,7 +36,7 @@ void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo&
|
||||
m_EventBroker->Publish(e);
|
||||
} else {
|
||||
isReloading = false;
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "FinalBlend", "Idle");
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "FinalBlend", "ReloadEnd");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,21 @@ void DefenderWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
reloadTimer = reloadTime;
|
||||
|
||||
// Play animation
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "FinalBlend", "Reload");
|
||||
if (wi.FirstPersonEntity.Valid()) {
|
||||
Events::AutoAnimationBlend eBlendStart;
|
||||
eBlendStart.RootNode = wi.FirstPersonEntity;
|
||||
eBlendStart.NodeName = "ReloadStart";
|
||||
eBlendStart.Restart = true;
|
||||
eBlendStart.Start = true;
|
||||
m_EventBroker->Publish(eBlendStart);
|
||||
Events::AutoAnimationBlend eBlendLoop;
|
||||
eBlendLoop.RootNode = wi.FirstPersonEntity;
|
||||
eBlendLoop.NodeName = "ReloadLoop";
|
||||
eBlendLoop.Restart = true;
|
||||
eBlendLoop.Start = true;
|
||||
eBlendLoop.AnimationEntity = wi.FirstPersonEntity.FirstChildByName("ReloadStart");
|
||||
m_EventBroker->Publish(eBlendLoop);
|
||||
}
|
||||
}
|
||||
|
||||
void DefenderWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
@@ -114,17 +128,18 @@ void DefenderWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
|
||||
bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e)
|
||||
{
|
||||
if (e.Command == "SpecialAbility" && IsServer) {
|
||||
if (e.Command == "SpecialAbility") {
|
||||
EntityWrapper attachment = wi.Player.FirstChildByName("ShieldAttachment");
|
||||
if (attachment.Valid()) {
|
||||
if (e.Value > 0) {
|
||||
SpawnerSystem::Spawn(attachment, attachment);
|
||||
if (IsServer) {
|
||||
SpawnerSystem::Spawn(attachment, attachment);
|
||||
}
|
||||
|
||||
EntityWrapper root = wi.FirstPersonEntity.FirstParentWithComponent("Model");
|
||||
if (root.Valid()) {
|
||||
EntityWrapper subTree = root.FirstChildByName("FinalBlend");
|
||||
if (subTree.Valid()) {
|
||||
EntityWrapper animationNode = subTree.FirstChildByName("Shield");
|
||||
if (IsClient) {
|
||||
EntityWrapper root = wi.FirstPersonEntity;
|
||||
if (root.Valid()) {
|
||||
EntityWrapper animationNode = root.FirstChildByName("Shield");
|
||||
if (animationNode.Valid()) {
|
||||
Events::AutoAnimationBlend eFireBlend;
|
||||
eFireBlend.RootNode = root;
|
||||
@@ -138,11 +153,10 @@ bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInf
|
||||
} else {
|
||||
attachment.DeleteChildren();
|
||||
|
||||
EntityWrapper root = wi.FirstPersonEntity.FirstParentWithComponent("Model");
|
||||
if (root.Valid()) {
|
||||
EntityWrapper subTree = root.FirstChildByName("FinalBlend");
|
||||
if (subTree.Valid()) {
|
||||
EntityWrapper animationNode = subTree.FirstChildByName("ActionBlend");
|
||||
if (IsClient) {
|
||||
EntityWrapper root = wi.FirstPersonEntity;
|
||||
if (root.Valid()) {
|
||||
EntityWrapper animationNode = root.FirstChildByName("ActionBlend");
|
||||
if (animationNode.Valid()) {
|
||||
Events::AutoAnimationBlend eFireBlend;
|
||||
eFireBlend.RootNode = root;
|
||||
@@ -232,7 +246,7 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
}
|
||||
|
||||
// Play animation
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "BlendTreeDefenderWeapon", "Fire");
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "FinalBlend", "Fire");
|
||||
|
||||
// Sound
|
||||
Events::PlaySoundOnEntity e;
|
||||
|
||||
@@ -52,7 +52,7 @@ void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"];
|
||||
|
||||
// Get weapon model based on current person
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponModelEntity(wi);
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponEntity(wi);
|
||||
if (!weaponModelEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user