MXVK Vulkan Framework 0.35.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
walk::RawWallRenderer Class Reference

Classes

struct  WallUniforms
struct  WallVertex

Public Member Functions

void cleanup (mxvk::VK_Window *targetWindow)
void cleanup (mxvk::VK_Window *targetWindow)
void load (mxvk::VK_Window *targetWindow, const std::string &textureManifestPath, const std::string &textureBasePath, const std::vector< char > &vertexShaderSpv, const std::vector< char > &fragmentShaderSpv)
void load (mxvk::VK_Window *targetWindow, const std::string &textureManifestPath, const std::string &textureBasePath, const std::vector< char > &vertexShaderSpv, const std::vector< char > &fragmentShaderSpv)
void reloadFragShader (const std::vector< char > &newFragSpv)
 Hot-swap the fragment shader without rebuilding geometry or descriptors.
void reloadFragShader (const std::vector< char > &newFragSpv)
 Hot-swap the fragment shader without rebuilding geometry or descriptors.
void render (VkCommandBuffer cmd, uint32_t imageIndex, const std::vector< WallSegment > &walls, float wallThickness, const glm::mat4 &view, const glm::mat4 &proj, const glm::vec4 &fx)
void render (VkCommandBuffer cmd, uint32_t imageIndex, const std::vector< WallSegment > &walls, float wallThickness, const glm::mat4 &view, const glm::mat4 &proj, const glm::vec4 &fx)
void resize (mxvk::VK_Window *targetWindow)
void resize (mxvk::VK_Window *targetWindow)

Detailed Description

Definition at line 1471 of file room.cpp.

Member Function Documentation

◆ cleanup() [1/2]

void walk::RawWallRenderer::cleanup ( mxvk::VK_Window * targetWindow)
inline

Definition at line 1534 of file room.cpp.

1534 {
1535 if (targetWindow == nullptr || targetWindow->getDevice() == VK_NULL_HANDLE) {
1536 return;
1537 }
1538
1539 window = targetWindow;
1540 destroyPipeline();
1541 destroyDescriptors();
1542 destroyTexture();
1543 destroyBuffers();
1544 window = nullptr;
1545 }
VkDevice getDevice() const noexcept
Get the Vulkan logical device handle.
Definition mxvk.hpp:198

◆ cleanup() [2/2]

void walk::RawWallRenderer::cleanup ( mxvk::VK_Window * targetWindow)
inline

Definition at line 1536 of file room.cpp.

1536 {
1537 if (targetWindow == nullptr || targetWindow->getDevice() == VK_NULL_HANDLE) {
1538 return;
1539 }
1540
1541 window = targetWindow;
1542 destroyPipeline();
1543 destroyDescriptors();
1544 destroyTexture();
1545 destroyBuffers();
1546 window = nullptr;
1547 }

◆ load() [1/2]

void walk::RawWallRenderer::load ( mxvk::VK_Window * targetWindow,
const std::string & textureManifestPath,
const std::string & textureBasePath,
const std::vector< char > & vertexShaderSpv,
const std::vector< char > & fragmentShaderSpv )
inline

Definition at line 1485 of file room.cpp.

1485 {
1486 if (targetWindow == nullptr) {
1487 throw mxvk::Exception("walk: raw wall renderer requires a valid window");
1488 }
1489 window = targetWindow;
1490 vertSpv = vertexShaderSpv;
1491 fragSpv = fragmentShaderSpv;
1492
1493 if (!window->ensureRenderResources()) {
1494 throw mxvk::Exception("walk: raw wall renderer requires render resources");
1495 }
1496
1497 buildGeometry();
1498 loadTexture(textureManifestPath, textureBasePath);
1499 createTextureSampler();
1500 createDescriptorSetLayout();
1501 createUniformBuffers();
1502 createDescriptorPool();
1503 createDescriptorSets();
1504 createPipeline();
1505 }

◆ load() [2/2]

void walk::RawWallRenderer::load ( mxvk::VK_Window * targetWindow,
const std::string & textureManifestPath,
const std::string & textureBasePath,
const std::vector< char > & vertexShaderSpv,
const std::vector< char > & fragmentShaderSpv )
inline

Definition at line 1487 of file room.cpp.

1487 {
1488 if (targetWindow == nullptr) {
1489 throw mxvk::Exception("walk: raw wall renderer requires a valid window");
1490 }
1491 window = targetWindow;
1492 vertSpv = vertexShaderSpv;
1493 fragSpv = fragmentShaderSpv;
1494
1495 if (!window->ensureRenderResources()) {
1496 throw mxvk::Exception("walk: raw wall renderer requires render resources");
1497 }
1498
1499 buildGeometry();
1500 loadTexture(textureManifestPath, textureBasePath);
1501 createTextureSampler();
1502 createDescriptorSetLayout();
1503 createUniformBuffers();
1504 createDescriptorPool();
1505 createDescriptorSets();
1506 createPipeline();
1507 }

◆ reloadFragShader() [1/2]

void walk::RawWallRenderer::reloadFragShader ( const std::vector< char > & newFragSpv)
inline

Hot-swap the fragment shader without rebuilding geometry or descriptors.

Parameters
newFragSpvCompiled SPIR-V bytecode for the new fragment shader.

Definition at line 1524 of file room.cpp.

1524 {
1525 if (window == nullptr || window->getDevice() == VK_NULL_HANDLE || newFragSpv.empty()) {
1526 return;
1527 }
1528 vkDeviceWaitIdle(window->getDevice());
1529 fragSpv = newFragSpv;
1530 destroyPipeline();
1531 createPipeline();
1532 }

◆ reloadFragShader() [2/2]

void walk::RawWallRenderer::reloadFragShader ( const std::vector< char > & newFragSpv)
inline

Hot-swap the fragment shader without rebuilding geometry or descriptors.

Parameters
newFragSpvCompiled SPIR-V bytecode for the new fragment shader.

Definition at line 1526 of file room.cpp.

1526 {
1527 if (window == nullptr || window->getDevice() == VK_NULL_HANDLE || newFragSpv.empty()) {
1528 return;
1529 }
1530 vkDeviceWaitIdle(window->getDevice());
1531 fragSpv = newFragSpv;
1532 destroyPipeline();
1533 createPipeline();
1534 }

◆ render() [1/2]

void walk::RawWallRenderer::render ( VkCommandBuffer cmd,
uint32_t imageIndex,
const std::vector< WallSegment > & walls,
float wallThickness,
const glm::mat4 & view,
const glm::mat4 & proj,
const glm::vec4 & fx )
inline

Definition at line 1547 of file room.cpp.

1547 {
1548 if (cmd == VK_NULL_HANDLE || pipeline == VK_NULL_HANDLE || pipelineLayout == VK_NULL_HANDLE) {
1549 return;
1550 }
1551 if (imageIndex >= uniformBuffersMapped.size() || descriptorSets.empty() || vertexBuffer == VK_NULL_HANDLE || indexBuffer == VK_NULL_HANDLE) {
1552 return;
1553 }
1554
1555 WallUniforms uniforms{};
1556 uniforms.view = view;
1557 uniforms.proj = proj;
1558 uniforms.fx = fx;
1559 std::memcpy(uniformBuffersMapped[imageIndex], &uniforms, sizeof(WallUniforms));
1560
1561 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1562 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[imageIndex], 0, nullptr);
1563
1564 const VkDeviceSize offset = 0;
1565 vkCmdBindVertexBuffers(cmd, 0, 1, &vertexBuffer, &offset);
1566 vkCmdBindIndexBuffer(cmd, indexBuffer, 0, VK_INDEX_TYPE_UINT32);
1567
1568 const float thickness = std::max(0.02f, wallThickness);
1569 // Extend each wall by about half its thickness on both ends so adjoining
1570 // runs meet cleanly without visible seam slivers.
1571 const float wallOverlap = thickness * 0.55f;
1572 for (const WallSegment &segment : walls) {
1573 const glm::vec3 center = (segment.start + segment.end) * 0.5f;
1574 const glm::vec3 span = segment.end - segment.start;
1575 const float length = glm::length(span);
1576 if (length < 0.0001f) {
1577 continue;
1578 }
1579 // Unit wall geometry has Y in [0..1]. Sink slightly to avoid floor/wall
1580 // depth fighting where the floor top plane is also at y=0.
1581 constexpr float baseSink = 0.01f;
1582 glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(center.x, -baseSink, center.z));
1583 model = glm::rotate(model, std::atan2(span.z, span.x), glm::vec3(0.0f, 1.0f, 0.0f));
1584 model = glm::scale(model, glm::vec3(length + wallOverlap * 2.0f, segment.height, thickness));
1585 vkCmdPushConstants(cmd, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &model);
1586 vkCmdDrawIndexed(cmd, indexCount, 1, 0, 0, 0);
1587 }
1588 }

◆ render() [2/2]

void walk::RawWallRenderer::render ( VkCommandBuffer cmd,
uint32_t imageIndex,
const std::vector< WallSegment > & walls,
float wallThickness,
const glm::mat4 & view,
const glm::mat4 & proj,
const glm::vec4 & fx )
inline

Definition at line 1549 of file room.cpp.

1549 {
1550 if (cmd == VK_NULL_HANDLE || pipeline == VK_NULL_HANDLE || pipelineLayout == VK_NULL_HANDLE) {
1551 return;
1552 }
1553 if (imageIndex >= uniformBuffersMapped.size() || descriptorSets.empty() || vertexBuffer == VK_NULL_HANDLE || indexBuffer == VK_NULL_HANDLE) {
1554 return;
1555 }
1556
1557 WallUniforms uniforms{};
1558 uniforms.view = view;
1559 uniforms.proj = proj;
1560 uniforms.fx = fx;
1561 std::memcpy(uniformBuffersMapped[imageIndex], &uniforms, sizeof(WallUniforms));
1562
1563 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1564 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[imageIndex], 0, nullptr);
1565
1566 const VkDeviceSize offset = 0;
1567 vkCmdBindVertexBuffers(cmd, 0, 1, &vertexBuffer, &offset);
1568 vkCmdBindIndexBuffer(cmd, indexBuffer, 0, VK_INDEX_TYPE_UINT32);
1569
1570 const float thickness = std::max(0.02f, wallThickness);
1571 // Extend each wall by about half its thickness on both ends so adjoining
1572 // runs meet cleanly without visible seam slivers.
1573 const float wallOverlap = thickness * 0.55f;
1574 for (const WallSegment &segment : walls) {
1575 const glm::vec3 center = (segment.start + segment.end) * 0.5f;
1576 const glm::vec3 span = segment.end - segment.start;
1577 const float length = glm::length(span);
1578 if (length < 0.0001f) {
1579 continue;
1580 }
1581 // Unit wall geometry has Y in [0..1]. Sink slightly to avoid floor/wall
1582 // depth fighting where the floor top plane is also at y=0.
1583 constexpr float baseSink = 0.01f;
1584 glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(center.x, -baseSink, center.z));
1585 model = glm::rotate(model, std::atan2(span.z, span.x), glm::vec3(0.0f, 1.0f, 0.0f));
1586 model = glm::scale(model, glm::vec3(length + wallOverlap * 2.0f, segment.height, thickness));
1587 vkCmdPushConstants(cmd, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &model);
1588 vkCmdDrawIndexed(cmd, indexCount, 1, 0, 0, 0);
1589 }
1590 }

◆ resize() [1/2]

void walk::RawWallRenderer::resize ( mxvk::VK_Window * targetWindow)
inline

Definition at line 1507 of file room.cpp.

1507 {
1508 if (targetWindow == nullptr || targetWindow->getDevice() == VK_NULL_HANDLE) {
1509 return;
1510 }
1511
1512 window = targetWindow;
1513 destroyPipeline();
1514 destroyDescriptors();
1515 createDescriptorSetLayout();
1516 createUniformBuffers();
1517 createDescriptorPool();
1518 createDescriptorSets();
1519 createPipeline();
1520 }

◆ resize() [2/2]

void walk::RawWallRenderer::resize ( mxvk::VK_Window * targetWindow)
inline

Definition at line 1509 of file room.cpp.

1509 {
1510 if (targetWindow == nullptr || targetWindow->getDevice() == VK_NULL_HANDLE) {
1511 return;
1512 }
1513
1514 window = targetWindow;
1515 destroyPipeline();
1516 destroyDescriptors();
1517 createDescriptorSetLayout();
1518 createUniformBuffers();
1519 createDescriptorPool();
1520 createDescriptorSets();
1521 createPipeline();
1522 }

The documentation for this class was generated from the following files: