DKGL2 sample codes

ComputeShader.cpp 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. #include <cstddef>
  2. #include "app.h"
  3. #include "util.h"
  4. class UVQuad : public GPUGeometry
  5. {
  6. private:
  7. struct Vertex
  8. {
  9. DKVector3 Pos;
  10. DKVector2 UV;
  11. };
  12. DKArray<UVQuad::Vertex> vertices =
  13. {
  14. { { 1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f } },
  15. { { -1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f } },
  16. { { -1.0f, -1.0f, 0.0f }, { 0.0f, 0.0f } },
  17. { { 1.0f, -1.0f, 0.0f }, { 1.0f, 0.0f } }
  18. };
  19. DKArray<uint32_t> indices = { 0,1,2,2,3,0 };
  20. public:
  21. UVQuad() = default;
  22. size_t VerticesCount() const { return vertices.Count(); }
  23. size_t IndicesCount() const { return indices.Count(); }
  24. UVQuad::Vertex* VerticesData() { return vertices; }
  25. uint32_t* IndicesData() { return indices; }
  26. void InitializeGpuResource(DKCommandQueue* queue)
  27. {
  28. DKGraphicsDevice* device = queue->Device();
  29. uint32_t vertexBufferSize = static_cast<uint32_t>(VerticesCount()) * sizeof(UVQuad::Vertex);
  30. uint32_t indexBufferSize = IndicesCount() * sizeof(uint32_t);
  31. vertexBuffer = device->CreateBuffer(vertexBufferSize, DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  32. memcpy(vertexBuffer->Contents(), VerticesData(), vertexBufferSize);
  33. vertexBuffer->Flush();
  34. indexBuffer = device->CreateBuffer(indexBufferSize, DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  35. memcpy(indexBuffer->Contents(), IndicesData(), indexBufferSize);
  36. indexBuffer->Flush();
  37. // setup vertex buffer and attributes
  38. vertexDesc.attributes = {
  39. { DKVertexFormat::Float3, offsetof(UVQuad::Vertex, Pos), 0, 0 },
  40. { DKVertexFormat::Float2, offsetof(UVQuad::Vertex, UV), 0, 2 },
  41. };
  42. vertexDesc.layouts = {
  43. { DKVertexStepRate::Vertex, sizeof(UVQuad::Vertex), 0 },
  44. };
  45. }
  46. };
  47. class TextureComputeTarget
  48. {
  49. private:
  50. DKObject<DKTexture> textureTarget = nullptr;
  51. public:
  52. TextureComputeTarget() = default;
  53. DKTexture* ComputeTarget(DKCommandQueue* queue, int w, int h)
  54. {
  55. auto device = queue->Device();
  56. if (textureTarget)
  57. {
  58. if (textureTarget->Width() != w ||
  59. textureTarget->Height() != h)
  60. textureTarget = nullptr;
  61. }
  62. if (textureTarget == nullptr)
  63. {
  64. // create depth buffer
  65. DKTextureDescriptor texDesc = {};
  66. texDesc.textureType = DKTexture::Type2D;
  67. texDesc.pixelFormat = DKPixelFormat::BGRA8Unorm;
  68. texDesc.width = w;
  69. texDesc.height = h;
  70. texDesc.depth = 1;
  71. texDesc.mipmapLevels = 1;
  72. texDesc.sampleCount = 1;
  73. texDesc.arrayLength = 1;
  74. texDesc.usage = DKTexture::UsageShaderRead | DKTexture::UsageShaderWrite;
  75. textureTarget = device->CreateTexture(texDesc);
  76. }
  77. return textureTarget;
  78. }
  79. };
  80. class GPUShader
  81. {
  82. private:
  83. DKObject<DKData> shaderData = nullptr;
  84. DKObject<DKShaderModule> shaderModule = nullptr;
  85. DKObject<DKShaderFunction> shaderFunc = nullptr;
  86. public:
  87. GPUShader(DKData* data) : shaderData(data)
  88. {
  89. }
  90. void InitializeGpuResource(DKCommandQueue* queue)
  91. {
  92. if (shaderData)
  93. {
  94. DKGraphicsDevice* device = queue->Device();
  95. DKShader shader(shaderData);
  96. shaderModule = device->CreateShaderModule(&shader);
  97. shaderFunc = shaderModule->CreateFunction(shaderModule->FunctionNames().Value(0));
  98. }
  99. }
  100. DKShaderFunction* Function() { return shaderFunc; }
  101. };
  102. class GraphicShaderBindingSet
  103. {
  104. public:
  105. struct UBO
  106. {
  107. DKMatrix4 projectionMatrix;
  108. DKMatrix4 modelMatrix;
  109. DKMatrix4 viewMatrix;
  110. };
  111. private:
  112. DKShaderBindingSetLayout descriptorSetLayout;
  113. DKObject<DKShaderBindingSet> descriptorSetPreCompute;
  114. DKObject<DKShaderBindingSet> descriptorSetPostCompute;
  115. DKObject<DKRenderPipelineState> pipelineState;
  116. DKObject<DKGpuBuffer> uniformBuffer;
  117. UBO* ubo = nullptr;
  118. public:
  119. GraphicShaderBindingSet() = default;
  120. DKShaderBindingSet* PrecomputeDescSet() { return descriptorSetPreCompute; }
  121. DKShaderBindingSet* PostcomputeDescSet() { return descriptorSetPostCompute; }
  122. DKRenderPipelineState* GraphicPipelineState() { return pipelineState; }
  123. void InitializeGpuResource(DKGraphicsDevice* device)
  124. {
  125. if (1)
  126. {
  127. DKShaderBinding bindings[2] = {
  128. {
  129. 0,
  130. DKShader::DescriptorTypeUniformBuffer,
  131. 1,
  132. nullptr
  133. },
  134. {
  135. 1,
  136. DKShader::DescriptorTypeTextureSampler,
  137. 1,
  138. nullptr
  139. },
  140. };
  141. descriptorSetLayout.bindings.Add(bindings, 2);
  142. }
  143. descriptorSetPreCompute = device->CreateShaderBindingSet(descriptorSetLayout);
  144. descriptorSetPostCompute = device->CreateShaderBindingSet(descriptorSetLayout);
  145. uniformBuffer = device->CreateBuffer(sizeof(GraphicShaderBindingSet::UBO), DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  146. if (descriptorSetPreCompute)
  147. {
  148. if (uniformBuffer)
  149. {
  150. ubo = reinterpret_cast<UBO*>(uniformBuffer->Contents());
  151. ubo->projectionMatrix = DKMatrix4::identity;
  152. ubo->modelMatrix = DKMatrix4::identity;
  153. ubo->viewMatrix = DKMatrix4::identity;
  154. uniformBuffer->Flush();
  155. descriptorSetPreCompute->SetBuffer(0, uniformBuffer, 0, sizeof(UBO));
  156. }
  157. }
  158. if (descriptorSetPostCompute)
  159. {
  160. if (uniformBuffer && ubo)
  161. {
  162. descriptorSetPostCompute->SetBuffer(0, uniformBuffer, 0, sizeof(UBO));
  163. }
  164. }
  165. //descriptorSetPreCompute->SetTexture(1, texture);
  166. //descriptorSetPreCompute->SetSamplerState(1, sampler);
  167. }
  168. DKGpuBuffer* UniformBuffer() { return uniformBuffer; }
  169. UBO* UniformBufferO() { return ubo; }
  170. };
  171. class MeshDemo : public SampleApp
  172. {
  173. DKObject<DKWindow> window;
  174. DKObject<DKThread> renderThread;
  175. DKAtomicNumber32 runningRenderThread;
  176. //Resource
  177. DKObject<UVQuad> Quad;
  178. DKObject<DKTexture> textureColorMap;
  179. DKObject<TextureComputeTarget> ComputeTarget;
  180. DKObject<DKSamplerState> sampleState = nullptr;;
  181. DKObject<GraphicShaderBindingSet> graphicShaderBindingSet = nullptr;
  182. public:
  183. DKObject<DKTexture> LoadTexture2D(DKCommandQueue* queue, DKData* data)
  184. {
  185. DKObject<DKImage> image = DKImage::Create(data);
  186. if (image)
  187. {
  188. DKGraphicsDevice* device = queue->Device();
  189. DKTextureDescriptor texDesc = {};
  190. texDesc.textureType = DKTexture::Type2D;
  191. texDesc.pixelFormat = DKPixelFormat::RGBA8Unorm;
  192. texDesc.width = image->Width();
  193. texDesc.height = image->Height();
  194. texDesc.depth = 1;
  195. texDesc.mipmapLevels = 1;
  196. texDesc.sampleCount = 1;
  197. texDesc.arrayLength = 1;
  198. texDesc.usage = DKTexture::UsageCopyDestination | DKTexture::UsageSampled;
  199. DKObject<DKTexture> tex = device->CreateTexture(texDesc);
  200. if (tex)
  201. {
  202. size_t bytesPerPixel = image->BytesPerPixel();
  203. DKASSERT_DESC(bytesPerPixel == DKPixelFormatBytesPerPixel(texDesc.pixelFormat), "BytesPerPixel mismatch!");
  204. uint32_t width = image->Width();
  205. uint32_t height = image->Height();
  206. size_t bufferLength = bytesPerPixel * width * height;
  207. DKObject<DKGpuBuffer> stagingBuffer = device->CreateBuffer(bufferLength, DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  208. memcpy(stagingBuffer->Contents(), image->Contents(), bufferLength);
  209. stagingBuffer->Flush();
  210. DKObject<DKCommandBuffer> cb = queue->CreateCommandBuffer();
  211. DKObject<DKCopyCommandEncoder> encoder = cb->CreateCopyCommandEncoder();
  212. encoder->CopyFromBufferToTexture(stagingBuffer,
  213. { 0, width, height },
  214. tex,
  215. { 0,0, 0,0,0 },
  216. { width,height,1 });
  217. encoder->EndEncoding();
  218. cb->Commit();
  219. DKLog("Texture created!");
  220. return tex;
  221. }
  222. }
  223. return nullptr;
  224. }
  225. void RenderThread(void)
  226. {
  227. // Device and Queue Preperation
  228. DKObject<DKGraphicsDevice> device = DKGraphicsDevice::SharedInstance();
  229. DKObject<DKCommandQueue> graphicsQueue = device->CreateCommandQueue(DKCommandQueue::Graphics);
  230. DKObject<DKCommandQueue> computeQueue = device->CreateCommandQueue(DKCommandQueue::Compute);
  231. // create shaders
  232. DKObject<DKData> vertData = resourcePool.LoadResourceData("shaders/ComputeShader/texture.vert.spv");
  233. DKObject<DKData> fragData = resourcePool.LoadResourceData("shaders/ComputeShader/texture.frag.spv");
  234. DKObject<DKData> embossData = resourcePool.LoadResourceData("shaders/ComputeShader/emboss.comp.spv");
  235. DKObject<DKData> edgedetectData = resourcePool.LoadResourceData("shaders/ComputeShader/edgedetect.comp.spv");
  236. DKObject<DKData> sharpenData = resourcePool.LoadResourceData("shaders/ComputeShader/sharpen.comp.spv");
  237. DKObject<GPUShader> VS = DKOBJECT_NEW GPUShader(vertData);
  238. DKObject<GPUShader> FS = DKOBJECT_NEW GPUShader(fragData);
  239. DKObject<GPUShader> CS_E = DKOBJECT_NEW GPUShader(embossData);
  240. DKObject<GPUShader> CS_ED = DKOBJECT_NEW GPUShader(edgedetectData);
  241. DKObject<GPUShader> CS_SH = DKOBJECT_NEW GPUShader(sharpenData);
  242. VS->InitializeGpuResource(graphicsQueue);
  243. FS->InitializeGpuResource(graphicsQueue);
  244. CS_E->InitializeGpuResource(computeQueue);
  245. CS_ED->InitializeGpuResource(computeQueue);
  246. CS_SH->InitializeGpuResource(computeQueue);
  247. auto VSF = VS->Function();
  248. auto FSF = FS->Function();
  249. auto CS_EF = CS_E->Function();
  250. auto CS_EDF = CS_ED->Function();
  251. auto CS_SHF = CS_SH->Function();
  252. // Geometry Initialzie
  253. Quad->InitializeGpuResource(graphicsQueue);
  254. // Texture Resource Initialize
  255. ComputeTarget = DKOBJECT_NEW TextureComputeTarget();
  256. DKSamplerDescriptor computeSamplerDesc = {};
  257. computeSamplerDesc.magFilter = DKSamplerDescriptor::MinMagFilterLinear;
  258. computeSamplerDesc.minFilter = DKSamplerDescriptor::MinMagFilterLinear;
  259. computeSamplerDesc.mipFilter = DKSamplerDescriptor::MipFilterLinear;
  260. computeSamplerDesc.addressModeU = DKSamplerDescriptor::AddressModeClampToEdge;
  261. computeSamplerDesc.addressModeV = DKSamplerDescriptor::AddressModeClampToEdge;
  262. computeSamplerDesc.addressModeW = DKSamplerDescriptor::AddressModeClampToEdge;
  263. computeSamplerDesc.maxAnisotropy = 1.0f;
  264. computeSamplerDesc.compareFunction = DKCompareFunctionNever;
  265. DKObject<DKSamplerState> computeSampler = device->CreateSamplerState(computeSamplerDesc);
  266. // create texture
  267. DKObject<DKTexture> texture = LoadTexture2D(graphicsQueue, resourcePool.LoadResourceData("textures/deathstar3.png"));
  268. // create sampler
  269. DKSamplerDescriptor samplerDesc = {};
  270. samplerDesc.magFilter = DKSamplerDescriptor::MinMagFilterLinear;
  271. samplerDesc.minFilter = DKSamplerDescriptor::MinMagFilterLinear;
  272. samplerDesc.addressModeU = DKSamplerDescriptor::AddressModeClampToEdge;
  273. samplerDesc.addressModeV = DKSamplerDescriptor::AddressModeClampToEdge;
  274. samplerDesc.addressModeW = DKSamplerDescriptor::AddressModeClampToEdge;
  275. samplerDesc.maxAnisotropy = 1;
  276. DKObject<DKSamplerState> sampler = device->CreateSamplerState(samplerDesc);
  277. DKObject<DKSwapChain> swapChain = graphicsQueue->CreateSwapChain(window);
  278. DKLog("VertexFunction.VertexAttributes: %d", VSF->StageInputAttributes().Count());
  279. for (int i = 0; i < VSF->StageInputAttributes().Count(); ++i)
  280. {
  281. const DKShaderAttribute& attr = VSF->StageInputAttributes().Value(i);
  282. DKLog(" --> VertexAttribute[%d]: \"%ls\" (location:%u)", i, (const wchar_t*)attr.name, attr.location);
  283. }
  284. DKRenderPipelineDescriptor pipelineDescriptor;
  285. // setup shader
  286. pipelineDescriptor.vertexFunction = VSF;
  287. pipelineDescriptor.fragmentFunction = FSF;
  288. // setup color-attachment render-targets
  289. pipelineDescriptor.colorAttachments.Resize(1);
  290. pipelineDescriptor.colorAttachments.Value(0).pixelFormat = swapChain->ColorPixelFormat();
  291. pipelineDescriptor.colorAttachments.Value(0).blendingEnabled = false;
  292. pipelineDescriptor.colorAttachments.Value(0).sourceRGBBlendFactor = DKBlendFactor::SourceAlpha;
  293. pipelineDescriptor.colorAttachments.Value(0).destinationRGBBlendFactor = DKBlendFactor::OneMinusSourceAlpha;
  294. // setup depth-stencil
  295. pipelineDescriptor.depthStencilAttachmentPixelFormat = DKPixelFormat::D32Float;
  296. pipelineDescriptor.depthStencilDescriptor.depthWriteEnabled = true;
  297. pipelineDescriptor.depthStencilDescriptor.depthCompareFunction = DKCompareFunctionLessEqual;
  298. // setup vertex buffer and attributes
  299. pipelineDescriptor.vertexDescriptor = Quad->VertexDescriptor();
  300. // setup topology and rasterization
  301. pipelineDescriptor.primitiveTopology = DKPrimitiveType::Triangle;
  302. pipelineDescriptor.frontFace = DKFrontFace::CCW;
  303. pipelineDescriptor.triangleFillMode = DKTriangleFillMode::Fill;
  304. pipelineDescriptor.depthClipMode = DKDepthClipMode::Clip;
  305. pipelineDescriptor.cullMode = DKCullMode::Back;
  306. pipelineDescriptor.rasterizationEnabled = true;
  307. DKPipelineReflection reflection;
  308. DKObject<DKRenderPipelineState> pipelineState = device->CreateRenderPipeline(pipelineDescriptor, &reflection);
  309. if (pipelineState)
  310. {
  311. PrintPipelineReflection(&reflection, DKLogCategory::Verbose);
  312. }
  313. ///
  314. graphicShaderBindingSet = DKOBJECT_NEW GraphicShaderBindingSet();
  315. graphicShaderBindingSet->InitializeGpuResource(device);
  316. auto uboBuffer = graphicShaderBindingSet->UniformBuffer();
  317. auto ubo = graphicShaderBindingSet->UniformBufferO();
  318. // ComputerBuffer Layout
  319. DKShaderBindingSetLayout ComputeLayout;
  320. if (1)
  321. {
  322. DKShaderBinding bindings[2] = {
  323. {
  324. 0,
  325. DKShader::DescriptorTypeStorageTexture,
  326. 1,
  327. nullptr
  328. }, // Input Image (read-only)
  329. {
  330. 1,
  331. DKShader::DescriptorTypeStorageTexture,
  332. 1,
  333. nullptr
  334. }, // Output image (write)
  335. };
  336. ComputeLayout.bindings.Add(bindings, 2);
  337. }
  338. DKObject<DKShaderBindingSet> computebindSet = device->CreateShaderBindingSet(ComputeLayout);
  339. //auto CS_EF = CS_E->Function();
  340. //auto CS_EDF = CS_ED->Function();
  341. //auto CS_SHF = CS_SH->Function();
  342. DKComputePipelineDescriptor embossComputePipelineDescriptor;
  343. embossComputePipelineDescriptor.computeFunction = CS_EF;
  344. auto Emboss = device->CreateComputePipeline(embossComputePipelineDescriptor);
  345. DKObject<DKTexture> depthBuffer = nullptr;
  346. DKObject<DKTexture> targettex = nullptr;
  347. DKCamera camera;
  348. DKVector3 cameraPosition = { 0, 5, 10 };
  349. DKVector3 cameraTartget = { 0, 0, 0 };
  350. DKAffineTransform3 tm(DKLinearTransform3().Scale(5).Rotate(DKVector3(-1,0,0), DKGL_PI * 0.5));
  351. DKTimer timer;
  352. timer.Reset();
  353. DKLog("Render thread begin");
  354. while (!runningRenderThread.CompareAndSet(0, 0))
  355. {
  356. DKRenderPassDescriptor rpd = swapChain->CurrentRenderPassDescriptor();
  357. double t = timer.Elapsed();
  358. double waveT = (cos(t) + 1.0) * 0.5;
  359. rpd.colorAttachments.Value(0).clearColor = DKColor(waveT, 0.0, 0.0, 0.0);
  360. int width = rpd.colorAttachments.Value(0).renderTarget->Width();
  361. int height = rpd.colorAttachments.Value(0).renderTarget->Height();
  362. if (depthBuffer)
  363. {
  364. if (depthBuffer->Width() != width ||
  365. depthBuffer->Height() != height )
  366. depthBuffer = nullptr;
  367. }
  368. if (depthBuffer == nullptr)
  369. {
  370. // create depth buffer
  371. DKTextureDescriptor texDesc = {};
  372. texDesc.textureType = DKTexture::Type2D;
  373. texDesc.pixelFormat = DKPixelFormat::D32Float;
  374. texDesc.width = width;
  375. texDesc.height = height;
  376. texDesc.depth = 1;
  377. texDesc.mipmapLevels = 1;
  378. texDesc.sampleCount = 1;
  379. texDesc.arrayLength = 1;
  380. texDesc.usage = DKTexture::UsageRenderTarget;
  381. depthBuffer = device->CreateTexture(texDesc);
  382. }
  383. rpd.depthStencilAttachment.renderTarget = depthBuffer;
  384. rpd.depthStencilAttachment.loadAction = DKRenderPassAttachmentDescriptor::LoadActionClear;
  385. rpd.depthStencilAttachment.storeAction = DKRenderPassAttachmentDescriptor::StoreActionDontCare;
  386. targettex = ComputeTarget->ComputeTarget(computeQueue, width, height);
  387. DKObject<DKCommandBuffer> computeCmdbuffer = computeQueue->CreateCommandBuffer();
  388. DKObject<DKComputeCommandEncoder> computeEncoder = computeCmdbuffer->CreateComputeCommandEncoder();
  389. if (computeEncoder)
  390. {
  391. if (computebindSet)
  392. {
  393. computebindSet->SetTexture(0, texture);
  394. computebindSet->SetSamplerState(0, sampler);
  395. computebindSet->SetTexture(1, targettex);
  396. computebindSet->SetSamplerState(1, sampler);
  397. }
  398. computeEncoder->SetComputePipelineState(Emboss);
  399. computeEncoder->SetResources(0, computebindSet);
  400. computeEncoder->Dispatch(width / 16, height / 16, 1);
  401. computeEncoder->EndEncoding();
  402. }
  403. DKObject<DKCommandBuffer> buffer = graphicsQueue->CreateCommandBuffer();
  404. DKObject<DKRenderCommandEncoder> encoder = buffer->CreateRenderCommandEncoder(rpd);
  405. if (encoder)
  406. {
  407. if (graphicShaderBindingSet->PostcomputeDescSet() && ubo)
  408. {
  409. camera.SetView(cameraPosition, cameraTartget - cameraPosition, DKVector3(0, 1, 0));
  410. camera.SetPerspective(DKGL_DEGREE_TO_RADIAN(90), float(width)/float(height), 1, 1000);
  411. ubo->projectionMatrix = camera.ProjectionMatrix();
  412. ubo->viewMatrix = camera.ViewMatrix();
  413. DKQuaternion quat(DKVector3(0, 1, 0), t);
  414. DKAffineTransform3 trans = tm * DKAffineTransform3(quat);
  415. ubo->modelMatrix = trans.Matrix4();
  416. uboBuffer->Flush();
  417. graphicShaderBindingSet->PostcomputeDescSet()->SetBuffer(0, uboBuffer, 0, sizeof(GraphicShaderBindingSet::UBO));
  418. graphicShaderBindingSet->PostcomputeDescSet()->SetTexture(0, targettex);
  419. graphicShaderBindingSet->PostcomputeDescSet()->SetSamplerState(0, sampler);
  420. }
  421. encoder->SetRenderPipelineState(pipelineState);
  422. encoder->SetVertexBuffer(Quad->VertexBuffer(), 0, 0);
  423. encoder->SetIndexBuffer(Quad->IndexBuffer(), 0, DKIndexType::UInt32);
  424. encoder->SetResources(0, graphicShaderBindingSet->PostcomputeDescSet());
  425. // draw scene!
  426. encoder->DrawIndexed(Quad->IndicesCount(), 1, 0, 0, 0);
  427. encoder->EndEncoding();
  428. if (computeCmdbuffer)
  429. computeCmdbuffer->Commit();
  430. buffer->Commit();
  431. swapChain->Present();
  432. }
  433. else
  434. {
  435. }
  436. DKThread::Sleep(0.01);
  437. }
  438. DKLog("RenderThread terminating...");
  439. }
  440. void OnInitialize(void) override
  441. {
  442. SampleApp::OnInitialize();
  443. DKLogD("%s", DKGL_FUNCTION_NAME);
  444. // create window
  445. window = DKWindow::Create("DefaultWindow");
  446. window->SetOrigin({ 0, 0 });
  447. window->Resize({ 320, 240 });
  448. window->Activate();
  449. window->AddEventHandler(this, DKFunction([this](const DKWindow::WindowEvent& e)
  450. {
  451. if (e.type == DKWindow::WindowEvent::WindowClosed)
  452. DKApplication::Instance()->Terminate(0);
  453. }), NULL, NULL);
  454. Quad = DKOBJECT_NEW UVQuad();
  455. runningRenderThread = 1;
  456. renderThread = DKThread::Create(DKFunction(this, &MeshDemo::RenderThread)->Invocation());
  457. }
  458. void OnTerminate(void) override
  459. {
  460. DKLogD("%s", DKGL_FUNCTION_NAME);
  461. runningRenderThread = 0;
  462. renderThread->WaitTerminate();
  463. renderThread = NULL;
  464. window = NULL;
  465. SampleApp::OnTerminate();
  466. }
  467. };
  468. #ifdef _WIN32
  469. int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
  470. _In_opt_ HINSTANCE hPrevInstance,
  471. _In_ LPWSTR lpCmdLine,
  472. _In_ int nCmdShow)
  473. #else
  474. int main(int argc, const char * argv[])
  475. #endif
  476. {
  477. MeshDemo app;
  478. DKPropertySet::SystemConfig().SetValue("AppDelegate", "AppDelegate");
  479. DKPropertySet::SystemConfig().SetValue("GraphicsAPI", "Vulkan");
  480. return app.Run();
  481. }