DynamicDrawExampleComponent.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project
  3. *
  4. * SPDX-License-Identifier: Apache-2.0 OR MIT
  5. *
  6. */
  7. #include <DynamicDrawExampleComponent.h>
  8. #include <SampleComponentManager.h>
  9. #include <Automation/ScriptableImGui.h>
  10. #include <Automation/ScriptRunnerBus.h>
  11. #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
  12. #include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
  13. #include <Atom/RPI.Public/RPIUtils.h>
  14. namespace AtomSampleViewer
  15. {
  16. void DynamicDrawExampleComponent::Reflect(AZ::ReflectContext* context)
  17. {
  18. if (AZ::SerializeContext * serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  19. {
  20. serializeContext->Class<DynamicDrawExampleComponent, AZ::Component>()
  21. ->Version(0)
  22. ;
  23. }
  24. }
  25. DynamicDrawExampleComponent::DynamicDrawExampleComponent()
  26. {
  27. m_sampleName = "DynamicDrawExampleComponent";
  28. }
  29. void DynamicDrawExampleComponent::Activate()
  30. {
  31. using namespace AZ;
  32. // List of all assets this example needs.
  33. AZStd::vector<AZ::AssetCollectionAsyncLoader::AssetToLoadInfo> assetList = {
  34. {"Shaders/dynamicdraw/dynamicdrawexample.azshader", azrtti_typeid<AZ::RPI::ShaderAsset>()},
  35. };
  36. ScriptRunnerRequestBus::Broadcast(&ScriptRunnerRequests::PauseScript);
  37. PreloadAssets(assetList);
  38. }
  39. void DynamicDrawExampleComponent::OnAllAssetsReadyActivate()
  40. {
  41. AZ::TickBus::Handler::BusConnect();
  42. m_imguiSidebar.Activate();
  43. using namespace AZ;
  44. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Enable,
  45. azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  46. AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequestBus::Events::SetPosition, Vector3(-0.11f, -3.01f, -0.02f));
  47. AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequestBus::Events::SetHeading, DegToRad(-4.0f));
  48. AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequestBus::Events::SetPitch, DegToRad(1.9f));
  49. // Create and initialize dynamic draw context
  50. m_dynamicDraw = RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(RPI::RPISystemInterface::Get()->GetDefaultScene().get());
  51. const char* shaderFilepath = "Shaders/dynamicdraw/dynamicdrawexample.azshader";
  52. Data::Asset<RPI::ShaderAsset> shaderAsset = m_assetLoadManager.GetAsset<RPI::ShaderAsset>(shaderFilepath);
  53. m_dynamicDraw->InitShader(shaderAsset);
  54. m_dynamicDraw->InitVertexFormat(
  55. {{ "POSITION", RHI::Format::R32G32B32_FLOAT },
  56. { "COLOR", RHI::Format::R32G32B32A32_FLOAT }}
  57. );
  58. m_dynamicDraw->AddDrawStateOptions(RPI::DynamicDrawContext::DrawStateOptions::BlendMode | RPI::DynamicDrawContext::DrawStateOptions::PrimitiveType
  59. | RPI::DynamicDrawContext::DrawStateOptions::DepthState | RPI::DynamicDrawContext::DrawStateOptions::FaceCullMode);
  60. m_dynamicDraw->EndInit();
  61. Data::Instance<RPI::ShaderResourceGroup> contextSrg = m_dynamicDraw->GetPerContextSrg();
  62. if (contextSrg)
  63. {
  64. auto index = contextSrg->FindShaderInputConstantIndex(Name("m_scale"));
  65. contextSrg->SetConstant(index, 1);
  66. contextSrg->Compile();
  67. }
  68. AZ_Assert(m_dynamicDraw->IsVertexSizeValid(sizeof(ExampleVertex)), "Invalid vertex format");
  69. ScriptRunnerRequestBus::Broadcast(&ScriptRunnerRequests::ResumeScript);
  70. }
  71. void DynamicDrawExampleComponent::Deactivate()
  72. {
  73. using namespace AZ;
  74. m_imguiSidebar.Deactivate();
  75. TickBus::Handler::BusDisconnect();
  76. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Disable);
  77. m_dynamicDraw = nullptr;
  78. m_contextSrg = nullptr;
  79. }
  80. void DynamicDrawExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
  81. {
  82. using namespace AZ;
  83. if (m_imguiSidebar.Begin())
  84. {
  85. ScriptableImGui::Checkbox("CullMode::None", &m_showCullModeNull);
  86. ScriptableImGui::Checkbox("CullMode: Front", &m_showCullModeFront);
  87. ScriptableImGui::Checkbox("CullMode: Back", &m_showCullModeBack);
  88. ScriptableImGui::Checkbox("PrimitiveTopology: LineList", &m_showLineList);
  89. ScriptableImGui::Checkbox("Alpha Blend", &m_showAlphaBlend);
  90. ScriptableImGui::Checkbox("Alpha Additive", &m_showAlphaAdditive);
  91. ScriptableImGui::Checkbox("Per Draw Viewport", &m_showPerDrawViewport);
  92. m_imguiSidebar.End();
  93. }
  94. // draw srg with default offset
  95. Data::Instance<RPI::ShaderResourceGroup> drawSrg = m_dynamicDraw->NewDrawSrg();
  96. auto index = drawSrg->FindShaderInputConstantIndex(Name("m_positionOffset"));
  97. drawSrg->SetConstant(index, Vector3(0, 0, 0));
  98. drawSrg->Compile();
  99. // Tetrahedron
  100. const uint32_t TetrahedronVertexCount = 12;
  101. const uint32_t TetrahedronIndexCount = 12;
  102. const uint32_t TetrahedronWireframeIndexCount = 6;
  103. float positions[4][3] =
  104. {
  105. { 0.2, 0.2f, 0.2f },
  106. { 0.2, -0.2f, -0.2f },
  107. { -0.2, 0.2f, -0.2f },
  108. { -0.2, -0.2f, 0.2f }
  109. };
  110. float colors[4][4] = { { 1, 0, 0, 0.5f }, { 0, 1, 0, 0.5f }, { 0, 0, 1, 0.5f }, {1, 1, 0, 0.5f}};
  111. ExampleVertex tetrahedronVerts[TetrahedronVertexCount] = {
  112. ExampleVertex{positions[0], colors[0]}, // 0
  113. ExampleVertex{positions[3], colors[0]}, // 3
  114. ExampleVertex{positions[1], colors[0]}, // 1
  115. ExampleVertex{positions[0], colors[1]}, // 0
  116. ExampleVertex{positions[1], colors[1]}, // 1
  117. ExampleVertex{positions[2], colors[1]}, // 2
  118. ExampleVertex{positions[0], colors[2]}, // 0
  119. ExampleVertex{positions[2], colors[2]}, // 2
  120. ExampleVertex{positions[3], colors[2]}, // 3
  121. ExampleVertex{positions[1], colors[3]}, // 1
  122. ExampleVertex{positions[3], colors[3]}, // 3
  123. ExampleVertex{positions[2], colors[3]} // 2
  124. };
  125. u16 tetrahedronIndices[TetrahedronIndexCount] = {
  126. 0, 1, 2,
  127. 3, 4, 5,
  128. 6, 7, 8,
  129. 9, 10, 11
  130. };
  131. ExampleVertex tetrahedronWireFrameVerts[4] = {
  132. ExampleVertex{ positions[0], colors[0] },
  133. ExampleVertex{ positions[1], colors[1] },
  134. ExampleVertex{ positions[2], colors[2] },
  135. ExampleVertex{ positions[3], colors[3] }
  136. };
  137. u16 tetrahedronWireframeIndices[TetrahedronIndexCount] =
  138. {
  139. 0, 1,
  140. 0, 2,
  141. 0, 3,
  142. 1, 2,
  143. 2, 3,
  144. 3, 1
  145. };
  146. // Enable depth test and write
  147. RHI::DepthState depthState;
  148. depthState.m_enable = true;
  149. depthState.m_writeMask = RHI::DepthWriteMask::All;
  150. depthState.m_func = RHI::ComparisonFunc::GreaterEqual;
  151. m_dynamicDraw->SetDepthState(depthState);
  152. // Disable blend
  153. RHI::TargetBlendState blendState;
  154. blendState.m_enable = false;
  155. m_dynamicDraw->SetTarget0BlendState(blendState);
  156. float xPos = -1.5f;
  157. const float xOffset = 0.5f;
  158. // no cull
  159. if (m_showCullModeNull)
  160. {
  161. m_dynamicDraw->SetCullMode(RHI::CullMode::None);
  162. drawSrg = m_dynamicDraw->NewDrawSrg();
  163. drawSrg->SetConstant(index, Vector3(xPos, 0, 0));
  164. drawSrg->Compile();
  165. m_dynamicDraw->DrawIndexed(tetrahedronVerts, TetrahedronVertexCount, tetrahedronIndices, TetrahedronIndexCount, RHI::IndexFormat::Uint16, drawSrg);
  166. }
  167. //front cull
  168. xPos += xOffset;
  169. if (m_showCullModeFront)
  170. {
  171. m_dynamicDraw->SetCullMode(RHI::CullMode::Front);
  172. drawSrg = m_dynamicDraw->NewDrawSrg();
  173. drawSrg->SetConstant(index, Vector3(xPos, 0, 0));
  174. drawSrg->Compile();
  175. m_dynamicDraw->DrawIndexed(tetrahedronVerts, TetrahedronVertexCount, tetrahedronIndices, TetrahedronIndexCount, RHI::IndexFormat::Uint16, drawSrg);
  176. m_dynamicDraw->SetCullMode(RHI::CullMode::None);
  177. }
  178. // back cull
  179. xPos += xOffset;
  180. if (m_showCullModeBack)
  181. {
  182. m_dynamicDraw->SetCullMode(RHI::CullMode::Back);
  183. drawSrg = m_dynamicDraw->NewDrawSrg();
  184. drawSrg->SetConstant(index, Vector3(xPos, 0, 0));
  185. drawSrg->Compile();
  186. m_dynamicDraw->DrawIndexed(tetrahedronVerts, TetrahedronVertexCount, tetrahedronIndices, TetrahedronIndexCount, RHI::IndexFormat::Uint16, drawSrg);
  187. m_dynamicDraw->SetCullMode(RHI::CullMode::None);
  188. }
  189. // Draw line lists
  190. xPos += xOffset;
  191. if (m_showLineList)
  192. {
  193. drawSrg = m_dynamicDraw->NewDrawSrg();
  194. drawSrg->SetConstant(index, Vector3(xPos, 0, 0));
  195. drawSrg->Compile();
  196. m_dynamicDraw->SetPrimitiveType(RHI::PrimitiveTopology::LineList);
  197. m_dynamicDraw->DrawIndexed(tetrahedronWireFrameVerts, 4, tetrahedronWireframeIndices, TetrahedronIndexCount, RHI::IndexFormat::Uint16, drawSrg);
  198. m_dynamicDraw->SetPrimitiveType(RHI::PrimitiveTopology::TriangleList);
  199. }
  200. // disable depth write
  201. depthState.m_writeMask = RHI::DepthWriteMask::Zero;
  202. m_dynamicDraw->SetDepthState(depthState);
  203. // alpha blend
  204. xPos += xOffset;
  205. if (m_showAlphaBlend)
  206. {
  207. blendState.m_enable = true;
  208. blendState.m_blendOp = RHI::BlendOp::Add;
  209. blendState.m_blendSource = RHI::BlendFactor::AlphaSource;
  210. blendState.m_blendDest = RHI::BlendFactor::AlphaSourceInverse;
  211. m_dynamicDraw->SetTarget0BlendState(blendState);
  212. drawSrg = m_dynamicDraw->NewDrawSrg();
  213. drawSrg->SetConstant(index, Vector3(xPos, 0, 0));
  214. drawSrg->Compile();
  215. m_dynamicDraw->DrawIndexed(tetrahedronVerts, TetrahedronVertexCount, tetrahedronIndices, TetrahedronIndexCount, RHI::IndexFormat::Uint16, drawSrg);
  216. }
  217. // alpha additive
  218. xPos += xOffset;
  219. if (m_showAlphaAdditive)
  220. {
  221. blendState.m_enable = true;
  222. blendState.m_blendOp = RHI::BlendOp::Add;
  223. blendState.m_blendSource = RHI::BlendFactor::AlphaSource;
  224. blendState.m_blendDest = RHI::BlendFactor::One;
  225. m_dynamicDraw->SetTarget0BlendState(blendState);
  226. drawSrg = m_dynamicDraw->NewDrawSrg();
  227. drawSrg->SetConstant(index, Vector3(xPos, 0, 0));
  228. drawSrg->Compile();
  229. m_dynamicDraw->DrawIndexed(tetrahedronVerts, TetrahedronVertexCount, tetrahedronIndices, TetrahedronIndexCount, RHI::IndexFormat::Uint16, drawSrg);
  230. }
  231. // enable depth write
  232. depthState.m_writeMask = RHI::DepthWriteMask::All;
  233. m_dynamicDraw->SetDepthState(depthState);
  234. // disable blend
  235. blendState.m_enable = false;
  236. m_dynamicDraw->SetTarget0BlendState(blendState);
  237. // per draw viewport
  238. xPos += xOffset;
  239. if (m_showPerDrawViewport)
  240. {
  241. m_dynamicDraw->SetViewport(RHI::Viewport(0, 200, 0, 200));
  242. drawSrg = m_dynamicDraw->NewDrawSrg();
  243. drawSrg->SetConstant(index, Vector3(0, 0, 0));
  244. drawSrg->Compile();
  245. m_dynamicDraw->DrawIndexed(tetrahedronVerts, TetrahedronVertexCount, tetrahedronIndices, TetrahedronIndexCount, RHI::IndexFormat::Uint16, drawSrg);
  246. m_dynamicDraw->UnsetViewport();
  247. }
  248. }
  249. } // namespace AtomSampleViewer