From b6cf6c08c3414f7f9b4f84bd48b66f7a1215deb5 Mon Sep 17 00:00:00 2001 From: connellpaxton Date: Wed, 31 Jan 2024 16:44:45 -0500 Subject: [PATCH] Created working geometry shader --- CMakeLists.txt | 1 + Input/Input.cpp | 6 ++++- Renderer/Pipeline.cpp | 2 +- Renderer/Renderer.cpp | 20 ++++++++++----- Renderer/Renderer.hpp | 1 + UI/UI.cpp | 4 ++- UI/UI.hpp | 1 + Window/Window.cpp | 1 - Window/Window.hpp | 8 +++--- assets/shaders/basic.frag | 4 +-- assets/shaders/basic.frag.spv | Bin 1104 -> 972 bytes assets/shaders/basic.vert | 3 ++- assets/shaders/basic.vert.spv | Bin 1556 -> 1484 bytes assets/shaders/explode.geom | 44 ++++++++++++++++++++++++++++++++ assets/shaders/explode.geom.spv | Bin 0 -> 3908 bytes pléascach.cpp | 23 ++++++++++++++++- util/Timer.hpp | 1 + 17 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 assets/shaders/explode.geom create mode 100644 assets/shaders/explode.geom.spv diff --git a/CMakeLists.txt b/CMakeLists.txt index d70c85e..9f0a232 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ add_executable (pleascach ${SOURCES}) file(GLOB SHADER_SOURCE_FILES assets/shaders/*.frag assets/shaders/*.vert + assets/shaders/*.geom ) foreach(SHADER_SOURCE ${SHADER_SOURCE_FILES}) diff --git a/Input/Input.cpp b/Input/Input.cpp index 6136f43..1e8e5d8 100644 --- a/Input/Input.cpp +++ b/Input/Input.cpp @@ -77,7 +77,11 @@ void Input::handleMovementKeys(Renderer& ren) { if (ImGui::GetIO().WantCaptureKeyboard) return; - const auto forward = glm::vec3(glm::cos(ren.cam.phi), 0.0, glm::sin(ren.cam.phi)); + glm::vec3 forward; + if (ren.flycam) + forward = 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::vec3(glm::cos(ren.cam.phi), 0.0, glm::sin(ren.cam.phi)); const auto right = glm::cross(forward, glm::vec3(0.0, 1.0, 0.0)); const auto speed = glfwGetKey(in, GLFW_KEY_LEFT_SHIFT)? 2.0f : 1.0f; diff --git a/Renderer/Pipeline.cpp b/Renderer/Pipeline.cpp index 33db072..d37e8f0 100644 --- a/Renderer/Pipeline.cpp +++ b/Renderer/Pipeline.cpp @@ -83,7 +83,7 @@ GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector& sh const auto raster_info = vk::PipelineRasterizationStateCreateInfo { .depthClampEnable = vk::False, .polygonMode = vk::PolygonMode::eFill, - .cullMode = vk::CullModeFlagBits::eBack, + .cullMode = vk::CullModeFlagBits::eNone, .frontFace = vk::FrontFace::eCounterClockwise, .depthBiasEnable = vk::False, .lineWidth = 1.0, diff --git a/Renderer/Renderer.cpp b/Renderer/Renderer.cpp index 9eab03b..466c164 100644 --- a/Renderer/Renderer.cpp +++ b/Renderer/Renderer.cpp @@ -122,10 +122,10 @@ Renderer::Renderer(Window& win) : win(win) { .pQueuePriorities = priorities, }; - /* enumerate available device features */ std::vector req_dev_extensions; req_dev_extensions.push_back("VK_KHR_swapchain"); req_dev_extensions.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); + auto dev_extentions = phys_dev.enumerateDeviceExtensionProperties(); Log::info("%zu available device extensions\n", dev_extentions.size()); for (const auto& ext : dev_extentions) { @@ -141,7 +141,11 @@ Renderer::Renderer(Window& win) : win(win) { "VK_LAYER_KHRONOS_validation" }; - auto dev_info = vk::DeviceCreateInfo{ + const auto features = vk::PhysicalDeviceFeatures { + .geometryShader = vk::True, + }; + + auto dev_info = vk::DeviceCreateInfo { .flags = vk::DeviceCreateFlagBits(0), .queueCreateInfoCount = 1, .pQueueCreateInfos = &queue_info, @@ -149,6 +153,7 @@ Renderer::Renderer(Window& win) : win(win) { .ppEnabledLayerNames = dev_layer_names.data(), .enabledExtensionCount = static_cast(req_dev_extensions.size()), .ppEnabledExtensionNames = req_dev_extensions.data(), + .pEnabledFeatures = &features, }; dev = phys_dev.createDevice(dev_info); @@ -181,6 +186,7 @@ Renderer::Renderer(Window& win) : win(win) { std::vector shaders = { { dev, "assets/shaders/basic.vert.spv", vk::ShaderStageFlagBits::eVertex }, + { dev, "assets/shaders/explode.geom.spv", vk::ShaderStageFlagBits::eGeometry }, { dev, "assets/shaders/basic.frag.spv", vk::ShaderStageFlagBits::eFragment }, }; @@ -191,17 +197,19 @@ Renderer::Renderer(Window& win) : win(win) { /* initialize models */ // models.push_back(std::make_shared(phys_dev, dev, "assets/models/dragon.gltf")); + Timer model_timer; models.push_back(std::make_shared(phys_dev, dev, "assets/models/dragon.gltf")); + auto t = model_timer.stop(); - Log::debug("#%zu vertex indices\n", models[0]->indices.size()); + Log::debug("Models loaded in %lf milliseconds\n", model_timer.read()); pipeline = std::make_unique(dev, shaders, swapchain->extent, *render_pass, bindings, *models[0]->vertex_buffer); pipeline->update(0, *uniform_buffer); pipeline->update(1, textures[0]); - shaders[0].cleanup(); - shaders[1].cleanup(); + for (auto& shader : shaders) + shader.cleanup(); ui = std::make_unique(this); } @@ -263,7 +271,7 @@ void Renderer::draw() { command_buffer->begin(); vk::ClearValue clear_values[] = { - vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f), + vk::ClearColorValue(1.0f, 1.0f, 1.0f, 1.0f), vk::ClearDepthStencilValue {.depth = 1.0f} }; diff --git a/Renderer/Renderer.hpp b/Renderer/Renderer.hpp index bdada14..78d4a13 100644 --- a/Renderer/Renderer.hpp +++ b/Renderer/Renderer.hpp @@ -63,4 +63,5 @@ struct Renderer { Camera cam {}; bool capture_mouse = false; + bool flycam = false; }; diff --git a/UI/UI.cpp b/UI/UI.cpp index 342cc4f..6bf1943 100644 --- a/UI/UI.cpp +++ b/UI/UI.cpp @@ -11,7 +11,7 @@ #include -UI::UI(Renderer* ren) : info{ .cam = ren->cam }, dev(ren->dev) { +UI::UI(Renderer* ren) : info{ .flycam = ren->flycam, .cam = ren->cam }, dev(ren->dev) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -90,6 +90,8 @@ void UI::newFrame() { ImGui::Begin("Rendering Info", nullptr); ImGui::Text("FPS: %f", info.fps); + ImGui::Checkbox("Fly Camera", &info.flycam); + ImGui::Text("Fly Camera mode: %b"); ImGui::SliderAngle("Theta", &info.cam.theta, 0.01, 179.9); ImGui::SliderAngle("Phi", &info.cam.phi, 0.0, 360.0, "%.0f def"); ImGui::SliderFloat("cam.x", &info.cam.pos.x, -1e2, 1e2); diff --git a/UI/UI.hpp b/UI/UI.hpp index a4fa466..c334c91 100644 --- a/UI/UI.hpp +++ b/UI/UI.hpp @@ -11,6 +11,7 @@ struct Camera; struct UI { struct UI_Info { float fps = 0.0; + bool& flycam; /* camera stuff */ Camera& cam; } info; diff --git a/Window/Window.cpp b/Window/Window.cpp index b71f9cd..b55aa82 100644 --- a/Window/Window.cpp +++ b/Window/Window.cpp @@ -2,7 +2,6 @@ #include -#define WINDOW_PTR GLFWwindow* #define INPUT_PTR GLFWwindow* #include #include diff --git a/Window/Window.hpp b/Window/Window.hpp index 5e51d6d..07b5b69 100644 --- a/Window/Window.hpp +++ b/Window/Window.hpp @@ -9,13 +9,11 @@ #include -#ifndef WINDOW_PTR -#define WINDOW_PTR void* -#endif - #define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS #include +#include + /* * Window class - abstracts away implementation/platform-specific realities of window * @@ -37,7 +35,7 @@ struct Window { vk::SurfaceKHR getSurface(vk::Instance& inst); std::unique_ptr getInput(); - WINDOW_PTR win = nullptr; + GLFWwindow* win = nullptr; private: u32 width, height; diff --git a/assets/shaders/basic.frag b/assets/shaders/basic.frag index f5f1c3b..1e64096 100644 --- a/assets/shaders/basic.frag +++ b/assets/shaders/basic.frag @@ -12,7 +12,5 @@ layout (set = 0, binding = 0) uniform Matrices { layout (set = 0, binding = 1) uniform sampler2D tex; void main() { - //FragColor = vec4(1.0); - FragColor = texture(tex, texCoord) * vec4(norm, 1.0); -// FragColor = vec4(texCoord, 0.0, 1.0); + FragColor = vec4(0.0, 0.0, 0.0, 1.0); } \ No newline at end of file diff --git a/assets/shaders/basic.frag.spv b/assets/shaders/basic.frag.spv index 671f15ac01509b6ff61400855c18936b825075da..24651e1c346b8581561e2d362d514ca26daf601b 100644 GIT binary patch literal 972 zcmZQ(Qf6mhU}WHC;AN0zfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N*wB3=CkLo0ypglHg=uVBlw9U=U(pU=Uzn2FtNCFfcGPFf%YQFfg291gYm@aQBIK z_xE@Aag9$dD2OjEsmw`@&&kY7jZeueN=+`wEK3Ec<3LiEnU|bXnu4r=m4O9pKFn@b z237`;{cc5x>CX8%`9%y23?MZi_vGal<$~M?QUh{ZNos|2etuC3OiYAVc-DAH3L}O8p;R72`JTQGq8a5azX8f@wvhL274U_cCbDk1_lO@8W;x2 zgY4pEU;yg}nFX?oj{%f=85ls~AiF?(P&k9!4pI*aBaqubVF6Mv2vrXf2dM|~LGb`m zFTudVAj|-9H^?t?&^Q5!fy@Bu7iEBi0VrL7^n>`I@CBJK$-v1V4s{>MJg}Fb1dK1u zz|0^44mVKvu`ozNr8cR;lO literal 1104 zcmZQ(Qf6mhU}WHC;AK!^fB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!N*wB3=CkLo0ypglHg=uU=UCX8%`9%y246F>y47>~s3?-=*3?O-s+e%U^ob&UGQb6tnnE`TZUVc$7 zgwM(#&%nUon^;nmnVeb-5@Tav0gHjyxn%_mYzz=Jpl~Y5%uNM}gX~cRF&G#a+!%D+$XHZ z1_qEgNIi%T3VV=xZ3Y&wTO~l2F*MjqFt9Ly;soSpkbmW%@d6S9g#pMsP`H5H0!l+5 z^FVx1c!I>t7+Aq!2+|8O66A&-3``85IJIS90sEVefdQOeL41%OgrNB;oPiY_ros#i z3?MZiagZ92yTzgTEs%i~>|RN5+<CH9jXZFEu_TvnVyWB(p3Pq>ckgU1nZ#PH76V0#*hV z24uTg8Q8!sO3#T8NG%FWEh}#2 zrGnJKeRULe#K;!!XegBEZVP%Am%;z~Gx$Qk0pT z3O1XKfdwoEQlDE^z`zDo1M*u*W-i!IAh&6N6fiI_crdVn{SM+nVi6$*(gP9$(J*zO zZ~%#c{0tKVu|Z;>IB;iR2Ac;`=gz7N>`vT z2ie01wFl%kkUbziKgd$3yFmU2xeKHoWS$_@4Ipulc_2P0ZNl_})QW)hH`s&JOG51j zxeeq`X$FY9LE#3Hmx0QI#6jkP_@Fq3*$0a|m^_FNigS>CApM{)2C0R)2gC=(14s;H z9>{&5I0LDdU|?ZTWnch@H7K0rpy>f5268vZJaq<0{D9H`NI!@Vic64t%@|n0aR<^1 z@*>EN9}G+kptNMmzyeMy!q9RnkO5SRFffRM;~%7&fdM8a1{DLj2__~E6$9B5z`zc6 zqXYv)KS(`D9u%&Q46F>GFqL9p0GAJ-xUyqlW&rU)>Ot-Rg%v1Wfx-zS2MSLRA0!6~ XClzQ}3X%hb6^Q?rfsw(2fsp|K-??e% literal 1556 zcmZQ(Qf6mhU}WHC;APNdfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!NCH9jXZFEu_TvnVyWB(p3Pq>ckgU1nZ#PH76V0#*hV z24uTg8Q8!sO3#T8NG%FWEh}#2 zrGnJKJ!)R=~gpRReNENoFqCZjc$mAO#Ez3?M&(!ZR@-AFLl_CMax6 zQY)PE^NUhI%0ObEuucp?2!iy1!ags*C>NrJ1so5Feh>i<23D}&L2{5-WMF`af!qQT z1JN)sP&k0ZKz@daf!H81P#m~3FoVqlsq;YcBP#>MTu?ZG>{131XkzRP3=9HDVjz1# z>Kqst7(nKN^n%QFXJBCfg^Lo@3>aS#i4O`ZIV3(PtU!E_nIQF`a02mR=7GWp#0O~s z$%E1=h!0XP%)kUrvx?x<%K&DJF)%Z*F)%PFFfcHPGq5m#+z#S{!a$UPg@FSq2Qp6^ z%I9PNd$wAX4%nU9D1_lsTU|?b30p}S|K4f69hVnt_3KZrbd-$OC zfZPeP2gK(GS<1k`Ai=-_4o{G|Aa}_@;{z1NAh&|d7h-_;2Nbp-^Fe%2*n+|ZBrgJ$ z2k8O%Q=9?fZjk*Tc?qbWK;j_%AU-JUVeSFhBMo*>gFQ$+D2_mSL2d$>2Z~>i8kl`5 zQ2&C&LFR$@ptu9+0qIwR+6R*d@j-D3vJWJ$3DpmC4~P$nTabQ`c_8jD`-B@ZZm z85lrfATwcNvJ4P0ki9T5Q2GL?1Nl9GfgPNNdZP#9@I%U_TjC>%k2kQ~U}I?ys1BnJv35dSX&BZCD4 GBLe^;!EC7j diff --git a/assets/shaders/explode.geom b/assets/shaders/explode.geom new file mode 100644 index 0000000..a9291ad --- /dev/null +++ b/assets/shaders/explode.geom @@ -0,0 +1,44 @@ +#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 mvp; + float time; +}; + +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 = mvp * 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 = mvp * explode(gl_in[i].gl_Position, n); + _texCoord = texCoord[i]; + _norm = n; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/assets/shaders/explode.geom.spv b/assets/shaders/explode.geom.spv new file mode 100644 index 0000000000000000000000000000000000000000..2f5eb55d555c3500251ecb386983e56b27c3034a GIT binary patch literal 3908 zcmZQ(Qf6mhU}WHC;ANP^00DvwObkp63=G^1Yz&MH3=Hl*!9IG$B`JC)rUoDtd<@JW z3M|LZzzycHFfcIWCT8Y=B-|Jn82lI*7{VDC7@`;$7!ny67*ZG*7z7xY89?g9z-$&U z8>Aj&2TV>DNluD^0cK~8>3szzCwiFH|; zu{FqjtPIQyJPZsB1^LAcAT}=p0|UsTAhsab-|1j+VURyFix^lLSQ$Wm^i3=&%1llz z2ARRezycNnv2)7`7}%g{Kz=XD%uNM}gUpivF&G%Y=9x1vFl2(+Yz!_83=HWx@d2qt zVW~wWsTCk)Yzz=_5E~?yUz}NznV-kN#=s6%4>B7po|#t?oLL37111NG-}Ib#=bX#} zm(1dl#JuEGxIR$qg5*kba^P|xw}IjnWEU#~8-o`P_khGfYQXj)xd$YU%RL}DTI=NEa0>U<$~h`ln&!dQY)PE^NT>~5fo1#8c7Ho z?m0;DTM3T?7KRp38b~Zkgqh!t#P>joUseVN1`lZbg2F->M4*YWgVQ-e9Vl!->Ks7% zje!}QRzP9m&cMO|N)t*@Ghlp0C?8}GC~bha+#mvK4@eATCP)lK!_ds>%!7%6*dQ^O*&y>k>OlSg z#g`n&P_UmN@rBF>#TSSVvIC?Z6jw05Ftm(PWB`>84B+xXjDeYfje&tdfq{WRoPmV_ z6viMv$ZiD&76uLm2Cx`N93;=lzyMYcawABd3n~v1S7cyi0J$5a7Nid(2T~&dRRc0t zn}G$aUkKs{2MGoi22rRy$WA$EngEG`)PwYkGr-)+z+lb5!T{of;ujPqq6{nyl2G@9 z{0uT5#0QmwAU;UHG*myxJdiwy289U&gM$N%4@nyejxfFk#C;4R3``70VDniR%%JWB znGaG2qAj56V0?RM`3rKFBUm3q0Z1OicVYn591ILH3@i-J(69uF$wA8{P}qUo2a*F} zko#SsW`fcu$p0Wds9b@?fjiWHpfCfO14=LG=D_UthMEPk--m$#Tqc3UK=$}T-3Af| z*#qK(>Lge=20-OOW`op+K+S^j!=QXnS^((>@j>YoOp)^ z{(#w+29*ct0fiSRev6=CYsSC|&M%-e3W`yX9X}YD7(nF~$ShFW0M$L9umJHvX&+Q3 z!uTM0P`L=>gYpNcY=rSa>Oo~Ai0{b2$^c5UpoRk|orBV{Ei~U4GB7ZJ#CI^Tg43lj z0|Ns{43wU~GcYrlf*i-d!0?NKg#jdI!oUC)1GyE%wqsys0J#&CZhtZ`F<3G%Fo5Jh z^fv|;22kZ~12qFAZwr+N(I7W~!o-e&0c^%bs2f1#FGviO_CfZ7_*M*{yb3WJ#0L2Z zlukVu7{FyS$bOJ{pfu|VE`J#qKzxw-{!sHB8Q2&=X)X}jHUf#m^nt=Dh=G9tBsY-( z)DmG}2xeel0GS062iXTopP>v444}LM(g*T8h!0W+vnv{I7b^oOy~RS?Um$Ui8c^Dc zV_;waiG%cm(ldw;k^{LF)Ib1*C&)ff`bh`1XFzQt28e$^X(>^{+z-kZATgNwG6n_)kXQf%8`z$51_lOD zdWPW+sQsV@97rul9%c?m48#WIEs*~}VNwN6vmhFjrfV1&7;2HybRAS4M1$M_ipP2e z1_qEBur%Gkz`y_!gQaN@znX!80b~{^yg_VG7=Y4rBbGGX#K6D+5{H@J3^gB?rdy$D z8YB*KH%J{QO}8;HFo5Jhegc&bAU;SA6lWdKa01DJ$_fzQ65Il1VCZCE0Jp_KdO&ip zJkiC#zyNX!NFL-~P@d>U%M&0zNFB%?P+0W9-O9=UO4Gg2Gz}65sR5_>7ZD8GRCu=Ea!2T=HdXpnl4eG{Pe!P5Ig1_lO@7$_}*%m>8_NDMh{ zLGb`f?-mS<450EE6n>!o2q>yS?GSSYW^nrj)DHo%L1iqc9|E$UA6!1MFo4=7g3x*$ zR&Im(Bp|auc7xTX-5@`J#6apneoOu0Lwi77tgY4C1U|;~*4N~)ufr$ac2gMfvz_vm6 literal 0 HcmV?d00001 diff --git a/pléascach.cpp b/pléascach.cpp index 87b786a..d82bdb4 100644 --- a/pléascach.cpp +++ b/pléascach.cpp @@ -13,6 +13,11 @@ int main(int argc, char* argv[]) { try { Window win(argv[0], 256, 512); + + auto mon = glfwGetPrimaryMonitor(); + auto v = glfwGetVideoMode(mon); + glfwSetWindowMonitor(win.win, mon, 0, 0, v->width, v->height, v->refreshRate); + auto in = win.getInput(); Renderer ren(win); @@ -31,6 +36,16 @@ int main(int argc, char* argv[]) { /* no need to have a resize() function in the renderer, b/c swapchain images will be * automatically marked out-of-date, and recreation will be triggered in our code */ + /* but still block while waiting for window to be opened again */ + if (event.resize.height == 0 || event.resize.width == 0) { + int h = event.resize.height; + int w = event.resize.width; + do { + glfwPollEvents(); + glfwGetWindowSize(win.win, &w, &h); + } while (h * w == 0); + } + break; case InputEvent::Tag::eEXIT: win.close(); @@ -41,9 +56,15 @@ int main(int argc, char* argv[]) { case InputEvent::Tag::eBUTTON: break; case InputEvent::Tag::eKEY: - if (event.key.key == GLFW_KEY_ESCAPE && event.key.state == GLFW_PRESS) { + if (event.key.key == GLFW_KEY_Q) { + return 0; + } else if (event.key.key == GLFW_KEY_ESCAPE && event.key.state == GLFW_PRESS) { ren.capture_mouse = !ren.capture_mouse; in->setCursor(!ren.capture_mouse); + } else if (event.key.key == GLFW_KEY_R && event.key.state == GLFW_PRESS) { + ren.frame = 0; + } else if (event.key.key == GLFW_KEY_C && event.key.state == GLFW_PRESS) { + ren.flycam = !ren.flycam; } break; } diff --git a/util/Timer.hpp b/util/Timer.hpp index 3e548c8..638500d 100644 --- a/util/Timer.hpp +++ b/util/Timer.hpp @@ -21,6 +21,7 @@ struct Timer { start(); } + /* returns time in milliseconds */ inline double read() { if (running) { auto end = std::chrono::steady_clock::now();