From ff771ba127bd3b3c86f92c1bafe5c1e33c54c32a Mon Sep 17 00:00:00 2001 From: connellpaxton Date: Mon, 19 Feb 2024 11:58:04 -0500 Subject: [PATCH] Dealing with incredibly annoying issue in rendering the BSPs --- Renderer/Renderer.cpp | 19 ++++++----- Renderer/Renderer.hpp | 2 ++ Scene/BSP.cpp | 63 ++++++++++++++++++++++++------------ Scene/BSP.hpp | 2 +- UI/UI.cpp | 3 +- UI/UI.hpp | 1 + assets/shaders/bsp.vert | 8 +---- assets/shaders/bsp.vert.spv | Bin 3500 -> 3244 bytes pléascach.cpp | 4 ++- 9 files changed, 63 insertions(+), 39 deletions(-) diff --git a/Renderer/Renderer.cpp b/Renderer/Renderer.cpp index 4e293dd..b2029a0 100644 --- a/Renderer/Renderer.cpp +++ b/Renderer/Renderer.cpp @@ -356,7 +356,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 */ @@ -381,24 +381,27 @@ void Renderer::draw() { uniform_buffer->upload(uni); - /* - command_buffer->bind(*terrain_pipeline); command_buffer->command_buffer.setViewport(0, viewport); command_buffer->command_buffer.setScissor(0, scissor); + /*if (line_mode) + command_buffer->command_buffer.setPolygonModeEXT(vk::PolygonMode::eLine); + else + command_buffer->command_buffer.setPolygonModeEXT(vk::PolygonMode::eFill);*/ + + /*command_buffer->bind(*terrain_pipeline); + command_buffer->bind(terrain_pipeline->layout, terrain_pipeline->desc_set); command_buffer->bind(terrain.get()); - command_buffer->command_buffer.drawIndexed(terrain->indices.size(), 1, 0, 0, 0); + command_buffer->command_buffer.drawIndexed(terrain->indices.size(), 1, 0, 0, 0);*/ - command_buffer->bind(*model_pipeline); + /*command_buffer->bind(*model_pipeline); command_buffer->bind(model_pipeline->layout, model_pipeline->desc_set); command_buffer->bind(models[0]); command_buffer->command_buffer.drawIndexed(models[0]->indices.size(), 10, 0, 0, 0);*/ - bsp->load_indices(cam.pos); + bsp->load_indices(cam.pos, visibility_testing); command_buffer->bind(bsp.get()); - command_buffer->command_buffer.setViewport(0, viewport); - command_buffer->command_buffer.setScissor(0, scissor); command_buffer->command_buffer.drawIndexed(bsp->indices.size(), 1, 0, 0, 0); /* draw User Interface stuff */ diff --git a/Renderer/Renderer.hpp b/Renderer/Renderer.hpp index 4d1ce0e..18fb324 100644 --- a/Renderer/Renderer.hpp +++ b/Renderer/Renderer.hpp @@ -77,6 +77,8 @@ struct Renderer { float speed = 1.0; bool running = true; + bool visibility_testing; + float tess_factor = 1.8f; float tess_edge_size = 20.0f; }; diff --git a/Scene/BSP.cpp b/Scene/BSP.cpp index 0c04ae8..e115544 100644 --- a/Scene/BSP.cpp +++ b/Scene/BSP.cpp @@ -23,32 +23,36 @@ static inline void copy_data(void* file_data, std::vector& dst, Lump& lump) { std::memcpy(dst.data(), ((u8*)file_data) + lump.offset, lump.len); } -void BSP::load_indices(const glm::vec3& cam_pos) { +void BSP::load_indices(const glm::vec3& cam_pos, bool visibility_test) { std::set present_faces; std::vector visible_faces; - auto leaf_idx = determine_leaf(cam_pos); - if (leaf_idx == last_leaf) - return; + if (visibility_test) { + auto leaf_idx = determine_leaf(cam_pos); + if (leaf_idx == last_leaf) + return; - last_leaf = leaf_idx; - auto& cam_leaf = leafs[leaf_idx]; + last_leaf = leaf_idx; + auto& cam_leaf = leafs[leaf_idx]; - std::vector visible_leafs; - for (auto& leaf : leafs) { - if (determine_visibility(cam_leaf.cluster_idx, leaf.cluster_idx)) - visible_leafs.push_back(leaf); - } - - for (const auto& leaf : visible_leafs) { - for (size_t i = 0; i < leaf.n_leaf_faces; i++) { - auto idx = leaf_faces[leaf.first_leaf_face_idx + i].face_idx; - if (present_faces.contains(idx)) - continue; - - present_faces.insert(idx); - visible_faces.push_back(faces[idx]); + std::vector visible_leafs; + for (auto& leaf : leafs) { + if (determine_visibility(cam_leaf.cluster_idx, leaf.cluster_idx)) + visible_leafs.push_back(leaf); } + + for (const auto& leaf : visible_leafs) { + for (size_t i = 0; i < leaf.n_leaf_faces; i++) { + auto idx = leaf_faces[leaf.first_leaf_face_idx + i].face_idx; + if (present_faces.contains(idx)) + continue; + + present_faces.insert(idx); + visible_faces.push_back(faces[idx]); + } + } + } else { + visible_faces = faces; } for (auto& face : visible_faces) { @@ -99,6 +103,13 @@ bool BSP::determine_visibility(int vis, int cluster) { return !!(set & (1 << (cluster & 0x7))); } +/* changes handedness by swapping z and y */ +static inline void change_swizzle(glm::vec3& v) { + auto tmp = v.y; + v.y = v.z; + v.z = tmp; +} + BSP::BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname) : dev(dev), filename(fname) { file_data = file::slurpb(fname); Log::debug("File size: %zu\n", file_data.size()); @@ -113,6 +124,10 @@ BSP::BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname) copy_data(file_data.data(), entities, header->entities); copy_data(file_data.data(), textures, header->textures); copy_data(file_data.data(), planes, header->planes); + /* change swizzle */ + for (auto& plane : planes) { + change_swizzle(plane.norm); + } 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); @@ -121,6 +136,12 @@ BSP::BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname) 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); + /* correct for handedness */ + for (auto& vertex : vertices) { + change_swizzle(vertex.pos); + change_swizzle(vertex.norm); + } + 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); @@ -136,7 +157,7 @@ BSP::BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname) vertex_buffer->upload(vertices); /* set limit at 256Mi indices */ - index_buffer = std::make_unique(phys_dev, dev, 0x1000000 * sizeof(u32), + index_buffer = std::make_unique(phys_dev, dev, 0x10000000 * sizeof(u32), vk::BufferUsageFlagBits::eIndexBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible ); } \ No newline at end of file diff --git a/Scene/BSP.hpp b/Scene/BSP.hpp index 2541b67..dbc55df 100644 --- a/Scene/BSP.hpp +++ b/Scene/BSP.hpp @@ -207,7 +207,7 @@ namespace Q3BSP { struct BSP { BSP(vk::PhysicalDevice phys_dev, vk::Device dev, const std::string& fname); - void load_indices(const glm::vec3& cam_pos); + void load_indices(const glm::vec3& cam_pos, bool visibility_testing); int determine_leaf(glm::vec3 cam_pos); bool determine_visibility(int vis, int cluster); diff --git a/UI/UI.cpp b/UI/UI.cpp index 922f228..b5e5e63 100644 --- a/UI/UI.cpp +++ b/UI/UI.cpp @@ -11,7 +11,7 @@ #include -UI::UI(Renderer* ren) : info{ .flycam = ren->flycam, .time = ren->time, .cam = ren->cam, .tess_factor = ren->tess_factor, .tess_edge_size = ren->tess_edge_size }, dev(ren->dev) { +UI::UI(Renderer* ren) : info{ .flycam = ren->flycam, .visibility_testing = ren->visibility_testing, .time = ren->time, .cam = ren->cam, .tess_factor = ren->tess_factor, .tess_edge_size = ren->tess_edge_size }, dev(ren->dev) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -92,6 +92,7 @@ void UI::newFrame() { ImGui::Text("FPS: %f", info.fps); ImGui::Text("Time: %f", info.time); ImGui::Checkbox("Fly Camera", &info.flycam); + ImGui::Checkbox("Visibility Testing", &info.visibility_testing); ImGui::SliderFloat("Tessellation Factor", &info.tess_factor, 0.1, 10.0); ImGui::SliderFloat("Edge Size", &info.tess_edge_size, 0.0, 40.0); diff --git a/UI/UI.hpp b/UI/UI.hpp index af2683f..708f38e 100644 --- a/UI/UI.hpp +++ b/UI/UI.hpp @@ -12,6 +12,7 @@ struct UI { struct UI_Info { float fps = 0.0; bool& flycam; + bool& visibility_testing; float& time; /* camera stuff */ Camera& cam; diff --git a/assets/shaders/bsp.vert b/assets/shaders/bsp.vert index 4f93195..0180762 100644 --- a/assets/shaders/bsp.vert +++ b/assets/shaders/bsp.vert @@ -32,14 +32,8 @@ vec4 unpackABGR(uint packedABGR) { void main() { - mat4 zup_to_yup = mat4( - 1.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - ); - gl_Position = proj * view * zup_to_yup * vec4(aPos, 1.0); + gl_Position = proj * view * vec4(aPos, 1.0); texCoord = aTexCoord; norm = aNorm; color = unpackABGR(aColor); diff --git a/assets/shaders/bsp.vert.spv b/assets/shaders/bsp.vert.spv index ff4549c1cb9628385ae0fceb00078215a7b50e49..20490d73700ee23494645ace27e675e834997763 100644 GIT binary patch literal 3244 zcmZQ(Qf6mhU}WHC;AO~QfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!Nvtmz>v(qz>vCH9jXZFEu_TvnVyWB(p3Pq>ckg zU1nZ#PH76V0#*hV24r`zGO#i5FfcHb<`pC+XFEE%2WgZVS~D=PGO#jmGcYiKL{n2h z;vg{=27U$xhT`PJoKyx7pP4}r>Sk63W(H{n28JZ4xH8laAaQL528JTAI2(f%NIWM# zAhjqgwWuVu0u&Z(3=nY;J3S{pAip@XBr`vcfsKJ3tR583VDZenlHklLkkxQGQ23L!R@kiE%?x$y=0#SAdLpfCrCrDPVt#aI~_ z7}APLi%Uv#89-qGvX_m4fdOQ1L4HvQ#2z-Vd)OHm7)nx$i{sN0lS}eJX0U_BIbhOgJ=iA_Kf1Gyh0wg5>CWFJUu1CkiXKOivyMv$K%c7W^ziAf-dfzk#@ zOoowx0TeDEzk=KX3KvlNPy%_F0VK!50OBhm@j+#i91?e&N-H2f zNDD|FRF;AGAb*1RptJ(w!|Vr@aUed(&mehF+5quE^1=*E;Brq9TmmwH*`f?A;CNI3 zS-`-+puoVw0P-^kgTh0Mftdm1Uy!^w0}BHu0|S^3GG7r~dNP2;Kb>7$D}!Ft9LKLgheWa?tV*=4Ox_2!q^d4Xy_mz-ii=frSCY2bEu-a0QtQveyhz7X>ls`cBg2X`TouKML@gT>*4bCqhGeMYx zfq?;J9teZB9X_l3%V%m?WQ z@j>Yjl;%MCLG}cI{n}s;QXd8l8<6`!{0Jx?I}evo+}_khwhNIi%TvLBSLLGmE|pt=tv2MSw|JctiU=O8fj_mq2FxU|?bZ<#&);P}&5QpCH~dU=U?sU;v4M%A?~@F>wZnxEQF-1})D(Wfe#qWDY3rNHQ>h+i$JVIF^EzXCQHq zy&yM(#6apn;U|M;FQ|M5iGj*Fn7#503=AM~WP3qnFi0F^4#-|my#n$R%wABv15yJL z2iXe>8;}@CJ;+`aG<($;7#Kiepz;)EuQ~$*14ta%UJV8Y29P+&9FV=5X#Uk=U|;~L z0f~d`1;qhK45S`puMX5+m>s$d3=AMKWIOa27#Kj}AUz;E^wI19HU2?rK;j@fK=BF^ zgQ+(J*B1;7FuoB30|Uq%FupMZ1GpUxqz|MPB>#_ri2)=I GO1A*darzMe literal 3500 zcmZQ(Qf6mhU}WHC;AJRcfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!Nv(qz>vzoz>vYfz>vwnz>p16!@$5$$iTqB%)rdR z#K6FChLM4Rg@KE~-6!7N-{0NGH9onZAilVyGAA`YCo?ZKJ|(j#HMu0SEES}V14&(G zUUE)p3bF!L1{MZncd#-CHe7{r3D~;Yz!_SwK?$tsYPL_MJ1^fpzvX1fQW9?%1x5K;$YLP-OEPnzZi46q*_)i0 z8()xL%mC91iU*KbN@fvUjFo|bA+4yixTG|f0Tc!xd)XKm7(n(G|q1Dhn<0e zp(M4qI6f^gxg;NC20K`s116rDlAao03=SQTAN@d@!EwR@PJ4*~`C$Kn{0vHmC8-t8 z`T0dDAY~vikOvY&5Q3nz14^fP`9--9H7wvXo9G7-0Lg>WZ*qQ4J}94n_#lOe&JY0* zAC&kD5{nW+;-It#O6NJ5=@})ti3KprJs4QQaSXBplmATbaP69a`eNDLIl zFfkAtBnAp&cLrv#c_4M}3@i*@3=9mQFcn~6VDMmI0f!mL4p7*G^n=12#0RBe5REJb z3Ug$AAa@|^1Mxxn9KdEn;vOW1&<7C%xdo)I0ZARm%^{$dTR`CgN*_uf4>N$|SQtQjMI=6` zypluWgVGF$5Aq*KKPbH*^Fe6^#0O~s$%D!_5Fg}E5FeCQKzx|}pfmyEgZvDV2c-=V zA0#i#zyvM}6~Uz<1DGw!zygj(1&{>{3=9ekEDRt&gD@yO#2Ah{Ei!-n=a56A} z`5^NZ!6hmKSPY~dq!(05gV-QF+6*jUwV=3eY-q3s*(D6N15^_*Fo5Jid=Ul)1_=fT zA7Up1!+$6rBrnUrzyLA>rd}251_=fh1`7s={UG;%?6+iK0J|R~4pI+thc(!54fZg; z4Vcfspu@lpcDpSD0|Q76NF0V?a&`<13@|a68kn3tR1PK%QU{X*rCksohCymTav*m( zGB7ZJ>;#z&G6SR*j}-zAbUZ18)Oei45Z#0sveYv4T{SiG$qc%K%AdpgaO{8;B3e6Ckr-Zu5uw8Kgb{svcxEh#vu!1DOxf z58{LJ5GcQZL3&~GAU-J1fy6-ap!yc1 z7G@ua56XieF_3v6`$2gSq#ncv*$>KtAbF7f9H@IiVG5E5@j-bKrXFM;C{Kd;W(=(0 zJP1m=py&aa@q>Yh0aP}D^n%hdsICX)ClDV*gUWsoZO6dO0FncxB}WEU22i*KGBAM4 z8&G)KLi0ut0|Ns{9Hu51ss@xEU}{1b7#Kj}lNeaR`6-lvfdQlsBo0#(#=ro!52hxZ zfq?;}4kQjz0}8JwXnQP>ffbzZqZt?&Kw==j!Ng*qVj%y+#A2ahpfnKx&69Bq3=AOs zAoU=5Q2v?7zzWW<@eB+MAp1dTK>h;70jT{1O7kFpfx-sF2dM+O4HVaD&^97S4wN21 ze2^T--JpgCC{96gptuI{L2{rt%!jrmL2{t52k|YT?kHej0Jr-<;vjiYIsl3NWng5m zU|?hb#V;sbg4%|lFyLZfU@&K32A5BudKDDcyx_8j1>Cv?wF^OU3yNz{ISOhQBJ)9Q zLu5Xv4npRG+K3=N$SokVKxHP(A41@EHUq;U22hKEfkBjkfdM22DtnJZ#l#sP;$omS zE41temCGP;kU5|{Ey=(DZojrd<5&t>c7w!0_JZ6D5(B9Rg`W(Xy`Z`XBnB$eVfM;1 zFff3`k?jT5Hz0A4IUsvMbtuSBFnd9DEJzJV9AqyjY(Qcl^&opy(Ck%XU|;}=f$9#J zz3L1M3?Ol2do>ss7(n76b3pcLqWM>gfq?;}1|$x$7Ze8|F_3zYy*f~PVRq;;fa)0r z24p+*7#J8p;vhXBJM_`)0Cj#qYCz&3J3#RY5`(EX1lNtAIs{U`8Zj_1fZPF-H)db} l_ak6@69xuw9|M-ROc@v$KxTmSfz*QJ|1mHzfW$%R765)!5xM{X diff --git a/pléascach.cpp b/pléascach.cpp index e034535..218011f 100644 --- a/pléascach.cpp +++ b/pléascach.cpp @@ -28,7 +28,7 @@ int main(int argc, char* argv[]) { while (in->queue.size()) { /* take event from front of queue, then process it */ - const auto event = in->queue.front(); + const InputEvent event = in->queue.front(); in->queue.pop(); switch (event.tag) { case InputEvent::Tag::eRESIZE: @@ -71,6 +71,8 @@ int main(int argc, char* argv[]) { ren.speed *= 10.0; } else if (event.key.key == GLFW_KEY_Y && event.key.state == GLFW_PRESS) { ren.speed /= 10.0; + } else if (event.key.key == GLFW_KEY_V && event.key.state == GLFW_PRESS) { + ren.visibility_testing = !ren.visibility_testing; } break; }