buildDrawCommand.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import BoundingSphere from "../../Core/BoundingSphere.js";
  2. import clone from "../../Core/clone.js";
  3. import defined from "../../Core/defined.js";
  4. import DeveloperError from "../../Core/DeveloperError.js";
  5. import Matrix4 from "../../Core/Matrix4.js";
  6. import DrawCommand from "../../Renderer/DrawCommand.js";
  7. import RenderState from "../../Renderer/RenderState.js";
  8. import VertexArray from "../../Renderer/VertexArray.js";
  9. import ModelFS from "../../Shaders/Model/ModelFS.js";
  10. import ModelVS from "../../Shaders/Model/ModelVS.js";
  11. import SceneMode from "../SceneMode.js";
  12. import ShadowMode from "../ShadowMode.js";
  13. import ClassificationModelDrawCommand from "./ClassificationModelDrawCommand.js";
  14. import ModelUtility from "./ModelUtility.js";
  15. import ModelDrawCommand from "./ModelDrawCommand.js";
  16. /**
  17. * Builds the {@link ModelDrawCommand} for a {@link ModelRuntimePrimitive}
  18. * using its render resources. If the model classifies another asset, it
  19. * builds a {@link ClassificationModelDrawCommand} instead.
  20. *
  21. * @param {PrimitiveRenderResources} primitiveRenderResources The render resources for a primitive.
  22. * @param {FrameState} frameState The frame state for creating GPU resources.
  23. *
  24. * @returns {ModelDrawCommand|ClassificationModelDrawCommand} The generated ModelDrawCommand or ClassificationModelDrawCommand.
  25. *
  26. * @private
  27. */
  28. function buildDrawCommand(primitiveRenderResources, frameState) {
  29. const shaderBuilder = primitiveRenderResources.shaderBuilder;
  30. shaderBuilder.addVertexLines(ModelVS);
  31. shaderBuilder.addFragmentLines(ModelFS);
  32. const indexBuffer = getIndexBuffer(primitiveRenderResources);
  33. const vertexArray = new VertexArray({
  34. context: frameState.context,
  35. indexBuffer: indexBuffer,
  36. attributes: primitiveRenderResources.attributes,
  37. });
  38. const model = primitiveRenderResources.model;
  39. model._pipelineResources.push(vertexArray);
  40. const shaderProgram = shaderBuilder.buildShaderProgram(frameState.context);
  41. model._pipelineResources.push(shaderProgram);
  42. const pass = primitiveRenderResources.alphaOptions.pass;
  43. const sceneGraph = model.sceneGraph;
  44. const is3D = frameState.mode === SceneMode.SCENE3D;
  45. let modelMatrix, boundingSphere;
  46. if (!is3D && !frameState.scene3DOnly && model._projectTo2D) {
  47. modelMatrix = Matrix4.multiplyTransformation(
  48. sceneGraph._computedModelMatrix,
  49. primitiveRenderResources.runtimeNode.computedTransform,
  50. new Matrix4()
  51. );
  52. const runtimePrimitive = primitiveRenderResources.runtimePrimitive;
  53. boundingSphere = runtimePrimitive.boundingSphere2D;
  54. } else {
  55. const computedModelMatrix = is3D
  56. ? sceneGraph._computedModelMatrix
  57. : sceneGraph._computedModelMatrix2D;
  58. modelMatrix = Matrix4.multiplyTransformation(
  59. computedModelMatrix,
  60. primitiveRenderResources.runtimeNode.computedTransform,
  61. new Matrix4()
  62. );
  63. boundingSphere = BoundingSphere.transform(
  64. primitiveRenderResources.boundingSphere,
  65. modelMatrix,
  66. primitiveRenderResources.boundingSphere
  67. );
  68. }
  69. // Initialize render state with default values
  70. let renderState = clone(
  71. RenderState.fromCache(primitiveRenderResources.renderStateOptions),
  72. true
  73. );
  74. renderState.cull.face = ModelUtility.getCullFace(
  75. modelMatrix,
  76. primitiveRenderResources.primitiveType
  77. );
  78. renderState = RenderState.fromCache(renderState);
  79. const hasClassification = defined(model.classificationType);
  80. const castShadows = hasClassification
  81. ? false
  82. : ShadowMode.castShadows(model.shadows);
  83. const receiveShadows = hasClassification
  84. ? false
  85. : ShadowMode.receiveShadows(model.shadows);
  86. // Pick IDs are only added to specific draw commands for classification.
  87. // This behavior is handled by ClassificationModelDrawCommand.
  88. const pickId = hasClassification
  89. ? undefined
  90. : primitiveRenderResources.pickId;
  91. const command = new DrawCommand({
  92. boundingVolume: boundingSphere,
  93. modelMatrix: modelMatrix,
  94. uniformMap: primitiveRenderResources.uniformMap,
  95. renderState: renderState,
  96. vertexArray: vertexArray,
  97. shaderProgram: shaderProgram,
  98. cull: model.cull,
  99. pass: pass,
  100. count: primitiveRenderResources.count,
  101. owner: model,
  102. pickId: pickId,
  103. instanceCount: primitiveRenderResources.instanceCount,
  104. primitiveType: primitiveRenderResources.primitiveType,
  105. debugShowBoundingVolume: model.debugShowBoundingVolume,
  106. castShadows: castShadows,
  107. receiveShadows: receiveShadows,
  108. });
  109. if (hasClassification) {
  110. return new ClassificationModelDrawCommand({
  111. primitiveRenderResources: primitiveRenderResources,
  112. command: command,
  113. });
  114. }
  115. return new ModelDrawCommand({
  116. primitiveRenderResources: primitiveRenderResources,
  117. command: command,
  118. });
  119. }
  120. /**
  121. * @private
  122. */
  123. function getIndexBuffer(primitiveRenderResources) {
  124. const wireframeIndexBuffer = primitiveRenderResources.wireframeIndexBuffer;
  125. if (defined(wireframeIndexBuffer)) {
  126. return wireframeIndexBuffer;
  127. }
  128. const indices = primitiveRenderResources.indices;
  129. if (!defined(indices)) {
  130. return undefined;
  131. }
  132. //>>includeStart('debug', pragmas.debug);
  133. if (!defined(indices.buffer)) {
  134. throw new DeveloperError("Indices must be provided as a Buffer");
  135. }
  136. //>>includeEnd('debug');
  137. return indices.buffer;
  138. }
  139. export default buildDrawCommand;