DKGL2 sample codes

StaticMesh.cpp 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include "StaticMesh.h"
  2. #include "ObjImportUtil.h"
  3. StaticMesh::StaticMesh()
  4. : mesh(nullptr)
  5. {
  6. memset(shaderData, 0
  7. , sizeof(DKObject<DKData>) * static_cast<int>(DKShaderStage::Compute));
  8. }
  9. bool StaticMesh::LoadMeshResourceFromFile(DKObject<DKGraphicsDevice> inDevice
  10. , DKResourcePool& inDKResourcePool, const DKString& inFileName)
  11. {
  12. if (inDevice == nullptr)
  13. return false;
  14. if (inFileName.Length() == 0)
  15. return false;
  16. if (inFileName.HasSuffix("obj"))
  17. {
  18. ObjImportUtil::ObjImportedMeshData loadedData
  19. = ObjImportUtil::LoadFromObjFile(inFileName, inDKResourcePool);
  20. mesh = DKObject<DKMesh>::New();
  21. uint32_t vertexBufferSize
  22. = static_cast<uint32_t>(loadedData.vertices.Count()) * loadedData.vertexSize;
  23. DKVertexBuffer vb = {};
  24. {
  25. DKObject<DKGpuBuffer> vertexBuffer
  26. = inDevice->CreateBuffer(vertexBufferSize, DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  27. memcpy(vertexBuffer->Contents(), loadedData.vertices, vertexBufferSize);
  28. vertexBuffer->Flush();
  29. vb.buffer = vertexBuffer;
  30. vb.count = loadedData.vertices.Count();
  31. vb.offset = 0;
  32. vb.size = loadedData.vertexSize;
  33. vb.declarations =
  34. {
  35. {DKVertexStream::Position, DKVertexFormat::Float3, false, offsetof(ObjImportUtil::ObjVertex, inPos), DKString("Position")},
  36. {DKVertexStream::Color, DKVertexFormat::Float3, false, offsetof(ObjImportUtil::ObjVertex, inColor), DKString("Color")},
  37. {DKVertexStream::Normal, DKVertexFormat::Float3, false, offsetof(ObjImportUtil::ObjVertex, inNormal), DKString("Normal")},
  38. {DKVertexStream::TexCoord, DKVertexFormat::Float2, false, offsetof(ObjImportUtil::ObjVertex, inTexCoord), DKString("TexCoord")},
  39. };
  40. mesh->vertexBuffers.Add(vb);
  41. }
  42. DKSubMesh subMesh = {};
  43. {
  44. uint32_t indexBufferSize
  45. = loadedData.indices.Count() * sizeof(uint32_t);
  46. DKObject<DKGpuBuffer> indexBuffer =
  47. inDevice->CreateBuffer(indexBufferSize
  48. , DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  49. memcpy(indexBuffer->Contents(), loadedData.indices, indexBufferSize);
  50. indexBuffer->Flush();
  51. subMesh.indexBuffer = indexBuffer;
  52. subMesh.indexCount = loadedData.indices.Count();
  53. subMesh.indexOffset = 0;
  54. subMesh.indexType = DKIndexType::UInt32;
  55. subMesh.vertexOffset = 0;
  56. subMesh.visible = true;
  57. }
  58. mesh->subMeshes.Add(subMesh);
  59. aabb = loadedData.aabb;
  60. return true;
  61. }
  62. return false;
  63. }
  64. bool StaticMesh::LoadTextureFromFile(DKResourcePool& inDKResourcePool
  65. , const DKString& inFileName)
  66. {
  67. textureSrc = DKImage::Create(inDKResourcePool.LoadResourceData(inFileName));
  68. if (textureSrc)
  69. return true;
  70. return false;
  71. }
  72. bool StaticMesh::LoadRenderResourceTexture(DKObject<DKCommandQueue> queue)
  73. {
  74. if (textureSrc && texture == nullptr)
  75. {
  76. DKGraphicsDevice* device = queue->Device();
  77. DKTextureDescriptor texDesc = {};
  78. texDesc.textureType = DKTexture::Type2D;
  79. texDesc.pixelFormat = DKPixelFormat::RGBA8Unorm;
  80. texDesc.width = textureSrc->Width();
  81. texDesc.height = textureSrc->Height();
  82. texDesc.depth = 1;
  83. texDesc.mipmapLevels = 1;
  84. texDesc.sampleCount = 1;
  85. texDesc.arrayLength = 1;
  86. texDesc.usage = DKTexture::UsageCopyDestination | DKTexture::UsageSampled;
  87. DKObject<DKTexture> tex = device->CreateTexture(texDesc);
  88. if (tex)
  89. {
  90. size_t bytesPerPixel = textureSrc->BytesPerPixel();
  91. DKASSERT_DESC(bytesPerPixel
  92. == DKPixelFormatBytesPerPixel(texDesc.pixelFormat)
  93. , "BytesPerPixel mismatch!");
  94. uint32_t width = textureSrc->Width();
  95. uint32_t height = textureSrc->Height();
  96. size_t bufferLength = bytesPerPixel * texDesc.width * texDesc.height;
  97. DKObject<DKGpuBuffer> stagingBuffer = device->CreateBuffer(bufferLength
  98. , DKGpuBuffer::StorageModeShared, DKCpuCacheModeReadWrite);
  99. memcpy(stagingBuffer->Contents(), textureSrc->Contents(), bufferLength);
  100. stagingBuffer->Flush();
  101. DKObject<DKCommandBuffer> cb = queue->CreateCommandBuffer();
  102. DKObject<DKCopyCommandEncoder> encoder = cb->CreateCopyCommandEncoder();
  103. encoder->CopyFromBufferToTexture(stagingBuffer,
  104. { 0, width, height },
  105. tex,
  106. { 0,0, 0,0,0 },
  107. { width,height,1 });
  108. encoder->EndEncoding();
  109. cb->Commit();
  110. DKLog("Texture created!");
  111. texture = tex;
  112. // create sampler
  113. DKSamplerDescriptor samplerDesc = {};
  114. samplerDesc.magFilter = DKSamplerDescriptor::MinMagFilterLinear;
  115. samplerDesc.minFilter = DKSamplerDescriptor::MinMagFilterLinear;
  116. samplerDesc.addressModeU = DKSamplerDescriptor::AddressModeClampToEdge;
  117. samplerDesc.addressModeV = DKSamplerDescriptor::AddressModeClampToEdge;
  118. samplerDesc.addressModeW = DKSamplerDescriptor::AddressModeClampToEdge;
  119. samplerDesc.maxAnisotropy = 16;
  120. textureSampler = device->CreateSamplerState(samplerDesc);
  121. return true;
  122. }
  123. }
  124. return false;
  125. }
  126. bool StaticMesh::LoadShaderFromFile(DKResourcePool& inDKResourcePool
  127. , const DKString& inFileName
  128. , DKShaderStage inStage)
  129. {
  130. DKObject<DKData> data = inDKResourcePool.LoadResourceData(inFileName);
  131. shaderData[static_cast<int>(inStage)] = data;
  132. if (data)
  133. return true;
  134. return false;
  135. }
  136. bool StaticMesh::LoadRenderResourceShader(DKObject<DKGraphicsDevice> inDevice
  137. , DKShaderStage inStage)
  138. {
  139. DKShader shader(shaderData[static_cast<int>(inStage)]);
  140. DKObject<DKShaderModule> module = inDevice->CreateShaderModule(&shader);
  141. DKObject<DKShaderFunction> function
  142. = module->CreateFunction(module->FunctionNames().Value(0));
  143. shaderModule[static_cast<int>(inStage)] = module;
  144. shaderFunction[static_cast<int>(inStage)] = function;
  145. if (module && function)
  146. {
  147. if (inStage == DKShaderStage::Vertex)
  148. {
  149. DKLog("VertexFunction.VertexAttributes: %d", function->StageInputAttributes().Count());
  150. for (int i = 0; i < function->StageInputAttributes().Count(); ++i)
  151. {
  152. const DKShaderAttribute& attr = function->StageInputAttributes().Value(i);
  153. DKLog(" --> VertexAttribute[%d]: \"%ls\" (location:%u)", i, (const wchar_t*)attr.name, attr.location);
  154. }
  155. }
  156. return true;
  157. }
  158. return false;
  159. }
  160. void StaticMesh::SetupPipelineDecriptor(DKRenderPipelineDescriptor& pipelineDescriptor)
  161. {
  162. // setup shader
  163. pipelineDescriptor.vertexFunction = shaderFunction[static_cast<int>(DKShaderStage::Vertex)];
  164. pipelineDescriptor.fragmentFunction = shaderFunction[static_cast<int>(DKShaderStage::Fragment)];
  165. uint32_t i = 0;
  166. for (auto decl : mesh->vertexBuffers[0].declarations)
  167. {
  168. pipelineDescriptor.vertexDescriptor.attributes.Add(
  169. DKVertexAttributeDescriptor{ decl.format, decl.offset, 0, i }
  170. );
  171. i++;
  172. }
  173. pipelineDescriptor.vertexDescriptor.layouts = {
  174. { DKVertexStepRate::Vertex, mesh->vertexBuffers[0].size, 0 },
  175. };
  176. }
  177. void StaticMesh::SetupMaterial(DKObject<DKGraphicsDevice> inDevice)
  178. {
  179. DKShaderBindingSetLayout layout;
  180. if (1)
  181. {
  182. DKShaderBinding bindings[2] = {
  183. {
  184. 0,
  185. DKShader::DescriptorTypeUniformBuffer,
  186. 1,
  187. nullptr
  188. }, // Scene Uniform Buffer
  189. {
  190. 1,
  191. DKShader::DescriptorTypeTextureSampler,
  192. 1,
  193. nullptr
  194. }, // Texture
  195. };
  196. layout.bindings.Add(bindings, 2);
  197. }
  198. bindSet = inDevice->CreateShaderBindingSet(layout);
  199. if (bindSet == nullptr)
  200. return;
  201. bindSet->SetTexture(1, texture);
  202. bindSet->SetSamplerState(1, textureSampler);
  203. }
  204. void StaticMesh::SetupExternalUniformBuffer(DKObject<DKGpuBuffer> uniformBuffer, size_t uniformBufferSize, int index)
  205. {
  206. if (uniformBuffer == nullptr || bindSet == nullptr)
  207. return;
  208. bindSet->SetBuffer(index, uniformBuffer, 0, uniformBufferSize);
  209. }
  210. bool StaticMesh::EncodeRenderCommand(DKRenderCommandEncoder* encoder) const
  211. {
  212. encoder->SetVertexBuffer(mesh->vertexBuffers[0].buffer, 0, 0);
  213. encoder->SetIndexBuffer(mesh->subMeshes[0].indexBuffer, 0, mesh->subMeshes[0].indexType);
  214. encoder->SetResources(0, bindSet);
  215. // draw scene!
  216. encoder->DrawIndexed(mesh->subMeshes[0].indexCount, 1, 0, 0, 0);
  217. encoder->EndEncoding();
  218. return true;
  219. }