134 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
package kha.graphics4;
 | 
						|
 | 
						|
import js.html.webgl.GL;
 | 
						|
import kha.graphics4.VertexData;
 | 
						|
 | 
						|
class PipelineState extends PipelineStateBase {
 | 
						|
	var program: Dynamic = null;
 | 
						|
	var textures: Array<String>;
 | 
						|
	var textureValues: Array<Dynamic>;
 | 
						|
 | 
						|
	public function new() {
 | 
						|
		super();
 | 
						|
		textures = new Array<String>();
 | 
						|
		textureValues = new Array<Dynamic>();
 | 
						|
	}
 | 
						|
 | 
						|
	public function delete(): Void {
 | 
						|
		if (program != null) {
 | 
						|
			SystemImpl.gl.deleteProgram(program);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public function compile(): Void {
 | 
						|
		if (program != null) {
 | 
						|
			SystemImpl.gl.deleteProgram(program);
 | 
						|
		}
 | 
						|
		program = SystemImpl.gl.createProgram();
 | 
						|
		compileShader(vertexShader);
 | 
						|
		compileShader(fragmentShader);
 | 
						|
		SystemImpl.gl.attachShader(program, vertexShader.shader);
 | 
						|
		SystemImpl.gl.attachShader(program, fragmentShader.shader);
 | 
						|
 | 
						|
		var index = 0;
 | 
						|
		for (structure in inputLayout) {
 | 
						|
			for (element in structure.elements) {
 | 
						|
				SystemImpl.gl.bindAttribLocation(program, index, element.name);
 | 
						|
				if (element.data == VertexData.Float32_4X4) {
 | 
						|
					index += 4;
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					++index;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		SystemImpl.gl.linkProgram(program);
 | 
						|
		if (!SystemImpl.gl.getProgramParameter(program, GL.LINK_STATUS)) {
 | 
						|
			var message = "Could not link the shader program:\n" + SystemImpl.gl.getProgramInfoLog(program);
 | 
						|
			trace("Error: " + message);
 | 
						|
			throw message;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public function set(): Void {
 | 
						|
		SystemImpl.gl.useProgram(program);
 | 
						|
		for (index in 0...textureValues.length)
 | 
						|
			SystemImpl.gl.uniform1i(textureValues[index], index);
 | 
						|
		SystemImpl.gl.colorMask(colorWriteMaskRed, colorWriteMaskGreen, colorWriteMaskBlue, colorWriteMaskAlpha);
 | 
						|
	}
 | 
						|
 | 
						|
	function compileShader(shader: Dynamic): Void {
 | 
						|
		if (shader.shader != null)
 | 
						|
			return;
 | 
						|
		var s = SystemImpl.gl.createShader(shader.type);
 | 
						|
		var highp = SystemImpl.gl.getShaderPrecisionFormat(GL.FRAGMENT_SHADER, GL.HIGH_FLOAT);
 | 
						|
		var highpSupported = highp.precision != 0;
 | 
						|
		var files: Array<String> = shader.files;
 | 
						|
		for (i in 0...files.length) {
 | 
						|
			if (SystemImpl.gl2) {
 | 
						|
				if (files[i].indexOf("-webgl2") >= 0 || files[i].indexOf("runtime-string") >= 0) {
 | 
						|
					SystemImpl.gl.shaderSource(s, shader.sources[i]);
 | 
						|
					break;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				if (!highpSupported && (files[i].indexOf("-relaxed") >= 0 || files[i].indexOf("runtime-string") >= 0)) {
 | 
						|
					SystemImpl.gl.shaderSource(s, shader.sources[i]);
 | 
						|
					break;
 | 
						|
				}
 | 
						|
				if (highpSupported && (files[i].indexOf("-relaxed") < 0 || files[i].indexOf("runtime-string") >= 0)) {
 | 
						|
					SystemImpl.gl.shaderSource(s, shader.sources[i]);
 | 
						|
					break;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		SystemImpl.gl.compileShader(s);
 | 
						|
		if (!SystemImpl.gl.getShaderParameter(s, GL.COMPILE_STATUS)) {
 | 
						|
			var message = "Could not compile shader:\n" + SystemImpl.gl.getShaderInfoLog(s);
 | 
						|
			trace("Error: " + message);
 | 
						|
			throw message;
 | 
						|
		}
 | 
						|
		shader.shader = s;
 | 
						|
	}
 | 
						|
 | 
						|
	public function getConstantLocation(name: String): kha.graphics4.ConstantLocation {
 | 
						|
		var location = SystemImpl.gl.getUniformLocation(program, name);
 | 
						|
		if (location == null) {
 | 
						|
			trace("Warning: Uniform " + name + " not found.");
 | 
						|
		}
 | 
						|
		var type = GL.FLOAT;
 | 
						|
		var count: Int = SystemImpl.gl.getProgramParameter(program, GL.ACTIVE_UNIFORMS);
 | 
						|
		for (i in 0...count) {
 | 
						|
			var info = SystemImpl.gl.getActiveUniform(program, i);
 | 
						|
			if (info.name == name || info.name == name + "[0]") {
 | 
						|
				type = info.type;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		return new kha.js.graphics4.ConstantLocation(location, type);
 | 
						|
	}
 | 
						|
 | 
						|
	public function getTextureUnit(name: String): kha.graphics4.TextureUnit {
 | 
						|
		var index = findTexture(name);
 | 
						|
		if (index < 0) {
 | 
						|
			var location = SystemImpl.gl.getUniformLocation(program, name);
 | 
						|
			if (location == null) {
 | 
						|
				trace("Warning: Sampler " + name + " not found.");
 | 
						|
			}
 | 
						|
			index = textures.length;
 | 
						|
			textureValues.push(location);
 | 
						|
			textures.push(name);
 | 
						|
		}
 | 
						|
		return new kha.js.graphics4.TextureUnit(index);
 | 
						|
	}
 | 
						|
 | 
						|
	function findTexture(name: String): Int {
 | 
						|
		for (index in 0...textures.length) {
 | 
						|
			if (textures[index] == name)
 | 
						|
				return index;
 | 
						|
		}
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
}
 |