mouse picking
This commit is contained in:
parent
4f83af1857
commit
1701aa5a61
12 changed files with 100 additions and 19 deletions
|
@ -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;
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue