Compare commits
27 Commits
dronuilleo
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8158a61f10 | ||
|
|
87d310b55c | ||
|
|
b9bd185968 | ||
|
|
8a806b8c65 | ||
|
|
05927da1d4 | ||
|
|
4433d34e32 | ||
|
|
0bba09a055 | ||
|
|
762c994e5c | ||
|
|
55c15cef4e | ||
|
|
dc24036efb | ||
|
|
5ffdc17d79 | ||
|
|
e85882df04 | ||
|
|
a9e53cc4cb | ||
|
|
479722185f | ||
|
|
bc865c969d | ||
|
|
dc8e5a5483 | ||
|
|
b2de337c43 | ||
|
|
7f189b2ed6 | ||
|
|
9d9d0044ee | ||
|
|
f95c48bac6 | ||
|
|
346038a8f7 | ||
|
|
ff771ba127 | ||
|
|
f2e78fbf76 | ||
|
|
87fbb1c603 | ||
|
|
dfd39257c0 | ||
|
|
c9a6f11a7a | ||
|
|
1ce25b26bd |
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,6 +15,9 @@
|
||||
*.userprefs
|
||||
|
||||
|
||||
# compiled shaders
|
||||
assets/shaders/*.spv
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
|
||||
@ -4,9 +4,9 @@ set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_FLAGS "-D_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS "")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "-D_DEBUG -Wall -D_GLIBCXX_DEBUG -g -fsanitize=address")
|
||||
set(CMAKE_CXX_FLAGS "-D_DEBUG -Wall")
|
||||
endif()
|
||||
|
||||
project(Pleascach)
|
||||
@ -25,17 +25,22 @@ add_executable (pleascach ${SOURCES})
|
||||
|
||||
# shader compilation
|
||||
file(GLOB SHADER_SOURCE_FILES
|
||||
assets/shaders/*.frag
|
||||
assets/shaders/*.vert
|
||||
assets/shaders/*.geom
|
||||
assets/shaders/*.tese
|
||||
assets/shaders/*.tesc
|
||||
assets/shaders/**/*.frag
|
||||
assets/shaders/**/*.vert
|
||||
assets/shaders/**/*.geom
|
||||
assets/shaders/**/*.tese
|
||||
assets/shaders/**/*.tesc
|
||||
assets/shaders/*/*/*.frag
|
||||
assets/shaders/*/*/*.vert
|
||||
assets/shaders/*/*/*.geom
|
||||
assets/shaders/*/*/*.tese
|
||||
assets/shaders/*/*/*.tesc
|
||||
)
|
||||
|
||||
foreach(SHADER_SOURCE ${SHADER_SOURCE_FILES})
|
||||
message("Processing shader file")
|
||||
get_filename_component(FILE_NAME ${SHADER_SOURCE} NAME)
|
||||
set(SPIRV "${CMAKE_SOURCE_DIR}/assets/shaders/${FILE_NAME}.spv")
|
||||
set(SPIRV "${CMAKE_SOURCE_DIR}/assets/shaders/bin/${FILE_NAME}.spv")
|
||||
add_custom_command(
|
||||
OUTPUT ${SPIRV}
|
||||
COMMAND glslc -o ${SPIRV} ${SHADER_SOURCE}
|
||||
@ -44,7 +49,6 @@ foreach(SHADER_SOURCE ${SHADER_SOURCE_FILES})
|
||||
list(APPEND SPIRV_BIN_FILES ${SPIRV})
|
||||
endforeach(SHADER_SOURCE)
|
||||
|
||||
|
||||
add_custom_target (
|
||||
shaders
|
||||
DEPENDS ${SPIRV_BIN_FILES}
|
||||
|
||||
@ -77,23 +77,25 @@ void Input::handleMovementKeys(Renderer& ren) {
|
||||
if (ImGui::GetIO().WantCaptureKeyboard && ren.in_menu)
|
||||
return;
|
||||
|
||||
auto dir = ren.cam.dir();
|
||||
glm::vec3 forward;
|
||||
if (ren.flycam)
|
||||
forward = dir;
|
||||
else
|
||||
forward = glm::normalize(glm::vec3(dir.x, 0.0, dir.z));
|
||||
|
||||
forward = glm::normalize(glm::vec3(glm::sin(ren.cam.theta)*glm::cos(ren.cam.phi), glm::cos(ren.cam.theta), glm::sin(ren.cam.theta)*glm::sin(ren.cam.phi)));
|
||||
else {
|
||||
forward = glm::normalize(glm::vec3(glm::cos(ren.cam.phi), 0.0, glm::sin(ren.cam.phi)));
|
||||
}
|
||||
const auto right = glm::normalize(glm::cross(forward, glm::vec3(0.0, 1.0, 0.0)));
|
||||
const auto up = glm::normalize(glm::cross(right, forward));
|
||||
|
||||
const auto speed = glfwGetKey(in, GLFW_KEY_LEFT_SHIFT)? 2.0f : 1.0f;
|
||||
auto speed = glfwGetKey(in, GLFW_KEY_LEFT_SHIFT)? 2.0f : 1.0f;
|
||||
speed *= ren.speed * ren.frametime / 8.0;
|
||||
|
||||
if(glfwGetKey(in, GLFW_KEY_UP)) {
|
||||
ren.cam.theta -= 0.02;
|
||||
ren.cam.theta -= 0.01;
|
||||
}
|
||||
|
||||
if(glfwGetKey(in, GLFW_KEY_UP)) {
|
||||
ren.cam.theta -= 0.01;
|
||||
}
|
||||
if(glfwGetKey(in, GLFW_KEY_DOWN)) {
|
||||
ren.cam.theta += 0.02;
|
||||
ren.cam.theta += 0.01;
|
||||
}
|
||||
|
||||
if(glfwGetKey(in, GLFW_KEY_LEFT)) {
|
||||
@ -105,28 +107,28 @@ void Input::handleMovementKeys(Renderer& ren) {
|
||||
}
|
||||
/* move "forward" or "backward" */
|
||||
if (glfwGetKey(in, GLFW_KEY_W)) {
|
||||
ren.cam.pos += forward * 0.1f * speed;
|
||||
ren.cam.pos += forward * 1.0f * speed;
|
||||
}
|
||||
|
||||
if (glfwGetKey(in, GLFW_KEY_S)) {
|
||||
ren.cam.pos += forward * -0.1f * speed;
|
||||
ren.cam.pos += forward * -1.0f * speed;
|
||||
}
|
||||
|
||||
/* move "left" or "right" */
|
||||
if (glfwGetKey(in, GLFW_KEY_A)) {
|
||||
ren.cam.pos -= right * 0.1f * speed;
|
||||
ren.cam.pos -= right * 1.0f * speed;
|
||||
}
|
||||
|
||||
if (glfwGetKey(in, GLFW_KEY_D)) {
|
||||
ren.cam.pos += right * 0.1f * speed;
|
||||
ren.cam.pos += right * 1.0f * speed;
|
||||
}
|
||||
|
||||
if(glfwGetKey(in, GLFW_KEY_SPACE)) {
|
||||
ren.cam.pos.y += 0.1;
|
||||
ren.cam.pos.y += 1.0 * speed;
|
||||
}
|
||||
|
||||
if(glfwGetKey(in, GLFW_KEY_LEFT_CONTROL)) {
|
||||
ren.cam.pos.y -= 0.1;
|
||||
ren.cam.pos.y -= 1.0 * speed;
|
||||
}
|
||||
|
||||
ren.cam.theta = glm::clamp(ren.cam.theta, 0.01f, glm::pi<float>() - 0.01f);
|
||||
@ -147,9 +149,8 @@ void Input::handleCursorMovement(Renderer& ren, double x, double y) {
|
||||
return;
|
||||
}
|
||||
|
||||
// scaling factor
|
||||
ren.cam.phi += rel_mouse_x / 200.0;
|
||||
ren.cam.theta += rel_mouse_y / 200.0;
|
||||
ren.cam.phi += rel_mouse_x / 100.0;
|
||||
ren.cam.theta += rel_mouse_y / 100.0;
|
||||
|
||||
last_mouse = glm::vec2(x,y);
|
||||
|
||||
|
||||
160
Model/Model.cpp
Normal file
160
Model/Model.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include <Model/Model.hpp>
|
||||
|
||||
#include <util/log.hpp>
|
||||
#include <util/file.hpp>
|
||||
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <tinygltf/tiny_gltf.h>
|
||||
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
Model::Model(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname) {
|
||||
Log::debug("Loading model " + fname + "\n");
|
||||
|
||||
tinygltf::TinyGLTF loader;
|
||||
std::string err, warn;
|
||||
|
||||
model = std::make_shared<tinygltf::Model>();
|
||||
|
||||
auto ret = loader.LoadASCIIFromFile(model.get(), &err, &warn, fname);
|
||||
|
||||
if(!warn.empty()) {
|
||||
Log::debug(fname + ": " + warn);
|
||||
}
|
||||
|
||||
if(!err.empty()) {
|
||||
Log::debug(fname + ": " + err);
|
||||
}
|
||||
|
||||
if(!ret) {
|
||||
Log::error("Failed to pase glTF model\n");
|
||||
}
|
||||
|
||||
for(auto& node: model->nodes)
|
||||
initNode(node, nullptr);
|
||||
|
||||
/* vertex, index buffer should be populated now */
|
||||
Log::debug("%zu vertices loaded from model " + fname + "\n", vertices.size());
|
||||
vertex_buffer = std::make_unique<VertexBuffer>(phys_dev, dev, vertices.size());
|
||||
vertex_buffer->upload(vertices);
|
||||
|
||||
index_buffer = std::make_unique<Buffer>(phys_dev, dev, indices.size()*sizeof(uint16_t),
|
||||
vk::BufferUsageFlagBits::eIndexBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
index_buffer->upload(reinterpret_cast<uint8_t*>(indices.data()), static_cast<vk::DeviceSize>(indices.size()*sizeof(uint16_t)));
|
||||
}
|
||||
|
||||
void Model::initVertices(Node* node, const tinygltf::Primitive& prim) {
|
||||
Log::debug("Loading vertices\n");
|
||||
uint32_t first_idx = indices.size();
|
||||
uint32_t vert_start = vertices.size();
|
||||
uint32_t idx_count = 0;
|
||||
|
||||
const float* pos_buff = nullptr;
|
||||
const float* norm_buff = nullptr;
|
||||
const float* uv_buff = nullptr;
|
||||
size_t vertex_count = 0;
|
||||
|
||||
auto loc = prim.attributes.find("POSITION");
|
||||
if(loc != prim.attributes.end()) {
|
||||
auto& accessor = model->accessors[loc->second];
|
||||
const auto& view = model->bufferViews[accessor.bufferView];
|
||||
pos_buff = reinterpret_cast<const float*>(&model->buffers[view.buffer].data[accessor.byteOffset+view.byteOffset]);
|
||||
vertex_count = accessor.count;
|
||||
}
|
||||
loc = prim.attributes.find("NORMAL");
|
||||
if(loc != prim.attributes.end()) {
|
||||
auto& accessor = model->accessors[loc->second];
|
||||
const auto& view = model->bufferViews[accessor.bufferView];
|
||||
norm_buff = reinterpret_cast<const float*>(&model->buffers[view.buffer].data[accessor.byteOffset+view.byteOffset]);
|
||||
}
|
||||
loc = prim.attributes.find("TEXCOORD_0");
|
||||
if(loc != prim.attributes.end()) {
|
||||
auto& accessor = model->accessors[loc->second];
|
||||
const auto& view = model->bufferViews[accessor.bufferView];
|
||||
uv_buff = reinterpret_cast<const float*>(&model->buffers[view.buffer].data[accessor.byteOffset+view.byteOffset]);
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < vertex_count; i++) {
|
||||
vertices.push_back(glTFVertex {
|
||||
.pos = pos_buff? glm::make_vec3(pos_buff+i*3) : glm::vec3(0.0),
|
||||
.norm = norm_buff? glm::normalize(glm::make_vec3(norm_buff+i*3)) : glm::vec3(0.0),
|
||||
.uv = uv_buff? glm::make_vec2(uv_buff+i*2) : glm::vec2(0.0),
|
||||
.color = glm::vec3(0.0),
|
||||
});
|
||||
}
|
||||
|
||||
Log::debug("Finished loading %zu vertices\n", vertex_count);
|
||||
|
||||
const auto& accessor = model->accessors[prim.indices];
|
||||
const auto& view = model->bufferViews[accessor.bufferView];
|
||||
const auto& buffer = model->buffers[view.buffer];
|
||||
|
||||
idx_count += accessor.count;
|
||||
|
||||
switch(accessor.componentType) {
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT:
|
||||
for(size_t i = 0; i < accessor.count; i++)
|
||||
indices.push_back(
|
||||
reinterpret_cast<const uint32_t*>(
|
||||
&buffer.data[accessor.byteOffset+view.byteOffset
|
||||
])[i]
|
||||
+ vert_start
|
||||
);
|
||||
break;
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT:
|
||||
for(size_t i = 0; i < accessor.count; i++)
|
||||
indices.push_back(
|
||||
reinterpret_cast<const uint16_t*>(
|
||||
&buffer.data[accessor.byteOffset+view.byteOffset
|
||||
])[i]
|
||||
+ vert_start
|
||||
);
|
||||
break;
|
||||
case TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE:
|
||||
for(size_t i = 0; i < accessor.count; i++)
|
||||
indices.push_back(
|
||||
reinterpret_cast<const uint8_t*>(
|
||||
&buffer.data[accessor.byteOffset+view.byteOffset
|
||||
])[i]
|
||||
+ vert_start
|
||||
);
|
||||
break;
|
||||
default:
|
||||
Log::error("Unrecognized index type in model\n");
|
||||
break;
|
||||
}
|
||||
|
||||
Log::debug("Loaded %zu indices of type %d\n", accessor.count, (accessor.componentType-TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE)/2+1);
|
||||
|
||||
node->mesh.push_back(Primitive {
|
||||
.first_idx = first_idx,
|
||||
.idx_count = idx_count,
|
||||
});
|
||||
}
|
||||
|
||||
void Model::initNode(const tinygltf::Node& node, Node* parent, int level) {
|
||||
Log::debug("%*sNode:"+node.name+"\n", level*4, " ");
|
||||
|
||||
Node* ret = new Node;
|
||||
|
||||
ret->parent = parent;
|
||||
|
||||
/* load kids */
|
||||
for(auto& child_idx : node.children) {
|
||||
initNode(model->nodes[child_idx], ret, level+1);
|
||||
}
|
||||
|
||||
if(node.mesh >= 0) {
|
||||
const auto& mesh = model->meshes[node.mesh];
|
||||
for(auto& prim : mesh.primitives) {
|
||||
initVertices(ret, prim);
|
||||
}
|
||||
}
|
||||
|
||||
if(ret->parent)
|
||||
ret->parent->children.push_back(ret);
|
||||
else
|
||||
nodes.push_back(ret);
|
||||
}
|
||||
54
Model/Model.hpp
Normal file
54
Model/Model.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <Memory/Buffer.hpp>
|
||||
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <tinygltf/tiny_gltf.h>
|
||||
|
||||
struct Model {
|
||||
struct Primitive {
|
||||
uint32_t first_idx;
|
||||
uint32_t idx_count;
|
||||
uint32_t mat_idx;
|
||||
};
|
||||
|
||||
using Mesh = std::vector<Primitive>;
|
||||
struct Node {
|
||||
Node* parent;
|
||||
std::vector<Node*> children;
|
||||
Mesh mesh;
|
||||
glm::mat4 mat;
|
||||
~Node() {
|
||||
for(auto& n : children)
|
||||
delete n;
|
||||
}
|
||||
};
|
||||
|
||||
Model(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname);
|
||||
|
||||
std::shared_ptr<tinygltf::Model> model;
|
||||
|
||||
void initVertices(Node*, const tinygltf::Primitive&);
|
||||
|
||||
std::unique_ptr<VertexBuffer> vertex_buffer;
|
||||
std::unique_ptr<Buffer> index_buffer;
|
||||
std::vector<glTFVertex> vertices;
|
||||
std::vector<uint16_t> indices;
|
||||
|
||||
/* recusively initialize nodes with an accumulative vertex and index buffer collector */
|
||||
void initNode(const tinygltf::Node& node, Node* parent, int level = 0);
|
||||
|
||||
std::vector<Node*> nodes;
|
||||
|
||||
~Model() {
|
||||
for(auto& n : nodes)
|
||||
delete n;
|
||||
|
||||
vertex_buffer.reset();
|
||||
index_buffer.reset();
|
||||
}
|
||||
};
|
||||
26
README.md
26
README.md
@ -1,12 +1,34 @@
|
||||
# Pléascach - Dronuilleog
|
||||
# Pléascach
|
||||
|
||||
No models, everything RAYMARCHED!!!!
|
||||
###### Check out the raymarching branch (pléascach-dronuilleog)!
|
||||
|
||||
Small Vulkan 3D renderer.
|
||||

|
||||

|
||||
|
||||
#### List of 3rd party code included in this repository:
|
||||
- Imgui (and Imgui-console): for debugging UI
|
||||
- STB: for image loading
|
||||
- GLM: for math
|
||||
- GLFW: for cross-platform windowing
|
||||
- TinyglTF: for glTF parsing
|
||||
|
||||
## Features
|
||||
- glTF Model loading
|
||||
- QuakeIII BSP Map Loading
|
||||
- Tessellation-controlled heightmap terrains with dynamic normal calculation
|
||||
- Working lighting!
|
||||
|
||||
## Short Term Changes
|
||||
- Make index buffer device-local instead of host-coherent
|
||||
- Possibly restructure Buffer class to use templates to change
|
||||
constructor and functions to use staging buffers if needed.
|
||||
## Constant Improvements
|
||||
- Add more comments
|
||||
## Long Term Improvements
|
||||
- ~~Properly query surface to find supported formats for surfaces~~
|
||||
- Fix all this cleanup vs destructor NONSENSE (inconsistency)
|
||||
- Add pipeline caching
|
||||
- Make more robust solution to window minimization (flushing out Input system should provide candidates)
|
||||
- Command buffer per swapchain image
|
||||
- Make smaller memory allocation object to pass around instead of directly passing physical device to everything
|
||||
@ -2,6 +2,10 @@
|
||||
#include <Renderer/Pipeline.hpp>
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
#include <Scene/Terrain.hpp>
|
||||
|
||||
#include <Model/Model.hpp>
|
||||
|
||||
#include <Memory/Buffer.hpp>
|
||||
#include <Memory/Image.hpp>
|
||||
|
||||
@ -61,18 +65,30 @@ void CommandBuffer::copy(Buffer& src, Image& dst, vk::ImageLayout layout) {
|
||||
|
||||
void CommandBuffer::bind(const GraphicsPipeline& pipeline) {
|
||||
command_buffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.pipeline);
|
||||
command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.layout, 0, pipeline.desc_set, nullptr);
|
||||
}
|
||||
|
||||
void CommandBuffer::bind(vk::PipelineLayout layout, vk::ArrayProxy<vk::DescriptorSet> desc_sets) {
|
||||
command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, desc_sets, nullptr);
|
||||
}
|
||||
|
||||
void CommandBuffer::bind(const VertexBuffer& vertex_buffer, uint32_t binding) {
|
||||
const std::array<vk::DeviceSize, 1> offsets = {0};
|
||||
|
||||
command_buffer.bindVertexBuffers(binding, vertex_buffer.buffer->buffer, offsets);
|
||||
void CommandBuffer::bind(std::shared_ptr<Model> model) {
|
||||
bind(*model->vertex_buffer);
|
||||
command_buffer.bindIndexBuffer(*model->index_buffer, 0, vk::IndexType::eUint16);
|
||||
}
|
||||
|
||||
void CommandBuffer::bind(Terrain* terrain) {
|
||||
bind(*terrain->vertex_buffer);
|
||||
command_buffer.bindIndexBuffer(*terrain->index_buffer, 0, vk::IndexType::eUint32);
|
||||
}
|
||||
|
||||
void CommandBuffer::bind(HLBSP::BSP* bsp) {
|
||||
bind(*bsp->pipeline);
|
||||
bind(*bsp->vertex_buffer);
|
||||
bind(bsp->pipeline->layout, bsp->pipeline->desc_set);
|
||||
}
|
||||
|
||||
|
||||
void CommandBuffer::draw(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) {
|
||||
command_buffer.draw(vertex_count, instance_count, first_vertex, first_instance);
|
||||
}
|
||||
@ -83,6 +99,7 @@ void CommandBuffer::end() {
|
||||
|
||||
void CommandBuffer::recycle() {
|
||||
command_buffer.reset();
|
||||
|
||||
}
|
||||
|
||||
void CommandBuffer::cleanup(vk::Device dev) {
|
||||
|
||||
@ -7,11 +7,14 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
#include <Scene/BSP.hpp>
|
||||
|
||||
struct Buffer;
|
||||
struct Image;
|
||||
struct GraphicsPipeline;
|
||||
struct ComputePipeline;
|
||||
struct VertexBuffer;
|
||||
struct Model;
|
||||
struct Terrain;
|
||||
|
||||
@ -30,7 +33,17 @@ struct CommandBuffer {
|
||||
|
||||
void bind(const GraphicsPipeline& pipeline);
|
||||
void bind(vk::PipelineLayout layout, vk::ArrayProxy<vk::DescriptorSet> desc_sets);
|
||||
void bind(const VertexBuffer& vertex_buffer, uint32_t binding = 0);
|
||||
template <typename Vertex>
|
||||
|
||||
void bind(const GeneralVertexBuffer<Vertex>& vertex_buffer, uint32_t binding = 0) {
|
||||
const std::array<vk::DeviceSize, 1> offsets = { 0 };
|
||||
|
||||
command_buffer.bindVertexBuffers(binding, vertex_buffer.buffer->buffer, offsets);
|
||||
}
|
||||
|
||||
void bind(std::shared_ptr<Model> model);
|
||||
void bind(Terrain* terrain);
|
||||
void bind(HLBSP::BSP* bsp);
|
||||
|
||||
void draw(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex = 0, uint32_t first_instance = 0);
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
#include <Renderer/Shader.hpp>
|
||||
#include <Renderer/RenderPass.hpp>
|
||||
#include <Renderer/UniformBuffer.hpp>
|
||||
#include <Renderer/ShaderBuffer.hpp>
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
#include <Resources/Texture.hpp>
|
||||
|
||||
@ -10,7 +9,9 @@
|
||||
|
||||
#include <util/log.hpp>
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& shaders, const vk::Extent2D& extent, const RenderPass& render_pass, vk::ArrayProxy<vk::DescriptorSetLayoutBinding> bindings, const VertexBuffer& vertex_buffer) : dev(dev) {
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& shaders, const vk::Extent2D& extent, const RenderPass& render_pass, vk::ArrayProxy<vk::DescriptorSetLayoutBinding> bindings, const vk::VertexInputBindingDescription& vertex_binding, const std::vector<vk::VertexInputAttributeDescription>& vertex_attrs, enum Type type, bool wireframe, bool culling)
|
||||
: dev(dev), shaders(shaders), extent(extent), render_pass(render_pass), bindings(bindings), vertex_binding(vertex_binding), vertex_attrs(vertex_attrs), type(type) {
|
||||
/* create layout
|
||||
* Eventually add a graphicspipline constructor that allows specification of layouts etc
|
||||
* kinda like how Image::Image has all those versions
|
||||
@ -56,65 +57,93 @@ GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& sh
|
||||
})[0];
|
||||
|
||||
/* shader setup */
|
||||
std::vector<vk::PipelineShaderStageCreateInfo> shader_info;
|
||||
shader_info.reserve(shaders.size());
|
||||
for (const auto& shader : shaders)
|
||||
shader_info.push_back(shader.info());
|
||||
|
||||
/* vertex input setup */
|
||||
const std::vector<vk::VertexInputBindingDescription> vertex_bindings = {
|
||||
vertex_buffer.binding(0),
|
||||
vertex_bindings = {
|
||||
vertex_binding,
|
||||
};
|
||||
|
||||
auto attrs = vertex_buffer.attrs(0);
|
||||
|
||||
const auto vertex_input_info = vk::PipelineVertexInputStateCreateInfo{
|
||||
vertex_input_info = vk::PipelineVertexInputStateCreateInfo {
|
||||
.vertexBindingDescriptionCount = static_cast<uint32_t>(vertex_bindings.size()),
|
||||
.pVertexBindingDescriptions = vertex_bindings.data(),
|
||||
.vertexAttributeDescriptionCount = static_cast<uint32_t>(attrs.size()),
|
||||
.pVertexAttributeDescriptions = attrs.data(),
|
||||
.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertex_attrs.size()),
|
||||
.pVertexAttributeDescriptions = vertex_attrs.data(),
|
||||
};
|
||||
|
||||
const auto input_asm_info = vk::PipelineInputAssemblyStateCreateInfo{
|
||||
.topology = vk::PrimitiveTopology::eTriangleList,
|
||||
input_asm_info = vk::PipelineInputAssemblyStateCreateInfo {
|
||||
/* matters later if we use strip primitives */
|
||||
.primitiveRestartEnable = vk::False,
|
||||
};
|
||||
|
||||
switch (type) {
|
||||
case eVERTEX:
|
||||
case eGLTF:
|
||||
case eBSP:
|
||||
input_asm_info.topology = vk::PrimitiveTopology::eTriangleList;
|
||||
break;
|
||||
case eTERRAIN:
|
||||
input_asm_info.topology = vk::PrimitiveTopology::ePatchList;
|
||||
break;
|
||||
case eBOX:
|
||||
input_asm_info.topology = vk::PrimitiveTopology::ePointList;
|
||||
break;
|
||||
}
|
||||
|
||||
const vk::PipelineTessellationStateCreateInfo* ptesselation_info = nullptr;
|
||||
|
||||
const auto raster_info = vk::PipelineRasterizationStateCreateInfo {
|
||||
tess_info = vk::PipelineTessellationStateCreateInfo {
|
||||
/* quads*/
|
||||
.patchControlPoints = 4,
|
||||
};
|
||||
|
||||
if(type == Type::eTERRAIN) {
|
||||
ptesselation_info = &tess_info;
|
||||
}
|
||||
|
||||
raster_info = vk::PipelineRasterizationStateCreateInfo {
|
||||
.depthClampEnable = vk::False,
|
||||
.polygonMode = vk::PolygonMode::eFill,
|
||||
.cullMode = vk::CullModeFlagBits::eNone,
|
||||
.polygonMode = (type == eBOX || wireframe) ? vk::PolygonMode::eLine : vk::PolygonMode::eFill,
|
||||
.cullMode = (type == eBOX || !culling) ? vk::CullModeFlagBits::eNone : vk::CullModeFlagBits::eBack,
|
||||
.frontFace = vk::FrontFace::eCounterClockwise,
|
||||
.depthBiasEnable = vk::False,
|
||||
.depthBiasEnable = type == eBOX,
|
||||
.depthBiasConstantFactor = 0.01,
|
||||
.lineWidth = 1.0,
|
||||
};
|
||||
|
||||
const auto multisample_info = vk::PipelineMultisampleStateCreateInfo {
|
||||
multisample_info = vk::PipelineMultisampleStateCreateInfo {
|
||||
.rasterizationSamples = vk::SampleCountFlagBits::e1,
|
||||
.sampleShadingEnable = vk::False,
|
||||
};
|
||||
|
||||
const auto depth_stencil_info = vk::PipelineDepthStencilStateCreateInfo{
|
||||
.depthTestEnable = vk::False,
|
||||
.depthWriteEnable = vk::False,
|
||||
.depthCompareOp = vk::CompareOp::eLessOrEqual,
|
||||
depth_stencil_info = vk::PipelineDepthStencilStateCreateInfo{
|
||||
.depthTestEnable = vk::True,
|
||||
.depthWriteEnable = type != eBOX,
|
||||
.depthCompareOp = vk::CompareOp::eLess,
|
||||
.depthBoundsTestEnable = vk::False,
|
||||
.stencilTestEnable = vk::False,
|
||||
.minDepthBounds = 0.0,
|
||||
.maxDepthBounds = 1.0,
|
||||
};
|
||||
|
||||
const auto color_blend_attachment = vk::PipelineColorBlendAttachmentState{
|
||||
.blendEnable = vk::False,
|
||||
color_blend_attachment = vk::PipelineColorBlendAttachmentState {
|
||||
/* only the box has blending */
|
||||
.blendEnable = type == eBOX,
|
||||
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
|
||||
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
|
||||
.colorBlendOp = vk::BlendOp::eMax,
|
||||
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
|
||||
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
|
||||
.alphaBlendOp = vk::BlendOp::eAdd,
|
||||
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eB
|
||||
| vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eA,
|
||||
|
||||
};
|
||||
|
||||
const std::array<float, 4> blend_constants = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
const auto color_blend_info = vk::PipelineColorBlendStateCreateInfo{
|
||||
blend_constants = {0.0f, 0.0f, 0.0f, 0.0f };
|
||||
color_blend_info = vk::PipelineColorBlendStateCreateInfo{
|
||||
.logicOpEnable = vk::False,
|
||||
.logicOp = vk::LogicOp::eCopy,
|
||||
.attachmentCount = 1,
|
||||
@ -123,36 +152,34 @@ GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& sh
|
||||
};
|
||||
|
||||
/* temporary viewport and scissor, since it is a dynamic state due to the existence of window resizing */
|
||||
const auto viewport = vk::Viewport{
|
||||
viewport = vk::Viewport{
|
||||
.x = 0.0,
|
||||
.y = static_cast<float>(extent.height),
|
||||
.width = static_cast<float>(extent.width),
|
||||
.height = -static_cast<float>(extent.height),
|
||||
};
|
||||
|
||||
const auto scissor = vk::Rect2D {
|
||||
scissor = vk::Rect2D {
|
||||
.offset = 0,
|
||||
.extent = extent,
|
||||
};
|
||||
|
||||
const auto viewport_info = vk::PipelineViewportStateCreateInfo {
|
||||
viewport_info = vk::PipelineViewportStateCreateInfo {
|
||||
.viewportCount = 1,
|
||||
.pViewports = &viewport,
|
||||
.scissorCount = 1,
|
||||
.pScissors = &scissor,
|
||||
};
|
||||
|
||||
const vk::DynamicState dyn_states[] = {
|
||||
vk::DynamicState::eScissor,
|
||||
vk::DynamicState::eViewport,
|
||||
};
|
||||
dyn_states[0] = vk::DynamicState::eScissor;
|
||||
dyn_states[1] = vk::DynamicState::eViewport;
|
||||
|
||||
const auto dyn_info = vk::PipelineDynamicStateCreateInfo{
|
||||
.dynamicStateCount = std::size(dyn_states),
|
||||
dyn_info = vk::PipelineDynamicStateCreateInfo {
|
||||
.dynamicStateCount = (uint32_t)std::size(dyn_states),
|
||||
.pDynamicStates = dyn_states,
|
||||
};
|
||||
|
||||
const auto pipeline_info = vk::GraphicsPipelineCreateInfo {
|
||||
pipeline_info = vk::GraphicsPipelineCreateInfo {
|
||||
.stageCount = static_cast<uint32_t>(shaders.size()),
|
||||
.pStages = shader_info.data(),
|
||||
.pVertexInputState = &vertex_input_info,
|
||||
@ -192,21 +219,6 @@ void GraphicsPipeline::update(uint32_t binding, const UniformBuffer& uni) {
|
||||
}, nullptr);
|
||||
}
|
||||
|
||||
void GraphicsPipeline::update(uint32_t binding, const ShaderBuffer& ssbo) {
|
||||
auto buff_info = vk::DescriptorBufferInfo{
|
||||
.buffer = ssbo,
|
||||
.offset = 0,
|
||||
.range = vk::WholeSize,
|
||||
};
|
||||
dev.updateDescriptorSets(vk::WriteDescriptorSet {
|
||||
.dstSet = desc_set,
|
||||
.dstBinding = binding,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = vk::DescriptorType::eStorageBuffer,
|
||||
.pBufferInfo = &buff_info,
|
||||
}, nullptr);
|
||||
}
|
||||
|
||||
void GraphicsPipeline::update(uint32_t binding, const Texture& tex) {
|
||||
auto tex_info = vk::DescriptorImageInfo {
|
||||
.sampler = tex.sampler,
|
||||
@ -223,7 +235,30 @@ void GraphicsPipeline::update(uint32_t binding, const Texture& tex) {
|
||||
}, nullptr);
|
||||
}
|
||||
|
||||
void GraphicsPipeline::rebuild(bool wireframe, bool culling) {
|
||||
vertex_input_info = vk::PipelineVertexInputStateCreateInfo {
|
||||
.vertexBindingDescriptionCount = static_cast<uint32_t>(vertex_bindings.size()),
|
||||
.pVertexBindingDescriptions = vertex_bindings.data(),
|
||||
.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertex_attrs.size()),
|
||||
.pVertexAttributeDescriptions = vertex_attrs.data(),
|
||||
};
|
||||
|
||||
raster_info.cullMode = culling ? vk::CullModeFlagBits::eBack : vk::CullModeFlagBits::eNone;
|
||||
raster_info.polygonMode = wireframe ? vk::PolygonMode::eLine : vk::PolygonMode::eFill;
|
||||
auto res = dev.createGraphicsPipeline(nullptr, pipeline_info);
|
||||
if (res.result != vk::Result::eSuccess) {
|
||||
Log::error("Failed to create pipeline: (Vulkan error code: %d)\n", res.result);
|
||||
}
|
||||
|
||||
defunct_pipelines.push_back(pipeline);
|
||||
|
||||
pipeline = res.value;
|
||||
}
|
||||
|
||||
GraphicsPipeline::~GraphicsPipeline() {
|
||||
for(auto& p : defunct_pipelines) {
|
||||
dev.destroyPipeline(p);
|
||||
}
|
||||
dev.destroyDescriptorSetLayout(desc_layout);
|
||||
dev.destroyPipelineLayout(layout);
|
||||
dev.destroyDescriptorPool(desc_pool);
|
||||
|
||||
@ -3,34 +3,81 @@
|
||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include <util/log.hpp>
|
||||
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
struct Shader;
|
||||
struct ShaderBuffer;
|
||||
struct UniformBuffer;
|
||||
struct VertexBuffer;
|
||||
struct RenderPass;
|
||||
struct Texture;
|
||||
|
||||
struct GraphicsPipeline {
|
||||
enum Type {
|
||||
eVERTEX,
|
||||
eGLTF,
|
||||
eBSP,
|
||||
eTERRAIN,
|
||||
eBOX,
|
||||
};
|
||||
|
||||
GraphicsPipeline(vk::Device dev, const std::vector<Shader>& shaders,
|
||||
const vk::Extent2D& extent, const RenderPass& render_pass,
|
||||
vk::ArrayProxy<vk::DescriptorSetLayoutBinding> bindings,
|
||||
const VertexBuffer& vertex_buffer);
|
||||
const vk::VertexInputBindingDescription& vertex_binding,
|
||||
const std::vector<vk::VertexInputAttributeDescription>& vertex_attrs,
|
||||
enum Type type = Type::eVERTEX, bool wireframe = false, bool culling = true);
|
||||
|
||||
/* everything needed for recreation */
|
||||
vk::Device dev;
|
||||
const std::vector<Shader> shaders;
|
||||
const vk::Extent2D extent;
|
||||
const RenderPass& render_pass;
|
||||
const vk::ArrayProxy<vk::DescriptorSetLayoutBinding> bindings;
|
||||
const vk::VertexInputBindingDescription vertex_binding;
|
||||
const std::vector<vk::VertexInputAttributeDescription> vertex_attrs;
|
||||
const Type type;
|
||||
|
||||
|
||||
vk::Pipeline pipeline;
|
||||
vk::PipelineLayout layout;
|
||||
vk::DescriptorSetLayout desc_layout;
|
||||
vk::DescriptorPool desc_pool;
|
||||
vk::DescriptorSet desc_set;
|
||||
|
||||
/* pipeline creation info cached for rebuilding */
|
||||
std::vector<vk::PipelineShaderStageCreateInfo> shader_info;
|
||||
std::vector<vk::VertexInputBindingDescription> vertex_bindings;
|
||||
vk::PipelineVertexInputStateCreateInfo vertex_input_info;
|
||||
vk::PipelineInputAssemblyStateCreateInfo input_asm_info;
|
||||
vk::PipelineTessellationStateCreateInfo tess_info;
|
||||
vk::PipelineRasterizationStateCreateInfo raster_info;
|
||||
vk::PipelineMultisampleStateCreateInfo multisample_info;
|
||||
vk::PipelineDepthStencilStateCreateInfo depth_stencil_info;
|
||||
vk::PipelineColorBlendAttachmentState color_blend_attachment;
|
||||
std::array<float, 4> blend_constants;
|
||||
vk::PipelineColorBlendStateCreateInfo color_blend_info;
|
||||
vk::Viewport viewport;
|
||||
vk::Rect2D scissor;
|
||||
vk::PipelineViewportStateCreateInfo viewport_info;
|
||||
vk::DynamicState dyn_states[2];
|
||||
vk::PipelineDynamicStateCreateInfo dyn_info;
|
||||
vk::GraphicsPipelineCreateInfo pipeline_info;
|
||||
|
||||
|
||||
std::vector<vk::Pipeline> defunct_pipelines;
|
||||
|
||||
inline operator vk::Pipeline&() {
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
/* create overload for every type of object we need to update */
|
||||
void update(uint32_t binding, const UniformBuffer& uni);
|
||||
void update(uint32_t binding, const ShaderBuffer& ssbo);
|
||||
void update(uint32_t binding, const Texture& tex);
|
||||
|
||||
|
||||
void rebuild(bool wireframe, bool culling);
|
||||
|
||||
~GraphicsPipeline();
|
||||
};
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ RenderPass::RenderPass(vk::Device dev, vk::Format image_format, vk::Format depth
|
||||
|
||||
|
||||
/* designates producer and consumer of the image to position subpass */
|
||||
auto color_dep = vk::SubpassDependency{
|
||||
auto color_dep = vk::SubpassDependency {
|
||||
.srcSubpass = vk::SubpassExternal,
|
||||
.dstSubpass = 0,
|
||||
.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
|
||||
@ -15,12 +15,12 @@
|
||||
#include <Renderer/UniformBuffer.hpp>
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
#include <Scene/March.hpp>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <UI/UI.hpp>
|
||||
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
Renderer::Renderer(Window& win) : win(win) {
|
||||
@ -194,78 +194,40 @@ Renderer::Renderer(Window& win) : win(win) {
|
||||
|
||||
uniform_buffer = std::make_unique<UniformBuffer>(phys_dev, dev);
|
||||
|
||||
objects.reserve(2);
|
||||
uint id = 0;
|
||||
|
||||
objects.push_back(Object{
|
||||
.center = glm::vec4(0.0),
|
||||
.dimensions = glm::vec4(1.0),
|
||||
.id = id,
|
||||
.shape = Shape::eSPHERE,
|
||||
});
|
||||
|
||||
objects.push_back(Object{
|
||||
.center = glm::vec4(1.0),
|
||||
.dimensions = glm::vec4(0.5),
|
||||
.id = id,
|
||||
.shape = Shape::eBOX,
|
||||
});
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
for (const auto& plane : bsp->planes) {
|
||||
/* for planes, center.xyz holds normal, dimensions.x holds distance */
|
||||
objects.push_back(Object{
|
||||
.center = glm::vec4(plane.norm, 0.0),
|
||||
.dimensions = glm::vec4(plane.dist, 0.0, 0.0, 0.0),
|
||||
.id = id,
|
||||
.shape = Shape::ePLANE,
|
||||
});
|
||||
id++;
|
||||
}
|
||||
#endif
|
||||
|
||||
shader_buffer = std::make_unique<ShaderBuffer>(phys_dev, dev, MAX_OBJECTS);
|
||||
|
||||
shader_buffer->upload(objects);
|
||||
|
||||
|
||||
textures = createResources({
|
||||
"assets/textures/oil.jpg",
|
||||
});
|
||||
|
||||
std::vector<Shader> shaders = {
|
||||
{dev, "assets/shaders/ray.vert.spv", vk::ShaderStageFlagBits::eVertex },
|
||||
{ dev, "assets/shaders/ray.frag.spv", vk::ShaderStageFlagBits::eFragment },
|
||||
};
|
||||
|
||||
std::vector<vk::DescriptorSetLayoutBinding> bindings = {
|
||||
uniform_buffer->binding(0),
|
||||
textures[0].binding(1),
|
||||
shader_buffer->binding(2),
|
||||
};
|
||||
|
||||
vertex_buffer = std::make_unique<VertexBuffer>(phys_dev, dev, 6);
|
||||
/* BSP loader */
|
||||
bsp = std::make_unique<HLBSP::BSP>(phys_dev, dev, "assets/maps/dmc.bsp");
|
||||
bsp_shaders = {
|
||||
{ dev, "assets/shaders/bin/bsp.vert.spv", vk::ShaderStageFlagBits::eVertex },
|
||||
{ dev, "assets/shaders/bin/bsp.frag.spv", vk::ShaderStageFlagBits::eFragment },
|
||||
};
|
||||
|
||||
/* simple quad */
|
||||
vertex_buffer->upload(std::vector<Vertex> {
|
||||
{ { -1.0, -1.0 } },
|
||||
{ { -1.0, 1.0 } },
|
||||
{ { 1.0, 1.0 } },
|
||||
{ { 1.0, 1.0 } },
|
||||
{ { 1.0,-1.0 } },
|
||||
{ { -1.0,-1.0 } },
|
||||
});
|
||||
bsp->pipeline = std::make_unique<GraphicsPipeline>(dev, bsp_shaders, swapchain->extent, *render_pass, bindings, bsp->vertex_buffer->binding(0), bsp->vertex_buffer->attrs(0));
|
||||
bsp->pipeline->update(0, *uniform_buffer);
|
||||
|
||||
pipeline = std::make_unique<GraphicsPipeline>(dev, shaders, swapchain->extent, *render_pass, bindings, *vertex_buffer);
|
||||
/* bounding and hitboxs */
|
||||
box_shaders = {
|
||||
{ dev, "assets/shaders/bin/box.vert.spv", vk::ShaderStageFlagBits::eVertex },
|
||||
{ dev, "assets/shaders/bin/box.geom.spv", vk::ShaderStageFlagBits::eGeometry },
|
||||
{ dev, "assets/shaders/bin/box.frag.spv", vk::ShaderStageFlagBits::eFragment },
|
||||
};
|
||||
|
||||
pipeline->update(0, *uniform_buffer);
|
||||
pipeline->update(1, textures[0]);
|
||||
pipeline->update(2, *shader_buffer);
|
||||
std::vector<BoxVertex> boxes;
|
||||
boxes.reserve(bsp->leaves.size());
|
||||
for (auto& leaf : bsp->leaves) {
|
||||
boxes.push_back(BoxVertex{
|
||||
.mins = leaf.bb_mins,
|
||||
.maxes = leaf.bb_maxes,
|
||||
});
|
||||
}
|
||||
box_buffer = std::make_unique<GeneralVertexBuffer<BoxVertex>>(phys_dev, dev, boxes.size());
|
||||
box_buffer->upload(boxes);
|
||||
|
||||
for (auto& shader : shaders)
|
||||
shader.cleanup();
|
||||
box_pipeline = std::make_unique<GraphicsPipeline>(dev, box_shaders, swapchain->extent, *render_pass, bindings, box_buffer->binding(0), box_buffer->attrs(0), GraphicsPipeline::Type::eBOX);
|
||||
box_pipeline->update(0, *uniform_buffer);
|
||||
|
||||
ui = std::make_unique<UI>(this);
|
||||
}
|
||||
@ -355,7 +317,7 @@ void Renderer::draw() {
|
||||
|
||||
auto scissor = vk::Rect2D {
|
||||
.offset = {0, 0},
|
||||
.extent = swapchain->extent,
|
||||
.extent = win.getDimensions(),
|
||||
};
|
||||
|
||||
/* no secondary command buffers (yet), so contents are passed inline */
|
||||
@ -363,28 +325,38 @@ void Renderer::draw() {
|
||||
|
||||
auto sz = win.getDimensions();
|
||||
|
||||
/* re-upload objects if out-of-sync */
|
||||
if(uniform_buffer->data_copy.n_objects != objects.size())
|
||||
shader_buffer->upload(objects);
|
||||
const auto p = glm::perspective(glm::radians(90.0f), static_cast<float>(sz.width) / static_cast<float>(sz.height), near_plane, far_plane);
|
||||
|
||||
uniform_buffer->upload(UniformData{
|
||||
.cam_pos = cam.pos,
|
||||
auto uni = UniformData{
|
||||
.view = cam.view(),
|
||||
.proj = p,
|
||||
.time = time,
|
||||
.viewport = glm::vec4(viewport.width, viewport.y, 0.0, 0.0),
|
||||
.cam_pos = cam.pos,
|
||||
.cam_dir = cam.dir(),
|
||||
.n_objects = static_cast<unsigned int>(objects.size()),
|
||||
.rad = rad,
|
||||
});
|
||||
.viewport = glm::vec2(viewport.width, viewport.y),
|
||||
.tess_factor = tess_factor,
|
||||
.tess_edge_size = tess_edge_size,
|
||||
};
|
||||
|
||||
std::memcpy(uni.frustum, frustum(p * uni.view).data(), sizeof(uni.frustum));
|
||||
|
||||
uniform_buffer->upload(uni);
|
||||
|
||||
command_buffer->bind(*pipeline);
|
||||
command_buffer->command_buffer.setViewport(0, viewport);
|
||||
command_buffer->command_buffer.setScissor(0, scissor);
|
||||
command_buffer->bind(pipeline->layout, pipeline->desc_set);
|
||||
command_buffer->bind(*vertex_buffer);
|
||||
//shader_buffer->objects[0].center.y += glm::sin(time)/10.0;
|
||||
command_buffer->command_buffer.draw(6, 1, 0, 0);
|
||||
|
||||
bsp->load_vertices(cam.pos, visibility_testing, p * uni.view);
|
||||
command_buffer->bind(bsp.get());
|
||||
/*command_buffer->draw(bsp->vertices.size(), 1);*/
|
||||
command_buffer->draw(bsp->textured_vertices.size(), 1);
|
||||
|
||||
n_indices = bsp->textured_vertices.size();
|
||||
|
||||
if (show_bboxes) {
|
||||
command_buffer->bind(*box_pipeline);
|
||||
command_buffer->bind(*box_buffer);
|
||||
command_buffer->draw(box_buffer->buffer->size / sizeof(BoxVertex), 1);
|
||||
}
|
||||
|
||||
/* draw User Interface stuff */
|
||||
ui->newFrame();
|
||||
@ -431,22 +403,26 @@ void Renderer::present() {
|
||||
default:
|
||||
Log::error("Failed to present surface.\n");
|
||||
break;
|
||||
|
||||
}
|
||||
time += frametime / 1000.0 * speed * static_cast<float>(!paused);
|
||||
|
||||
frame++;
|
||||
time += frametime / 1000.0 * speed * static_cast<float>(!paused);
|
||||
}
|
||||
|
||||
Renderer::~Renderer() {
|
||||
dev.waitIdle();
|
||||
|
||||
ui.reset();
|
||||
bsp.reset();
|
||||
|
||||
box_buffer.reset();
|
||||
box_pipeline.reset();
|
||||
uniform_buffer.reset();
|
||||
shader_buffer.reset();
|
||||
vertex_buffer.reset();
|
||||
pipeline.reset();
|
||||
|
||||
for (auto& shader : box_shaders)
|
||||
shader.cleanup();
|
||||
for (auto& shader : bsp_shaders)
|
||||
shader.cleanup();
|
||||
|
||||
for (auto& tex : textures) {
|
||||
tex.cleanup();
|
||||
|
||||
@ -5,23 +5,25 @@
|
||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include <Renderer/Swapchain.hpp>
|
||||
#include <Renderer/CommandBuffer.hpp>
|
||||
#include <Renderer/RenderPass.hpp>
|
||||
#include <Renderer/ShaderBuffer.hpp>
|
||||
#include <Renderer/Swapchain.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
#include <Scene/Camera.hpp>
|
||||
#include <Scene/BSP.hpp>
|
||||
#include <Scene/Terrain.hpp>
|
||||
|
||||
#include <Model/Model.hpp>
|
||||
|
||||
#include <UI/UI.hpp>
|
||||
|
||||
|
||||
struct Window;
|
||||
struct UniformBuffer;
|
||||
struct VertexBuffer;
|
||||
struct Texture;
|
||||
|
||||
#define MAX_OBJECTS 256
|
||||
|
||||
/* Contains all of the Vulkan objects involved in rendering the scene */
|
||||
struct Renderer {
|
||||
Renderer(Window& win);
|
||||
@ -49,39 +51,45 @@ struct Renderer {
|
||||
std::unique_ptr<CommandBuffer> command_buffer;
|
||||
std::unique_ptr<RenderPass> render_pass;
|
||||
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
/* just holds single quad */
|
||||
std::unique_ptr<ShaderBuffer> shader_buffer;
|
||||
std::unique_ptr<VertexBuffer> vertex_buffer;
|
||||
std::vector<Shader> box_shaders;
|
||||
std::unique_ptr<GraphicsPipeline> box_pipeline;
|
||||
std::unique_ptr<GeneralVertexBuffer<BoxVertex>> box_buffer;
|
||||
std::unique_ptr<UniformBuffer> uniform_buffer;
|
||||
|
||||
std::vector<Shader> bsp_shaders;
|
||||
std::unique_ptr<HLBSP::BSP> bsp;
|
||||
|
||||
std::vector<Texture> textures;
|
||||
|
||||
uint32_t current_image_idx;
|
||||
uint64_t frame = 0;
|
||||
|
||||
std::vector<Object> objects;
|
||||
|
||||
std::unique_ptr<UI> ui;
|
||||
|
||||
Camera cam{ .pos = glm::vec3(0.0, 0.0, -1.0), };
|
||||
Camera cam{ .pos = glm::vec3(0.0, 5.0, 0.0), };
|
||||
|
||||
bool capture_mouse = false;
|
||||
|
||||
float fps;
|
||||
bool in_menu = false;
|
||||
bool flycam = false;
|
||||
/* time speed */
|
||||
float time = 0.0;
|
||||
float frametime = 0.0;
|
||||
float fps = 0.0;
|
||||
float max_fps = 60.0;
|
||||
float speed = 1.0;
|
||||
float rad = 1.0;
|
||||
|
||||
bool in_menu = false;
|
||||
bool should_close = false;
|
||||
bool paused = false;
|
||||
bool running = true;
|
||||
bool visibility_testing = false;
|
||||
bool show_bboxes = false;
|
||||
bool should_close = false;
|
||||
bool wireframe_mode = false;
|
||||
bool backface_culling = true;
|
||||
|
||||
std::map<std::string, int> scene_map;
|
||||
size_t n_indices;
|
||||
|
||||
std::string scene_file = "scene.txt";
|
||||
float near_plane = 2.0f;
|
||||
float far_plane = 10000.0f;
|
||||
|
||||
float tess_factor = 1.8f;
|
||||
float tess_edge_size = 20.0f;
|
||||
|
||||
float frametime = 0.0;
|
||||
float max_fps = 120.0;
|
||||
};
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
#include <Renderer/ShaderBuffer.hpp>
|
||||
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <util/glsl_types.hpp>
|
||||
|
||||
#include <Scene/Object.hpp>
|
||||
|
||||
#include <Memory/Buffer.hpp>
|
||||
|
||||
using namespace glsl;
|
||||
|
||||
/* Wrapper for SSBO */
|
||||
struct ShaderBuffer {
|
||||
|
||||
ShaderBuffer(vk::PhysicalDevice phys_dev, vk::Device dev, const size_t n_objects = 0x1000) : phys_dev(phys_dev), dev(dev), n_objects(n_objects) {
|
||||
buffer = std::make_unique<Buffer>(
|
||||
phys_dev, dev, n_objects * sizeof(Object),
|
||||
vk::BufferUsageFlagBits::eStorageBuffer,
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent
|
||||
| vk::MemoryPropertyFlagBits::eHostVisible
|
||||
);
|
||||
objects = reinterpret_cast<Object*>(buffer->p);
|
||||
}
|
||||
|
||||
vk::PhysicalDevice phys_dev;
|
||||
vk::Device dev;
|
||||
size_t n_objects;
|
||||
Object* objects;
|
||||
|
||||
std::unique_ptr<Buffer> buffer;
|
||||
|
||||
operator vk::Buffer&() const {
|
||||
return *buffer;
|
||||
}
|
||||
|
||||
inline vk::DescriptorSetLayoutBinding binding(uint32_t binding, vk::ShaderStageFlags stages = vk::ShaderStageFlagBits::eFragment) {
|
||||
return vk::DescriptorSetLayoutBinding {
|
||||
.binding = binding,
|
||||
.descriptorType = vk::DescriptorType::eStorageBuffer,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = stages,
|
||||
.pImmutableSamplers = nullptr,
|
||||
};
|
||||
}
|
||||
|
||||
inline void upload(const std::vector<Object>& scene) {
|
||||
buffer->upload(reinterpret_cast<const uint8_t*>(scene.data()), scene.size() * sizeof(Object));
|
||||
}
|
||||
|
||||
~ShaderBuffer() {
|
||||
buffer.reset();
|
||||
}
|
||||
};
|
||||
@ -60,7 +60,7 @@ void Swapchain::create(vk::SwapchainKHR old_swapchain) {
|
||||
/* see if this allows see through windows on Wayland */
|
||||
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
||||
/* waits for refresh (V-Sync), consider playing with relaxed fifo later on*/
|
||||
// .presentMode = vk::PresentModeKHR::eFifo,
|
||||
// .presentMode = vk::PresentModeKHR::eFifoRelaxed,
|
||||
.presentMode = vk::PresentModeKHR::eMailbox,
|
||||
.clipped = VK_TRUE,
|
||||
.oldSwapchain = old_swapchain,
|
||||
|
||||
@ -8,9 +8,19 @@ UniformBuffer::UniformBuffer(vk::PhysicalDevice phys_dev, vk::Device dev) {
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible
|
||||
);
|
||||
|
||||
Log::debug("Offset of view: %zu\n", offsetof(UniformData, view));
|
||||
Log::debug("Offset of proj: %zu\n", offsetof(UniformData, proj));
|
||||
Log::debug("Offset of time: %zu\n", offsetof(UniformData, time));
|
||||
Log::debug("Offset of pad0: %zu\n", offsetof(UniformData, pad0));
|
||||
Log::debug("Offset of pad1: %zu\n", offsetof(UniformData, pad1));
|
||||
Log::debug("Offset of pad2: %zu\n", offsetof(UniformData, pad2));
|
||||
Log::debug("Offset of cam_pos: %zu\n", offsetof(UniformData, cam_pos));
|
||||
Log::debug("Offset of viewport: %zu\n", offsetof(UniformData, viewport));
|
||||
Log::debug("Offset of tess_factor: %zu\n", offsetof(UniformData, tess_factor));
|
||||
Log::debug("Offset of tess_edge_size: %zu\n", offsetof(UniformData, tess_edge_size));
|
||||
|
||||
}
|
||||
|
||||
void UniformBuffer::upload(const UniformData& data) {
|
||||
data_copy = data;
|
||||
buffer->upload(reinterpret_cast<const uint8_t*>(&data), sizeof(UniformData));
|
||||
}
|
||||
@ -9,36 +9,43 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <util/glsl_types.hpp>
|
||||
|
||||
using namespace glsl;
|
||||
|
||||
/* Uniform:
|
||||
*
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
vec3 cam_pos;
|
||||
float time;
|
||||
vec4 viewport;
|
||||
vec3 cam_dir;
|
||||
uint n_objects;
|
||||
float rad;
|
||||
};
|
||||
* layout (set = 0, binding = 0) uniform Matrices {
|
||||
* mat4 view;
|
||||
* mat4 proj;
|
||||
* float time;
|
||||
* vec3 cam_pos;
|
||||
* vec3 cam_dir;
|
||||
* vec4 frustum[6];
|
||||
* vec2 viewport;
|
||||
* float tess_factor;
|
||||
* float tess_edge_size;
|
||||
* };
|
||||
*
|
||||
*/
|
||||
|
||||
struct UniformData {
|
||||
vec3 cam_pos;
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj;
|
||||
float time;
|
||||
vec4 viewport;
|
||||
vec3 cam_dir;
|
||||
uint n_objects;
|
||||
float rad;
|
||||
float pad0;
|
||||
float pad1;
|
||||
float pad2;
|
||||
glm::vec3 cam_pos;
|
||||
float pad3;
|
||||
glm::vec3 cam_dir;
|
||||
float pad4;
|
||||
glm::vec4 frustum[6];
|
||||
glm::vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
struct UniformBuffer {
|
||||
UniformBuffer(vk::PhysicalDevice phys_dev, vk::Device dev);
|
||||
|
||||
std::unique_ptr<Buffer> buffer;
|
||||
UniformData data_copy { 0.0 };
|
||||
|
||||
void upload(const UniformData& data);
|
||||
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
#include <Memory/Buffer.hpp>
|
||||
|
||||
#include <tinygltf/tiny_gltf.h>
|
||||
|
||||
VertexBuffer::VertexBuffer(vk::PhysicalDevice phys_dev, vk::Device dev, size_t n_vertices) {
|
||||
buffer = std::make_unique<Buffer>(phys_dev, dev, n_vertices * sizeof(Vertex),
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
}
|
||||
|
||||
void VertexBuffer::upload(const std::vector<Vertex>& data) {
|
||||
buffer->upload(reinterpret_cast<const uint8_t*>(data.data()), sizeof(Vertex)*data.size());
|
||||
}
|
||||
|
||||
void VertexBuffer::upload(const tinygltf::Buffer& buff, const tinygltf::BufferView& view) {
|
||||
std::memcpy(buffer->p, buff.data.data() + view.byteOffset, view.byteLength);
|
||||
}
|
||||
@ -8,18 +8,91 @@
|
||||
|
||||
#include <tinygltf/tiny_gltf.h>
|
||||
|
||||
struct Vertex {
|
||||
glm::vec2 pos;
|
||||
struct glTFVertex {
|
||||
glm::vec3 pos;
|
||||
glm::vec3 norm;
|
||||
glm::vec2 uv;
|
||||
glm::vec3 color;
|
||||
|
||||
static inline std::vector<vk::VertexInputAttributeDescription> attrs(uint32_t binding) {
|
||||
return std::vector<vk::VertexInputAttributeDescription> {
|
||||
{
|
||||
.location = 0,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32B32Sfloat,
|
||||
.offset = offsetof(glTFVertex, pos),
|
||||
}, {
|
||||
.location = 1,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32B32Sfloat,
|
||||
.offset = offsetof(glTFVertex, norm),
|
||||
}, {
|
||||
.location = 2,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32Sfloat,
|
||||
.offset = offsetof(glTFVertex, uv),
|
||||
}, {
|
||||
.location = 3,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32B32Sfloat,
|
||||
.offset = offsetof(glTFVertex, color),
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct VertexBuffer {
|
||||
|
||||
enum BoxType {
|
||||
eBounding,
|
||||
eEnemyHit,
|
||||
};
|
||||
/* for hitboxes and bounding boxes */
|
||||
struct BoxVertex {
|
||||
glm::vec3 mins;
|
||||
glm::vec3 maxes;
|
||||
unsigned int id;
|
||||
|
||||
static inline std::vector<vk::VertexInputAttributeDescription> attrs(uint32_t binding) {
|
||||
return std::vector<vk::VertexInputAttributeDescription> {
|
||||
{
|
||||
.location = 0,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32B32Sfloat,
|
||||
.offset = offsetof(BoxVertex, mins),
|
||||
}, {
|
||||
.location = 1,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32B32Sfloat,
|
||||
.offset = offsetof(BoxVertex, maxes),
|
||||
}, {
|
||||
.location = 2,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32Uint,
|
||||
.offset = offsetof(BoxVertex, id),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename Vertex>
|
||||
struct GeneralVertexBuffer {
|
||||
std::unique_ptr<Buffer> buffer;
|
||||
|
||||
GeneralVertexBuffer(vk::PhysicalDevice phys_dev, vk::Device dev, size_t n_vertices) {
|
||||
buffer = std::make_unique<Buffer>(phys_dev, dev, n_vertices * sizeof(Vertex),
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
}
|
||||
|
||||
VertexBuffer(vk::PhysicalDevice phys_dev, vk::Device dev, size_t n_vertices);
|
||||
|
||||
void upload(const std::vector<Vertex>& data);
|
||||
void upload(const tinygltf::Buffer& buff, const tinygltf::BufferView& view);
|
||||
void upload(const std::vector<Vertex>& data) {
|
||||
buffer->upload(reinterpret_cast<const uint8_t*>(data.data()), sizeof(Vertex) * data.size());
|
||||
}
|
||||
void upload(const tinygltf::Buffer& buff, const tinygltf::BufferView& view) {
|
||||
std::memcpy(buffer->p, buff.data.data() + view.byteOffset, view.byteLength);
|
||||
}
|
||||
|
||||
inline vk::VertexInputBindingDescription binding(uint32_t binding, vk::ShaderStageFlags stages = vk::ShaderStageFlagBits::eVertex) const {
|
||||
return vk::VertexInputBindingDescription {
|
||||
@ -30,13 +103,9 @@ struct VertexBuffer {
|
||||
}
|
||||
|
||||
inline std::vector<vk::VertexInputAttributeDescription> attrs(uint32_t binding) const {
|
||||
return std::vector<vk::VertexInputAttributeDescription> {
|
||||
{
|
||||
.location = 0,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32Sfloat,
|
||||
.offset = offsetof(Vertex, pos),
|
||||
},
|
||||
};
|
||||
return Vertex::attrs(binding);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
using VertexBuffer = GeneralVertexBuffer<glTFVertex>;
|
||||
|
||||
|
||||
257
Scene/BSP.cpp
Normal file
257
Scene/BSP.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
#include <Scene/BSP.hpp>
|
||||
|
||||
#include <Renderer/Pipeline.hpp>
|
||||
|
||||
#include <util/geo.hpp>
|
||||
#include <util/file.hpp>
|
||||
#include <util/log.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
/* changes handedness by swapping z and y */
|
||||
template<typename T>
|
||||
static inline void change_swizzle(T& v) {
|
||||
auto tmp = v.y;
|
||||
v.y = v.z;
|
||||
v.z = tmp;
|
||||
}
|
||||
|
||||
using namespace HLBSP;
|
||||
|
||||
static inline void copy_data(void* file_data, std::string& dst, Lump& lump) {
|
||||
dst.resize(lump.len);
|
||||
std::memcpy(dst.data(), (u8*)file_data + (size_t)lump.offset, lump.len);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void copy_data(void* file_data, std::vector<T>& dst, Lump& lump) {
|
||||
Log::debug("%zu items\n", lump.len / sizeof(T));
|
||||
dst.resize(lump.len / sizeof(T));
|
||||
std::memcpy(dst.data(), ((u8*)file_data) + lump.offset, lump.len);
|
||||
}
|
||||
|
||||
static inline glm::vec2 calc_tex_coords(glm::vec3 v, const TexInfo& t) {
|
||||
change_swizzle(v);
|
||||
return glm::vec2(
|
||||
t.shift_s + glm::dot(v, t.shift_s_dir),
|
||||
t.shift_t + glm::dot(v, t.shift_t_dir)
|
||||
);
|
||||
}
|
||||
|
||||
void BSP::load_vertices(const glm::vec3& cam_pos, bool visibility_test, const glm::mat4& view) {
|
||||
std::set<int> present_faces;
|
||||
std::vector<Face> visible_faces;
|
||||
if (visibility_test) {
|
||||
auto leaf_idx = determine_leaf(cam_pos);
|
||||
|
||||
auto fr_planes = frustum(view);
|
||||
|
||||
if (leaf_idx == last_leaf)
|
||||
return;
|
||||
|
||||
last_leaf = leaf_idx;
|
||||
auto& cam_leaf = leaves[leaf_idx];
|
||||
|
||||
|
||||
std::vector<Leaf> visible_leafs;
|
||||
for (auto& leaf : leaves) {
|
||||
|
||||
const auto min = leaf.bb_mins;
|
||||
const auto max = leaf.bb_maxes;
|
||||
|
||||
const glm::vec3 bounding_planes[8] = {
|
||||
{ min.x, min.y, min.z },
|
||||
{ max.x, min.y, min.z },
|
||||
{ max.x, max.y, min.z },
|
||||
{ min.x, max.y, min.z },
|
||||
{ min.x, min.y, max.z },
|
||||
{ max.x, min.y, max.z },
|
||||
{ max.x, max.y, max.z },
|
||||
{ min.x, max.y, max.z },
|
||||
};
|
||||
|
||||
if (determine_visibility(cam_leaf, leaf, fr_planes, bounding_planes))
|
||||
visible_leafs.push_back(leaf);
|
||||
}
|
||||
|
||||
for (const auto& leaf : visible_leafs) {
|
||||
for (size_t i = 0; i < leaf.n_mark_surfaces; i++) {
|
||||
auto idx = mark_surfaces[leaf.first_mark_surface_idx + i];
|
||||
if (present_faces.contains(idx))
|
||||
continue;
|
||||
|
||||
present_faces.insert(idx);
|
||||
visible_faces.push_back(faces[idx]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
visible_faces = faces;
|
||||
}
|
||||
|
||||
textured_vertices.clear();
|
||||
|
||||
for (auto& face : visible_faces) {
|
||||
auto& tex_info = tex_infos[face.tex_info_idx];
|
||||
|
||||
for (i16 i = 1, j = 2; j < face.n_surf_edges; i++, j++) {
|
||||
textured_vertices.push_back(Vertex{
|
||||
.pos = processed_vertices[face.first_surf_edge_idx],
|
||||
.uv = calc_tex_coords(processed_vertices[face.first_surf_edge_idx], tex_info),
|
||||
});
|
||||
textured_vertices.push_back(Vertex{
|
||||
.pos = processed_vertices[face.first_surf_edge_idx+i],
|
||||
.uv = calc_tex_coords(processed_vertices[face.first_surf_edge_idx+i], tex_info),
|
||||
});
|
||||
textured_vertices.push_back(Vertex{
|
||||
.pos = processed_vertices[face.first_surf_edge_idx+j],
|
||||
.uv = calc_tex_coords(processed_vertices[face.first_surf_edge_idx+j], tex_info),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
vertex_buffer->upload(textured_vertices);
|
||||
}
|
||||
|
||||
int BSP::get_index_from_surfedge(int surfedge) {
|
||||
int surf = surfedges[surfedge];
|
||||
if(surf >= 0) {
|
||||
return edges[surf].vertex_indices[0];
|
||||
}
|
||||
else {
|
||||
return edges[-surf].vertex_indices[1];
|
||||
}
|
||||
}
|
||||
|
||||
int BSP::determine_leaf(glm::vec3 cam_pos) {
|
||||
/* use SDF of planes to determine relative position with respect to partitioning planes */
|
||||
int idx = 0;
|
||||
/* positive values are node indices, negative values are leaf indices */
|
||||
while (idx >= 0) {
|
||||
const auto& plane = planes[nodes[idx].plane];
|
||||
const auto dist = glm::dot(plane.norm, cam_pos) - plane.dist;
|
||||
|
||||
if (dist >= 0)
|
||||
idx = nodes[idx].children[0];
|
||||
else
|
||||
idx = nodes[idx].children[1];
|
||||
}
|
||||
|
||||
return -idx - 1;
|
||||
}
|
||||
|
||||
|
||||
bool BSP::determine_visibility(const Leaf& cam_leaf, const Leaf& leaf, const std::array<glm::vec4, 6>& frustum, const glm::vec3 box_verts[8]) {
|
||||
/* perform fustrum culling */
|
||||
return box_in_frustum(frustum, box_verts);
|
||||
}
|
||||
|
||||
static std::vector<std::map<std::string, std::string>> load_entities(const std::string& in) {
|
||||
/* TODO */
|
||||
return {
|
||||
{{"test", "this"}},
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<MipTexture> load_mip_textures(const u8* data, u32 offset) {
|
||||
const TextureLump* lump = reinterpret_cast<const TextureLump*>(data + offset);
|
||||
std::vector<MipTexture> ret;
|
||||
ret.resize(lump->n_mip_textures);
|
||||
|
||||
for(size_t i = 0; i < ret.size(); i++) {
|
||||
ret[i] = *reinterpret_cast<const MipTexture*>(data + lump->offsets[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BSP::BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname) : dev(dev), filename(fname) {
|
||||
file_data = file::slurpb(fname);
|
||||
Log::debug("BSP file size: %zu\n", file_data.size());
|
||||
header = reinterpret_cast<Header*>(file_data.data());
|
||||
|
||||
Log::info("Loading BSP: %s\n", fname.c_str());
|
||||
|
||||
if(header->version != 30) {
|
||||
Log::error("BSP file not expected version (Half Life has version 30)!\n");
|
||||
}
|
||||
|
||||
Log::debug("Loading entities\n");
|
||||
std::string entities_buff;
|
||||
copy_data(file_data.data(), entities_buff, header->entities);
|
||||
entities = load_entities(entities_buff);
|
||||
|
||||
Log::debug("Loading planes\n");
|
||||
copy_data(file_data.data(), planes, header->planes);
|
||||
/* change swizzle */
|
||||
for (auto& plane : planes) {
|
||||
change_swizzle(plane.norm);
|
||||
}
|
||||
|
||||
Log::debug("Loading textures\n");
|
||||
textures = load_mip_textures(file_data.data(), header->textures.offset);
|
||||
|
||||
Log::debug("Loading vertices\n");
|
||||
copy_data(file_data.data(), vertices, header->vertices);
|
||||
for (auto& vertex : vertices) {
|
||||
change_swizzle(vertex);
|
||||
}
|
||||
|
||||
Log::debug("Loading nodes\n");
|
||||
copy_data(file_data.data(), nodes, header->nodes);
|
||||
for (auto& node : nodes) {
|
||||
change_swizzle(node.bb_mins);
|
||||
change_swizzle(node.bb_maxes);
|
||||
}
|
||||
|
||||
Log::debug("Loading texinfo\n");
|
||||
copy_data(file_data.data(), tex_infos, header->texinfo);
|
||||
|
||||
Log::debug("Loading faces\n");
|
||||
copy_data(file_data.data(), faces, header->faces);
|
||||
|
||||
Log::debug("Loading lightmap\n");
|
||||
lightmap.lights = reinterpret_cast<rgb*>(file_data.data()+header->lighting.offset);
|
||||
|
||||
Log::debug("Loading clip nodes\n");
|
||||
copy_data(file_data.data(), clip_nodes, header->clip_nodes);
|
||||
|
||||
Log::debug("Loading leaves\n");
|
||||
copy_data(file_data.data(), leaves, header->leaves);
|
||||
for (auto& leaf : leaves) {
|
||||
change_swizzle(leaf.bb_mins);
|
||||
change_swizzle(leaf.bb_maxes);
|
||||
}
|
||||
|
||||
Log::debug("Loading mark surfaces\n");
|
||||
copy_data(file_data.data(), mark_surfaces, header->mark_surfaces);
|
||||
|
||||
Log::debug("Loading edges\n");
|
||||
copy_data(file_data.data(), edges, header->edges);
|
||||
|
||||
Log::debug("Loading surfedges\n");
|
||||
copy_data(file_data.data(), surfedges, header->surf_edges);
|
||||
processed_vertices.reserve(surfedges.size());
|
||||
/* use this to build our processed_vertices, idea thanks to gzalo's HalfMapper */
|
||||
for(const auto& s : surfedges) {
|
||||
processed_vertices.push_back(vertices[edges[s > 0? s : -s].vertex_indices[s<=0]]);
|
||||
}
|
||||
|
||||
Log::debug("Loading models\n");
|
||||
copy_data(file_data.data(), models, header->models);
|
||||
for (auto& model : models) {
|
||||
change_swizzle(model.bb_mins);
|
||||
change_swizzle(model.bb_maxes);
|
||||
}
|
||||
|
||||
size_t max_vertex_count = 0;
|
||||
|
||||
for (const auto& face : faces) {
|
||||
max_vertex_count += (face.n_surf_edges - 2) * 3;
|
||||
}
|
||||
|
||||
Log::debug("Creating vertex buffer of size %zu\n", max_vertex_count);
|
||||
vertex_buffer = std::make_unique<GeneralVertexBuffer<Vertex>>(phys_dev, dev, max_vertex_count);
|
||||
textured_vertices.reserve(max_vertex_count);
|
||||
}
|
||||
239
Scene/BSP.hpp
Normal file
239
Scene/BSP.hpp
Normal file
@ -0,0 +1,239 @@
|
||||
#pragma once
|
||||
|
||||
#include <util/int.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
#include <Renderer/Pipeline.hpp>
|
||||
|
||||
|
||||
#define MAX_TEXTURE_NAME 16
|
||||
#define MIP_LEVELS 4
|
||||
|
||||
#define MAX_MAP_HULLS 4
|
||||
/* contains loading functions for Half Life BSPs */
|
||||
namespace HLBSP {
|
||||
|
||||
struct Lump {
|
||||
u32 offset;
|
||||
u32 len;
|
||||
};
|
||||
using rgb = glm::u8vec3;
|
||||
using rgba = glm::u8vec4;
|
||||
|
||||
using vec3 = glm::vec3;
|
||||
using vec2 = glm::vec2;
|
||||
using ivec3 = glm::vec<3, i16>;
|
||||
|
||||
struct Header {
|
||||
u32 version;
|
||||
|
||||
union {
|
||||
Lump lumps[15];
|
||||
struct {
|
||||
Lump entities,
|
||||
planes,
|
||||
textures,
|
||||
vertices,
|
||||
visibility,
|
||||
nodes,
|
||||
texinfo,
|
||||
faces,
|
||||
lighting,
|
||||
clip_nodes,
|
||||
leaves,
|
||||
mark_surfaces,
|
||||
edges,
|
||||
surf_edges,
|
||||
models;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct Plane {
|
||||
vec3 norm;
|
||||
float dist;
|
||||
/* exists for certain optimizations (swaped y and z) */
|
||||
enum PlaneType {
|
||||
eX,
|
||||
eZ,
|
||||
eY,
|
||||
eAnyX,
|
||||
eAnyZ,
|
||||
eAnyY,
|
||||
} type;
|
||||
};
|
||||
|
||||
struct TextureLump {
|
||||
u32 n_mip_textures;
|
||||
i32 offsets[];
|
||||
};
|
||||
|
||||
struct MipTexture {
|
||||
char name[MAX_TEXTURE_NAME];
|
||||
u32 width, height;
|
||||
/* is 0 if stored in WAD, otherwise, offset is from beginning of this struct */
|
||||
u32 mip_offsets[MIP_LEVELS];
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
vec3 pos;
|
||||
vec2 uv;
|
||||
|
||||
static inline std::vector<vk::VertexInputAttributeDescription> attrs(uint32_t binding) {
|
||||
return std::vector<vk::VertexInputAttributeDescription> {
|
||||
{
|
||||
.location = 0,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32B32Sfloat,
|
||||
.offset = offsetof(Vertex, pos),
|
||||
}, {
|
||||
.location = 1,
|
||||
.binding = binding,
|
||||
.format = vk::Format::eR32G32Sfloat,
|
||||
.offset = offsetof(Vertex, uv),
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct Vis {};
|
||||
|
||||
struct Node {
|
||||
i32 plane;
|
||||
/* negative numbers are leaf indices */
|
||||
i16 children[2];
|
||||
|
||||
/* bounding box coords (integer) */
|
||||
ivec3 bb_mins;
|
||||
ivec3 bb_maxes;
|
||||
|
||||
i16 first_face_idx;
|
||||
i16 n_faces;
|
||||
};
|
||||
|
||||
struct TexInfo {
|
||||
vec3 shift_s_dir;
|
||||
float shift_s;
|
||||
vec3 shift_t_dir;
|
||||
float shift_t;
|
||||
u32 mip_tex_idx;
|
||||
/* seems to always be 0 */
|
||||
u32 flags;
|
||||
|
||||
};
|
||||
|
||||
struct Face {
|
||||
u16 plane_idx;
|
||||
/* set if different normals orientation */
|
||||
u16 plane_side;
|
||||
u32 first_surf_edge_idx;
|
||||
i16 n_surf_edges;
|
||||
i16 tex_info_idx;
|
||||
u8 lighting_styles[4];
|
||||
u32 lightmap_offset;
|
||||
};
|
||||
|
||||
struct Lightmap {
|
||||
rgb* lights;
|
||||
};
|
||||
|
||||
struct ClipNode {
|
||||
i32 plane_idx;
|
||||
/* negative numbers are contents */
|
||||
i16 children[2];
|
||||
};
|
||||
|
||||
struct Leaf {
|
||||
enum {
|
||||
eEmpty = -1,
|
||||
eSolid = -2,
|
||||
eWater = -3,
|
||||
eSlime = -4,
|
||||
eLava = -5,
|
||||
eSky = -6,
|
||||
eOrigin = -7,
|
||||
eClip = -8,
|
||||
eCurrent0 = -9,
|
||||
eCurrent90 = -10,
|
||||
eCurrent180 = -11,
|
||||
eCurrent270 = -12,
|
||||
eCurrentUp = -13,
|
||||
eCurrentDown = -14,
|
||||
eTranslucent = -15,
|
||||
} contents;
|
||||
/* if this is -1, no VIS data */
|
||||
i32 vis_offset;
|
||||
ivec3 bb_mins;
|
||||
ivec3 bb_maxes;
|
||||
u16 first_mark_surface_idx;
|
||||
u16 n_mark_surfaces;
|
||||
u8 ambient_sound_levels[4];
|
||||
};
|
||||
|
||||
typedef u16 MarkSurface;
|
||||
|
||||
struct Edge {
|
||||
u16 vertex_indices[2];
|
||||
};
|
||||
|
||||
typedef i32 Surfedge;
|
||||
|
||||
struct Model {
|
||||
vec3 bb_mins;
|
||||
vec3 bb_maxes;
|
||||
vec3 origin;
|
||||
i32 head_node_indices[MAX_MAP_HULLS];
|
||||
i32 vis_leafs;
|
||||
i32 first_face_idx;
|
||||
i32 n_faces;
|
||||
};
|
||||
|
||||
struct BSP {
|
||||
BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname);
|
||||
void load_vertices(const vec3& cam_pos, bool visibility_testing, const glm::mat4& view);
|
||||
int determine_leaf(vec3 cam_pos);
|
||||
bool determine_visibility(const Leaf& cam_leaf, const Leaf& leaf, const std::array<glm::vec4, 6>& frustum, const vec3 box_verts[8]);
|
||||
int get_index_from_surfedge(int surfedge);
|
||||
|
||||
|
||||
vk::Device dev;
|
||||
Header* header;
|
||||
std::string filename;
|
||||
std::vector<u8> file_data;
|
||||
|
||||
std::vector<::std::map<::std::string, std::string>> entities;
|
||||
std::vector<Plane> planes;
|
||||
std::vector<MipTexture> textures;
|
||||
std::vector<glm::vec3> vertices;
|
||||
std::vector<glm::vec3> processed_vertices;
|
||||
/* skipping vis for now */
|
||||
std::vector<Node> nodes;
|
||||
std::vector<TexInfo> tex_infos;
|
||||
std::vector<Face> faces;
|
||||
Lightmap lightmap;
|
||||
std::vector<ClipNode> clip_nodes;
|
||||
std::vector<Leaf> leaves;
|
||||
std::vector<MarkSurface> mark_surfaces;
|
||||
std::vector<Edge> edges;
|
||||
std::vector<Surfedge> surfedges;
|
||||
std::vector<Model> models;
|
||||
|
||||
std::vector<Vertex> textured_vertices;
|
||||
std::unique_ptr<GeneralVertexBuffer<Vertex>> vertex_buffer;
|
||||
std::unique_ptr<GraphicsPipeline> pipeline;
|
||||
/* to eliminate needless re-loading*/
|
||||
int last_leaf = -0x1337;
|
||||
|
||||
~BSP() {
|
||||
vertex_buffer.reset();
|
||||
pipeline.reset();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -15,11 +15,7 @@ struct Camera {
|
||||
glm::vec3 pos = glm::vec3(0.0f);
|
||||
|
||||
inline glm::vec3 dir() {
|
||||
return glm::vec3(
|
||||
sin(theta) * cos(phi),
|
||||
cos(theta),
|
||||
sin(theta) * sin(phi)
|
||||
);
|
||||
return glm::vec3(sin(theta) * cos(phi), cos(theta), sin(theta) * sin(phi));
|
||||
}
|
||||
|
||||
inline glm::mat4 view() {
|
||||
|
||||
168
Scene/March.hpp
168
Scene/March.hpp
@ -1,168 +0,0 @@
|
||||
#pragma once
|
||||
/* file format for storing raymarched scene for dynamic SDF */
|
||||
#include <Scene/Object.hpp>
|
||||
#include <util/log.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
namespace March {
|
||||
static std::vector<Object> readFile(const std::string& fname, std::map<std::string, int>& name_map) {
|
||||
/* this should be rewritten once we are loading more than 250 objects */
|
||||
std::ifstream in(fname);
|
||||
|
||||
std::vector<Object> ret;
|
||||
Object tmp;
|
||||
std::string name;
|
||||
|
||||
std::string type;
|
||||
int id = 0;
|
||||
|
||||
while(in >> type) {
|
||||
Log::info("Object Type: %s\n", type.c_str());
|
||||
char dummy;
|
||||
in >> dummy;
|
||||
if (dummy != '(') {
|
||||
Log::error("Expected '(', found %c\n", dummy);
|
||||
}
|
||||
in >> tmp.center.x;
|
||||
in >> tmp.center.y;
|
||||
in >> tmp.center.z;
|
||||
in >> dummy;
|
||||
if (dummy != ')') {
|
||||
Log::error("Expected ')', found %c\n", dummy);
|
||||
}
|
||||
|
||||
if (type == "SPHERE") {
|
||||
tmp.shape = Shape::eSPHERE;
|
||||
char dummy;
|
||||
in >> dummy;
|
||||
if (dummy != '(') {
|
||||
Log::error("Expected '(', found %c\n", dummy);
|
||||
}
|
||||
in >> tmp.dimensions.x;
|
||||
in >> dummy;
|
||||
if (dummy != ')') {
|
||||
Log::error("Expected ')', found %c\n", dummy);
|
||||
}
|
||||
} else if (type == "BOX") {
|
||||
tmp.shape = Shape::eBOX;
|
||||
char dummy;
|
||||
in >> dummy;
|
||||
if (dummy != '(') {
|
||||
Log::error("Expected '(', found %c\n", dummy);
|
||||
}
|
||||
in >> tmp.dimensions.x;
|
||||
in >> tmp.dimensions.y;
|
||||
in >> tmp.dimensions.z;
|
||||
in >> dummy;
|
||||
if (dummy != ')') {
|
||||
Log::error("Expected ')', found %c\n", dummy);
|
||||
}
|
||||
} else {
|
||||
Log::error("Expected type name, but not recognized %s!\n", type.c_str());
|
||||
}
|
||||
|
||||
in >> name;
|
||||
if (name_map.find(name) == name_map.end())
|
||||
name_map[name] = id++;
|
||||
|
||||
tmp.id = name_map[name];
|
||||
|
||||
ret.push_back(tmp);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::string find_name(const std::map<std::string, int>& map, const int id, bool& found) {
|
||||
found = false;
|
||||
std::string name = "##";
|
||||
for (const auto& p : map) {
|
||||
if (p.second == id) {
|
||||
found = true;
|
||||
name = p.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static void add_sphere(const std::string& name, glm::vec3 center, float rad, Renderer* ren) {
|
||||
unsigned int id = 0xDEADBEEF;
|
||||
if (ren->scene_map.find(name) == ren->scene_map.end()) {
|
||||
/* start iterating from the number of total objects, which will break immediately if stuff is deleted and new things added before saving, so please change this */
|
||||
id = ren->scene_map.size();
|
||||
ren->scene_map[name] = id;
|
||||
} else {
|
||||
id = ren->scene_map[name];
|
||||
}
|
||||
|
||||
ren->objects.push_back(Object{
|
||||
.center = glm::vec4(center.x, center.y, center.z, 0.0),
|
||||
.dimensions = glm::vec4(rad),
|
||||
.id = id,
|
||||
.shape = eSPHERE,
|
||||
});
|
||||
}
|
||||
|
||||
static void add_box(const std::string& name, glm::vec3 center, glm::vec3 dim, Renderer* ren) {
|
||||
unsigned int id = 0xDEADBEEF;
|
||||
if (ren->scene_map.find(name) == ren->scene_map.end()) {
|
||||
/* start iterating from the number of total objects, which will break immediately if stuff is deleted and new things added before saving, so please change this */
|
||||
id = ren->scene_map.size();
|
||||
ren->scene_map[name] = id;
|
||||
} else {
|
||||
id = ren->scene_map[name];
|
||||
}
|
||||
|
||||
ren->objects.push_back(Object{
|
||||
.center = glm::vec4(center.x, center.y, center.z, 0.0),
|
||||
.dimensions = glm::vec4(dim.x, dim.y, dim.z, 0.0),
|
||||
.id = id,
|
||||
.shape = eBOX,
|
||||
});
|
||||
}
|
||||
|
||||
static void writeFile(const std::string& fname, const std::vector<Object>& objs, const std::map<std::string, int>& map) {
|
||||
std::ofstream out(fname);
|
||||
const char* shape_names[] = {
|
||||
"SPHERE",
|
||||
"BOX",
|
||||
"PLANE",
|
||||
};
|
||||
|
||||
int anon = 0;
|
||||
for (const auto& obj : objs) {
|
||||
out << shape_names[obj.shape] << " ( " << obj.center.x << " " << obj.center.y << " " << obj.center.z << " ) ( ";
|
||||
|
||||
switch (obj.shape) {
|
||||
case eSPHERE:
|
||||
out << obj.dimensions.x << " ";
|
||||
break;
|
||||
case eBOX:
|
||||
out << obj.dimensions.x << " "
|
||||
<< obj.dimensions.y << " "
|
||||
<< obj.dimensions.z << " ";
|
||||
break;
|
||||
case ePLANE:
|
||||
out << obj.dimensions.x << " "
|
||||
<< obj.dimensions.y << " "
|
||||
<< obj.dimensions.z << " ";
|
||||
break;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
auto name = find_name(map, obj.id, found);
|
||||
|
||||
if (!found || name[0] == '#') {
|
||||
name = std::string("#") + std::to_string(anon++);
|
||||
}
|
||||
out << ") " << name << std::endl;
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <util/glsl_types.hpp>
|
||||
|
||||
using namespace glsl;
|
||||
|
||||
|
||||
enum Shape {
|
||||
eSPHERE,
|
||||
eBOX,
|
||||
ePLANE,
|
||||
};
|
||||
|
||||
struct Object {
|
||||
vec4 center;
|
||||
vec4 dimensions;
|
||||
uint id;
|
||||
Shape shape;
|
||||
float pad0;
|
||||
float pad1;
|
||||
};
|
||||
123
Scene/Terrain.cpp
Normal file
123
Scene/Terrain.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
#include <Renderer/CommandBuffer.hpp>
|
||||
#include <Scene/Terrain.hpp>
|
||||
|
||||
#include <util/int.hpp>
|
||||
|
||||
float Terrain::getHeight(int32_t x, int32_t y) {
|
||||
if (x < 0)
|
||||
x += 64;
|
||||
if (y < 0)
|
||||
y += 64;
|
||||
|
||||
x %= 64;
|
||||
y %= 64;
|
||||
|
||||
float xf = x;
|
||||
float yf = y;
|
||||
xf /= 64.0;
|
||||
xf *= heightmap_tex->extent.width;
|
||||
yf /= 64.0;
|
||||
yf *= heightmap_tex->extent.height;
|
||||
|
||||
return static_cast<float>(heightmap_tex->image_data[static_cast<int>(static_cast<int>(yf) * heightmap_tex->extent.width + xf) * 4]) / 256.0f * 15.0f;
|
||||
}
|
||||
|
||||
Terrain::Terrain(vk::PhysicalDevice phys_dev, vk::Device dev, Texture& tex) : phys_dev(phys_dev), dev(dev) {
|
||||
/* tell Texture() not to free so we can apply our sobel filter */
|
||||
heightmap_tex = &tex;
|
||||
|
||||
const auto patch_size = 64_u32;
|
||||
const auto uv_scale = 1.0f;
|
||||
const auto vertex_count = patch_size * patch_size;
|
||||
|
||||
vertices.resize(vertex_count);
|
||||
|
||||
for (size_t x = 0; x < patch_size; x++)
|
||||
for (size_t y = 0; y < patch_size; y++)
|
||||
vertices[x + y*patch_size] = (glTFVertex {
|
||||
.pos = glm::vec3(
|
||||
2.0f * x + 1.0f - patch_size,
|
||||
0.0f,
|
||||
2.0f * y + 1.0f - patch_size),
|
||||
.uv = glm::vec2(static_cast<float>(x)/patch_size, static_cast<float>(y) / patch_size) * uv_scale,
|
||||
});
|
||||
|
||||
/* use sobel filters to get normal:
|
||||
* X sobel:
|
||||
* +----+----+----+
|
||||
* | +1 | +0 | -1 |
|
||||
* +----+----+----+
|
||||
* | +2 | +0 | -2 |
|
||||
* +----+----+----+
|
||||
* | +1 | +0 | -1 |
|
||||
* +----+----+----+
|
||||
* Y sobel:
|
||||
* +----+----+----+
|
||||
* | +1 | +2 | +1 |
|
||||
* +----+----+----+
|
||||
* | +0 | +0 | +0 |
|
||||
* +----+----+----+
|
||||
* | -1 | -2 | -1 |
|
||||
* +----+----+----+
|
||||
*/
|
||||
|
||||
for(auto x = 0_i32; x < patch_size; x++)
|
||||
for (auto y = 0_i32; y < patch_size; y++) {
|
||||
float moores_heights[3][3] = {
|
||||
{ getHeight(x - 1, y - 1), getHeight(x - 1, y), getHeight(x - 1, y + 1) },
|
||||
{ getHeight(x + 0, y - 1), getHeight(x + 0, y), getHeight(x + 0, y + 1) },
|
||||
{ getHeight(x + 1, y - 1), getHeight(x + 1, y), getHeight(x + 1, y + 1) },
|
||||
};
|
||||
|
||||
// auto normal = glm::vec3(
|
||||
// /* x gets X sobel filter */
|
||||
// moores_heights[0][0] + 2.0f * moores_heights[0][1] + moores_heights[0][2]
|
||||
// - moores_heights[2][0] - 2.0f * moores_heights[2][1] - moores_heights[2][2],
|
||||
// 0.0,
|
||||
// /* z gets Y sobel filter */
|
||||
// moores_heights[0][0] + 2.0f * moores_heights[1][0] + moores_heights[2][0]
|
||||
// - moores_heights[0][2] - 2.0f * moores_heights[1][2] - moores_heights[2][2]
|
||||
// );
|
||||
|
||||
auto relx = glm::vec3(2.0, getHeight(x + 1, y)-getHeight(x, y), 0.0);
|
||||
auto relz = glm::vec3(0.0, getHeight(x, y + 1)-getHeight(x, y), 2.0);
|
||||
auto normal = glm::normalize(glm::cross(relz, relx));
|
||||
|
||||
|
||||
/* fill in missing component, first scalar scales bump */
|
||||
//normal.y = 0.25 * glm::sqrt(glm::abs(1.0 - normal.x*normal.x - normal.z*normal.z));
|
||||
|
||||
//vertices[x + y * patch_size].norm = glm::vec3(getHeight(x, y));
|
||||
vertices[x + y * patch_size].norm = normal;
|
||||
}
|
||||
|
||||
vertex_buffer = std::make_unique<VertexBuffer>(phys_dev, dev, vertices.size());
|
||||
vertex_buffer->upload(vertices);
|
||||
|
||||
/* index generation */
|
||||
const auto w = patch_size - 1;
|
||||
indices.resize(w * w * 4);
|
||||
|
||||
for (auto x = 0_u32; x < w; x++)
|
||||
for (auto y = 0_u32; y < w; y++) {
|
||||
auto idx = (x + y * w) * 4;
|
||||
indices[idx] = x+y*patch_size;
|
||||
indices[idx+1] = indices[idx] + patch_size;
|
||||
indices[idx+2] = indices[idx+1] + 1;
|
||||
indices[idx + 3] = indices[idx] + 1;
|
||||
}
|
||||
|
||||
index_buffer = std::make_unique<Buffer>(phys_dev, dev, sizeof(uint32_t)*indices.size(),
|
||||
vk::BufferUsageFlagBits::eIndexBuffer, vk::MemoryPropertyFlagBits::eHostCoherent
|
||||
| vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
|
||||
index_buffer->upload(indices);
|
||||
}
|
||||
|
||||
void Terrain::draw(CommandBuffer& cmd) {
|
||||
}
|
||||
|
||||
Terrain::~Terrain() {
|
||||
index_buffer.reset();
|
||||
vertex_buffer.reset();
|
||||
}
|
||||
26
Scene/Terrain.hpp
Normal file
26
Scene/Terrain.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <Resources/Texture.hpp>
|
||||
#include <Renderer/VertexBuffer.hpp>
|
||||
|
||||
#include <Memory/Buffer.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
struct CommandBuffer;
|
||||
|
||||
struct Terrain {
|
||||
vk::PhysicalDevice phys_dev;
|
||||
vk::Device dev;
|
||||
Texture* heightmap_tex;
|
||||
|
||||
std::unique_ptr<VertexBuffer> vertex_buffer;
|
||||
std::unique_ptr<Buffer> index_buffer;
|
||||
std::vector<glTFVertex> vertices;
|
||||
std::vector<uint32_t> indices;
|
||||
|
||||
Terrain(vk::PhysicalDevice phys_dev, vk::Device dev, Texture& hieghtmap);
|
||||
float getHeight(int32_t x, int32_t y);
|
||||
void draw(CommandBuffer& cmd);
|
||||
~Terrain();
|
||||
};
|
||||
105
UI/UI.cpp
105
UI/UI.cpp
@ -11,7 +11,6 @@
|
||||
#include <Renderer/Renderer.hpp>
|
||||
|
||||
#include <Scene/Camera.hpp>
|
||||
#include <Scene/March.hpp>
|
||||
|
||||
/* this pains me to do, but its the only way :( */
|
||||
Renderer* __ren;
|
||||
@ -25,18 +24,14 @@ static csys::ItemLog& operator<<(csys::ItemLog& log, ImVector<float>& vec) {
|
||||
return log << vec[vec.size() - 1] << " }";
|
||||
}
|
||||
|
||||
static void scene_load(csys::String fname) {
|
||||
__ren->objects = March::readFile(fname.m_String, __ren->scene_map);
|
||||
|
||||
__ren->shader_buffer->upload(__ren->objects);
|
||||
static void pipeline_setter(bool& v, bool in) {
|
||||
if(v == in)
|
||||
return;
|
||||
v = in;
|
||||
__ren->bsp->pipeline->rebuild(__ren->wireframe_mode, __ren->backface_culling);
|
||||
}
|
||||
|
||||
static void scene_write(csys::String fname) {
|
||||
March::writeFile(fname.m_String, __ren->objects, __ren->scene_map);
|
||||
}
|
||||
|
||||
|
||||
UI::UI(Renderer* ren) : ren(ren) {
|
||||
UI::UI(Renderer* ren) : ren(ren), dev(ren->dev) {
|
||||
__ren = ren;
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
@ -110,59 +105,40 @@ UI::UI(Renderer* ren) : ren(ren) {
|
||||
auto& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
|
||||
console = new ImGuiConsole("developer console");
|
||||
console = std::make_unique<ImGuiConsole>("developer console");
|
||||
console->System().RegisterCommand("pause", "Pauses or unpauses the engine", [this]() {
|
||||
this->ren->paused = !this->ren->paused;
|
||||
console->System().Log(csys::ItemType::eINFO) << "Paused: " << (this->ren->paused ? "True" : "False") << csys::endl;
|
||||
console->System().Log(csys::ItemType::eINFO) << "Paused: " << (this->ren->paused? "True" : "False") << csys::endl;
|
||||
});
|
||||
|
||||
|
||||
console->System().RegisterCommand("quit", "Quits the engine", [this]() {
|
||||
this->ren->should_close = true;
|
||||
console->System().Log(csys::ItemType::eINFO) << "Quitting..." << csys::endl;
|
||||
});
|
||||
|
||||
console->System().RegisterCommand("read_scene", "Adds elements from a scene file", [this](csys::String fname) {
|
||||
console->System().Log(csys::ItemType::eINFO) << "Loading file: " << fname.m_String << csys::endl;
|
||||
scene_load(fname);
|
||||
}, csys::Arg<csys::String>("file-name"));
|
||||
console->System().RegisterCommand("write_scene", "Writes elements to a scene file (destroys underlying data if present)", [this](csys::String fname) {
|
||||
Log::info("Writing to " + fname.m_String + "\n");
|
||||
console->System().Log(csys::ItemType::eINFO) << "Writing to file: " << fname.m_String << "\n";
|
||||
scene_write(fname);
|
||||
}, csys::Arg<csys::String>("file-name"));
|
||||
|
||||
console->System().RegisterCommand("add_sphere", "Adds sphere to the scene.", [this](csys::String name, float cx, float cy, float cz, float rad) {
|
||||
March::add_sphere(name.m_String, glm::vec3(cx, cy, cz), rad, __ren);
|
||||
}, csys::Arg<csys::String>("Name"), csys::Arg<float>("center.x"), csys::Arg<float>("center.y"), csys::Arg<float>("center.z"), csys::Arg<float>("radius"));
|
||||
|
||||
console->System().RegisterCommand("add_box", "Adds box to the scene.", [this](csys::String name, float cx, float cy, float cz, float dx, float dy, float dz) {
|
||||
March::add_box(name.m_String, glm::vec3(cx, cy, cz), glm::vec3(dx, dy, dz), __ren);
|
||||
}, csys::Arg<csys::String>("Name"),
|
||||
csys::Arg<float>("center.x"), csys::Arg<float>("center.y"), csys::Arg<float>("center.z"),
|
||||
csys::Arg<float>("dim.x"), csys::Arg<float>("dim.y"), csys::Arg<float>("dim.z"));
|
||||
|
||||
console->System().RegisterCommand("list-vars", "List variables accessible from developer console", [this]() {
|
||||
const std::vector<std::string> names = {
|
||||
// "show_bboxes",
|
||||
// "visibility_testing",
|
||||
"show_bboxes",
|
||||
"visibility_testing",
|
||||
"flycam",
|
||||
"speed",
|
||||
"max_fps",
|
||||
// "wireframe",
|
||||
// "backface_culling",
|
||||
"wireframe",
|
||||
"backface_culling",
|
||||
};
|
||||
|
||||
for (const auto& name : names)
|
||||
for(const auto& name : names)
|
||||
console->System().Log(csys::ItemType::eINFO) << name << csys::endl;
|
||||
});
|
||||
});
|
||||
|
||||
// console->System().RegisterVariable("show_bboxes", ren->show_bboxes, csys::Arg<bool>("value"));
|
||||
// console->System().RegisterVariable("visibility_testing", ren->visibility_testing, csys::Arg<bool>("value"));
|
||||
console->System().RegisterVariable("show_bboxes", ren->show_bboxes, csys::Arg<bool>("value"));
|
||||
console->System().RegisterVariable("visibility_testing", ren->visibility_testing, csys::Arg<bool>("value"));
|
||||
console->System().RegisterVariable("flycam", ren->flycam, csys::Arg<bool>("value"));
|
||||
console->System().RegisterVariable("speed", ren->speed, csys::Arg<float>("value"));
|
||||
console->System().RegisterVariable("max_fps", ren->max_fps, csys::Arg<float>("value"));
|
||||
// console->System().RegisterVariable("wireframe", ren->wireframe_mode, pipeline_setter);
|
||||
// console->System().RegisterVariable("backface_culling", ren->backface_culling, pipeline_setter);
|
||||
|
||||
console->System().RegisterVariable("wireframe", ren->wireframe_mode, pipeline_setter);
|
||||
console->System().RegisterVariable("backface_culling", ren->backface_culling, pipeline_setter);
|
||||
|
||||
console->System().Log(csys::ItemType::eINFO) << "Welcome to Pleascach!" << csys::endl;
|
||||
}
|
||||
@ -172,39 +148,15 @@ void UI::newFrame() {
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.5f);
|
||||
ImGui::Begin("Rendering Info", nullptr);
|
||||
ImGui::Begin("Rendering Info", nullptr, ImGuiWindowFlags_::ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
|
||||
ImGui::Text("# of Indices: %zu", ren->n_indices);
|
||||
ImGui::Text("FPS: %f", ren->fps);
|
||||
ImGui::Text("Time: %f", ren->time);
|
||||
ImGui::SliderFloat("Rad", &ren->rad, 0.0, 3.0);
|
||||
ImGui::SliderFloat("Theta", &ren->cam.theta, 0.0, glm::pi<float>());
|
||||
ImGui::SliderFloat("Phi", &ren->cam.phi, 0.0, glm::two_pi<float>());
|
||||
|
||||
ImGui::SliderFloat("X", &ren->cam.pos.x, -1000.0, 1000.0);
|
||||
ImGui::SliderFloat("Y", &ren->cam.pos.y, -1000.0, 1000.0);
|
||||
ImGui::SliderFloat("Z", &ren->cam.pos.z, -1000.0, 1000.0);
|
||||
ImGui::Text("Speed: %f", ren->speed * ren->frametime / 8.0);
|
||||
|
||||
|
||||
if(ImGui::CollapsingHeader("Objects")) {
|
||||
int anon = 0;
|
||||
for (const auto& obj : ren->objects) {
|
||||
bool found = false;
|
||||
auto name = March::find_name(ren->scene_map, obj.id, found);
|
||||
|
||||
if (!found || name[0] == '#') {
|
||||
name = std::string("#") + std::to_string(anon++);
|
||||
}
|
||||
|
||||
ImGui::Text("(%f %f %f %f) (%f %f %f %f) \"%s\"",
|
||||
obj.center.x, obj.center.y, obj.center.z, obj.center.w,
|
||||
obj.dimensions.x, obj.dimensions.y, obj.dimensions.z, obj.dimensions.w,
|
||||
name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (ren->in_menu)
|
||||
if(ren->in_menu)
|
||||
console->Draw();
|
||||
|
||||
ImGui::End();
|
||||
@ -216,9 +168,12 @@ void UI::render(vk::CommandBuffer cmd) {
|
||||
}
|
||||
|
||||
UI::~UI() {
|
||||
// dev.destroyDescriptorPool(desc_pool);
|
||||
|
||||
console.reset();
|
||||
dev.destroyDescriptorPool(desc_pool);
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
// for whatever reason, this segfaults with a read to -1 when it tries saving characteristics.
|
||||
// TOOD: Debug
|
||||
// ImGui::DestroyContext();
|
||||
}
|
||||
@ -3,14 +3,12 @@
|
||||
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
|
||||
#include <Renderer/CommandBuffer.hpp>
|
||||
|
||||
#include <imgui/imgui_console.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
struct Object;
|
||||
struct Renderer;
|
||||
struct Camera;
|
||||
|
||||
@ -21,8 +19,8 @@ struct UI {
|
||||
|
||||
UI(Renderer* ren);
|
||||
|
||||
ImGuiConsole* console;
|
||||
|
||||
std::unique_ptr<ImGuiConsole> console;
|
||||
void newFrame();
|
||||
void render(vk::CommandBuffer cmd);
|
||||
|
||||
|
||||
BIN
assets/maps/dmc.bsp
Executable file
BIN
assets/maps/dmc.bsp
Executable file
Binary file not shown.
BIN
assets/maps/hl1.bsp
Normal file
BIN
assets/maps/hl1.bsp
Normal file
Binary file not shown.
BIN
assets/models/ball.bin
Normal file
BIN
assets/models/ball.bin
Normal file
Binary file not shown.
108
assets/models/ball.gltf
Normal file
108
assets/models/ball.gltf
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"asset":{
|
||||
"generator":"Khronos glTF Blender I/O v4.0.44",
|
||||
"version":"2.0"
|
||||
},
|
||||
"scene":0,
|
||||
"scenes":[
|
||||
{
|
||||
"name":"Scene",
|
||||
"nodes":[
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"name":"Mball"
|
||||
},
|
||||
{
|
||||
"name":"Circle",
|
||||
"translation":[
|
||||
0,
|
||||
0,
|
||||
-2.97784423828125
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"Circle.001"
|
||||
},
|
||||
{
|
||||
"mesh":0,
|
||||
"name":"Sphere"
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"name":"Sphere",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":0,
|
||||
"NORMAL":1
|
||||
},
|
||||
"indices":2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":30729,
|
||||
"max":[
|
||||
0.9991506934165955,
|
||||
0.9976890087127686,
|
||||
0.9973824620246887
|
||||
],
|
||||
"min":[
|
||||
-0.9990072846412659,
|
||||
-0.9995680451393127,
|
||||
-0.9988008141517639
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":30729,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5123,
|
||||
"count":56796,
|
||||
"type":"SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":368748,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":368748,
|
||||
"byteOffset":368748,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":113592,
|
||||
"byteOffset":737496,
|
||||
"target":34963
|
||||
}
|
||||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":851088,
|
||||
"uri":"ball.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
assets/models/bunny.bin
Normal file
BIN
assets/models/bunny.bin
Normal file
Binary file not shown.
107
assets/models/bunny.gltf
Normal file
107
assets/models/bunny.gltf
Normal file
@ -0,0 +1,107 @@
|
||||
{
|
||||
"asset":{
|
||||
"generator":"Khronos glTF Blender I/O v4.0.44",
|
||||
"version":"2.0"
|
||||
},
|
||||
"scene":0,
|
||||
"scenes":[
|
||||
{
|
||||
"name":"Scene",
|
||||
"nodes":[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"mesh":0,
|
||||
"name":"stanford-bunny",
|
||||
"rotation":[
|
||||
0.7071068286895752,
|
||||
0,
|
||||
0,
|
||||
0.7071068286895752
|
||||
],
|
||||
"scale":[
|
||||
10.410737037658691,
|
||||
10.410737037658691,
|
||||
10.410737037658691
|
||||
],
|
||||
"translation":[
|
||||
0,
|
||||
-0.39514416456222534,
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"name":"stanford-bunny",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":0,
|
||||
"NORMAL":1
|
||||
},
|
||||
"indices":2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":207619,
|
||||
"max":[
|
||||
0.0610090009868145,
|
||||
0.058800000697374344,
|
||||
-0.032986998558044434
|
||||
],
|
||||
"min":[
|
||||
-0.0946900025010109,
|
||||
-0.06187399849295616,
|
||||
-0.1873210072517395
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":207619,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5125,
|
||||
"count":208353,
|
||||
"type":"SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2491428,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":2491428,
|
||||
"byteOffset":2491428,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":833412,
|
||||
"byteOffset":4982856,
|
||||
"target":34963
|
||||
}
|
||||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":5816268,
|
||||
"uri":"bunny.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
224
assets/models/dragon.gltf
Normal file
224
assets/models/dragon.gltf
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/models/monk.bin
Normal file
BIN
assets/models/monk.bin
Normal file
Binary file not shown.
219
assets/models/monk.gltf
Normal file
219
assets/models/monk.gltf
Normal file
@ -0,0 +1,219 @@
|
||||
{
|
||||
"asset":{
|
||||
"generator":"Khronos glTF Blender I/O v4.0.44",
|
||||
"version":"2.0"
|
||||
},
|
||||
"scene":0,
|
||||
"scenes":[
|
||||
{
|
||||
"name":"Scene",
|
||||
"nodes":[
|
||||
0,
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"mesh":0,
|
||||
"name":"Suzanne",
|
||||
"rotation":[
|
||||
0.06356222927570343,
|
||||
0.536848247051239,
|
||||
-0.8056020140647888,
|
||||
0.2424030303955078
|
||||
],
|
||||
"translation":[
|
||||
0.1063065230846405,
|
||||
-0.6601571440696716,
|
||||
-0.6140139698982239
|
||||
]
|
||||
},
|
||||
{
|
||||
"mesh":1,
|
||||
"name":"Cube",
|
||||
"rotation":[
|
||||
0.1050531193614006,
|
||||
-0.23102691769599915,
|
||||
-0.3264787197113037,
|
||||
0.9104955196380615
|
||||
],
|
||||
"scale":[
|
||||
0.6794998645782471,
|
||||
1,
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"materials":[
|
||||
{
|
||||
"doubleSided":true,
|
||||
"name":"Material",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorFactor":[
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1
|
||||
],
|
||||
"metallicFactor":0,
|
||||
"roughnessFactor":0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"name":"Suzanne",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":0,
|
||||
"NORMAL":1,
|
||||
"TEXCOORD_0":2
|
||||
},
|
||||
"indices":3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"Cube",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":4,
|
||||
"NORMAL":5,
|
||||
"TEXCOORD_0":6
|
||||
},
|
||||
"indices":7,
|
||||
"material":0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":1970,
|
||||
"max":[
|
||||
1.3671875,
|
||||
0.984375,
|
||||
0.8515625
|
||||
],
|
||||
"min":[
|
||||
-1.3671875,
|
||||
-0.984375,
|
||||
-0.8515625
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":1970,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5126,
|
||||
"count":1970,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":3,
|
||||
"componentType":5123,
|
||||
"count":2904,
|
||||
"type":"SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView":4,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"max":[
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"min":[
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":5,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":6,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":7,
|
||||
"componentType":5123,
|
||||
"count":36,
|
||||
"type":"SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":23640,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":23640,
|
||||
"byteOffset":23640,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":15760,
|
||||
"byteOffset":47280,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":5808,
|
||||
"byteOffset":63040,
|
||||
"target":34963
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":288,
|
||||
"byteOffset":68848,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":288,
|
||||
"byteOffset":69136,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":192,
|
||||
"byteOffset":69424,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":72,
|
||||
"byteOffset":69616,
|
||||
"target":34963
|
||||
}
|
||||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":69688,
|
||||
"uri":"monk.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
assets/models/monkebox.bin
Normal file
BIN
assets/models/monkebox.bin
Normal file
Binary file not shown.
219
assets/models/monkebox.gltf
Normal file
219
assets/models/monkebox.gltf
Normal file
@ -0,0 +1,219 @@
|
||||
{
|
||||
"asset":{
|
||||
"generator":"Khronos glTF Blender I/O v4.0.44",
|
||||
"version":"2.0"
|
||||
},
|
||||
"scene":0,
|
||||
"scenes":[
|
||||
{
|
||||
"name":"Scene",
|
||||
"nodes":[
|
||||
0,
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"mesh":0,
|
||||
"name":"Suzanne",
|
||||
"rotation":[
|
||||
0.06356222927570343,
|
||||
0.536848247051239,
|
||||
-0.8056020140647888,
|
||||
0.2424030303955078
|
||||
],
|
||||
"translation":[
|
||||
0.1063065230846405,
|
||||
-0.6601571440696716,
|
||||
-0.6140139698982239
|
||||
]
|
||||
},
|
||||
{
|
||||
"mesh":1,
|
||||
"name":"Cube",
|
||||
"rotation":[
|
||||
0.1050531193614006,
|
||||
-0.23102691769599915,
|
||||
-0.3264787197113037,
|
||||
0.9104955196380615
|
||||
],
|
||||
"scale":[
|
||||
0.6794998645782471,
|
||||
1,
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"materials":[
|
||||
{
|
||||
"doubleSided":true,
|
||||
"name":"Material",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorFactor":[
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
0.800000011920929,
|
||||
1
|
||||
],
|
||||
"metallicFactor":0,
|
||||
"roughnessFactor":0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"name":"Suzanne",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":0,
|
||||
"NORMAL":1,
|
||||
"TEXCOORD_0":2
|
||||
},
|
||||
"indices":3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"Cube",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":4,
|
||||
"NORMAL":5,
|
||||
"TEXCOORD_0":6
|
||||
},
|
||||
"indices":7,
|
||||
"material":0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":1970,
|
||||
"max":[
|
||||
1.3671875,
|
||||
0.984375,
|
||||
0.8515625
|
||||
],
|
||||
"min":[
|
||||
-1.3671875,
|
||||
-0.984375,
|
||||
-0.8515625
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":1970,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5126,
|
||||
"count":1970,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":3,
|
||||
"componentType":5123,
|
||||
"count":2904,
|
||||
"type":"SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView":4,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"max":[
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"min":[
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":5,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":6,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":7,
|
||||
"componentType":5123,
|
||||
"count":36,
|
||||
"type":"SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":23640,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":23640,
|
||||
"byteOffset":23640,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":15760,
|
||||
"byteOffset":47280,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":5808,
|
||||
"byteOffset":63040,
|
||||
"target":34963
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":288,
|
||||
"byteOffset":68848,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":288,
|
||||
"byteOffset":69136,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":192,
|
||||
"byteOffset":69424,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":72,
|
||||
"byteOffset":69616,
|
||||
"target":34963
|
||||
}
|
||||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":69688,
|
||||
"uri":"monkebox.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
assets/shaders/basic.frag.spv
Normal file
BIN
assets/shaders/basic.frag.spv
Normal file
Binary file not shown.
BIN
assets/shaders/basic.geom.spv
Normal file
BIN
assets/shaders/basic.geom.spv
Normal file
Binary file not shown.
BIN
assets/shaders/basic.vert.spv
Normal file
BIN
assets/shaders/basic.vert.spv
Normal file
Binary file not shown.
BIN
assets/shaders/bsp.frag.spv
Normal file
BIN
assets/shaders/bsp.frag.spv
Normal file
Binary file not shown.
BIN
assets/shaders/bsp.vert.spv
Normal file
BIN
assets/shaders/bsp.vert.spv
Normal file
Binary file not shown.
BIN
assets/shaders/explode.geom.spv
Normal file
BIN
assets/shaders/explode.geom.spv
Normal file
Binary file not shown.
BIN
assets/shaders/fraglight.geom.spv
Normal file
BIN
assets/shaders/fraglight.geom.spv
Normal file
Binary file not shown.
BIN
assets/shaders/fraglight.vert.spv
Normal file
BIN
assets/shaders/fraglight.vert.spv
Normal file
Binary file not shown.
BIN
assets/shaders/gooch.frag.spv
Normal file
BIN
assets/shaders/gooch.frag.spv
Normal file
Binary file not shown.
BIN
assets/shaders/lambert.frag.spv
Normal file
BIN
assets/shaders/lambert.frag.spv
Normal file
Binary file not shown.
37
assets/shaders/lighting/fraglight.geom
Normal file
37
assets/shaders/lighting/fraglight.geom
Normal file
@ -0,0 +1,37 @@
|
||||
#version 450 core
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip) out;
|
||||
layout (max_vertices = 3) out;
|
||||
|
||||
layout (location = 0) in vec3 norm[];
|
||||
layout (location = 1) in vec2 texCoord[];
|
||||
layout (location = 2) in vec3 pos[];
|
||||
|
||||
layout (location = 0) out vec3 _norm;
|
||||
layout (location = 1) out vec2 _texCoord;
|
||||
layout (location = 2) out vec3 _pos;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
|
||||
void main(void) {
|
||||
for(int i = 0; i < gl_in.length(); i++) {
|
||||
gl_Position = proj * view * gl_in[i].gl_Position;
|
||||
_norm = norm[i];
|
||||
_texCoord = texCoord[i];
|
||||
_pos = pos[i];
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
BIN
assets/shaders/lighting/fraglight.geom.spv
Normal file
BIN
assets/shaders/lighting/fraglight.geom.spv
Normal file
Binary file not shown.
27
assets/shaders/lighting/fraglight.vert
Normal file
27
assets/shaders/lighting/fraglight.vert
Normal file
@ -0,0 +1,27 @@
|
||||
#version 460 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNorm;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
layout (location = 0) out vec3 norm;
|
||||
layout (location = 1) out vec2 texCoord;
|
||||
layout (location = 2) out vec3 pos;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
void main() {
|
||||
pos = (aPos + (vec3(10.0) * gl_InstanceIndex));
|
||||
gl_Position = vec4(pos, 1.0);
|
||||
texCoord = aTexCoord;
|
||||
norm = aNorm;
|
||||
}
|
||||
BIN
assets/shaders/lighting/fraglight.vert.spv
Normal file
BIN
assets/shaders/lighting/fraglight.vert.spv
Normal file
Binary file not shown.
38
assets/shaders/lighting/gooch.frag
Normal file
38
assets/shaders/lighting/gooch.frag
Normal file
@ -0,0 +1,38 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 norm;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
layout (location = 2) in vec3 pos;
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
vec3 light_pos = normalize(vec3(cos(time), sin(time), 0.0))*10.0;
|
||||
/* calculate highlight using angle between fragment and viewer */
|
||||
vec3 I = normalize(cam_pos-pos);
|
||||
vec3 L = normalize(light_pos-pos);
|
||||
vec3 cool = vec3(0.0, 0.0, 0.55);
|
||||
vec3 warm = vec3(0.3, 0.3, 0);
|
||||
float t = (dot(norm, L)+1.0)/2.0;
|
||||
vec3 r = 2.0*(dot(norm,L)*norm)-L;
|
||||
float s = 100.0*(dot(r,I))-97.0;
|
||||
if(s < 0.0)
|
||||
s = 0.0;
|
||||
else if(s > 1.0)
|
||||
s = 1.0;
|
||||
|
||||
FragColor = vec4((1.0-s)*(t*warm + (vec3(0.5)-t)*cool) + s*vec3(1.0), 1.0);
|
||||
}
|
||||
BIN
assets/shaders/lighting/gooch.frag.spv
Normal file
BIN
assets/shaders/lighting/gooch.frag.spv
Normal file
Binary file not shown.
29
assets/shaders/lighting/lambert.frag
Normal file
29
assets/shaders/lighting/lambert.frag
Normal file
@ -0,0 +1,29 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 norm;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
layout (location = 2) in vec3 pos;
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
vec3 light_pos = normalize(vec3(cos(time), sin(time), 0.0))*10.0;
|
||||
vec3 L = normalize(light_pos-pos);
|
||||
float r = length(light_pos-pos);
|
||||
float t = clamp(dot(L, norm), 0.0, 1.0) * 20.0/(r*r);
|
||||
|
||||
FragColor = vec4(t, t/2.0, t*2.0, 1.0);
|
||||
}
|
||||
BIN
assets/shaders/lighting/lambert.frag.spv
Normal file
BIN
assets/shaders/lighting/lambert.frag.spv
Normal file
Binary file not shown.
65
assets/shaders/lighting/trace.frag
Normal file
65
assets/shaders/lighting/trace.frag
Normal file
@ -0,0 +1,65 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 norm;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 mvp;
|
||||
float time;
|
||||
float aspect_ratio;
|
||||
};
|
||||
|
||||
/* 4-float alignment in memory*/
|
||||
struct Ray {
|
||||
vec3 orig;
|
||||
float min;
|
||||
vec3 dir;
|
||||
float max;
|
||||
};
|
||||
|
||||
vec3 ray_color(vec3 ray) {
|
||||
float a = 0.5 * (ray.y+1.0);
|
||||
|
||||
return vec3(1.0-a) + a*vec3(0.5, 0.7, 1.0);
|
||||
}
|
||||
|
||||
/* returns float of where you hit, or -1.0 */
|
||||
float sphere(vec3 center, float r, Ray ray) {
|
||||
vec3 p = ray.orig-center;
|
||||
float a = dot(ray.dir, ray.dir);
|
||||
float half_b = dot(p, ray.dir);
|
||||
float c = dot(p, p) - r*r;
|
||||
float discr = half_b*half_b - a*c;
|
||||
|
||||
if(discr < 0.0)
|
||||
return -1.0;
|
||||
|
||||
return -half_b-sqrt(discr)/a;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 pixel = texCoord*2.0-1.0;
|
||||
Ray ray;
|
||||
ray.orig = vec3(0.0);
|
||||
ray.min = 0.1;
|
||||
ray.max = 10000.0;
|
||||
float fov = radians(90);
|
||||
ray.dir = normalize(vec3(pixel.x * aspect_ratio, pixel.y, tan(fov/2.0)));
|
||||
|
||||
vec3 sphere_center = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
float d = sphere(sphere_center, 0.5, ray);
|
||||
|
||||
FragColor = vec4(texCoord, 1.0, 1.0);
|
||||
return;
|
||||
|
||||
if(d < 0.0) {
|
||||
FragColor = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 n = normalize(ray.dir*d-sphere_center);
|
||||
FragColor = vec4((n+vec3(1.0)) / 2.0, 1.0);
|
||||
|
||||
}
|
||||
BIN
assets/shaders/lighting/trace.frag.spv
Normal file
BIN
assets/shaders/lighting/trace.frag.spv
Normal file
Binary file not shown.
@ -1,126 +0,0 @@
|
||||
#version 450 core
|
||||
|
||||
#define MAX_STEPS 100
|
||||
#define MAX_DIST 1000.0
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
vec3 cam_pos;
|
||||
float time;
|
||||
vec4 viewport;
|
||||
vec3 cam_dir;
|
||||
uint n_objects;
|
||||
float rad;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 pos;
|
||||
layout (location = 0) out vec4 fragColor;
|
||||
|
||||
vec2 eps = vec2(0.001, 0.0);
|
||||
|
||||
/* joins two parts of a scene */
|
||||
float op_union(float v1, float v2) {
|
||||
return min(v1, v2);
|
||||
}
|
||||
|
||||
/* subtracts sdf from scene */
|
||||
float op_subtract(float v1, float v2) {
|
||||
return max(v1, -v2);
|
||||
}
|
||||
|
||||
/* twists! in the xz */
|
||||
vec3 op_twist(vec3 p, float k) {
|
||||
float c = cos(k*p.y);
|
||||
float s = sin(k*p.y);
|
||||
mat2 m = mat2(c, -s, s, c);
|
||||
return vec3(m*p.xz, p.y);
|
||||
}
|
||||
|
||||
float box(vec3 p, vec3 r) {
|
||||
vec3 q = abs(p) - r;
|
||||
return length(max(q,0.0)) + min(max(q.x, max(q.y,q.z)), 0.0);
|
||||
}
|
||||
|
||||
/* square, centered at the origin */
|
||||
float box(vec2 p, vec2 r) {
|
||||
vec2 d = abs(p)-r;
|
||||
return length(max(d, 0.0)) + min(max(d.x,d.y), 0.0);
|
||||
}
|
||||
|
||||
/* infinite cross, used for construction of serpinski cube */
|
||||
float infcross(vec3 p, float r) {
|
||||
vec2 unit = vec2(r);
|
||||
float box1 = box(p.xy, unit);
|
||||
float box2 = box(p.yz, unit);
|
||||
float box3 = box(p.zx, unit);
|
||||
return op_union(op_union(box1, box2), box3);
|
||||
}
|
||||
|
||||
float sphere(vec3 p, float r) {
|
||||
return length(p) - r;
|
||||
}
|
||||
|
||||
float sdf(vec3 p) {
|
||||
p = op_twist(p.xzy, cos(time)).xzy;
|
||||
float d = box(p, vec3(1.0));
|
||||
float s = 1.0;
|
||||
for(int i = 0; i < 5; i++) {
|
||||
/* using mod to repeat across domain, then shift to +- */
|
||||
vec3 a = mod(p * s, 2.0) - 1.0;
|
||||
s *= 3.0;
|
||||
vec3 r = 1.0 - 3.0*abs(a);
|
||||
float c = infcross(r, rad)/s;
|
||||
d = max(d, c);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
vec3 norm(vec3 pos) {
|
||||
return normalize(
|
||||
vec3(
|
||||
sdf(pos+eps.xyy),
|
||||
sdf(pos+eps.yxy),
|
||||
sdf(pos+eps.yyx)
|
||||
) - sdf(pos)
|
||||
);
|
||||
}
|
||||
|
||||
vec2 raycast(vec3 dir) {
|
||||
float t = 0.0;
|
||||
for(int i = 0; i < MAX_STEPS; i++) {
|
||||
float dt = sdf(cam_pos + dir * t);
|
||||
if(dt < 0.0001*t)
|
||||
return vec2(t, float(i));
|
||||
else if(dt > MAX_DIST)
|
||||
return vec2(0.0, -1.0);
|
||||
t += dt;
|
||||
}
|
||||
|
||||
return vec2(0.0, 64.0);
|
||||
}
|
||||
|
||||
vec3 raygen() {
|
||||
vec3 forward = cam_dir;
|
||||
vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
|
||||
vec3 up = normalize(cross(right, forward));
|
||||
|
||||
return normalize(pos.x * right + pos.y * up + forward * 2.0);
|
||||
}
|
||||
|
||||
vec3 gamma(vec3 c) {
|
||||
return pow(c, vec3(0.4545));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 dir = raygen();
|
||||
vec2 d = raycast(dir);
|
||||
if(d.y == -1.0) {
|
||||
fragColor = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
fragColor = vec4(d.y/MAX_STEPS);
|
||||
|
||||
fragColor.xyz = gamma(fragColor.xyz);
|
||||
}
|
||||
Binary file not shown.
34
assets/shaders/map/bsp.frag
Normal file
34
assets/shaders/map/bsp.frag
Normal file
@ -0,0 +1,34 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec4 color;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||
|
||||
vec3 tex_map(vec2 coords) {
|
||||
return vec3(
|
||||
1-abs(cos(normalize(texCoord.xxy)))
|
||||
// 0.0,
|
||||
// sin(texCoord.y)
|
||||
// sin(texCoord.x/texCoord.y)
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
FragColor.xyz = tex_map(texCoord);
|
||||
FragColor.w = 1.0;
|
||||
}
|
||||
BIN
assets/shaders/map/bsp.frag.spv
Normal file
BIN
assets/shaders/map/bsp.frag.spv
Normal file
Binary file not shown.
35
assets/shaders/map/bsp.vert
Normal file
35
assets/shaders/map/bsp.vert
Normal file
@ -0,0 +1,35 @@
|
||||
#version 460 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
layout (location = 0) out vec4 color;
|
||||
layout (location = 1) out vec2 texCoord;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
vec4 unpackABGR(uint packedABGR) {
|
||||
float scale = 1.0 / 255.0;
|
||||
float a = float((packedABGR >> 24) & 0xFF) * scale;
|
||||
float b = float((packedABGR >> 16) & 0xFF) * scale;
|
||||
float g = float((packedABGR >> 8) & 0xFF) * scale;
|
||||
float r = float(packedABGR & 0xFF) * scale;
|
||||
return vec4(r,g,b,a);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
gl_Position = proj * view * vec4(aPos, 1.0);
|
||||
|
||||
color = vec4(0.0);
|
||||
texCoord = aTexCoord;
|
||||
}
|
||||
BIN
assets/shaders/map/bsp.vert.spv
Normal file
BIN
assets/shaders/map/bsp.vert.spv
Normal file
Binary file not shown.
23
assets/shaders/mesh/basic.frag
Normal file
23
assets/shaders/mesh/basic.frag
Normal file
@ -0,0 +1,23 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 norm;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(norm, 1.0);
|
||||
}
|
||||
BIN
assets/shaders/mesh/basic.frag.spv
Normal file
BIN
assets/shaders/mesh/basic.frag.spv
Normal file
Binary file not shown.
34
assets/shaders/mesh/basic.geom
Normal file
34
assets/shaders/mesh/basic.geom
Normal file
@ -0,0 +1,34 @@
|
||||
#version 450 core
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip) out;
|
||||
layout (max_vertices = 3) out;
|
||||
|
||||
layout (location = 0) in vec3 norm[];
|
||||
layout (location = 1) in vec2 texCoord[];
|
||||
|
||||
layout (location = 0) out vec3 _norm;
|
||||
layout (location = 1) out vec2 _texCoord;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
|
||||
void main(void) {
|
||||
for(int i = 0; i < gl_in.length(); i++) {
|
||||
gl_Position = proj * view * gl_in[i].gl_Position;
|
||||
_norm = norm[i];
|
||||
_texCoord = texCoord[i];
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
BIN
assets/shaders/mesh/basic.geom.spv
Normal file
BIN
assets/shaders/mesh/basic.geom.spv
Normal file
Binary file not shown.
25
assets/shaders/mesh/basic.vert
Normal file
25
assets/shaders/mesh/basic.vert
Normal file
@ -0,0 +1,25 @@
|
||||
#version 460 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNorm;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
layout (location = 0) out vec3 norm;
|
||||
layout (location = 1) out vec2 texCoord;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = proj * view * vec4(aPos, 1.0);
|
||||
texCoord = aTexCoord;
|
||||
norm = aNorm;
|
||||
}
|
||||
BIN
assets/shaders/mesh/basic.vert.spv
Normal file
BIN
assets/shaders/mesh/basic.vert.spv
Normal file
Binary file not shown.
51
assets/shaders/mesh/explode.geom
Normal file
51
assets/shaders/mesh/explode.geom
Normal file
@ -0,0 +1,51 @@
|
||||
#version 450 core
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip) out;
|
||||
layout (max_vertices = 3) out;
|
||||
|
||||
layout (location = 0) in vec3 norm[];
|
||||
layout (location = 1) in vec2 texCoord[];
|
||||
|
||||
layout (location = 0) out vec3 _norm;
|
||||
layout (location = 1) out vec2 _texCoord;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
vec4 explode(vec4 pos, vec3 n) {
|
||||
float mag = 2.0;
|
||||
vec3 dir = n * (time-3.0)/10.0 * mag;
|
||||
return pos + vec4(dir, 0.0);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
if (time < 3.0) {
|
||||
for(int i = 0; i < gl_in.length(); i++) {
|
||||
gl_Position = proj * view * gl_in[i].gl_Position;
|
||||
_norm = norm[i];
|
||||
_texCoord = texCoord[i];
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
return;
|
||||
}
|
||||
vec3 n = norm[0] + norm[1] + norm[2];
|
||||
n/=3;
|
||||
for(int i = 0; i < gl_in.length(); i++) {
|
||||
gl_Position = proj * view * explode(gl_in[i].gl_Position, n);
|
||||
_texCoord = texCoord[i];
|
||||
_norm = n;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
BIN
assets/shaders/mesh/explode.geom.spv
Normal file
BIN
assets/shaders/mesh/explode.geom.spv
Normal file
Binary file not shown.
@ -1,157 +0,0 @@
|
||||
#version 450 core
|
||||
|
||||
#define MAX_STEPS 64
|
||||
|
||||
const vec2 eps = vec2(0.001, 0.0);
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D tex;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
vec3 cam_pos;
|
||||
float time;
|
||||
vec4 viewport;
|
||||
vec3 cam_dir;
|
||||
uint n_objects;
|
||||
};
|
||||
|
||||
/*
|
||||
enum Shape {
|
||||
SPHERE,
|
||||
BOX,
|
||||
PLANE,
|
||||
};
|
||||
*/
|
||||
|
||||
#define SPHERE 0
|
||||
#define BOX 1
|
||||
#define PLANE 2
|
||||
|
||||
struct Object {
|
||||
vec4 center;
|
||||
vec4 dimensions;
|
||||
uint id;
|
||||
uint shape;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 2) readonly buffer Objects {
|
||||
Object objects[];
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 pos;
|
||||
layout (location = 0) out vec4 fragColor;
|
||||
|
||||
/* joins two parts of a scene */
|
||||
vec2 op_union(vec2 v1, float v2, float id) {
|
||||
if(v1.x > v2)
|
||||
return vec2(v2, id);
|
||||
return v1;
|
||||
}
|
||||
|
||||
/* subtracts sdf from scene */
|
||||
float op_subtract(float v1, float v2) {
|
||||
return max(v1, -v2);
|
||||
}
|
||||
|
||||
float sphere(vec3 p, vec3 c, float r) {
|
||||
return abs(length(p-c) - r);
|
||||
}
|
||||
|
||||
float box(vec3 p, vec3 c, vec3 r) {
|
||||
p -= c;
|
||||
vec3 q = abs(p) - r;
|
||||
return length(max(q,0.0)) + min(max(q.x, max(q.y,q.z)), 0.0);
|
||||
}
|
||||
|
||||
float plane(vec3 p, vec3 norm, float d) {
|
||||
return dot(p, normalize(norm)) + d;
|
||||
}
|
||||
|
||||
float obj_to_sdf(vec3 p, uint n) {
|
||||
switch(objects[n].shape) {
|
||||
case SPHERE:
|
||||
return sphere(p, objects[n].center.xyz, objects[n].dimensions.x);
|
||||
break;
|
||||
case BOX:
|
||||
return box(p, objects[n].center.xyz, objects[n].dimensions.xyz);
|
||||
break;
|
||||
case PLANE:
|
||||
return plane(p, objects[n].center.xyz, objects[n].dimensions.x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float map(vec2 p) {
|
||||
return sin(p.x)*sin(p.y);
|
||||
}
|
||||
|
||||
float terrain(vec3 p) {
|
||||
/* render terrain with bumps */
|
||||
return box(p, vec3(0.0), vec3(100.0, 0.1, 100.0)) - abs(map(p.xz));
|
||||
}
|
||||
|
||||
/* <distance, id> */
|
||||
vec2 sdf(vec3 pos) {
|
||||
vec2 d = vec2(100000000.0, -1.0);
|
||||
for(uint i = 0; i < n_objects; i++) {
|
||||
d = op_union(d, obj_to_sdf(pos, i), 1.0);
|
||||
// d = op_union(d, sphere(pos, objects[i].center.xyz, objects[i].dimensions.x), 1.0);
|
||||
}
|
||||
|
||||
|
||||
/*float dsphere = sphere(pos, vec3(0.0, 3.0*sin(time)-10.0, 0.0), 1.0);
|
||||
float dbox = box(pos, vec3(0.0, -10.0, 0.0), vec3(10.0, 1.0, 10.0));
|
||||
float dpellet = sphere(pos, vec3(0.0, 10.0*sin(time) - 10.0, 0.0), 0.1);
|
||||
float d = op_union(op_subtract(dbox, dsphere), dpellet);*/
|
||||
|
||||
//d = op_union(d, plane(pos, normalize(vec3(1.0)), 50.0));
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
vec2 raycast(vec3 dir) {
|
||||
float t = 0.0;
|
||||
for(int i = 0; i < MAX_STEPS; i++) {
|
||||
vec2 dt = sdf(cam_pos + dir * t);
|
||||
if(dt.y == -1.0)
|
||||
return dt;
|
||||
if(dt.x < 0.0001*t)
|
||||
// return vec2(t, dt.y);
|
||||
return vec2(t, float(i)/MAX_STEPS);
|
||||
else if(dt.x > 2000.0)
|
||||
return vec2(dt.x, -1.0);
|
||||
t += dt.x;
|
||||
}
|
||||
|
||||
return vec2(0.0, -1.0);
|
||||
}
|
||||
|
||||
vec3 norm(vec3 pos) {
|
||||
return normalize(
|
||||
vec3(
|
||||
sdf(pos+eps.xyy).x,
|
||||
sdf(pos+eps.yxy).x,
|
||||
sdf(pos+eps.yyx).x
|
||||
) - sdf(pos).x
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
vec3 raygen() {
|
||||
vec3 forward = cam_dir;
|
||||
vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
|
||||
vec3 up = normalize(cross(right, forward));
|
||||
|
||||
return normalize(pos.x * right + pos.y * up + forward * 2.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 dir = raygen();
|
||||
vec2 d = raycast(dir);
|
||||
|
||||
vec3 p = d.x*dir + cam_pos;
|
||||
|
||||
if(d.y != -1.0)
|
||||
fragColor = vec4(d.y);
|
||||
else
|
||||
fragColor = vec4(0.0);
|
||||
}
|
||||
Binary file not shown.
@ -1,17 +0,0 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec2 aCoord;
|
||||
|
||||
layout (location = 0) out vec2 pos;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
vec3 cam_pos;
|
||||
float time;
|
||||
vec4 viewport;
|
||||
vec3 cam_dir;
|
||||
};
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aCoord, 0.0, 1.0);
|
||||
pos = vec2(aCoord.x * viewport.x / viewport.y, aCoord.y);
|
||||
}
|
||||
Binary file not shown.
BIN
assets/shaders/terrain.frag.spv
Normal file
BIN
assets/shaders/terrain.frag.spv
Normal file
Binary file not shown.
BIN
assets/shaders/terrain.tesc.spv
Normal file
BIN
assets/shaders/terrain.tesc.spv
Normal file
Binary file not shown.
BIN
assets/shaders/terrain.tese.spv
Normal file
BIN
assets/shaders/terrain.tese.spv
Normal file
Binary file not shown.
BIN
assets/shaders/terrain.vert.spv
Normal file
BIN
assets/shaders/terrain.vert.spv
Normal file
Binary file not shown.
29
assets/shaders/terrain/terrain.frag
Normal file
29
assets/shaders/terrain/terrain.frag
Normal file
@ -0,0 +1,29 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 norm;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
layout (location = 2) in vec3 pos;
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D heightmap;
|
||||
|
||||
void main() {
|
||||
/* extract L (light direction) from view matrix */
|
||||
vec3 L = -cam_dir;
|
||||
float r = length(cam_pos-pos);
|
||||
float t = clamp(dot(L, norm), 0.0, 1.0) * 200.0/(r*r);
|
||||
|
||||
FragColor = vec4(vec3(t), 1.0);
|
||||
}
|
||||
BIN
assets/shaders/terrain/terrain.frag.spv
Normal file
BIN
assets/shaders/terrain/terrain.frag.spv
Normal file
Binary file not shown.
89
assets/shaders/terrain/terrain.tesc
Normal file
89
assets/shaders/terrain/terrain.tesc
Normal file
@ -0,0 +1,89 @@
|
||||
#version 450 core
|
||||
#extension GL_EXT_debug_printf : enable
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 1) uniform sampler2D heightmap;
|
||||
|
||||
layout (vertices = 4) out;
|
||||
|
||||
layout (location = 0) in vec3 norm[];
|
||||
layout (location = 1) in vec2 texCoord[];
|
||||
layout (location = 2) in vec3 pos[];
|
||||
|
||||
layout (location = 0) out vec3 _norm[4];
|
||||
layout (location = 1) out vec2 _texCoord[4];
|
||||
layout (location = 2) out vec3 _pos[4];
|
||||
|
||||
|
||||
float screen_space_tess(vec4 p0, vec4 p1) {
|
||||
/* calc midpoint + distance btw the two points */
|
||||
vec4 midp = 0.5*(p0+p1);
|
||||
float r = distance(p0, p1) / 2.0;
|
||||
|
||||
vec4 v0 = view * midp;
|
||||
|
||||
/* project into clip spaace */
|
||||
vec4 clip0 = proj * (v0 - vec4(r, vec3(0.0)));
|
||||
vec4 clip1 = proj * (v0 + vec4(r, vec3(0.0)));
|
||||
|
||||
clip0 /= clip0.w;
|
||||
clip1 /= clip1.w;
|
||||
|
||||
/* convert to viewport coords */
|
||||
clip0.xy *= viewport;
|
||||
clip1.xy *= viewport;
|
||||
|
||||
return clamp(distance(clip0, clip1) / tess_edge_size * tess_factor, 1.0, 64.0);
|
||||
}
|
||||
|
||||
bool frustum_culling() {
|
||||
/* square root of patch size */
|
||||
const float r = 8.0f;
|
||||
/* ensure this is consistent with tese shader */
|
||||
vec4 fpos = gl_in[gl_InvocationID].gl_Position;
|
||||
fpos.y += 15.0 * textureLod(heightmap, texCoord[0], 0.0).r;
|
||||
|
||||
for(int i = 0; i < 6; i++) {
|
||||
if(dot(fpos, frustum[i]) + r < 0.0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
if(gl_InvocationID == 0) {
|
||||
/* perform frustum culling */
|
||||
if(frustum_culling()) {
|
||||
gl_TessLevelOuter[0] = screen_space_tess(gl_in[3].gl_Position, gl_in[0].gl_Position);
|
||||
gl_TessLevelOuter[1] = screen_space_tess(gl_in[0].gl_Position, gl_in[1].gl_Position);
|
||||
gl_TessLevelOuter[2] = screen_space_tess(gl_in[1].gl_Position, gl_in[2].gl_Position);
|
||||
gl_TessLevelOuter[3] = screen_space_tess(gl_in[2].gl_Position, gl_in[3].gl_Position);
|
||||
gl_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5);
|
||||
gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);
|
||||
} else {
|
||||
gl_TessLevelOuter[0] = 0.0;
|
||||
gl_TessLevelOuter[1] = 0.0;
|
||||
gl_TessLevelOuter[2] = 0.0;
|
||||
gl_TessLevelOuter[3] = 0.0;
|
||||
gl_TessLevelInner[0] = 0.0;
|
||||
gl_TessLevelInner[1] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
|
||||
_norm[gl_InvocationID] = norm[gl_InvocationID];
|
||||
_texCoord[gl_InvocationID] = texCoord[gl_InvocationID];
|
||||
_pos[gl_InvocationID] = pos[gl_InvocationID];
|
||||
}
|
||||
BIN
assets/shaders/terrain/terrain.tesc.spv
Normal file
BIN
assets/shaders/terrain/terrain.tesc.spv
Normal file
Binary file not shown.
49
assets/shaders/terrain/terrain.tese
Normal file
49
assets/shaders/terrain/terrain.tese
Normal file
@ -0,0 +1,49 @@
|
||||
#version 450 core
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec3 cam_dir;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 1) uniform sampler2D heightmap;
|
||||
|
||||
layout(quads, equal_spacing, ccw) in;
|
||||
|
||||
|
||||
layout (location = 0) in vec3 norm[];
|
||||
layout (location = 1) in vec2 texCoord[];
|
||||
layout (location = 2) in vec3 pos[];
|
||||
|
||||
layout (location = 0) out vec3 _norm;
|
||||
layout (location = 1) out vec2 _texCoord;
|
||||
layout (location = 2) out vec3 _pos;
|
||||
|
||||
|
||||
void main() {
|
||||
/* interpolation of UV coordinates */
|
||||
vec2 uv1 = mix(texCoord[0], texCoord[1], gl_TessCoord.x);
|
||||
vec2 uv2 = mix(texCoord[3], texCoord[2], gl_TessCoord.x);
|
||||
_texCoord = mix(uv1, uv2, gl_TessCoord.y);
|
||||
|
||||
|
||||
vec3 norm1 = mix(norm[0], norm[1], gl_TessCoord.x);
|
||||
vec3 norm2 = mix(norm[3], norm[2], gl_TessCoord.x);
|
||||
_norm = mix(norm1, norm2, gl_TessCoord.y);
|
||||
|
||||
/* not displacing yet */
|
||||
vec4 pos1 = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);
|
||||
vec4 pos2 = mix(gl_in[3].gl_Position, gl_in[2].gl_Position, gl_TessCoord.x);
|
||||
|
||||
vec4 fpos = mix(pos1, pos2, gl_TessCoord.y);
|
||||
fpos.y = 15.0 * texture(heightmap, _texCoord).r;
|
||||
|
||||
_pos = fpos.xyz;
|
||||
gl_Position = proj * view * fpos;
|
||||
}
|
||||
BIN
assets/shaders/terrain/terrain.tese.spv
Normal file
BIN
assets/shaders/terrain/terrain.tese.spv
Normal file
Binary file not shown.
26
assets/shaders/terrain/terrain.vert
Normal file
26
assets/shaders/terrain/terrain.vert
Normal file
@ -0,0 +1,26 @@
|
||||
#version 460 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNorm;
|
||||
layout (location = 2) in vec2 aTexCoord;
|
||||
|
||||
layout (location = 0) out vec3 norm;
|
||||
layout (location = 1) out vec2 texCoord;
|
||||
layout (location = 2) out vec3 pos;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
vec3 cam_pos;
|
||||
vec4 frustum[6];
|
||||
vec2 viewport;
|
||||
float tess_factor;
|
||||
float tess_edge_size;
|
||||
};
|
||||
|
||||
void main() {
|
||||
pos = aPos;
|
||||
gl_Position = vec4(pos, 1.0);
|
||||
texCoord = aTexCoord;
|
||||
norm = aNorm;
|
||||
}
|
||||
BIN
assets/shaders/terrain/terrain.vert.spv
Normal file
BIN
assets/shaders/terrain/terrain.vert.spv
Normal file
Binary file not shown.
BIN
assets/shaders/trace.frag.spv
Normal file
BIN
assets/shaders/trace.frag.spv
Normal file
Binary file not shown.
14
assets/shaders/utils/box/box.frag
Normal file
14
assets/shaders/utils/box/box.frag
Normal file
@ -0,0 +1,14 @@
|
||||
#version 460 core
|
||||
layout (location = 0) flat in uint id;
|
||||
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
};
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(0.0, 0.0, 1.0, 0.2);
|
||||
}
|
||||
42
assets/shaders/utils/box/box.geom
Normal file
42
assets/shaders/utils/box/box.geom
Normal file
@ -0,0 +1,42 @@
|
||||
#version 450 core
|
||||
|
||||
layout (points) in;
|
||||
layout (triangle_strip, max_vertices = 14) out;
|
||||
|
||||
layout (location = 0) in vec3 mins[];
|
||||
layout (location = 1) in vec3 maxes[];
|
||||
layout (location = 2) in uint id[];
|
||||
|
||||
layout (location = 0) out uint _id;
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
};
|
||||
|
||||
|
||||
void main(void) {
|
||||
int cube_vertices[14] = {
|
||||
0, 1, 2, 3, 7, 6, 5, 4, 0, 1, 5, 6, 2, 3
|
||||
};
|
||||
|
||||
for(int i = 0; i < gl_in.length(); i++) {
|
||||
vec3 vertices[] = {
|
||||
vec3(mins[i].x, mins[i].y, mins[i].z),
|
||||
vec3(mins[i].x, mins[i].y, maxes[i].z),
|
||||
vec3(mins[i].x, maxes[i].y, mins[i].z),
|
||||
vec3(mins[i].x, maxes[i].y, maxes[i].z),
|
||||
vec3(maxes[i].x, mins[i].y, mins[i].z),
|
||||
vec3(maxes[i].x, mins[i].y, maxes[i].z),
|
||||
vec3(maxes[i].x, maxes[i].y, mins[i].z),
|
||||
vec3(maxes[i].x, maxes[i].y, maxes[i].z),
|
||||
};
|
||||
|
||||
_id = id[i];
|
||||
for(int j = 0; j < 14; j++) {
|
||||
gl_Position = proj*view*vec4(vertices[cube_vertices[j]], 1.0);
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
}
|
||||
16
assets/shaders/utils/box/box.vert
Normal file
16
assets/shaders/utils/box/box.vert
Normal file
@ -0,0 +1,16 @@
|
||||
#version 460 core
|
||||
/* simple passthrough */
|
||||
|
||||
layout (location = 0) in vec3 aMins;
|
||||
layout (location = 1) in vec3 aMaxes;
|
||||
layout (location = 2) in uint aId;
|
||||
|
||||
layout (location = 0) out vec3 mins;
|
||||
layout (location = 1) out vec3 maxes;
|
||||
layout (location = 2) out uint id;
|
||||
|
||||
void main() {
|
||||
mins = aMins;
|
||||
maxes = aMaxes;
|
||||
id = aId;
|
||||
}
|
||||
BIN
assets/textures/heightmap.png
Normal file
BIN
assets/textures/heightmap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 MiB |
BIN
bsp_capture.png
Normal file
BIN
bsp_capture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 547 KiB |
61
flake.lock
generated
61
flake.lock
generated
@ -1,61 +0,0 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1743315132,
|
||||
"narHash": "sha256-6hl6L/tRnwubHcA4pfUUtk542wn2Om+D4UnDhlDW9BE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "52faf482a3889b7619003c0daec593a1912fddc1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
31
flake.nix
31
flake.nix
@ -1,31 +0,0 @@
|
||||
{
|
||||
description = "Flake for Vulkan and GLSLC Project";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = [
|
||||
pkgs.git
|
||||
pkgs.cmake
|
||||
pkgs.vulkan-loader
|
||||
pkgs.vulkan-headers
|
||||
pkgs.vulkan-tools
|
||||
pkgs.vulkan-validation-layers
|
||||
pkgs.shaderc
|
||||
pkgs.glfw3
|
||||
];
|
||||
shellHook = ''
|
||||
echo "Vulkan development environment loaded."
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -632,7 +632,7 @@ void ImGuiConsole::SettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHand
|
||||
#define INI_CONSOLE_SAVE_FLOAT(var) buf->appendf(#var"=%.3f\n", console->var)
|
||||
#define INI_CONSOLE_SAVE_BOOL(var) buf->appendf(#var"=%i\n", console->var)
|
||||
|
||||
// Set header for CONSOLE Console
|
||||
// Set header for CONSOLE Console.
|
||||
buf->appendf("[%s][%s]\n", handler->TypeName, console->m_ConsoleName.data());
|
||||
|
||||
// Window settings.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user