diff --git a/README.md b/README.md index 24b91de..771e8b6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Pléascach ###### Check out the raymarching branch (pléascach-dronuilleog)! + Small Vulkan 3D renderer. ![really cool wireframe tessellated terrain)](capture.png "Terrain Capture") ## Features diff --git a/Renderer/Renderer.cpp b/Renderer/Renderer.cpp index bc8a47a..56b4102 100644 --- a/Renderer/Renderer.cpp +++ b/Renderer/Renderer.cpp @@ -222,7 +222,6 @@ Renderer::Renderer(Window& win) : win(win) { pipeline->update(0, *uniform_buffer); pipeline->update(1, textures[1]); - /* create Terrain */ terrain = std::make_unique(phys_dev, dev, textures[1]); @@ -364,6 +363,11 @@ void Renderer::draw() { command_buffer->bind(terrain.get()); command_buffer->command_buffer.drawIndexed(terrain->indices.size(), 1, 0, 0, 0); + command_buffer->bind(*pipeline); + command_buffer->bind(pipeline->layout, pipeline->desc_set); + command_buffer->bind(models[0]); + command_buffer->command_buffer.drawIndexed(models[0]->indices.size(), 10, 0, 0, 0); + /* draw User Interface stuff */ ui->newFrame(); diff --git a/Scene/BSP.cpp b/Scene/BSP.cpp new file mode 100644 index 0000000..0f00088 --- /dev/null +++ b/Scene/BSP.cpp @@ -0,0 +1,62 @@ +#include + +#include +#include + +#include + +using namespace Q3BSP; + +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 +static inline void copy_data(void* file_data, std::vector& dst, Lump& lump) { + Log::debug("Size: %zu (%zu)\n", lump.len/sizeof(T), lump.len); + dst.resize(lump.len / sizeof(T)); + puts("ALLOC'D"); + //Log::debug("%p %p\n", dst.data(), (u8*)file_data + lump.offset); + std::memcpy(dst.data(), ((u8*)file_data) + lump.offset, lump.len); +} + +BSP::BSP(const std::string& fname) : filename(fname) { + file_data = file::slurpb(fname); + Log::debug("File size: %zu\n", file_data.size()); + header = reinterpret_cast(file_data.data()); + + Log::info("Loading BSP: %s\n", fname.c_str()); + + if(header->magic != BSP_MAGIC) { + Log::error("BSP file missing magic!\n"); + } + + for (size_t i = 0; i < std::size(header->lumps); i++) { + Log::debug("%i: Offset: %u | Length: %u\n", i, header->lumps[i].offset, header->lumps[i].len); + Log::debug("\tPointer: 0x%p\n", (u8*)file_data.data() + (size_t)header->lumps[i].offset); + } + + copy_data(file_data.data(), entities, header->entities); + copy_data(file_data.data(), textures, header->textures); + copy_data(file_data.data(), planes, header->planes); + copy_data(file_data.data(), nodes, header->nodes); + copy_data(file_data.data(), leafs, header->leafs); + copy_data(file_data.data(), leaf_faces, header->leaf_faces); + copy_data(file_data.data(), leaf_brushes, header->leaf_brushes); + copy_data(file_data.data(), models, header->models); + copy_data(file_data.data(), brushes, header->brushes); + copy_data(file_data.data(), brush_sides, header->brush_sides); + copy_data(file_data.data(), vertices, header->vertices); + copy_data(file_data.data(), mesh_vertices, header->mesh_vertices); + copy_data(file_data.data(), effects, header->effects); + copy_data(file_data.data(), faces, header->faces); + copy_data(file_data.data(), lightmaps, header->lightmaps); + copy_data(file_data.data(), lightvols, header->lightvols); + + vis_info.sz_vectors = reinterpret_cast(file_data.data() + header->vis_info.offset)[1]; + auto sz = header->vis_info.len; + Log::debug("Size: %u\n", sz); + vis_info.vectors.resize(sz); + std::memcpy(vis_info.vectors.data(), file_data.data() + header->vis_info.offset + 2*sizeof(u32), sz); +} \ No newline at end of file diff --git a/Scene/BSP.hpp b/Scene/BSP.hpp new file mode 100644 index 0000000..7595592 --- /dev/null +++ b/Scene/BSP.hpp @@ -0,0 +1,194 @@ +#pragma once + +#include +#include + +#include +#include + +/* contains loading functions for Quake III-style BSPs */ +namespace Q3BSP { + struct Lump { + u32 offset; + u32 len; + }; + using rgb = glm::u8vec3; + using rgba = glm::u8vec4; + + /* "IBSP" */ + const uint32_t BSP_MAGIC = 0x50534249U; + struct Header { + u32 magic; + u32 version; + + union { + Lump lumps[17]; + struct { + Lump entities, + textures, + planes, + nodes, + leafs, + leaf_faces, + leaf_brushes, + models, + brushes, + brush_sides, + vertices, + mesh_vertices, + effects, + faces, + lightmaps, + lightvols, + vis_info; + }; + }; + }; + + struct Texture { + char name[64]; + /* values of unknown meaning - TODO: check darkplaces or some other 3rd party loader */ + i32 flags; + i32 contents; + }; + + struct Plane { + glm::vec3 norm; + float dist; + }; + + struct Node { + u32 plane; + /* negative numbers are leaf indices */ + i32 children[2]; + + /* bounding box coords (integer) */ + glm::ivec3 bb_mins; + glm::ivec3 bb_maxes; + }; + + struct Leaf { + i32 cluster_idx; + u32 area; + glm::ivec3 bb_mins; + glm::ivec3 bb_maxes; + i32 first_leaf_face_idx; + u32 n_leaf_faces; + i32 first_leaf_brush_idx; + u32 n_leaf_brushes; + }; + + + struct LeafFaces { + /* list of face indices (one list per leaf) */ + i32 face_idx; + }; + + struct LeafBrush { + /* list of brush indices (one list leaf) */ + i32 brush_idx; + }; + + struct Model { + glm::vec3 bb_mins; + glm::vec3 bb_maxes; + i32 first_face_idx; + u32 n_faces; + i32 first_brush_idx; + u32 n_brushes; + }; + + struct Brush { + i32 first_brushside_idx; + u32 n_brushsides; + i32 texture_idx; + }; + + struct BrushSide { + i32 plane_idx; + i32 texture_idx; + }; + + struct Vertex { + glm::vec3 position; + glm::vec2 tex_coords; + glm::vec2 lightmap_coords; + glm::vec3 normal; + glm::u8vec4 color; + }; + + struct MeshVertex { + i32 idx; + }; + + struct Effect { + char name[64]; + i32 brush_idx; + /* almost always 5 for some reason */ + i32 unknown; + }; + + struct Face { + i32 texture_idx; + /* -1 if no effect */ + i32 effect_idx; + enum FaceType { + ePOLYGON = 1, + ePATCH = 2, + eMESH = 3, + eBILLBOARD = 4, + } type; + i32 first_vertex_idx; + u32 n_vertices; + i32 first_mesh_vertex_idx; + u32 n_mesh_vertices; + i32 lightmap_idx; + glm::vec2 lightmap_start; + glm::vec2 lightmap_end; + + glm::vec3 lightmap_origin; + glm::vec3 lightmap_unit_vectors[2]; + glm::vec3 norm; + glm::ivec2 patch_dimensions; + }; + + struct Lightmap { + u8 map[128][128][3]; + }; + + struct Lightvol { + rgb ambient; + rgb directional; + /* spherical coordinates */ + glm::u8vec2 direction; + }; + + struct VisibilityInfo { + u32 sz_vectors; + std::vector vectors; + }; + + struct BSP { + Header* header; + BSP(const std::string& fname); + std::string filename; + std::vector file_data; + std::string entities; + std::vector textures; + std::vector planes; + std::vector nodes; + std::vector leafs; + std::vector leaf_brushes; + std::vector leaf_faces; + std::vector models; + std::vector brushes; + std::vector brush_sides; + std::vector vertices; + std::vector mesh_vertices; + std::vector effects; + std::vector faces; + std::vector lightmaps; + std::vector lightvols; + VisibilityInfo vis_info; + }; +} \ No newline at end of file diff --git a/Scene/Terrain.cpp b/Scene/Terrain.cpp index 8895be7..052cb91 100644 --- a/Scene/Terrain.cpp +++ b/Scene/Terrain.cpp @@ -3,7 +3,6 @@ #include - float Terrain::getHeight(int32_t x, int32_t y) { if (x < 0) x += 64; @@ -20,7 +19,7 @@ float Terrain::getHeight(int32_t x, int32_t y) { yf /= 64.0; yf *= heightmap_tex->extent.height; - return static_cast(heightmap_tex->image_data[static_cast(static_cast(yf) * heightmap_tex->extent.width + xf) * 4]) / 256.0f; + return static_cast(heightmap_tex->image_data[static_cast(static_cast(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) { @@ -70,20 +69,26 @@ Terrain::Terrain(vk::PhysicalDevice phys_dev, vk::Device dev, Texture& tex) : ph { 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 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)); + //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 = glm::normalize(normal * glm::vec3(2.0f, 1.0f, 2.0f)); + vertices[x + y * patch_size].norm = normal; } vertex_buffer = std::make_unique(phys_dev, dev, vertices.size()); diff --git a/assets/shaders/explode.geom b/assets/shaders/explode.geom index a9291ad..e59d442 100644 --- a/assets/shaders/explode.geom +++ b/assets/shaders/explode.geom @@ -11,8 +11,15 @@ layout (location = 0) out vec3 _norm; layout (location = 1) out vec2 _texCoord; layout (set = 0, binding = 0) uniform Matrices { - mat4 mvp; + 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) { @@ -24,7 +31,7 @@ vec4 explode(vec4 pos, vec3 n) { void main(void) { if (time < 3.0) { for(int i = 0; i < gl_in.length(); i++) { - gl_Position = mvp * gl_in[i].gl_Position; + gl_Position = proj * view * gl_in[i].gl_Position; _norm = norm[i]; _texCoord = texCoord[i]; EmitVertex(); @@ -35,7 +42,7 @@ void main(void) { vec3 n = norm[0] + norm[1] + norm[2]; n/=3; for(int i = 0; i < gl_in.length(); i++) { - gl_Position = mvp * explode(gl_in[i].gl_Position, n); + gl_Position = proj * view * explode(gl_in[i].gl_Position, n); _texCoord = texCoord[i]; _norm = n; EmitVertex(); diff --git a/assets/shaders/explode.geom.spv b/assets/shaders/explode.geom.spv index 2f5eb55..d6543ea 100644 Binary files a/assets/shaders/explode.geom.spv and b/assets/shaders/explode.geom.spv differ diff --git a/assets/shaders/fraglight.geom b/assets/shaders/fraglight.geom index 2a304a3..676dd93 100644 --- a/assets/shaders/fraglight.geom +++ b/assets/shaders/fraglight.geom @@ -13,14 +13,21 @@ layout (location = 1) out vec2 _texCoord; layout (location = 2) out vec3 _pos; layout (set = 0, binding = 0) uniform Matrices { - mat4 mvp; + 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 = mvp * gl_in[i].gl_Position; + gl_Position = proj * view * gl_in[i].gl_Position; _norm = norm[i]; _texCoord = texCoord[i]; _pos = pos[i]; diff --git a/assets/shaders/fraglight.geom.spv b/assets/shaders/fraglight.geom.spv index d212b9e..12a95a4 100644 Binary files a/assets/shaders/fraglight.geom.spv and b/assets/shaders/fraglight.geom.spv differ diff --git a/assets/shaders/fraglight.vert b/assets/shaders/fraglight.vert index 4e94796..3b3dc62 100644 --- a/assets/shaders/fraglight.vert +++ b/assets/shaders/fraglight.vert @@ -8,8 +8,15 @@ layout (location = 1) out vec2 texCoord; layout (location = 2) out vec3 pos; layout (set = 0, binding = 0) uniform Matrices { - mat4 mvp; + 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() { diff --git a/assets/shaders/fraglight.vert.spv b/assets/shaders/fraglight.vert.spv index 2b08c4a..aaafbc1 100644 Binary files a/assets/shaders/fraglight.vert.spv and b/assets/shaders/fraglight.vert.spv differ diff --git a/assets/shaders/gol.geom b/assets/shaders/gol.geom index 890f2a5..6dd178a 100644 --- a/assets/shaders/gol.geom +++ b/assets/shaders/gol.geom @@ -11,8 +11,15 @@ layout (location = 0) out vec3 _norm; layout (location = 1) out vec2 _texCoord; layout (set = 0, binding = 0) uniform Matrices { - mat4 mvp; + 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) { @@ -26,7 +33,7 @@ void main(void) { if (time < 3.0) { for(int i = 0; i < gl_in.length(); i++) { - gl_Position = mvp * gl_in[i].gl_Position; + gl_Position = proj * view * gl_in[i].gl_Position; _norm = norm[i]; _texCoord = texCoord[i]; EmitVertex(); @@ -35,7 +42,7 @@ void main(void) { vec3 n = norm[0] + norm[1] + norm[2]; n/=3; for(int i = 0; i < gl_in.length(); i++) { - gl_Position = mvp * explode(gl_in[i].gl_Position*abs(cos(time)), n); + gl_Position = proj * view * explode(gl_in[i].gl_Position*abs(cos(time)), n); _texCoord = texCoord[i]; _norm = n; EmitVertex(); diff --git a/assets/shaders/gol.geom.spv b/assets/shaders/gol.geom.spv index af5672d..0818235 100644 Binary files a/assets/shaders/gol.geom.spv and b/assets/shaders/gol.geom.spv differ diff --git a/assets/shaders/terrain.tese b/assets/shaders/terrain.tese index cda3c84..deddd35 100644 --- a/assets/shaders/terrain.tese +++ b/assets/shaders/terrain.tese @@ -42,7 +42,7 @@ void main() { 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; + fpos.y = 15.0 * texture(heightmap, _texCoord).r; _pos = fpos.xyz; gl_Position = proj * view * fpos; diff --git a/assets/shaders/terrain.tese.spv b/assets/shaders/terrain.tese.spv index 3dca697..053dc85 100644 Binary files a/assets/shaders/terrain.tese.spv and b/assets/shaders/terrain.tese.spv differ