mouse picking

This commit is contained in:
tylermurphy534 2022-10-03 06:50:49 -04:00
parent 4f83af1857
commit 1701aa5a61
12 changed files with 100 additions and 19 deletions

View file

@ -170,6 +170,7 @@ void Device::createLogicalDevice() {
VkPhysicalDeviceFeatures deviceFeatures = {}; VkPhysicalDeviceFeatures deviceFeatures = {};
deviceFeatures.samplerAnisotropy = VK_TRUE; deviceFeatures.samplerAnisotropy = VK_TRUE;
deviceFeatures.fillModeNonSolid = VK_TRUE;
VkDeviceCreateInfo createInfo = {}; VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;

View file

@ -10,6 +10,7 @@ RenderSystem::RenderSystem(
std::map<uint32_t, std::vector<Image*>> imageArrayBindings, std::map<uint32_t, std::vector<Image*>> imageArrayBindings,
uint32_t pushCunstantDataSize, uint32_t pushCunstantDataSize,
bool cullingEnabled, bool cullingEnabled,
bool wireframeEnabled,
std::vector<VkVertexInputAttributeDescription> attributeDescptions, std::vector<VkVertexInputAttributeDescription> attributeDescptions,
uint32_t vertexSize uint32_t vertexSize
) : xeDevice{Engine::getInstance()->xeDevice}, ) : xeDevice{Engine::getInstance()->xeDevice},
@ -23,7 +24,7 @@ RenderSystem::RenderSystem(
createUniformBuffers(); createUniformBuffers();
createDescriptorSets(); createDescriptorSets();
createPipelineLayout(); createPipelineLayout();
createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag, cullingEnabled, attributeDescptions, vertexSize); createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag, cullingEnabled, wireframeEnabled, attributeDescptions, vertexSize);
} }
RenderSystem::~RenderSystem() { RenderSystem::~RenderSystem() {
@ -155,7 +156,7 @@ void RenderSystem::createPipelineLayout() {
} }
void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, std::vector<VkVertexInputAttributeDescription> attributeDescptions, uint32_t vertexSize) { void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, bool wireframeEnabled, std::vector<VkVertexInputAttributeDescription> attributeDescptions, uint32_t vertexSize) {
assert(pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout"); assert(pipelineLayout != nullptr && "Cannot create pipeline before pipeline layout");
PipelineConfigInfo pipelineConfig{}; PipelineConfigInfo pipelineConfig{};
@ -163,6 +164,9 @@ void RenderSystem::createPipeline(VkRenderPass renderPass, std::string vert, std
if (cullingEnabled) { if (cullingEnabled) {
pipelineConfig.rasterizationInfo.cullMode = VK_CULL_MODE_BACK_BIT; pipelineConfig.rasterizationInfo.cullMode = VK_CULL_MODE_BACK_BIT;
} }
if(wireframeEnabled) {
pipelineConfig.rasterizationInfo.polygonMode = VK_POLYGON_MODE_LINE;
}
pipelineConfig.renderPass = renderPass; pipelineConfig.renderPass = renderPass;
pipelineConfig.pipelineLayout = pipelineLayout; pipelineConfig.pipelineLayout = pipelineLayout;
xePipeline = std::make_unique<Pipeline>( xePipeline = std::make_unique<Pipeline>(

View file

@ -74,8 +74,24 @@ class RenderSystem {
return *this; return *this;
} }
Builder& setWireframe(bool enabled) {
wireframeEnabled = enabled;
return *this;
}
std::unique_ptr<RenderSystem> build() { std::unique_ptr<RenderSystem> build() {
return std::make_unique<RenderSystem>(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<RenderSystem>(
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: private:
@ -92,6 +108,7 @@ class RenderSystem {
std::string frag; std::string frag;
bool cullingEnabled{false}; bool cullingEnabled{false};
bool wireframeEnabled{false};
}; };
RenderSystem( RenderSystem(
@ -102,6 +119,7 @@ class RenderSystem {
std::map<uint32_t, std::vector<Image*>> imageArrayBindings, std::map<uint32_t, std::vector<Image*>> imageArrayBindings,
uint32_t pushCunstantDataSize, uint32_t pushCunstantDataSize,
bool cullingEnabled, bool cullingEnabled,
bool wireframeEnabled,
std::vector<VkVertexInputAttributeDescription> attributeDescptions, std::vector<VkVertexInputAttributeDescription> attributeDescptions,
uint32_t vertexSize uint32_t vertexSize
); );
@ -127,7 +145,7 @@ class RenderSystem {
void createDescriptorSets(); void createDescriptorSets();
void updateDescriptorSet(int frameIndex, bool allocate); void updateDescriptorSet(int frameIndex, bool allocate);
void createPipelineLayout(); void createPipelineLayout();
void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, std::vector<VkVertexInputAttributeDescription> attributeDescptions, uint32_t vertexSize); void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag, bool cullingEnabled, bool wireframeEnabled, std::vector<VkVertexInputAttributeDescription> attributeDescptions, uint32_t vertexSize);
bool boundPipeline{false}; bool boundPipeline{false};
bool boundDescriptor{false}; bool boundDescriptor{false};

View file

@ -22,8 +22,8 @@ layout (push_constant) uniform Push {
const float AMBIENT = 0.02; const float AMBIENT = 0.02;
void main() { 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); vec3 normalWorldSpace = normalize(mat3(push.normalMatrix) * normal);
float lightIntensity = AMBIENT + max(dot(normalWorldSpace, ubo.directionToLight), 0); float lightIntensity = AMBIENT + max(dot(normalWorldSpace, ubo.directionToLight), 0);

View file

@ -391,6 +391,29 @@ void Chunk::setBlock(int32_t x, int32_t y, int32_t z, uint8_t block) {
cubes[index] = 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<int>(floor(x / Chunk::CHUNK_SIZE.x));
int gridZ = static_cast<int>(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<int>(x % Chunk::CHUNK_SIZE.x);
int gridZ = static_cast<int>(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) { bool Chunk::isGenerated(int32_t gridX, int32_t gridZ) {
Chunk* chunk = Chunk::getChunk(gridX, gridZ); Chunk* chunk = Chunk::getChunk(gridX, gridZ);
if(chunk == nullptr) return false; if(chunk == nullptr) return false;

View file

@ -68,6 +68,8 @@ class Chunk {
xe::Model* getMesh(); xe::Model* getMesh();
uint8_t getBlock(int32_t x, int32_t y, int32_t z); 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); 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 isGenerated(int32_t gridX, int32_t gridZ);
static bool isMeshed(int32_t gridX, int32_t gridZ); static bool isMeshed(int32_t gridX, int32_t gridZ);

View file

@ -24,7 +24,7 @@ void PlayerController::update(float dt) {
float yaw = viewerObject.transform.rotation.y; float yaw = viewerObject.transform.rotation.y;
const glm::vec3 forwardDir{sin(yaw), 0.f, cos(yaw)}; const glm::vec3 forwardDir{sin(yaw), 0.f, cos(yaw)};
const glm::vec3 rightDir{forwardDir.z, 0.f, -forwardDir.x}; 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}; glm::vec3 moveDir{0};
if(input.isKeyPressed(keys.moveForward)) moveDir += forwardDir; if(input.isKeyPressed(keys.moveForward)) moveDir += forwardDir;

View file

@ -3,6 +3,7 @@
#include "xe_game_object.hpp" #include "xe_game_object.hpp"
#include "xe_input.hpp" #include "xe_input.hpp"
#define GLM_FORCE_RADIANS
#include <glm/common.hpp> #include <glm/common.hpp>
#include <glm/fwd.hpp> #include <glm/fwd.hpp>
#include <glm/geometric.hpp> #include <glm/geometric.hpp>
@ -36,7 +37,7 @@ namespace app {
xe::GameObject &viewerObject; xe::GameObject &viewerObject;
KeyMappings keys{}; KeyMappings keys{};
float moveSpeed{250.f}; float moveSpeed{100.f};
float lookSpeed{1.5f}; float lookSpeed{1.5f};
}; };

View file

@ -1,9 +1,9 @@
#include "chunk_renderer.hpp" #include "skinned_renderer.hpp"
#include "chunk.hpp" #include "chunk.hpp"
namespace app { namespace app {
ChunkRenderer::ChunkRenderer(std::vector<xe::Image*> &images) { SkinnedRenderer::SkinnedRenderer(std::vector<xe::Image*> &images) {
xeRenderSystem = xe::RenderSystem::Builder("res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv") xeRenderSystem = xe::RenderSystem::Builder("res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv")
.addVertexBindingf(0, 3, 0) // position .addVertexBindingf(0, 3, 0) // position
.addVertexBindingf(1, 3, 12) // normal .addVertexBindingf(1, 3, 12) // normal
@ -14,10 +14,11 @@ ChunkRenderer::ChunkRenderer(std::vector<xe::Image*> &images) {
.addUniformBinding(0, sizeof(UniformBuffer)) .addUniformBinding(0, sizeof(UniformBuffer))
.addTextureArrayBinding(1, images) .addTextureArrayBinding(1, images)
.setCulling(true) .setCulling(true)
.setWireframe(false)
.build(); .build();
} }
void ChunkRenderer::render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera) { void SkinnedRenderer::render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera) {
xeRenderSystem->start(); xeRenderSystem->start();

View file

@ -16,16 +16,16 @@ struct PushConstant {
alignas(16) glm::mat4 normalMatrix{1.f}; alignas(16) glm::mat4 normalMatrix{1.f};
}; };
class ChunkRenderer { class SkinnedRenderer {
public: public:
ChunkRenderer(std::vector<xe::Image*> &images); SkinnedRenderer(std::vector<xe::Image*> &images);
~ChunkRenderer() {}; ~SkinnedRenderer() {};
ChunkRenderer(const ChunkRenderer&) = delete; SkinnedRenderer(const SkinnedRenderer&) = delete;
ChunkRenderer operator=(const ChunkRenderer&) = delete; SkinnedRenderer operator=(const SkinnedRenderer&) = delete;
void render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera); void render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera);

View file

@ -6,7 +6,7 @@ World::World(xe::GameObject& viewer, int renderDistance, int worldSeed)
: viewer{viewer}, : viewer{viewer},
renderDistance{renderDistance}, renderDistance{renderDistance},
worldSeed{worldSeed}, worldSeed{worldSeed},
chunkRenderer{Chunk::getTextures()} { skinnedRenderer{Chunk::getTextures()} {
reloadChunks(renderDistance); reloadChunks(renderDistance);
} }
@ -92,7 +92,26 @@ void World::updateChunkMeshs() {
void World::render(xe::Camera& camera) { void World::render(xe::Camera& camera) {
camera.setViewYXZ(viewer.transform.translation, viewer.transform.rotation); 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};
} }
} }

View file

@ -1,9 +1,14 @@
#pragma once #pragma once
#include "xe_game_object.hpp" #include "xe_game_object.hpp"
#include "chunk_renderer.hpp" #include "skinned_renderer.hpp"
#include "chunk.hpp" #include "chunk.hpp"
#define GLM_FORCE_RADIANS
#include <glm/common.hpp>
#include <glm/fwd.hpp>
#include <glm/geometric.hpp>
#include <vector> #include <vector>
namespace app { namespace app {
@ -12,6 +17,11 @@ class World {
public: public:
struct Ray {
glm::ivec3 pos;
int hit;
};
World(xe::GameObject& viewer, int renderDistance, int worldSeed); World(xe::GameObject& viewer, int renderDistance, int worldSeed);
~World(); ~World();
@ -20,6 +30,8 @@ class World {
void render(xe::Camera& camera); void render(xe::Camera& camera);
Ray raycast(float distance, int steps);
private: private:
void resetChunks(); void resetChunks();
@ -36,7 +48,7 @@ class World {
const xe::GameObject& viewer; const xe::GameObject& viewer;
std::vector<xe::GameObject> loadedChunks; std::vector<xe::GameObject> loadedChunks;
ChunkRenderer chunkRenderer; SkinnedRenderer skinnedRenderer;
}; };