forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			207 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
package kha.graphics4;
 | 
						|
 | 
						|
import kha.arrays.Float32Array;
 | 
						|
import js.html.webgl.GL;
 | 
						|
import kha.arrays.ByteArray;
 | 
						|
import kha.graphics4.Usage;
 | 
						|
import kha.graphics4.VertexStructure;
 | 
						|
 | 
						|
class VertexBuffer {
 | 
						|
	public var _data: ByteArray;
 | 
						|
 | 
						|
	var buffer: Dynamic;
 | 
						|
	var mySize: Int;
 | 
						|
	var myStride: Int;
 | 
						|
	var sizes: Array<Int>;
 | 
						|
	var offsets: Array<Int>;
 | 
						|
	var types: Array<Int>;
 | 
						|
	var instanceDataStepRate: Int;
 | 
						|
	var lockStart: Int = 0;
 | 
						|
	var lockEnd: Int = 0;
 | 
						|
 | 
						|
	public function new(vertexCount: Int, structure: VertexStructure, usage: Usage, instanceDataStepRate: Int = 0, canRead: Bool = false) {
 | 
						|
		this.instanceDataStepRate = instanceDataStepRate;
 | 
						|
		mySize = vertexCount;
 | 
						|
		myStride = 0;
 | 
						|
		for (element in structure.elements) {
 | 
						|
			myStride += VertexStructure.dataByteSize(element.data);
 | 
						|
		}
 | 
						|
 | 
						|
		buffer = SystemImpl.gl.createBuffer();
 | 
						|
		_data = ByteArray.make(vertexCount * myStride);
 | 
						|
 | 
						|
		sizes = new Array<Int>();
 | 
						|
		offsets = new Array<Int>();
 | 
						|
		types = new Array<Int>();
 | 
						|
		sizes[structure.elements.length - 1] = 0;
 | 
						|
		offsets[structure.elements.length - 1] = 0;
 | 
						|
		types[structure.elements.length - 1] = 0;
 | 
						|
 | 
						|
		var offset = 0;
 | 
						|
		var index = 0;
 | 
						|
		for (element in structure.elements) {
 | 
						|
			var size;
 | 
						|
			var type;
 | 
						|
			switch (element.data) {
 | 
						|
				case Float32_1X:
 | 
						|
					size = 1;
 | 
						|
					type = GL.FLOAT;
 | 
						|
				case Float32_2X:
 | 
						|
					size = 2;
 | 
						|
					type = GL.FLOAT;
 | 
						|
				case Float32_3X:
 | 
						|
					size = 3;
 | 
						|
					type = GL.FLOAT;
 | 
						|
				case Float32_4X:
 | 
						|
					size = 4;
 | 
						|
					type = GL.FLOAT;
 | 
						|
				case Float32_4X4:
 | 
						|
					size = 4 * 4;
 | 
						|
					type = GL.FLOAT;
 | 
						|
				case Int8_1X, Int8_1X_Normalized:
 | 
						|
					size = 1;
 | 
						|
					type = GL.BYTE;
 | 
						|
				case Int8_2X, Int8_2X_Normalized:
 | 
						|
					size = 2;
 | 
						|
					type = GL.BYTE;
 | 
						|
				case Int8_4X, Int8_4X_Normalized:
 | 
						|
					size = 4;
 | 
						|
					type = GL.BYTE;
 | 
						|
				case UInt8_1X, UInt8_1X_Normalized:
 | 
						|
					size = 1;
 | 
						|
					type = GL.UNSIGNED_BYTE;
 | 
						|
				case UInt8_2X, UInt8_2X_Normalized:
 | 
						|
					size = 2;
 | 
						|
					type = GL.UNSIGNED_BYTE;
 | 
						|
				case UInt8_4X, UInt8_4X_Normalized:
 | 
						|
					size = 4;
 | 
						|
					type = GL.UNSIGNED_BYTE;
 | 
						|
				case Int16_1X, Int16_1X_Normalized:
 | 
						|
					size = 1;
 | 
						|
					type = GL.SHORT;
 | 
						|
				case Int16_2X, Int16_2X_Normalized:
 | 
						|
					size = 2;
 | 
						|
					type = GL.SHORT;
 | 
						|
				case Int16_4X, Int16_4X_Normalized:
 | 
						|
					size = 4;
 | 
						|
					type = GL.SHORT;
 | 
						|
				case UInt16_1X, UInt16_1X_Normalized:
 | 
						|
					size = 1;
 | 
						|
					type = GL.UNSIGNED_SHORT;
 | 
						|
				case UInt16_2X, UInt16_2X_Normalized:
 | 
						|
					size = 2;
 | 
						|
					type = GL.UNSIGNED_SHORT;
 | 
						|
				case UInt16_4X, UInt16_4X_Normalized:
 | 
						|
					size = 4;
 | 
						|
					type = GL.UNSIGNED_SHORT;
 | 
						|
				case Int32_1X:
 | 
						|
					size = 1;
 | 
						|
					type = GL.INT;
 | 
						|
				case Int32_2X:
 | 
						|
					size = 2;
 | 
						|
					type = GL.INT;
 | 
						|
				case Int32_3X:
 | 
						|
					size = 3;
 | 
						|
					type = GL.INT;
 | 
						|
				case Int32_4X:
 | 
						|
					size = 4;
 | 
						|
					type = GL.INT;
 | 
						|
				case UInt32_1X:
 | 
						|
					size = 1;
 | 
						|
					type = GL.UNSIGNED_INT;
 | 
						|
				case UInt32_2X:
 | 
						|
					size = 2;
 | 
						|
					type = GL.UNSIGNED_INT;
 | 
						|
				case UInt32_3X:
 | 
						|
					size = 3;
 | 
						|
					type = GL.UNSIGNED_INT;
 | 
						|
				case UInt32_4X:
 | 
						|
					size = 4;
 | 
						|
					type = GL.UNSIGNED_INT;
 | 
						|
			}
 | 
						|
			sizes[index] = size;
 | 
						|
			offsets[index] = offset;
 | 
						|
			types[index] = type;
 | 
						|
			offset += VertexStructure.dataByteSize(element.data);
 | 
						|
			++index;
 | 
						|
		}
 | 
						|
 | 
						|
		SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
 | 
						|
		SystemImpl.gl.bufferData(GL.ARRAY_BUFFER, _data.subarray(0 * stride(), mySize * stride()),
 | 
						|
			usage == Usage.DynamicUsage ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
 | 
						|
	}
 | 
						|
 | 
						|
	public function delete(): Void {
 | 
						|
		_data = null;
 | 
						|
		SystemImpl.gl.deleteBuffer(buffer);
 | 
						|
	}
 | 
						|
 | 
						|
	public function lock(?start: Int, ?count: Int): Float32Array {
 | 
						|
		lockStart = start != null ? start : 0;
 | 
						|
		lockEnd = count != null ? start + count : mySize;
 | 
						|
		return _data.subarray(lockStart * stride(), lockEnd * stride());
 | 
						|
	}
 | 
						|
 | 
						|
	public function unlock(?count: Int): Void {
 | 
						|
		if (count != null)
 | 
						|
			lockEnd = lockStart + count;
 | 
						|
		SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
 | 
						|
		if (SystemImpl.safari) {
 | 
						|
			SystemImpl.gl.bufferData(GL.ARRAY_BUFFER, _data.subarray(0 * stride(), lockEnd * stride()), GL.DYNAMIC_DRAW);
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			SystemImpl.gl.bufferSubData(GL.ARRAY_BUFFER, lockStart * stride(), _data.subarray(lockStart * stride(), lockEnd * stride()));
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public function stride(): Int {
 | 
						|
		return myStride;
 | 
						|
	}
 | 
						|
 | 
						|
	public function count(): Int {
 | 
						|
		return mySize;
 | 
						|
	}
 | 
						|
 | 
						|
	public function set(offset: Int): Int {
 | 
						|
		var ext: Dynamic = SystemImpl.gl2 ? true : SystemImpl.gl.getExtension("ANGLE_instanced_arrays");
 | 
						|
		SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
 | 
						|
		var attributesOffset = 0;
 | 
						|
		for (i in 0...sizes.length) {
 | 
						|
			if (sizes[i] > 4) {
 | 
						|
				var size = sizes[i];
 | 
						|
				var addonOffset = 0;
 | 
						|
				while (size > 0) {
 | 
						|
					SystemImpl.gl.enableVertexAttribArray(offset + attributesOffset);
 | 
						|
					SystemImpl.gl.vertexAttribPointer(offset + attributesOffset, 4, GL.FLOAT, false, myStride, offsets[i] + addonOffset);
 | 
						|
					if (ext) {
 | 
						|
						if (SystemImpl.gl2) {
 | 
						|
							untyped SystemImpl.gl.vertexAttribDivisor(offset + attributesOffset, instanceDataStepRate);
 | 
						|
						}
 | 
						|
						else {
 | 
						|
							ext.vertexAttribDivisorANGLE(offset + attributesOffset, instanceDataStepRate);
 | 
						|
						}
 | 
						|
					}
 | 
						|
					size -= 4;
 | 
						|
					addonOffset += 4 * 4;
 | 
						|
					++attributesOffset;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				var normalized = types[i] == GL.FLOAT ? false : true;
 | 
						|
				SystemImpl.gl.enableVertexAttribArray(offset + attributesOffset);
 | 
						|
				SystemImpl.gl.vertexAttribPointer(offset + attributesOffset, sizes[i], types[i], normalized, myStride, offsets[i]);
 | 
						|
				if (ext) {
 | 
						|
					if (SystemImpl.gl2) {
 | 
						|
						untyped SystemImpl.gl.vertexAttribDivisor(offset + attributesOffset, instanceDataStepRate);
 | 
						|
					}
 | 
						|
					else {
 | 
						|
						ext.vertexAttribDivisorANGLE(offset + attributesOffset, instanceDataStepRate);
 | 
						|
					}
 | 
						|
				}
 | 
						|
				++attributesOffset;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		return attributesOffset;
 | 
						|
	}
 | 
						|
}
 |