DKGL2 sample codes

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include <cstddef>
  2. #include "app.h"
  3. #include "util.h"
  4. #include "StaticMesh.h"
  5. struct SceneUniformBuffer
  6. {
  7. DKMatrix4 projectionMatrix;
  8. DKMatrix4 modelMatrix;
  9. DKMatrix4 viewMatrix;
  10. };
  11. class DKGLDemo : public SampleApp
  12. {
  13. DKObject<DKWindow> window;
  14. DKObject<DKThread> renderThread;
  15. DKAtomicNumber32 runningRenderThread;
  16. DKObject<StaticMesh> sampleMesh;
  17. DKObject<DKGpuBuffer> sceneUniformBuffer;
  18. SceneUniformBuffer* sceneBufferData = nullptr;
  19. public:
  20. void LoadResource()
  21. {
  22. DKString vertexShaderPath
  23. = resourcePool.ResourceFilePath("shaders/ObjMeshShader/objmesh.vert.spv");
  24. DKString fragMentShaderPath
  25. = resourcePool.ResourceFilePath("shaders/ObjMeshShader/objmesh.frag.spv");
  26. DKString texturePath
  27. = resourcePool.ResourceFilePath("meshes/VikingRoom/viking_room.png");
  28. sampleMesh->LoadShaderFromFile(resourcePool, vertexShaderPath, DKShaderStage::Vertex);
  29. sampleMesh->LoadShaderFromFile(resourcePool, fragMentShaderPath, DKShaderStage::Fragment);
  30. sampleMesh->LoadTextureFromFile(resourcePool, texturePath);
  31. }
  32. void LoadRenderResource(DKObject<DKCommandQueue> queue)
  33. {
  34. DKLog("Loading Static Meshes");
  35. DKString path = resourcePool.ResourceFilePath("meshes/VikingRoom/viking_room.obj");
  36. sampleMesh->LoadMeshResourceFromFile(queue->Device(), resourcePool, path);
  37. sampleMesh->LoadRenderResourceShader(queue->Device(), DKShaderStage::Vertex);
  38. sampleMesh->LoadRenderResourceShader(queue->Device(), DKShaderStage::Fragment);
  39. sampleMesh->LoadRenderResourceTexture(queue);
  40. }
  41. void SetupPipeline(DKRenderPipelineDescriptor& pipelineDesc)
  42. {
  43. sampleMesh->SetupPipelineDecriptor(pipelineDesc);
  44. }
  45. void SetupMaterial(DKObject<DKGraphicsDevice> device)
  46. {
  47. sampleMesh->SetupMaterial(device);
  48. }
  49. void SetupSceneUniformBuffer(DKObject<DKGraphicsDevice> device)
  50. {
  51. // should Go to Scene Uniform Buffer
  52. sceneUniformBuffer = device->CreateBuffer(sizeof(SceneUniformBuffer)
  53. , DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  54. sceneBufferData = reinterpret_cast<SceneUniformBuffer*>(sceneUniformBuffer->Contents());
  55. sceneBufferData->projectionMatrix = DKMatrix4::identity;
  56. sceneBufferData->modelMatrix = DKMatrix4::identity;
  57. sceneBufferData->viewMatrix = DKMatrix4::identity;
  58. sceneUniformBuffer->Flush();
  59. //DKAffineTransform3 trans;
  60. //trans.Multiply(DKLinearTransform3().Scale(0.5).Rotate(DKVector3(0,1,0), DKGL_PI * 0.5));
  61. //ubo.modelMatrix.Multiply(trans.Matrix4());
  62. //memcpy(uboBuffer->Contents(), &ubo, sizeof(ubo));
  63. sampleMesh->SetupExternalUniformBuffer(sceneUniformBuffer, sizeof(SceneUniformBuffer), 0);
  64. }
  65. void EncodeScene(DKObject<DKRenderCommandEncoder> encoder)
  66. {
  67. sampleMesh->EncodeRenderCommand(encoder);
  68. }
  69. void RenderThread(void)
  70. {
  71. DKObject<DKGraphicsDevice> device = DKGraphicsDevice::SharedInstance();
  72. DKObject<DKCommandQueue> queue = device->CreateCommandQueue(DKCommandQueue::Graphics);
  73. LoadRenderResource(queue);
  74. DKObject<DKSwapChain> swapChain = queue->CreateSwapChain(window);
  75. DKRenderPipelineDescriptor pipelineDescriptor;
  76. // setup color-attachment render-targets
  77. pipelineDescriptor.colorAttachments.Resize(1);
  78. pipelineDescriptor.colorAttachments.Value(0).pixelFormat = swapChain->ColorPixelFormat();
  79. pipelineDescriptor.colorAttachments.Value(0).blendState.enabled = false;
  80. pipelineDescriptor.colorAttachments.Value(0).blendState.sourceRGBBlendFactor = DKBlendFactor::SourceAlpha;
  81. pipelineDescriptor.colorAttachments.Value(0).blendState.destinationRGBBlendFactor = DKBlendFactor::OneMinusSourceAlpha;
  82. // setup depth-stencil
  83. pipelineDescriptor.depthStencilAttachmentPixelFormat = DKPixelFormat::D32Float;
  84. pipelineDescriptor.depthStencilDescriptor.depthWriteEnabled = true;
  85. pipelineDescriptor.depthStencilDescriptor.depthCompareFunction = DKCompareFunctionLessEqual;
  86. // setup topology and rasterization
  87. pipelineDescriptor.primitiveTopology = DKPrimitiveType::Triangle;
  88. pipelineDescriptor.frontFace = DKFrontFace::CCW;
  89. pipelineDescriptor.triangleFillMode = DKTriangleFillMode::Fill;
  90. pipelineDescriptor.depthClipMode = DKDepthClipMode::Clip;
  91. pipelineDescriptor.cullMode = DKCullMode::Back;
  92. pipelineDescriptor.rasterizationEnabled = true;
  93. SetupPipeline(pipelineDescriptor);
  94. DKPipelineReflection reflection;
  95. DKObject<DKRenderPipelineState> pipelineState = device->CreateRenderPipeline(pipelineDescriptor, &reflection);
  96. if (pipelineState)
  97. {
  98. PrintPipelineReflection(&reflection, DKLogCategory::Verbose);
  99. }
  100. SetupMaterial(device);
  101. SetupSceneUniformBuffer(device);
  102. DKObject<DKTexture> depthBuffer = nullptr;
  103. DKCamera camera;
  104. DKVector3 cameraPosition = { 0, 5, 10 };
  105. DKVector3 cameraTartget = { 0, 0, 0 };
  106. DKAffineTransform3 tm(DKLinearTransform3().Scale(5).Rotate(DKVector3(-1, 0, 0), DKGL_PI * 0.5));
  107. DKTimer timer;
  108. timer.Reset();
  109. DKLog("Render thread begin");
  110. while (!runningRenderThread.CompareAndSet(0, 0))
  111. {
  112. DKRenderPassDescriptor rpd = swapChain->CurrentRenderPassDescriptor();
  113. double t = timer.Elapsed();
  114. double waveT = (cos(t) + 1.0) * 0.5;
  115. rpd.colorAttachments.Value(0).clearColor = DKColor(waveT, 0.0, 0.0, 0.0);
  116. int width = rpd.colorAttachments.Value(0).renderTarget->Width();
  117. int height = rpd.colorAttachments.Value(0).renderTarget->Height();
  118. if (depthBuffer)
  119. {
  120. if (depthBuffer->Width() != width ||
  121. depthBuffer->Height() != height)
  122. depthBuffer = nullptr;
  123. }
  124. if (depthBuffer == nullptr)
  125. {
  126. // create depth buffer
  127. DKTextureDescriptor texDesc = {};
  128. texDesc.textureType = DKTexture::Type2D;
  129. texDesc.pixelFormat = DKPixelFormat::D32Float;
  130. texDesc.width = width;
  131. texDesc.height = height;
  132. texDesc.depth = 1;
  133. texDesc.mipmapLevels = 1;
  134. texDesc.sampleCount = 1;
  135. texDesc.arrayLength = 1;
  136. texDesc.usage = DKTexture::UsageRenderTarget;
  137. depthBuffer = device->CreateTexture(texDesc);
  138. }
  139. rpd.depthStencilAttachment.renderTarget = depthBuffer;
  140. rpd.depthStencilAttachment.loadAction = DKRenderPassAttachmentDescriptor::LoadActionClear;
  141. rpd.depthStencilAttachment.storeAction = DKRenderPassAttachmentDescriptor::StoreActionDontCare;
  142. DKObject<DKCommandBuffer> buffer = queue->CreateCommandBuffer();
  143. DKObject<DKRenderCommandEncoder> encoder = buffer->CreateRenderCommandEncoder(rpd);
  144. if (encoder)
  145. {
  146. if (sceneUniformBuffer)
  147. {
  148. camera.SetView(cameraPosition, cameraTartget - cameraPosition, DKVector3(0, 1, 0));
  149. camera.SetPerspective(DKGL_DEGREE_TO_RADIAN(90), float(width) / float(height), 1, 1000);
  150. sceneBufferData->projectionMatrix = camera.ProjectionMatrix();
  151. sceneBufferData->viewMatrix = camera.ViewMatrix();
  152. DKQuaternion quat(DKVector3(0, 1, 0), t);
  153. DKAffineTransform3 trans = tm * DKAffineTransform3(quat);
  154. sceneBufferData->modelMatrix = trans.Matrix4();
  155. sceneUniformBuffer->Flush();
  156. sampleMesh->SetupExternalUniformBuffer(sceneUniformBuffer, sizeof(SceneUniformBuffer), 0);
  157. }
  158. encoder->SetRenderPipelineState(pipelineState);
  159. EncodeScene(encoder);
  160. buffer->Commit();
  161. swapChain->Present();
  162. }
  163. else
  164. {
  165. }
  166. DKThread::Sleep(0.01);
  167. }
  168. DKLog("RenderThread terminating...");
  169. }
  170. void OnInitialize(void) override
  171. {
  172. SampleApp::OnInitialize();
  173. DKLogD("%s", DKGL_FUNCTION_NAME);
  174. // create window
  175. window = DKWindow::Create("DefaultWindow");
  176. window->SetOrigin({ 0, 0 });
  177. window->Resize({ 320, 240 });
  178. window->Activate();
  179. window->AddEventHandler(this, DKFunction([this](const DKWindow::WindowEvent& e)
  180. {
  181. if (e.type == DKWindow::WindowEvent::WindowClosed)
  182. DKApplication::Instance()->Terminate(0);
  183. }), NULL, NULL);
  184. sampleMesh = DKObject<StaticMesh>::New();
  185. LoadResource();
  186. runningRenderThread = 1;
  187. renderThread = DKThread::Create(DKFunction(this, &DKGLDemo::RenderThread)->Invocation());
  188. }
  189. void OnTerminate(void) override
  190. {
  191. DKLogD("%s", DKGL_FUNCTION_NAME);
  192. runningRenderThread = 0;
  193. renderThread->WaitTerminate();
  194. renderThread = NULL;
  195. window = NULL;
  196. SampleApp::OnTerminate();
  197. }
  198. };
  199. #ifdef _WIN32
  200. int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
  201. _In_opt_ HINSTANCE hPrevInstance,
  202. _In_ LPWSTR lpCmdLine,
  203. _In_ int nCmdShow)
  204. #else
  205. int main(int argc, const char* argv[])
  206. #endif
  207. {
  208. DKGLDemo app;
  209. DKPropertySet::SystemConfig().SetValue("AppDelegate", "AppDelegate");
  210. DKPropertySet::SystemConfig().SetValue("GraphicsAPI", "Vulkan");
  211. return app.Run();
  212. }