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;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |