From 1701aa5a616f3de55b0a426f8d9e679f2c98a0c6 Mon Sep 17 00:00:00 2001 From: tylermurphy534 Date: Mon, 3 Oct 2022 06:50:49 -0400 Subject: mouse picking --- engine/xe_device.cpp | 1 + engine/xe_render_system.cpp | 8 ++++++-- engine/xe_render_system.hpp | 22 ++++++++++++++++++++-- res/shaders/simple_shader.vert | 2 +- src/chunk.cpp | 23 +++++++++++++++++++++++ src/chunk.hpp | 2 ++ src/chunk_renderer.cpp | 41 ----------------------------------------- src/chunk_renderer.hpp | 37 ------------------------------------- src/player_controller.cpp | 2 +- src/player_controller.hpp | 3 ++- src/skinned_renderer.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/skinned_renderer.hpp | 37 +++++++++++++++++++++++++++++++++++++ src/world.cpp | 23 +++++++++++++++++++++-- src/world.hpp | 16 ++++++++++++++-- 14 files changed, 170 insertions(+), 89 deletions(-) delete mode 100644 src/chunk_renderer.cpp delete mode 100644 src/chunk_renderer.hpp create mode 100644 src/skinned_renderer.cpp create mode 100644 src/skinned_renderer.hpp diff --git a/engine/xe_device.cpp b/engine/xe_device.cpp index dc4d5f1..3c13150 100755 --- a/engine/xe_device.cpp +++ b/engine/xe_device.cpp @@ -170,6 +170,7 @@ void Device::createLogicalDevice() { VkPhysicalDeviceFeatures deviceFeatures = {}; deviceFeatures.samplerAnisotropy = VK_TRUE; + deviceFeatures.fillModeNonSolid = VK_TRUE; VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; diff --git a/engine/xe_render_system.cpp b/engine/xe_render_system.cpp index ff745e6..99c92b1 100644 --- a/engine/xe_render_system.cpp +++ b/engine/xe_render_system.cpp @@ -10,6 +10,7 @@ RenderSystem::RenderSystem( std::map> imageArrayBindings, uint32_t pushCunstantDataSize, bool cullingEnabled, + bool wireframeEnabled, std::vector attributeDescptions, uint32_t vertexSize ) : xeDevice{Engine::getInstance()->xeDevice}, @@ -23,7 +24,7 @@ RenderSystem::RenderSystem( createUniformBuffers(); createDescriptorSets(); createPipelineLayout(); - createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag, cullingEnabled, attributeDescptions, vertexSize); + createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag, cullingEnabled, wireframeEnabled, attributeDescptions, vertexSize); } RenderSystem::~RenderSystem() { @@ -155,7 +156,7 @@ void RenderSystem::createPipelineLayout() { } -void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, std::vector attributeDescptions, uint32_t vertexSize) { +void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, bool wireframeEnabled, std::vector attributeDescptions, uint32_t vertexSize) { assert(pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout"); PipelineConfigInfo pipelineConfig{}; @@ -163,6 +164,9 @@ void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std if (cullingEnabled) { pipelineConfig.rasterizationInfo.cullMode = VK_CULL_MODE_BACK_BIT; } + if(wireframeEnabled) { + pipelineConfig.rasterizationInfo.polygonMode = VK_POLYGON_MODE_LINE; + } pipelineConfig.renderPass = renderPass; pipelineConfig.pipelineLayout = pipelineLayout; xePipeline = std::make_unique( diff --git a/engine/xe_render_system.hpp b/engine/xe_render_system.hpp index a07b5c0..04ce52f 100644 --- a/engine/xe_render_system.hpp +++ b/engine/xe_render_system.hpp @@ -74,8 +74,24 @@ class RenderSystem { return *this; } + Builder& setWireframe(bool enabled) { + wireframeEnabled = enabled; + return *this; + } + std::unique_ptr build() { - return std::make_unique(std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(imageArrayBindings), std::move(pushCunstantDataSize), std::move(cullingEnabled), std::move(attributeDescptions), std::move(vertexSize)); + return std::make_unique( + std::move(vert), + std::move(frag), + std::move(uniformBindings), + std::move(imageBindings), + std::move(imageArrayBindings), + std::move(pushCunstantDataSize), + std::move(cullingEnabled), + std::move(wireframeEnabled), + std::move(attributeDescptions), + std::move(vertexSize) + ); } private: @@ -92,6 +108,7 @@ class RenderSystem { std::string frag; bool cullingEnabled{false}; + bool wireframeEnabled{false}; }; RenderSystem( @@ -102,6 +119,7 @@ class RenderSystem { std::map> imageArrayBindings, uint32_t pushCunstantDataSize, bool cullingEnabled, + bool wireframeEnabled, std::vector attributeDescptions, uint32_t vertexSize ); @@ -127,7 +145,7 @@ class RenderSystem { void createDescriptorSets(); void updateDescriptorSet(int frameIndex, bool allocate); void createPipelineLayout(); - void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, std::vector attributeDescptions, uint32_t vertexSize); + void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, bool wireframeEnabled, std::vector attributeDescptions, uint32_t vertexSize); bool boundPipeline{false}; bool boundDescriptor{false}; diff --git a/res/shaders/simple_shader.vert b/res/shaders/simple_shader.vert index 33504ff..9c4c7c6 100755 --- a/res/shaders/simple_shader.vert +++ b/res/shaders/simple_shader.vert @@ -22,8 +22,8 @@ layout (push_constant) uniform Push { const float AMBIENT = 0.02; void main() { - gl_Position = ubo.projectionViewMatrix * push.modelMatrix * vec4(position, 1.0); + gl_Position = ubo.projectionViewMatrix * push.modelMatrix * vec4(position, 1.0); vec3 normalWorldSpace = normalize(mat3(push.normalMatrix) * normal); float lightIntensity = AMBIENT + max(dot(normalWorldSpace, ubo.directionToLight), 0); diff --git a/src/chunk.cpp b/src/chunk.cpp index 55f8832..18e3c69 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -391,6 +391,29 @@ void Chunk::setBlock(int32_t x, int32_t y, int32_t z, uint8_t block) { cubes[index] = block; } +uint8_t Chunk::getGlobalBlock(int32_t x, int32_t y, int32_t z) { + if(y >= CHUNK_SIZE.y) return AIR; + if(y < 0) return INVALID; + int gridX = static_cast(floor(x / Chunk::CHUNK_SIZE.x)); + int gridZ = static_cast(floor(z / Chunk::CHUNK_SIZE.z)); + Chunk* chunk = getChunk(gridX, gridZ); + if(chunk == nullptr) return INVALID; + int localX = x - gridX * CHUNK_SIZE.x; + int localZ = z - gridZ * CHUNK_SIZE.z; + return chunk->getBlock(localX, y, localZ); +} + +void Chunk::setGlobalBlock(int32_t x, int32_t y, int32_t z, uint8_t block) { + if(y < 0 || y >= CHUNK_SIZE.y) return; + int gridX = static_cast(x % Chunk::CHUNK_SIZE.x); + int gridZ = static_cast(floor(z / Chunk::CHUNK_SIZE.z)); + Chunk* chunk = getChunk(gridX, gridZ); + if(chunk == nullptr) return; + int localX = x - gridX * CHUNK_SIZE.x; + int localZ = z - gridZ * CHUNK_SIZE.z; + chunk->setBlock(localX, y, localZ, block); +} + bool Chunk::isGenerated(int32_t gridX, int32_t gridZ) { Chunk* chunk = Chunk::getChunk(gridX, gridZ); if(chunk == nullptr) return false; diff --git a/src/chunk.hpp b/src/chunk.hpp index 6223fc7..5fcec17 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -68,6 +68,8 @@ class Chunk { xe::Model* getMesh(); uint8_t getBlock(int32_t x, int32_t y, int32_t z); void setBlock(int32_t x, int32_t y, int32_t z, uint8_t block); + static uint8_t getGlobalBlock(int32_t x, int32_t y, int32_t z); + static void setGlobalBlock(int32_t x, int32_t y, int32_t z, uint8_t block); static bool isGenerated(int32_t gridX, int32_t gridZ); static bool isMeshed(int32_t gridX, int32_t gridZ); diff --git a/src/chunk_renderer.cpp b/src/chunk_renderer.cpp deleted file mode 100644 index 2dba6cb..0000000 --- a/src/chunk_renderer.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "chunk_renderer.hpp" -#include "chunk.hpp" - -namespace app { - -ChunkRenderer::ChunkRenderer(std::vector &images) { - xeRenderSystem = xe::RenderSystem::Builder("res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv") - .addVertexBindingf(0, 3, 0) // position - .addVertexBindingf(1, 3, 12) // normal - .addVertexBindingf(2, 2, 24) // uvs - .addVertexBindingi(3, 1, 32) // texture - .setVertexSize(36) - .addPushConstant(sizeof(PushConstant)) - .addUniformBinding(0, sizeof(UniformBuffer)) - .addTextureArrayBinding(1, images) - .setCulling(true) - .build(); -} - -void ChunkRenderer::render(std::vector &gameObjects, xe::Camera &xeCamera) { - - xeRenderSystem->start(); - - UniformBuffer ubo{}; - ubo.projectionView = xeCamera.getProjection() * xeCamera.getView(); - xeRenderSystem->loadUniformObject(0, &ubo); - - for(auto &obj : gameObjects) { - if(obj.model == nullptr) continue; - PushConstant pc{}; - pc.modelMatrix = obj.transform.mat4(); - pc.normalMatrix = obj.transform.normalMatrix(); - xeRenderSystem->loadPushConstant(&pc); - xeRenderSystem->render(obj); - } - - xeRenderSystem->stop(); - -} - -} \ No newline at end of file diff --git a/src/chunk_renderer.hpp b/src/chunk_renderer.hpp deleted file mode 100644 index e539f29..0000000 --- a/src/chunk_renderer.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "xe_render_system.hpp" - -#include - -namespace app { - -struct UniformBuffer { - alignas(16) glm::mat4 projectionView{1.f}; - alignas(4) glm::vec3 lightDirection = glm::normalize(glm::vec3{-1.f, 3.f, 1.f}); -}; - -struct PushConstant { - alignas(16) glm::mat4 modelMatrix{1.f}; - alignas(16) glm::mat4 normalMatrix{1.f}; -}; - -class ChunkRenderer { - - public: - - ChunkRenderer(std::vector &images); - - ~ChunkRenderer() {}; - - ChunkRenderer(const ChunkRenderer&) = delete; - ChunkRenderer operator=(const ChunkRenderer&) = delete; - - void render(std::vector &gameObjects, xe::Camera &xeCamera); - - private: - std::unique_ptr xeRenderSystem; - -}; - -} \ No newline at end of file diff --git a/src/player_controller.cpp b/src/player_controller.cpp index 1956f8e..45f5b4b 100644 --- a/src/player_controller.cpp +++ b/src/player_controller.cpp @@ -24,7 +24,7 @@ void PlayerController::update(float dt) { float yaw = viewerObject.transform.rotation.y; const glm::vec3 forwardDir{sin(yaw), 0.f, cos(yaw)}; const glm::vec3 rightDir{forwardDir.z, 0.f, -forwardDir.x}; - const glm::vec3 upDir{0.f, 01.f, 0.f}; + const glm::vec3 upDir{0.f, 1.f, 0.f}; glm::vec3 moveDir{0}; if(input.isKeyPressed(keys.moveForward)) moveDir += forwardDir; diff --git a/src/player_controller.hpp b/src/player_controller.hpp index e34f1ed..3d5d16d 100644 --- a/src/player_controller.hpp +++ b/src/player_controller.hpp @@ -3,6 +3,7 @@ #include "xe_game_object.hpp" #include "xe_input.hpp" +#define GLM_FORCE_RADIANS #include #include #include @@ -36,7 +37,7 @@ namespace app { xe::GameObject &viewerObject; KeyMappings keys{}; - float moveSpeed{250.f}; + float moveSpeed{100.f}; float lookSpeed{1.5f}; }; diff --git a/src/skinned_renderer.cpp b/src/skinned_renderer.cpp new file mode 100644 index 0000000..0b65d0d --- /dev/null +++ b/src/skinned_renderer.cpp @@ -0,0 +1,42 @@ +#include "skinned_renderer.hpp" +#include "chunk.hpp" + +namespace app { + +SkinnedRenderer::SkinnedRenderer(std::vector &images) { + xeRenderSystem = xe::RenderSystem::Builder("res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv") + .addVertexBindingf(0, 3, 0) // position + .addVertexBindingf(1, 3, 12) // normal + .addVertexBindingf(2, 2, 24) // uvs + .addVertexBindingi(3, 1, 32) // texture + .setVertexSize(36) + .addPushConstant(sizeof(PushConstant)) + .addUniformBinding(0, sizeof(UniformBuffer)) + .addTextureArrayBinding(1, images) + .setCulling(true) + .setWireframe(false) + .build(); +} + +void SkinnedRenderer::render(std::vector &gameObjects, xe::Camera &xeCamera) { + + xeRenderSystem->start(); + + UniformBuffer ubo{}; + ubo.projectionView = xeCamera.getProjection() * xeCamera.getView(); + xeRenderSystem->loadUniformObject(0, &ubo); + + for(auto &obj : gameObjects) { + if(obj.model == nullptr) continue; + PushConstant pc{}; + pc.modelMatrix = obj.transform.mat4(); + pc.normalMatrix = obj.transform.normalMatrix(); + xeRenderSystem->loadPushConstant(&pc); + xeRenderSystem->render(obj); + } + + xeRenderSystem->stop(); + +} + +} \ No newline at end of file diff --git a/src/skinned_renderer.hpp b/src/skinned_renderer.hpp new file mode 100644 index 0000000..0c87fb5 --- /dev/null +++ b/src/skinned_renderer.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "xe_render_system.hpp" + +#include + +namespace app { + +struct UniformBuffer { + alignas(16) glm::mat4 projectionView{1.f}; + alignas(4) glm::vec3 lightDirection = glm::normalize(glm::vec3{-1.f, 3.f, 1.f}); +}; + +struct PushConstant { + alignas(16) glm::mat4 modelMatrix{1.f}; + alignas(16) glm::mat4 normalMatrix{1.f}; +}; + +class SkinnedRenderer { + + public: + + SkinnedRenderer(std::vector &images); + + ~SkinnedRenderer() {}; + + SkinnedRenderer(const SkinnedRenderer&) = delete; + SkinnedRenderer operator=(const SkinnedRenderer&) = delete; + + void render(std::vector &gameObjects, xe::Camera &xeCamera); + + private: + std::unique_ptr xeRenderSystem; + +}; + +} \ No newline at end of file diff --git a/src/world.cpp b/src/world.cpp index 485615d..d11e4bc 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -6,7 +6,7 @@ World::World(xe::GameObject& viewer, int renderDistance, int worldSeed) : viewer{viewer}, renderDistance{renderDistance}, worldSeed{worldSeed}, - chunkRenderer{Chunk::getTextures()} { + skinnedRenderer{Chunk::getTextures()} { reloadChunks(renderDistance); } @@ -92,7 +92,26 @@ void World::updateChunkMeshs() { void World::render(xe::Camera& camera) { camera.setViewYXZ(viewer.transform.translation, viewer.transform.rotation); - chunkRenderer.render(loadedChunks, camera); + // World::Ray ray = raycast(7, 100); + skinnedRenderer.render(loadedChunks, camera); +} + +World::Ray World::raycast(float distance, int steps) { + + glm::vec3 position = glm::vec3(viewer.transform.translation); + + float pitch = viewer.transform.rotation.x; + float yaw = viewer.transform.rotation.y; + float clamp = 1-fabs(sin(-pitch)); + const glm::vec3 step = glm::normalize(glm::vec3(sin(yaw)*clamp, sin(-pitch), cos(yaw)*clamp)) * (distance/steps); + + for(int i = 0; i < steps; i++) { + position += step; + int hit = Chunk::getGlobalBlock(position.x, position.y, position.z); + if(hit == AIR) continue; + return World::Ray{position, hit}; + } + return World::Ray{position, INVALID}; } } \ No newline at end of file diff --git a/src/world.hpp b/src/world.hpp index 12e0285..e8882b2 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -1,9 +1,14 @@ #pragma once #include "xe_game_object.hpp" -#include "chunk_renderer.hpp" +#include "skinned_renderer.hpp" #include "chunk.hpp" +#define GLM_FORCE_RADIANS +#include +#include +#include + #include namespace app { @@ -12,6 +17,11 @@ class World { public: + struct Ray { + glm::ivec3 pos; + int hit; + }; + World(xe::GameObject& viewer, int renderDistance, int worldSeed); ~World(); @@ -20,6 +30,8 @@ class World { void render(xe::Camera& camera); + Ray raycast(float distance, int steps); + private: void resetChunks(); @@ -36,7 +48,7 @@ class World { const xe::GameObject& viewer; std::vector loadedChunks; - ChunkRenderer chunkRenderer; + SkinnedRenderer skinnedRenderer; }; -- cgit v1.2.3-freya