Skip to content

Commit

Permalink
Refactor drawNextFrame.
Browse files Browse the repository at this point in the history
  • Loading branch information
Flone-dnb committed Dec 26, 2023
1 parent 344b885 commit 2dad7af
Show file tree
Hide file tree
Showing 33 changed files with 1,601 additions and 843 deletions.
6 changes: 3 additions & 3 deletions res/engine/shaders/include/Lighting.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
/** Light color intensity of ambient lighting. 4th component is not used. */
vec4 ambientLight;

/** Total number of spawned point lights. */
/** Total number of spawned point lights in camera frustum. */
uint iPointLightCount;

/** Total number of spawned directional lights. */
/** Total number of spawned directional lights in camera frustum. */
uint iDirectionalLightCount;

/** Total number of spawned spotlights. */
/** Total number of spawned spotlights in camera frustum. */
uint iSpotlightCount;
#glsl } generalLightingData;
#hlsl }; ConstantBuffer<GeneralLightingData> generalLightingData : register(b1, space5);
Expand Down
3 changes: 2 additions & 1 deletion res/engine/shaders/include/Shapes.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct Plane{
float distanceFromOrigin;
};

/** Sphere represented by a center and a radius. */
/** Sphere shape. */
struct Sphere{
/** Location of the sphere's center point. */
vec3 center;
Expand All @@ -18,6 +18,7 @@ struct Sphere{
float radius;
};

/** Cone shape. */
struct Cone{
/** Location of cone's tip. */
vec3 location;
Expand Down
4 changes: 4 additions & 0 deletions src/engine_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ set(PROJECT_SOURCES
public/misc/shapes/Frustum.h
private/misc/shapes/Plane.cpp
public/misc/shapes/Plane.h
private/misc/shapes/Sphere.cpp
public/misc/shapes/Sphere.h
private/misc/shapes/Cone.cpp
public/misc/shapes/Cone.h
private/shader/general/ShaderPack.h
private/shader/general/ShaderPack.cpp
private/shader/general/ShaderMacro.h
Expand Down
13 changes: 13 additions & 0 deletions src/engine_lib/private/game/camera/CameraManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,17 @@ namespace ne {
}
}

CameraProperties* CameraManager::ActiveCamera::getCameraProperties() {
if (pCameraNode != nullptr) {
return pCameraNode->getCameraProperties();
}

if (pTransientCamera != nullptr) {
return pTransientCamera->getCameraProperties();
}

// No active camera.
return nullptr;
}

} // namespace ne
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ namespace ne {
->getLightingShaderResourceManager()
->getDirectionalLightDataArray();
auto result = pDirectionalLightArray->reserveNewSlot(
this,
sizeof(DirecionalLightShaderData),
[this]() { return onStartedUpdatingShaderData(); },
[this]() { onFinishedUpdatingShaderData(); });
Expand Down
24 changes: 23 additions & 1 deletion src/engine_lib/private/game/nodes/light/PointLightNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ namespace ne {
static_assert(sizeof(PointLightShaderData) == 48, "consider copying new parameters here");
#endif

// Recalculate sphere shape.
recalculateShape();

// Reserve a slot in the point light shader data array
// so that our parameters will be available in the shaders.
const auto pPointLightDataArray = getGameInstance()
Expand All @@ -35,6 +38,7 @@ namespace ne {
->getLightingShaderResourceManager()
->getPointLightDataArray();
auto result = pPointLightDataArray->reserveNewSlot(
this,
sizeof(PointLightShaderData),
[this]() { return onStartedUpdatingShaderData(); },
[this]() { onFinishedUpdatingShaderData(); });
Expand Down Expand Up @@ -87,8 +91,11 @@ namespace ne {
void PointLightNode::setLightDistance(float distance) {
std::scoped_lock guard(mtxShaderData.first);

// Save new parameter.
this->distance = std::max(distance, 0.0F);

// Update shader data.
mtxShaderData.second.shaderData.distance = distance;
mtxShaderData.second.shaderData.distance = this->distance;

// Mark updated shader data to be later copied to the GPU resource.
markShaderDataToBeCopiedToGpu();
Expand All @@ -100,6 +107,9 @@ namespace ne {
// Make sure our intensity is in range [0.0; 1.0].
intensity = std::clamp(intensity, 0.0F, 1.0F);

// Make sure distance is not negative.
distance = std::max(distance, 0.0F);

#if defined(DEBUG)
static_assert(sizeof(PointLightShaderData) == 48, "consider clamping new parameters here");
#endif
Expand All @@ -123,6 +133,9 @@ namespace ne {

// Mark as "needs update".
mtxShaderData.second.pPointLightArraySlot->markAsNeedsUpdate();

// Recalculate sphere shape.
recalculateShape();
}

glm::vec3 PointLightNode::getLightColor() const { return color; }
Expand All @@ -143,4 +156,13 @@ namespace ne {
markShaderDataToBeCopiedToGpu();
}

void PointLightNode::recalculateShape() {
std::scoped_lock guard(mtxShaderData.first, mtxShape.first);

mtxShape.second.center = mtxShaderData.second.shaderData.position;
mtxShape.second.radius = mtxShaderData.second.shaderData.distance;
}

std::pair<std::mutex, Sphere>* PointLightNode::getShape() { return &mtxShape; }

}
18 changes: 17 additions & 1 deletion src/engine_lib/private/game/nodes/light/SpotlightNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace ne {
->getLightingShaderResourceManager()
->getSpotlightDataArray();
auto result = pSpotlightDataArray->reserveNewSlot(
this,
sizeof(SpotlightShaderData),
[this]() { return onStartedUpdatingShaderData(); },
[this]() { onFinishedUpdatingShaderData(); });
Expand Down Expand Up @@ -75,7 +76,7 @@ namespace ne {
std::scoped_lock guard(mtxShaderData.first);

// Save new parameter.
this->distance = distance;
this->distance = glm::max(distance, 0.0F);

// Update shader data.
recalculateAndMarkShaderDataToBeCopiedToGpu();
Expand Down Expand Up @@ -113,6 +114,7 @@ namespace ne {
// Make sure our cutoff angle is in valid range.
innerConeAngle = std::clamp(innerConeAngle, 0.0F, maxConeAngle);
outerConeAngle = std::clamp(outerConeAngle, innerConeAngle, maxConeAngle);
distance = glm::max(distance, 0.0F);

#if defined(DEBUG)
static_assert(sizeof(SpotlightShaderData) == 80, "consider clamping new parameters here");
Expand Down Expand Up @@ -159,6 +161,9 @@ namespace ne {

// Mark as "needs update".
mtxShaderData.second.pSpotlightArraySlot->markAsNeedsUpdate();

// Recalculate sphere shape.
recalculateShape();
}

glm::vec3 SpotlightNode::getLightColor() const { return color; }
Expand All @@ -178,4 +183,15 @@ namespace ne {

float SpotlightNode::getLightOuterConeAngle() const { return outerConeAngle; }

std::pair<std::mutex, Cone>* SpotlightNode::getShape() { return &mtxShape; }

void SpotlightNode::recalculateShape() {
std::scoped_lock guard(mtxShaderData.first, mtxShape.first);

mtxShape.second.location = mtxShaderData.second.shaderData.position;
mtxShape.second.direction = mtxShaderData.second.shaderData.direction;
mtxShape.second.height = mtxShaderData.second.shaderData.distance;
mtxShape.second.bottomRadius = mtxShaderData.second.shaderData.coneBottomRadius;
}

}
4 changes: 2 additions & 2 deletions src/engine_lib/private/misc/shapes/AABB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace ne {
return aabb;
}

bool AABB::isIntersectsOrInFrontOfPlane(const Plane& plane) const {
bool AABB::isBehindPlane(const Plane& plane) const {
// Source: https://github.com/gdbooks/3DCollisions/blob/master/Chapter2/static_aabb_plane.md

const float projectionRadius = extents.x * std::abs(plane.normal.x) +
Expand All @@ -54,7 +54,7 @@ namespace ne {

const auto distanceToPlane = glm::dot(plane.normal, center) - plane.distanceFromOrigin;

return -projectionRadius <= distanceToPlane;
return !(-projectionRadius <= distanceToPlane);
}

}
27 changes: 27 additions & 0 deletions src/engine_lib/private/misc/shapes/Cone.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "misc/shapes/Cone.h"

namespace ne {

Cone::Cone(const glm::vec3& location, float height, const glm::vec3& direction, float bottomRadius) {
this->location = location;
this->height = height;
this->direction = direction;
this->bottomRadius = bottomRadius;
}

bool Cone::isBehindPlane(const Plane& plane) const {
// Source: Real-time collision detection, Christer Ericson (2005).

// Calculate an intermediate vector which is parallel but opposite to plane's normal and perpendicular
// to the cone's direction.
glm::vec3 m = glm::cross(glm::cross(plane.normal, direction), direction);

// Calculate the point Q that is on the base (bottom) of the cone that is farthest away from the plane
// in the direction of plane's normal.
glm::vec3 Q = location + direction * height - m * bottomRadius;

// The cone is behind the plane if both cone's tip and Q are behind the plane.
return plane.isPointBehindPlane(location) && plane.isPointBehindPlane(Q);
}

}
18 changes: 15 additions & 3 deletions src/engine_lib/private/misc/shapes/Frustum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,21 @@ namespace ne {
std::abs(glm::dot(obbScaledUp, glm::vec3(0.0F, 0.0F, 1.0F))); // project OBB Z on world Z

// Test each AABB face against the frustum.
return aabb.isIntersectsOrInFrontOfPlane(leftFace) && aabb.isIntersectsOrInFrontOfPlane(rightFace) &&
aabb.isIntersectsOrInFrontOfPlane(topFace) && aabb.isIntersectsOrInFrontOfPlane(bottomFace) &&
aabb.isIntersectsOrInFrontOfPlane(nearFace) && aabb.isIntersectsOrInFrontOfPlane(farFace);
return !aabb.isBehindPlane(leftFace) && !aabb.isBehindPlane(rightFace) &&
!aabb.isBehindPlane(topFace) && !aabb.isBehindPlane(bottomFace) &&
!aabb.isBehindPlane(nearFace) && !aabb.isBehindPlane(farFace);
}

bool Frustum::isSphereInFrustum(const Sphere& sphere) const {
return !sphere.isBehindPlane(leftFace) && !sphere.isBehindPlane(rightFace) &&
!sphere.isBehindPlane(topFace) && !sphere.isBehindPlane(bottomFace) &&
!sphere.isBehindPlane(nearFace) && !sphere.isBehindPlane(farFace);
}

bool Frustum::isConeInFrustum(const Cone& cone) const {
return !cone.isBehindPlane(leftFace) && !cone.isBehindPlane(rightFace) &&
!cone.isBehindPlane(topFace) && !cone.isBehindPlane(bottomFace) &&
!cone.isBehindPlane(nearFace) && !cone.isBehindPlane(farFace);
}

}
5 changes: 5 additions & 0 deletions src/engine_lib/private/misc/shapes/Plane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@ namespace ne {
distanceFromOrigin = glm::dot(normal, location);
}

bool Plane::isPointBehindPlane(const glm::vec3& point) const {
// Source: Real-time collision detection, Christer Ericson (2005).
return glm::dot(normal, point) - distanceFromOrigin < 0.0F;
}

}
15 changes: 15 additions & 0 deletions src/engine_lib/private/misc/shapes/Sphere.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "misc/shapes/Sphere.h"

namespace ne {

Sphere::Sphere(const glm::vec3& center, float radius) {
this->center = center;
this->radius = radius;
}

bool Sphere::isBehindPlane(const Plane& plane) const {
// Source: Real-time collision detection, Christer Ericson (2005).
return glm::dot(plane.normal, center) - plane.distanceFromOrigin < -radius;
}

}
Loading

0 comments on commit 2dad7af

Please sign in to comment.