From 6f61d0fd63e987d678711b8f3e724c9cbfdb216a Mon Sep 17 00:00:00 2001 From: saschawillems Date: Fri, 1 Apr 2016 22:48:16 +0200 Subject: [PATCH] Added space background sphere using a secondary command buffer --- .../shaders/multithreading/generate-spirv.bat | 4 +- data/shaders/multithreading/phong.vert | 10 +- data/shaders/multithreading/phong.vert.spv | Bin 2532 -> 3064 bytes data/shaders/multithreading/starsphere.frag | 42 +++++++ .../multithreading/starsphere.frag.spv | Bin 0 -> 2920 bytes data/shaders/multithreading/starsphere.vert | 19 +++ .../multithreading/starsphere.vert.spv | Bin 0 -> 1280 bytes multithreading/multithreading.cpp | 111 ++++++++++++++---- 8 files changed, 164 insertions(+), 22 deletions(-) create mode 100644 data/shaders/multithreading/starsphere.frag create mode 100644 data/shaders/multithreading/starsphere.frag.spv create mode 100644 data/shaders/multithreading/starsphere.vert create mode 100644 data/shaders/multithreading/starsphere.vert.spv diff --git a/data/shaders/multithreading/generate-spirv.bat b/data/shaders/multithreading/generate-spirv.bat index e9a2f883..0b4e02ac 100644 --- a/data/shaders/multithreading/generate-spirv.bat +++ b/data/shaders/multithreading/generate-spirv.bat @@ -1,2 +1,4 @@ glslangvalidator -V phong.vert -o phong.vert.spv -glslangvalidator -V phong.frag -o phong.frag.spv \ No newline at end of file +glslangvalidator -V phong.frag -o phong.frag.spv +glslangvalidator -V starsphere.vert -o starsphere.vert.spv +glslangvalidator -V starsphere.frag -o starsphere.frag.spv \ No newline at end of file diff --git a/data/shaders/multithreading/phong.vert b/data/shaders/multithreading/phong.vert index 3ce12417..ca66c224 100644 --- a/data/shaders/multithreading/phong.vert +++ b/data/shaders/multithreading/phong.vert @@ -21,7 +21,15 @@ layout (location = 4) out vec3 outLightVec; void main() { outNormal = inNormal; - outColor = inColor;// * pushConsts.color; + + if ( (inColor.r == 1.0) && (inColor.g == 0.0) && (inColor.b == 0.0)) + { + outColor = pushConsts.color; + } + else + { + outColor = inColor; + } gl_Position = pushConsts.mvp * vec4(inPos.xyz, 1.0); diff --git a/data/shaders/multithreading/phong.vert.spv b/data/shaders/multithreading/phong.vert.spv index 29c15b9ceb991fbe8a3310052c181dbbc1c2b2c0..4923982940bdee89a2d229ac460fea59a11b7826 100644 GIT binary patch literal 3064 zcmZ9N`%)ZL5XL9KlEi3Y%vFuJ1QlZ<#z-z2lR$`oiU|b8yPIVhVUlHci(S<6AFc8U zd>5a^9HGfj;-RB!k9oj%>)x$H7LG_gNP_VITh*-naaG#LUXiN0R?ar~iV zH0KwVR+pywgN>=_%NL=O!^yBNpF5H~mB%A|Za1@z;2?GgJB&?YSFv}o4J^Zk`5VIj zPSX*x7nT~c_is1)X|K7{9Hfo@R&yiWX>`{grmaE$|2a%$oy|tO+1cD}Zl;atOBZ|1 z)}y3GrK*M+j5@lzgS*|G?Pi-;PF-1NkIL7nGwaNC+ufZ!N6oA&h;rR)_~qUH)?ByK zSJNonD~ zGnVu1*~@y-%X6)sf$v{jW_JG?CCfi{N}n&-up231o#NPjycYk*zR9MFODrEcCWz%iN7T`Wj+cn-qc-#Hp^jJZ4t1FGGIj}5hp{?*!~S#j z-TSuVZr&_;?`D!%>^WG|_11~pw}{4-VNq_-z%)~ z-f!l)d@zE$MQq-_3O7@7zRP9q$oD^sx!(L4%(wC@b)CD7UB}E(-yHr9b`?{f`w^QL z`WJ{F*S`oSANt=XuIm2)EawRQ9}>$|^)HoNRsTnDt~cNLs{XrRdz+)ydAwX`y+{1G z)@3;P6;9T(y^qPo2!0hJ_(Efm|8a#^XXJlU^5!~%Un91Te6`M}6~0>Mvyzu{M4iux zts`Hp^F@VsZkb*A+wvvm-rPr_x!}J7t5scvhJybZY;XG%HAm^4B;R1xa-BJG#|>hC zyL?Obdw`iM?_C_kKPcmMd<%=UDY2Z`cla&l-QD9qv$Zx$PTt{u-PLqTWyRw_h7G$68s5|0U}h_8(yV-+BN5 literal 2532 zcmZ9M+j10D6o#856A{@j?%uIwr`D|X|Ld^VUVC?DXO@me(GmWRMLSWo&PFrfC{o9@UPPaW=1aca z+3BoIix(?vH&>yfQ_-xd^qr1Qmi8RK`$?7y-at+udQKr1kQjN2Y$3D!&7l8c(>bEs zo!-Xt2fb-JP9{l__NIHui*(W({rFSbFQ)&G!IkBM-Z04r2gxAqt=(81C;gXEi%QKN zS}^u8Iw+ovCi}?{Th6|+{E#X+`y_62G#pJZ;pWP|v%I2O%;9bL!LZj&C%fsSNPjVI zzUH;{jiy zF3<4}x_dC)+Z^RnXEaaGa<2WK$KWc)9{Tmc%)0^}H}X7d4437!k9MDBV?g?zU=J%7 zxK-XEv+87ny<#`*mz;MBx0|J}q@p%?&VB)LiJiOHe#FkaiG3$x=kkQA&f8_4D{$t^ zsRL(@oO27Dww!OGjmLUb?f>S~f-^qMZ3*mZa(pb&nFi;+#;qgPHP^bH$=O~*T;dqr zoPqCOT=g_pehXrIJx3MmEP}+^7qI5hF>;YCdlBo8!N+P_{!WdZd+;B}w%_0vhuMXA z@4D!Z!X2_#E1Jxdkj|9%|@Q?E5_0J@vb<*tad` zJ{Qq3VqNzUUqW1$z?ae1wXX$!y#qPVY5jN6&OzS#V(&&y|9iDfSy|25(=zKu3sxsF%;9b!xn`|v)WBGw7G`hOX*N2`1j zp4ny0-!Q&mW9?}fv9`F4_S+TT1*_jgy#IS-I}35}oyPX=_4y{m8&r2zzES7r9T@N2 zt|Iawe-S%Iw#o7QONg8+aPMQw9cgeM)SU0VOP9{{L&SXJ^?Mh8Qdi$ch|bnL=>IzQ>-~QQCm;G>!H$v8>*v^VuE4Eg%QgG|qUM_Y-+(jUc>T@(zXZFt zG4|@6$%S6muwU=>CY<~>lXbSY5V^1d{|!Xos~)TP+YR16L;RhZH`W#SZ?UZ-->h@D z!8hyNt9dzBsB<6NI`Yjr>kVFCxBezJusxgSu;;)(z_wTWvWLKLV!OBdtRwP%iw_ZN znP*J6<44%Of8Ubd!(+r)`S4B1Y5VQ?jfULsvE{_R!w%xzZSmDw>xY_?cX?jV_D8+f pGi+-ZXMMkOxlpf*-K@6_mQ!4z-f#7{{2b00Yi*&${}6Qx`4`|VsmK5T diff --git a/data/shaders/multithreading/starsphere.frag b/data/shaders/multithreading/starsphere.frag new file mode 100644 index 00000000..07e35d3f --- /dev/null +++ b/data/shaders/multithreading/starsphere.frag @@ -0,0 +1,42 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec3 inUVW; + +layout (location = 0) out vec4 outFragColor; + +#define HASHSCALE3 vec3(443.897, 441.423, 437.195) +#define STARFREQUENCY 0.01 + +// Hash function by Dave Hoskins (https://www.shadertoy.com/view/4djSRW) +float hash33(vec3 p3) +{ + p3 = fract(p3 * HASHSCALE3); + p3 += dot(p3, p3.yxz+19.19); + return fract(vec3((p3.x + p3.y)*p3.z + (p3.x+p3.z)*p3.y + (p3.y+p3.z)*p3.x)); +} + +float starField(vec3 pos) +{ + vec3 color = vec3(0.0); + float threshhold = (1.0 - STARFREQUENCY); + float rnd = hash33(pos); + if (rnd >= threshhold) + { + float starCol = pow((rnd - threshhold) / (1.0 - threshhold), 16.0); + color += vec3(starCol); + } + return color; +} + +void main() +{ + // Fake atmosphere at the bottom + vec3 atmosphere = clamp(vec3(0.1, 0.15, 0.4) * (inUVW.t - 5.0), 0.0, 1.0); + + vec3 color = starField(inUVW) + atmosphere; + + outFragColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/data/shaders/multithreading/starsphere.frag.spv b/data/shaders/multithreading/starsphere.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..9d590a2e29d72c8d90b1a758ea8529893594732a GIT binary patch literal 2920 zcmZ9NNpqA{6oxM(BtU|IOyWcUK?IDEFp3GpU;-Frh=7XPv`Lc=bkecAgCi28sB-1X zg}8FzZ*b|tH7?v*`X^jCRcZM=Uw=nhI(6#4?|X)O?)0T?@z&0i7V)<<-Ac{h>a-Z1 zQdjE8#?i6yvEF)PvUl&kJ|iATZCRi(D^q7`XVhkj)3Z9RVAru##Hlj@sEw*AeNR$* zT9!t~3PWdKDAY@H#agjZD%8ux$x^LQedkJPqEY{U46f6OS zpDUMYCG*>}J(`|9cm6`2(_p+eXM385->cb??PqnqF;Xi|Q8sIhzM6F&C)S_beGk5d z9e2++XS<&=ydKbv0L)!2`}{xTf=LHM?BfBuiJ zf&cd9Ps6*3w$5729OLvw-oxNcx9<$CqwZ#K59Uw5d`rffeQgCtui@X0wg?Np6YP4U z{)=FL(Z>i_EiB@WqkS`X{m5FfPk}@CY*Jb{68vJ54+ZBa(+_v=4g|jp|LV@h!QfL( z|6t5thMQxYKKFZ?(KWcX!#Vf;sOi6&;||8Cn?17h^-<67BXoVf1LHqt^eok_C-+XM z?dRsXKgRk~`vYYOqp_Z`cQtyEdoNqL_fkGYmc3Ol``wNWP{Uq)2kN(okymrgzCTAZ ze-3j$^qtP{$-Ce<8^_Rnhn_`PH=SCej=4{}FzcCb>>w+19s2Fb*lU=5>T?b9LwSGi zf&DJ1NBsL>YeWwpfQ<{gnXltRG=0Wf+x=3DI-h{m&g6650IT^6Z2_$2T0*;-Yo6C> zR^WMlikZKF>32Vz)AQB$Hx&+Ip0oSzx6q$&_yBR9=W@(5?`Di1SLOQcd`;`%YQEd< z{A|{P?azGu&MQ`rIvc=h!5_-`sre1&Q*j)9fbp&j$`r>XJ1*?a}Js(1gdv44>+)%aFcjdRjU+cSC0ry?4WQ=d=F|gkr zx%X=HK7OKw`!-LuaO1~w?j5z(2qw19aV+lrOJL{MXAOCL+s43Mn7V%FRExX!GFUD6 zD`4w?$6Y+dcp5WC{de-uGWz?AHR(HpskwG>)Oi)$TK62>y752ZJlGiZ$axLi8uL2* z0;c|1{x;qKo2##z-Sxe^iFsyzH}qe`T&w%1FY3PqR*O6EHdrmpxK4NhbHBYm@=KVS Z@z&LM3Hy^Z$J!kuzX&$QyCe4Q{0o(k<81%{ literal 0 HcmV?d00001 diff --git a/data/shaders/multithreading/starsphere.vert b/data/shaders/multithreading/starsphere.vert new file mode 100644 index 00000000..e22fbbda --- /dev/null +++ b/data/shaders/multithreading/starsphere.vert @@ -0,0 +1,19 @@ +#version 450 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout (location = 0) in vec3 inPos; + +layout (std140, push_constant) uniform PushConsts +{ + mat4 mvp; +} pushConsts; + +layout (location = 0) out vec3 outUVW; + +void main() +{ + outUVW = inPos; + gl_Position = pushConsts.mvp * vec4(inPos.xyz, 1.0); +} diff --git a/data/shaders/multithreading/starsphere.vert.spv b/data/shaders/multithreading/starsphere.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..055b3352d959592db8fe3d549eb8a3d6695a4515 GIT binary patch literal 1280 zcmY+C%Wl(P5QT@NNr6HOlwN=moTjirswz|v5&~3;lrFLeRFtJ<(qE~IYg@5{5G!7R zSK_JIAaOp&e-$R0%$zghx!KJ|Z_(_Eepl^@&E&QTOVU+oQ@@7nZ#7s@q(2A`KE4YJmq(MRbYXE8ow`Yw zeK~idviLtop*S6fNtBMK(b$Fi&-U_Y^wnCbG~W+Q&um(LI{9o>oc?h-%v4git=-JV zNjP+q6E`W{cR{f;9-mlN#ATeNVi&7?Zc_1aS{}zg9C<#*PKq5SasECo$|xPV%NW-o zHcgVtSW9={9!N{S4cXzeI6KVJg1y_?0S>wNmRC9VZP`G&p?vCqi3h@bZTRr7YRtR$@$2&0(Z|7lZ|dC?rXKsP>3>-^kRnfO zyds|(Tf*!>K3qp0_wY4{q0DthmKlgM7nt`AN1wa0ft0%R0k27sP2qJ}>M~bHPjNFi zYH!N2BOJBC+!2oW{n{s=+RQuqCVsvpz9Y;W)PJFO#GUDb!2c1$JAEydyWNm-vp0&; z1AL$i`aF=*o7u^y=av-SKmSlZ&wtP}%<@PIhj=cK563+`*R46`8)_2f-InrvASKRT dzf_l4PfBlcn2$XlOSwDqF+Z5Rzv}c-`VViwU;O|8 literal 0 HcmV?d00001 diff --git a/multithreading/multithreading.cpp b/multithreading/multithreading.cpp index 55b4079d..64108dce 100644 --- a/multithreading/multithreading.cpp +++ b/multithreading/multithreading.cpp @@ -46,6 +46,7 @@ public: struct { vkMeshLoader::MeshBuffer ufo; + vkMeshLoader::MeshBuffer skysphere; } meshes; // Shared matrices used for thread push constant blocks @@ -56,6 +57,7 @@ public: struct { VkPipeline phong; + VkPipeline starsphere; } pipelines; VkPipelineLayout pipelineLayout; @@ -63,6 +65,7 @@ public: VkDescriptorSetLayout descriptorSetLayout; VkCommandBuffer primaryCommandBuffer; + VkCommandBuffer secondaryCommandBuffer; // Number of animated objects to be renderer // by using threads and secondary command buffers @@ -86,10 +89,12 @@ public: }; struct ObjectData { + glm::mat4 model; glm::vec3 pos; glm::vec3 rotation; float rotationDir; float rotationSpeed; + float scale; float deltaT; }; @@ -120,8 +125,11 @@ public: // todo : May not work on all compilers (e.g. old GCC versions?) numThreads = std::thread::hardware_concurrency(); assert(numThreads > 0); - // todo : test, remove +#if defined(__ANDROID__) + LOGD("numThreads = %d", numThreads); +#else std::cout << "numThreads = " << numThreads << std::endl; +#endif srand(time(NULL)); threadPool.setThreadCount(numThreads); @@ -134,13 +142,16 @@ public: // Clean up used Vulkan resources // Note : Inherited destructor cleans up resources stored in base class vkDestroyPipeline(device, pipelines.phong, nullptr); + vkDestroyPipeline(device, pipelines.starsphere, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); vkFreeCommandBuffers(device, cmdPool, 1, &primaryCommandBuffer); + vkFreeCommandBuffers(device, cmdPool, 1, &secondaryCommandBuffer); vkMeshLoader::freeMeshBufferResources(device, &meshes.ufo); + vkMeshLoader::freeMeshBufferResources(device, &meshes.skysphere); for (auto& thread : threadData) { @@ -157,16 +168,22 @@ public: // Create all threads and initialize shader push constants void prepareMultiThreadedRenderer() { + // todo : separate func + // Since this demo updates the command buffers on each frame // we don't use the per-framebuffer command buffers from the // base class, and create a single primary command buffer instead - VkCommandBufferAllocateInfo primaryAllocateInfo = + VkCommandBufferAllocateInfo cmdBufAllocateInfo = vkTools::initializers::commandBufferAllocateInfo( cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); - vkTools::checkResult(vkAllocateCommandBuffers(device, &primaryAllocateInfo, &primaryCommandBuffer)); + vkTools::checkResult(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &primaryCommandBuffer)); + // Create a secondary command buffer for rendering the star sphere + cmdBufAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; + vkTools::checkResult(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &secondaryCommandBuffer)); + threadData.resize(numThreads); createSetupCommandBuffer(); @@ -188,12 +205,12 @@ public: // One secondary command buffer per object that is updated by this thread thread->commandBuffer.resize(numObjectsPerThread); // Generate secondary command buffers for each thread - VkCommandBufferAllocateInfo cmdBufAllocateInfo = + VkCommandBufferAllocateInfo secondaryCmdBufAllocateInfo = vkTools::initializers::commandBufferAllocateInfo( thread->commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY, thread->commandBuffer.size()); - vkTools::checkResult(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, thread->commandBuffer.data())); + vkTools::checkResult(vkAllocateCommandBuffers(device, &secondaryCmdBufAllocateInfo, thread->commandBuffer.data())); // Unique vertex and index buffers per thread @@ -250,12 +267,12 @@ public: posZ += 1.0f; } - thread->objectData[j].rotation = glm::vec3(0.0f, (float)(rand() % 360), 0.0f); + thread->objectData[j].rotation = glm::vec3(0.0f, rnd(360.0f), 0.0f); thread->objectData[j].deltaT = rnd(1.0f); thread->objectData[j].rotationDir = (rnd(100.0f) < 50.0f) ? 1.0f : -1.0f; - thread->objectData[i].rotationSpeed = (2.0f + rnd(4.0f)) * thread->objectData[i].rotationDir; + thread->objectData[j].rotationSpeed = (2.0f + rnd(4.0f)) * thread->objectData[i].rotationDir; + thread->objectData[j].scale = 0.75f + rnd(0.5f); - // Random object color thread->pushConstBlock[j].color = glm::vec3(rnd(1.0f), rnd(1.0f), rnd(1.0f)); } } @@ -293,17 +310,18 @@ public: { objectData->rotation.y -= 360.0f; } - objectData->deltaT += 0.0005f; + objectData->deltaT += 0.0015f; if (objectData->deltaT > 1.0f) objectData->deltaT -= 1.0f; objectData->pos.y = sin(glm::radians(objectData->deltaT * 360.0f)) * 1.5f; - glm::mat4 model = glm::translate(glm::mat4(), objectData->pos); - model = glm::rotate(model, -sinf(glm::radians(objectData->deltaT * 360.0f)) * 0.25f, glm::vec3(objectData->rotationDir, 0.0f, 0.0f)); - model = glm::rotate(model, glm::radians(objectData->rotation.y), glm::vec3(0.0f, objectData->rotationDir, 0.0f)); - model = glm::rotate(model, glm::radians(objectData->deltaT * 360.0f), glm::vec3(0.0f, objectData->rotationDir, 0.0f)); + objectData->model = glm::translate(glm::mat4(), objectData->pos); + objectData->model = glm::rotate(objectData->model, -sinf(glm::radians(objectData->deltaT * 360.0f)) * 0.25f, glm::vec3(objectData->rotationDir, 0.0f, 0.0f)); + objectData->model = glm::rotate(objectData->model, glm::radians(objectData->rotation.y), glm::vec3(0.0f, objectData->rotationDir, 0.0f)); + objectData->model = glm::rotate(objectData->model, glm::radians(objectData->deltaT * 360.0f), glm::vec3(0.0f, objectData->rotationDir, 0.0f)); + objectData->model = glm::scale(objectData->model, glm::vec3(objectData->scale)); - thread->pushConstBlock[cmdBufferIndex].mvp = matrices.projection * matrices.view * model; + thread->pushConstBlock[cmdBufferIndex].mvp = matrices.projection * matrices.view * objectData->model; // Update shader push constant block // Contains model view matrix @@ -323,6 +341,47 @@ public: vkTools::checkResult(vkEndCommandBuffer(cmdBuffer)); } + void updateSecondaryCommandBuffer(VkCommandBufferInheritanceInfo inheritanceInfo) + { + // Secondary command buffer for the sky sphere + VkCommandBufferBeginInfo commandBufferBeginInfo = vkTools::initializers::commandBufferBeginInfo(); + commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; + commandBufferBeginInfo.pInheritanceInfo = &inheritanceInfo; + + vkTools::checkResult(vkBeginCommandBuffer(secondaryCommandBuffer, &commandBufferBeginInfo)); + + VkViewport viewport = vkTools::initializers::viewport((float)width, (float)height, 0.0f, 1.0f); + vkCmdSetViewport(secondaryCommandBuffer, 0, 1, &viewport); + + VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0); + vkCmdSetScissor(secondaryCommandBuffer, 0, 1, &scissor); + + vkCmdBindPipeline(secondaryCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.starsphere); + + + glm::mat4 view = glm::mat4(); + view = glm::rotate(view, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); + view = glm::rotate(view, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); + view = glm::rotate(view, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); + + glm::mat4 mvp = matrices.projection * view; + + vkCmdPushConstants( + secondaryCommandBuffer, + pipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT, + 0, + sizeof(mvp), + &mvp); + + VkDeviceSize offsets[1] = { 0 }; + vkCmdBindVertexBuffers(secondaryCommandBuffer, 0, 1, &meshes.skysphere.vertices.buf, offsets); + vkCmdBindIndexBuffer(secondaryCommandBuffer, meshes.skysphere.indices.buf, 0, VK_INDEX_TYPE_UINT32); + vkCmdDrawIndexed(secondaryCommandBuffer, meshes.skysphere.indexCount, 1, 0, 0, 0); + + vkTools::checkResult(vkEndCommandBuffer(secondaryCommandBuffer)); + } + // Updates the secondary command buffers using a thread pool // and puts them into the primary command buffer that's // lat submitted to the queue for rendering @@ -353,14 +412,19 @@ public: // These are stored (and retrieved) from the secondary command buffers vkCmdBeginRenderPass(primaryCommandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); - std::vector commandBuffers; - // Inheritance info for the secondary command buffers VkCommandBufferInheritanceInfo inheritanceInfo = vkTools::initializers::commandBufferInheritanceInfo(); inheritanceInfo.renderPass = renderPass; // Secondary command buffer also use the currently active framebuffer inheritanceInfo.framebuffer = frameBuffer; + // Contains the list of secondary command buffers to be executed + std::vector commandBuffers; + + // Secondary command buffer with star background sphere + updateSecondaryCommandBuffer(inheritanceInfo); + commandBuffers.push_back(secondaryCommandBuffer); + for (uint32_t t = 0; t < numThreads; t++) { // Add a job to the thread's queue for each object to be rendered @@ -422,6 +486,7 @@ public: void loadMeshes() { loadMesh("./../data/models/retroufo_red.X", &meshes.ufo, vertexLayout, 0.12f); + loadMesh("./../data/models/sphere.obj", &meshes.skysphere, vertexLayout, 1.0f); } void setupVertexDescriptions() @@ -589,8 +654,8 @@ public: // Load shaders std::array shaderStages; - shaderStages[0] = loadShader("./../data/shaders/multithreading/phong.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); - shaderStages[1] = loadShader("./../data/shaders/multithreading/phong.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); + shaderStages[0] = loadShader(getAssetPath() + "shaders/multithreading/phong.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); + shaderStages[1] = loadShader(getAssetPath() + "shaders/multithreading/phong.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); VkGraphicsPipelineCreateInfo pipelineCreateInfo = vkTools::initializers::pipelineCreateInfo( @@ -609,8 +674,14 @@ public: pipelineCreateInfo.stageCount = shaderStages.size(); pipelineCreateInfo.pStages = shaderStages.data(); - VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.phong); - assert(!err); + vkTools::checkResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.phong)); + + // Star sphere rendering pipeline + rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT; + depthStencilState.depthWriteEnable = VK_FALSE; + shaderStages[0] = loadShader(getAssetPath() + "shaders/multithreading/starsphere.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); + shaderStages[1] = loadShader(getAssetPath() + "shaders/multithreading/starsphere.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); + vkTools::checkResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.starsphere)); } void updateMatrices()