renderBufferDirect method
void
renderBufferDirect()
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);
}
}