ThreeJS WebGLBufferRenderer/WebGLIndexedBufferRenderer DrawCall与API

537 阅读1分钟
// 绘制的类型
const GLenum POINTS                         = 0x0000;
const GLenum LINES                          = 0x0001;
const GLenum LINE_LOOP                      = 0x0002;
const GLenum LINE_STRIP                     = 0x0003;
const GLenum TRIANGLES                      = 0x0004;
const GLenum TRIANGLE_STRIP                 = 0x0005;
const GLenum TRIANGLE_FAN                   = 0x0006;

void drawArrays(GLenum mode,  //按照mode参数指定的方式绘制图形,上面
                GLint first,  //指定从哪个定点开始绘制
                GLsizei count); //指定绘制需要用到多少个顶点
				
void drawElements(GLenum mode, //按照mode参数指定的方式绘制图形,上面
                  GLsizei count, //指定绘制需要用到多少个顶点
                  GLenum type, //指定索引值数据类型。包括:UNSIGNED_BYTE、UNSIGNED_SHORT、UNSIGNED_INT 注意这三个
                  GLintptr offset); //指定索引数组中绘制的偏移位置,以字节为单位
drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount)
  • drawCall
    • drawArrays
    • drawElements
    • drawArraysInstancedANGLE
    • drawArraysInstanced
    • drawElementsInstanced
    • drawElementsInstancedANGLE
  • render
    • mode, start, count
    • 不考虑不同object,只考虑顶点数据起始,与总数
function WebGLBufferRenderer( gl, extensions, info, capabilities ) {
	const isWebGL2 = capabilities.isWebGL2;
	let mode;
	function setMode( value ) {
		mode = value;
	}
	//调用 WebGLBufferRenderer#render() 方法进行渲染。如下,就是进行最后的 drawArrays() 调用,将上层创建的 geometry 以及 material(组合起来就叫做 mesh) 渲染到 3D 场景的 canvas 中。
	function render( start, count ) {
		gl.drawArrays( mode, start, count ); 
		info.update( count, mode, 1 );
	}
	function renderInstances( start, count, primcount ) {
		if ( primcount === 0 ) return;
		let extension, methodName;
		if ( isWebGL2 ) {
			extension = gl;
			methodName = 'drawArraysInstanced';
		} else {
			extension = extensions.get( 'ANGLE_instanced_arrays' );
			methodName = 'drawArraysInstancedANGLE';
			if ( extension === null ) {
				console.error(
					'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.'
				);
				return;
			}
		}
		extension[ methodName ]( mode, start, count, primcount );
		info.update( count, mode, primcount );
	}
	//
	this.setMode = setMode;
	this.render = render;
	this.renderInstances = renderInstances;
}
function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) {
	const isWebGL2 = capabilities.isWebGL2;
	let mode;
	function setMode( value ) {
		mode = value;
	}
	let type, bytesPerElement;
	function setIndex( value ) {
		type = value.type;
		bytesPerElement = value.bytesPerElement;
	}
	function render( start, count ) {
		gl.drawElements( mode, count, type, start * bytesPerElement );
		info.update( count, mode, 1 );
	}
	function renderInstances( start, count, primcount ) {
		if ( primcount === 0 ) return;
		let extension, methodName;
		if ( isWebGL2 ) {
			extension = gl;
			methodName = 'drawElementsInstanced';
		} else {
			extension = extensions.get( 'ANGLE_instanced_arrays' );
			methodName = 'drawElementsInstancedANGLE';
			if ( extension === null ) {
				console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
				return;
			}
		}
		extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount );
		info.update( count, mode, primcount );
	}
	//
	this.setMode = setMode;
	this.setIndex = setIndex;
	this.render = render;
	this.renderInstances = renderInstances;
}
gl.drawArrays(gl.TRIANGLES, 0, n);  //n 一般是 数组/3
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); //n 一般是indices.length
ext = gl.getExtension("ANGLE_instanced_arrays");
ext.vertexAttribDivisorANGLE(aOffsetLocation, 1);
ext.vertexAttribDivisorANGLE(aColorLocation, 1);
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount);