diff --git a/include/vkcv/Logger.hpp b/include/vkcv/Logger.hpp index d484711f642506926b1281a830fb2c9caf8240a2..fb1185eb1d32b19bc972ce0ecf69746f2ae89669 100644 --- a/include/vkcv/Logger.hpp +++ b/include/vkcv/Logger.hpp @@ -5,6 +5,7 @@ namespace vkcv { enum class LogLevel { + RAW_INFO, INFO, WARNING, ERROR @@ -12,6 +13,7 @@ namespace vkcv { constexpr auto getLogOutput(LogLevel level) { switch (level) { + case LogLevel::RAW_INFO: case LogLevel::INFO: return stdout; default: @@ -21,6 +23,7 @@ namespace vkcv { constexpr const char* getLogName(LogLevel level) { switch (level) { + case LogLevel::RAW_INFO: case LogLevel::INFO: return "INFO"; case LogLevel::WARNING: @@ -41,24 +44,33 @@ namespace vkcv { #define __PRETTY_FUNCTION__ __FUNCSIG__ #endif -#define vkcv_log(level, ...) { \ - char output_message [ \ - VKCV_DEBUG_MESSAGE_LEN \ - ]; \ - snprintf( \ - output_message, \ - VKCV_DEBUG_MESSAGE_LEN, \ - __VA_ARGS__ \ - ); \ - fprintf( \ - getLogOutput(level), \ - "[%s]: %s [%s, line %d: %s]\n", \ - vkcv::getLogName(level), \ - output_message, \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__ \ - ); \ +#define vkcv_log(level, ...) { \ + char output_message [ \ + VKCV_DEBUG_MESSAGE_LEN \ + ]; \ + snprintf( \ + output_message, \ + VKCV_DEBUG_MESSAGE_LEN, \ + __VA_ARGS__ \ + ); \ + if (level != LogLevel::RAW_INFO) { \ + fprintf( \ + getLogOutput(level), \ + "[%s]: %s [%s, line %d: %s]\n", \ + vkcv::getLogName(level), \ + output_message, \ + __FILE__, \ + __LINE__, \ + __PRETTY_FUNCTION__ \ + ); \ + } else { \ + fprintf( \ + getLogOutput(level), \ + "[%s]: %s\n", \ + vkcv::getLogName(level), \ + output_message \ + ); \ + } \ } #else diff --git a/modules/scene/include/vkcv/scene/Mesh.hpp b/modules/scene/include/vkcv/scene/Mesh.hpp index 96d719b66c5fa21b1441ea5c4ac9499956f204b0..f725a681a7eaf01d53b4db035c4dccfc9fffaec1 100644 --- a/modules/scene/include/vkcv/scene/Mesh.hpp +++ b/modules/scene/include/vkcv/scene/Mesh.hpp @@ -27,6 +27,9 @@ namespace vkcv::scene { void recordDrawcalls(const glm::mat4& viewProjection, std::vector<glm::mat4>& matrices, std::vector<DrawcallInfo>& drawcalls); + + [[nodiscard]] + size_t getDrawcallCount() const; public: ~Mesh(); diff --git a/modules/scene/include/vkcv/scene/Node.hpp b/modules/scene/include/vkcv/scene/Node.hpp index 58cef8f3622a721bda66286dcfa7b7ac65bcbd13..2c12e25ad70d85921525f842f669ba5da44d6d92 100644 --- a/modules/scene/include/vkcv/scene/Node.hpp +++ b/modules/scene/include/vkcv/scene/Node.hpp @@ -26,6 +26,9 @@ namespace vkcv::scene { void recordDrawcalls(const glm::mat4& viewProjection, std::vector<glm::mat4>& matrices, std::vector<DrawcallInfo>& drawcalls); + + [[nodiscard]] + size_t getDrawcallCount() const; public: ~Node(); diff --git a/modules/scene/src/vkcv/scene/Mesh.cpp b/modules/scene/src/vkcv/scene/Mesh.cpp index 12402f10701f6ef1f7ad66ef7972c93672f231d2..c4943646ed66769972b9dd392a789f5f47e02709 100644 --- a/modules/scene/src/vkcv/scene/Mesh.cpp +++ b/modules/scene/src/vkcv/scene/Mesh.cpp @@ -79,10 +79,21 @@ namespace vkcv::scene { return *this; } - static glm::vec3 projectPoint(const glm::mat4& transform, const glm::vec3& point) { + static glm::vec3 projectPoint(const glm::mat4& transform, const glm::vec3& point, bool& negative_w) { const glm::vec4 position = transform * glm::vec4(point, 1.0f); const float perspective = std::abs(position[3]); + /* + * We divide by the absolute of the 4th coorditnate because + * clipping is weird and points have to move to the other + * side of the camera. + * + * We also need to collect if the 4th coordinate was negative + * to know if all corners are behind the camera. So these can + * be culled as well + */ + negative_w = (position[3] < 0.0f); + return glm::vec3( position[0] / perspective, position[1] / perspective, @@ -109,16 +120,19 @@ namespace vkcv::scene { const Bounds& bounds = part.getBounds(); const auto corners = bounds.getCorners(); - auto projected = projectPoint(transform, corners[0]); + bool negative_w; + auto projected = projectPoint(transform, corners[0], negative_w); Bounds aabb (projected, projected); for (size_t j = 1; j < corners.size(); j++) { - projected = projectPoint(transform, corners[j]); + bool flag_w; + projected = projectPoint(transform, corners[j], flag_w); aabb.extend(projected); + negative_w &= flag_w; } - if (!checkFrustum(aabb)) { + if ((negative_w) || (!checkFrustum(aabb))) { continue; } @@ -126,5 +140,9 @@ namespace vkcv::scene { drawcalls.push_back(m_drawcalls[i]); } } + + size_t Mesh::getDrawcallCount() const { + return m_drawcalls.size(); + } } diff --git a/modules/scene/src/vkcv/scene/Node.cpp b/modules/scene/src/vkcv/scene/Node.cpp index 9e7347036cec6a81797c33458bd7def645a8a3cd..82f4191e0f07b39be319c4984db93273419440ee 100644 --- a/modules/scene/src/vkcv/scene/Node.cpp +++ b/modules/scene/src/vkcv/scene/Node.cpp @@ -66,5 +66,19 @@ namespace vkcv::scene { node.recordDrawcalls(viewProjection, matrices, drawcalls); } } + + size_t Node::getDrawcallCount() const { + size_t count = 0; + + for (auto& mesh : m_meshes) { + count += mesh.getDrawcallCount(); + } + + for (auto& node : m_nodes) { + count += node.getDrawcallCount(); + } + + return count; + } } diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp index aa8c83b4a5f9f280c81c4e78f01f5f3d52615c5d..da0f7fb69a501d9ed448677fe0ab00652b7fa7be 100644 --- a/modules/scene/src/vkcv/scene/Scene.cpp +++ b/modules/scene/src/vkcv/scene/Scene.cpp @@ -73,13 +73,17 @@ namespace vkcv::scene { const std::vector<ImageHandle> &renderTargets) { std::vector<glm::mat4> matrices; std::vector<DrawcallInfo> drawcalls; + size_t count = 0; const glm::mat4 viewProjection = camera.getMVP(); for (auto& node : m_nodes) { + count += node.getDrawcallCount(); node.recordDrawcalls(viewProjection, matrices, drawcalls); } + vkcv_log(LogLevel::RAW_INFO, "Frustum culling: %lu / %lu", drawcalls.size(), count); + PushConstantData pushConstantData (matrices.data(), sizeof(glm::mat4)); m_core->recordDrawcallsToCmdStream(