yzt
2023-05-26 de4278af2fd46705a40bac58ec01122db6b7f3d7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import BlendingState from "../BlendingState.js";
import clone from "../../Core/clone.js";
import defined from "../../Core/defined.js";
import DrawCommand from "../../Renderer/DrawCommand.js";
import ModelExperimentalFS from "../../Shaders/ModelExperimental/ModelExperimentalFS.js";
import ModelExperimentalVS from "../../Shaders/ModelExperimental/ModelExperimentalVS.js";
import Pass from "../../Renderer/Pass.js";
import RenderState from "../../Renderer/RenderState.js";
import RuntimeError from "../../Core/RuntimeError.js";
import StyleCommandsNeeded from "./StyleCommandsNeeded.js";
import VertexArray from "../../Renderer/VertexArray.js";
 
/**
 * Builds the DrawCommands for a {@link ModelExperimentalPrimitive} using its render resources.
 *
 * @param {PrimitiveRenderResources} primitiveRenderResources The render resources for a primitive.
 * @param {FrameState} frameState The frame state for creating GPU resources.
 *
 * @returns {DrawCommand[]} The generated DrawCommands.
 *
 * @private
 */
export default function buildDrawCommands(
  primitiveRenderResources,
  frameState
) {
  var shaderBuilder = primitiveRenderResources.shaderBuilder;
  shaderBuilder.addVertexLines([ModelExperimentalVS]);
  shaderBuilder.addFragmentLines([ModelExperimentalFS]);
 
  var indexBuffer = defined(primitiveRenderResources.indices)
    ? primitiveRenderResources.indices.buffer
    : undefined;
 
  var vertexArray = new VertexArray({
    context: frameState.context,
    indexBuffer: indexBuffer,
    attributes: primitiveRenderResources.attributes,
  });
 
  var model = primitiveRenderResources.model;
  model._resources.push(vertexArray);
 
  var renderState = RenderState.fromCache(
    primitiveRenderResources.renderStateOptions
  );
 
  var shaderProgram = shaderBuilder.buildShaderProgram(frameState.context);
  model._resources.push(shaderProgram);
 
  var pass = primitiveRenderResources.alphaOptions.pass;
 
  var command = new DrawCommand({
    boundingVolume: primitiveRenderResources.boundingSphere,
    modelMatrix: primitiveRenderResources.modelMatrix,
    uniformMap: primitiveRenderResources.uniformMap,
    renderState: renderState,
    vertexArray: vertexArray,
    shaderProgram: shaderProgram,
    cull: model.cull,
    pass: pass,
    count: primitiveRenderResources.count,
    pickId: primitiveRenderResources.pickId,
    instanceCount: primitiveRenderResources.instanceCount,
    primitiveType: primitiveRenderResources.primitiveType,
    debugShowBoundingVolume: model.debugShowBoundingVolume,
  });
 
  var styleCommandsNeeded = primitiveRenderResources.styleCommandsNeeded;
 
  var commandList = [];
 
  if (defined(styleCommandsNeeded)) {
    var derivedCommands = createDerivedCommands(command);
 
    if (pass !== Pass.TRANSLUCENT) {
      switch (styleCommandsNeeded) {
        case StyleCommandsNeeded.ALL_OPAQUE:
          commandList.push(command);
          break;
        case StyleCommandsNeeded.ALL_TRANSLUCENT:
          commandList.push(derivedCommands.translucent);
          break;
        case StyleCommandsNeeded.OPAQUE_AND_TRANSLUCENT:
          // Push both opaque and translucent commands. The rendering of features based on opacity is handled in the shaders.
          commandList.push(command, derivedCommands.translucent);
          break;
        //>>includeStart('debug', pragmas.debug);
        default:
          throw new RuntimeError("styleCommandsNeeded is not a valid value.");
        //>>includeEnd('debug');
      }
    } else {
      // Command was originally translucent so no need to derive new commands;
      // as of now, a style can't change an originally translucent feature to
      // opaque since the style's alpha is modulated, not a replacement.  When
      // this changes, we need to derive new opaque commands here.
      commandList.push(command);
    }
  } else {
    commandList.push(command);
  }
 
  return commandList;
}
 
/**
 * @private
 */
function createDerivedCommands(command) {
  var derivedCommands = {};
  derivedCommands.translucent = deriveTranslucentCommand(command);
  return derivedCommands;
}
 
/**
 * @private
 */
function deriveTranslucentCommand(command) {
  var derivedCommand = DrawCommand.shallowClone(command);
  derivedCommand.pass = Pass.TRANSLUCENT;
  var rs = clone(command.renderState, true);
  rs.cull.enabled = false;
  rs.depthTest.enabled = true;
  rs.depthMask = false;
  rs.blending = BlendingState.ALPHA_BLEND;
  derivedCommand.renderState = RenderState.fromCache(rs);
  return derivedCommand;
}