renderBufferDirect method

void renderBufferDirect(
  1. Camera camera,
  2. Object3D? scene,
  3. BufferGeometry geometry,
  4. Material material,
  5. Object3D object,
  6. Map<String, dynamic>? group,
)

Implementation

void renderBufferDirect(
  Camera camera,
  Object3D? scene,
  BufferGeometry geometry,
  Material material,
  Object3D object,
  Map<String, dynamic>? group,
) {
  // print("renderBufferDirect .............material: ${material.runtimeType}  ");
  // renderBufferDirect second parameter used to be fog (could be null)
  scene ??= _emptyScene;
  final frontFaceCW = (object is Mesh && object.matrixWorld.determinant() < 0);

  WebGLProgram program = setProgram(camera, scene, geometry, material, object);

  state.setMaterial(material, frontFaceCW);

  BufferAttribute? index = geometry.index;
  int rangeFactor = 1;

  if (material.wireframe) {
    index = geometries.getWireframeAttribute(geometry);
    if (index == null) return;
    if(kIsWeb && !kIsWasm){
      rangeFactor = 2;
    }
  }

  if (geometry.morphAttributes["position"] != null || geometry.morphAttributes["normal"] != null) {
    morphtargets.update(object, geometry, program);
  }

  final drawRange = geometry.drawRange;
  BufferAttribute? position = geometry.attributes["position"];
  int drawStart = drawRange['start']! * rangeFactor;
  int drawEnd = ( drawRange['start']! + drawRange['count']! ) * rangeFactor;

  if ( group != null ) {
    drawStart = math.max( drawStart, group['start'] * rangeFactor );
    drawEnd = math.min( drawEnd, ( group['start'] + group['count'] ) * rangeFactor );
  }

  if ( index != null ) {
    drawStart = math.max( drawStart, 0 );
    drawEnd = math.min( drawEnd, index.count );
  } else if (position != null) {
    drawStart = math.max( drawStart, 0 );
    drawEnd = math.min( drawEnd, position.count );
  }

  final drawCount = drawEnd - drawStart;
  if ( drawCount < 0 || drawCount == double.maxFinite.toInt() ) return;

  bindingStates.setup(object, material, program, geometry, index);

  Map<String, dynamic> attribute;
  BaseWebGLBufferRenderer renderer = bufferRenderer;

  if (index != null) {
    attribute = attributes.get(index);
    renderer = indexedBufferRenderer;
    renderer.setIndex(attribute);
  }

  if (object is Mesh) {
    if (material.wireframe) {
      state.setLineWidth(material.wireframeLinewidth! * getTargetPixelRatio());
      renderer.setMode(WebGL.LINES);
    }
    else {
      renderer.setMode(WebGL.TRIANGLES);
    }
  }
  else if (object is Line) {
    double? lineWidth = material.linewidth;

    lineWidth ??= 1; // Not using Line*Material

    state.setLineWidth(lineWidth * getTargetPixelRatio());

    if (object is LineSegments) {
      renderer.setMode(WebGL.LINES);
    }
    else if (object is LineLoop) {
      renderer.setMode(WebGL.LINE_LOOP);
    }
    else {
      renderer.setMode(WebGL.LINE_STRIP);
    }
  }
  else if (object is Points) {
    renderer.setMode(WebGL.POINTS);
  }
  else if (object is Sprite) {
    renderer.setMode(WebGL.TRIANGLES);
  }

  if ( object is BatchedMesh ) {
    if (object.multiDrawInstances != null ) {
      renderer.renderMultiDrawInstances( object.multiDrawStarts, object.multiDrawCounts, object.multiDrawCount, object.multiDrawInstances! );
    }
    else {
      if ( ! extensions.get( 'WEBGL_multi_draw' ) ) {
        final starts = object.multiDrawStarts;
        final counts = object.multiDrawCounts;
        final drawCount = object.multiDrawCount;
        final bytesPerElement = index != null? attributes.get( index ).bytesPerElement : 1;
        final uniforms = properties.get( material )['currentProgram'].getUniforms();

        for ( int i = 0; i < drawCount; i ++ ) {
          uniforms.setValue( _gl, '_gl_DrawID', i );
          renderer.render( starts[ i ] ~/ bytesPerElement, counts[ i ] );
        }
      }
      else {
        renderer.renderMultiDraw( object.multiDrawStarts, object.multiDrawCounts, object.multiDrawCount );
      }
    }
  }
  if (object is InstancedMesh) {
    renderer.renderInstances(drawStart, drawCount, object.count!);
  }
  else if (geometry is InstancedBufferGeometry) {
    final instanceCount = math.min(geometry.instanceCount!, geometry.maxInstanceCount ?? 0);
    renderer.renderInstances(drawStart, drawCount, instanceCount);
  }
  else {
    renderer.render(drawStart, drawCount);
  }
}