forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			402 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			402 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package iron.data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import kha.graphics4.PipelineState;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.ConstantLocation;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.TextureUnit;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.VertexStructure;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.VertexData;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.CompareMode;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.CullMode;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.BlendingOperation;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.BlendingFactor;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.TextureAddressing;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.TextureFilter;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.MipMapFilter;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.VertexShader;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.FragmentShader;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.TextureFormat;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.DepthStencilFormat;
							 | 
						||
| 
								 | 
							
								import iron.data.SceneFormat;
							 | 
						||
| 
								 | 
							
								using StringTools;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class ShaderData {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var name: String;
							 | 
						||
| 
								 | 
							
									public var raw: TShaderData;
							 | 
						||
| 
								 | 
							
									public var contexts: Array<ShaderContext> = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#if (lnx_noembed && kha_krom)
							 | 
						||
| 
								 | 
							
									public static var shaderPath = "../krom-resources/";
							 | 
						||
| 
								 | 
							
									public static inline var shaderExt = #if kha_vulkan ".spirv" #elseif (krom_android || krom_wasm) ".essl" #elseif kha_opengl ".glsl" #elseif kha_metal ".metal" #else ".d3d11" #end ;
							 | 
						||
| 
								 | 
							
									#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(raw: TShaderData, done: ShaderData->Void, overrideContext: TShaderOverride = null) {
							 | 
						||
| 
								 | 
							
										this.raw = raw;
							 | 
						||
| 
								 | 
							
										this.name = raw.name;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (c in raw.contexts) contexts.push(null);
							 | 
						||
| 
								 | 
							
										var contextsLoaded = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (i in 0...raw.contexts.length) {
							 | 
						||
| 
								 | 
							
											var c = raw.contexts[i];
							 | 
						||
| 
								 | 
							
											new ShaderContext(c, function(con: ShaderContext) {
							 | 
						||
| 
								 | 
							
												contexts[i] = con;
							 | 
						||
| 
								 | 
							
												contextsLoaded++;
							 | 
						||
| 
								 | 
							
												if (contextsLoaded == raw.contexts.length) done(this);
							 | 
						||
| 
								 | 
							
											}, overrideContext);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public static function parse(file: String, name: String, done: ShaderData->Void, overrideContext: TShaderOverride = null) {
							 | 
						||
| 
								 | 
							
										Data.getSceneRaw(file, function(format: TSceneFormat) {
							 | 
						||
| 
								 | 
							
											var raw: TShaderData = Data.getShaderRawByName(format.shader_datas, name);
							 | 
						||
| 
								 | 
							
											if (raw == null) {
							 | 
						||
| 
								 | 
							
												trace('Shader data "$name" not found!');
							 | 
						||
| 
								 | 
							
												done(null);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											new ShaderData(raw, done, overrideContext);
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function delete() {
							 | 
						||
| 
								 | 
							
										for (c in contexts) c.delete();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getContext(name: String): ShaderContext {
							 | 
						||
| 
								 | 
							
										for (c in contexts) if (c.raw.name == name) return c;
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class ShaderContext {
							 | 
						||
| 
								 | 
							
									public var raw: TShaderContext;
							 | 
						||
| 
								 | 
							
									public var pipeState: PipelineState;
							 | 
						||
| 
								 | 
							
									public var constants: Array<ConstantLocation>;
							 | 
						||
| 
								 | 
							
									public var textureUnits: Array<TextureUnit>;
							 | 
						||
| 
								 | 
							
									public var overrideContext: TShaderOverride;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var structure: VertexStructure;
							 | 
						||
| 
								 | 
							
									var instancingType = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(raw: TShaderContext, done: ShaderContext->Void, overrideContext: TShaderOverride = null) {
							 | 
						||
| 
								 | 
							
										this.raw = raw;
							 | 
						||
| 
								 | 
							
										#if (!rp_voxels)
							 | 
						||
| 
								 | 
							
										if (raw.name == "voxel") {
							 | 
						||
| 
								 | 
							
											done(this);
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
										this.overrideContext = overrideContext;
							 | 
						||
| 
								 | 
							
										parseVertexStructure();
							 | 
						||
| 
								 | 
							
										compile(done);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function compile(done: ShaderContext->Void) {
							 | 
						||
| 
								 | 
							
										if (pipeState != null) pipeState.delete();
							 | 
						||
| 
								 | 
							
										pipeState = new PipelineState();
							 | 
						||
| 
								 | 
							
										constants = [];
							 | 
						||
| 
								 | 
							
										textureUnits = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (instancingType > 0) { // Instancing
							 | 
						||
| 
								 | 
							
											var instStruct = new VertexStructure();
							 | 
						||
| 
								 | 
							
											instStruct.add("ipos", VertexData.Float3);
							 | 
						||
| 
								 | 
							
											if (instancingType == 2 || instancingType == 4) {
							 | 
						||
| 
								 | 
							
												instStruct.add("irot", VertexData.Float3);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (instancingType == 3 || instancingType == 4) {
							 | 
						||
| 
								 | 
							
												instStruct.add("iscl", VertexData.Float3);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											instStruct.instanced = true;
							 | 
						||
| 
								 | 
							
											pipeState.inputLayout = [structure, instStruct];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else { // Regular
							 | 
						||
| 
								 | 
							
											pipeState.inputLayout = [structure];
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Depth
							 | 
						||
| 
								 | 
							
										pipeState.depthWrite = raw.depth_write;
							 | 
						||
| 
								 | 
							
										pipeState.depthMode = getCompareMode(raw.compare_mode);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Cull
							 | 
						||
| 
								 | 
							
										pipeState.cullMode = getCullMode(raw.cull_mode);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Blending
							 | 
						||
| 
								 | 
							
										if (raw.blend_source != null) pipeState.blendSource = getBlendingFactor(raw.blend_source);
							 | 
						||
| 
								 | 
							
										if (raw.blend_destination != null) pipeState.blendDestination = getBlendingFactor(raw.blend_destination);
							 | 
						||
| 
								 | 
							
										if (raw.blend_operation != null) pipeState.blendOperation = getBlendingOperation(raw.blend_operation);
							 | 
						||
| 
								 | 
							
										if (raw.alpha_blend_source != null) pipeState.alphaBlendSource = getBlendingFactor(raw.alpha_blend_source);
							 | 
						||
| 
								 | 
							
										if (raw.alpha_blend_destination != null) pipeState.alphaBlendDestination = getBlendingFactor(raw.alpha_blend_destination);
							 | 
						||
| 
								 | 
							
										if (raw.alpha_blend_operation != null) pipeState.alphaBlendOperation = getBlendingOperation(raw.alpha_blend_operation);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Per-target color write mask
							 | 
						||
| 
								 | 
							
										if (raw.color_writes_red != null) for (i in 0...raw.color_writes_red.length) pipeState.colorWriteMasksRed[i] = raw.color_writes_red[i];
							 | 
						||
| 
								 | 
							
										if (raw.color_writes_green != null) for (i in 0...raw.color_writes_green.length) pipeState.colorWriteMasksGreen[i] = raw.color_writes_green[i];
							 | 
						||
| 
								 | 
							
										if (raw.color_writes_blue != null) for (i in 0...raw.color_writes_blue.length) pipeState.colorWriteMasksBlue[i] = raw.color_writes_blue[i];
							 | 
						||
| 
								 | 
							
										if (raw.color_writes_alpha != null) for (i in 0...raw.color_writes_alpha.length) pipeState.colorWriteMasksAlpha[i] = raw.color_writes_alpha[i];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Color attachment format
							 | 
						||
| 
								 | 
							
										if (raw.color_attachments != null) {
							 | 
						||
| 
								 | 
							
											pipeState.colorAttachmentCount = raw.color_attachments.length;
							 | 
						||
| 
								 | 
							
											for (i in 0...raw.color_attachments.length) pipeState.colorAttachments[i] = getTextureFormat(raw.color_attachments[i]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Depth attachment format
							 | 
						||
| 
								 | 
							
										if (raw.depth_attachment != null) {
							 | 
						||
| 
								 | 
							
											#if (krom_windows || krom_linux || krom_darwin || krom_android || krom_ios)
							 | 
						||
| 
								 | 
							
											pipeState.depthStencilAttachment = getDepthStencilFormat(raw.depth_attachment);
							 | 
						||
| 
								 | 
							
											#end
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Conservative raster for voxelization
							 | 
						||
| 
								 | 
							
										if (raw.conservative_raster != null) pipeState.conservativeRasterization = raw.conservative_raster;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Shaders
							 | 
						||
| 
								 | 
							
										if (raw.shader_from_source) {
							 | 
						||
| 
								 | 
							
											pipeState.vertexShader = VertexShader.fromSource(raw.vertex_shader);
							 | 
						||
| 
								 | 
							
											pipeState.fragmentShader = FragmentShader.fromSource(raw.fragment_shader);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											#if kha_krom
							 | 
						||
| 
								 | 
							
											// Shader compile error
							 | 
						||
| 
								 | 
							
											if (pipeState.vertexShader.shader == null || pipeState.fragmentShader.shader == null) {
							 | 
						||
| 
								 | 
							
												done(null);
							 | 
						||
| 
								 | 
							
												return;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											finishCompile(done);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											#if (lnx_noembed && kha_krom) // Load shaders manually
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var shadersLoaded = 0;
							 | 
						||
| 
								 | 
							
											var numShaders = 2;
							 | 
						||
| 
								 | 
							
											if (raw.geometry_shader != null) numShaders++;
							 | 
						||
| 
								 | 
							
											if (raw.tesscontrol_shader != null) numShaders++;
							 | 
						||
| 
								 | 
							
											if (raw.tesseval_shader != null) numShaders++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											function loadShader(file: String, type: Int) {
							 | 
						||
| 
								 | 
							
												var path = ShaderData.shaderPath + file + ShaderData.shaderExt;
							 | 
						||
| 
								 | 
							
												Data.getBlob(path, function(b: kha.Blob) {
							 | 
						||
| 
								 | 
							
													if (type == 0) pipeState.vertexShader = new VertexShader([b], [file]);
							 | 
						||
| 
								 | 
							
													else if (type == 1) pipeState.fragmentShader = new FragmentShader([b], [file]);
							 | 
						||
| 
								 | 
							
													else if (type == 2) pipeState.geometryShader = new kha.graphics4.GeometryShader([b], [file]);
							 | 
						||
| 
								 | 
							
													else if (type == 3) pipeState.tessellationControlShader = new kha.graphics4.TessellationControlShader([b], [file]);
							 | 
						||
| 
								 | 
							
													else if (type == 4) pipeState.tessellationEvaluationShader = new kha.graphics4.TessellationEvaluationShader([b], [file]);
							 | 
						||
| 
								 | 
							
													shadersLoaded++;
							 | 
						||
| 
								 | 
							
													if (shadersLoaded >= numShaders) finishCompile(done);
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											loadShader(raw.vertex_shader, 0);
							 | 
						||
| 
								 | 
							
											loadShader(raw.fragment_shader, 1);
							 | 
						||
| 
								 | 
							
											if (raw.geometry_shader != null) loadShader(raw.geometry_shader, 2);
							 | 
						||
| 
								 | 
							
											if (raw.tesscontrol_shader != null) loadShader(raw.tesscontrol_shader, 3);
							 | 
						||
| 
								 | 
							
											if (raw.tesseval_shader != null) loadShader(raw.tesseval_shader, 4);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											#elseif lnx_shader_embed
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											pipeState.fragmentShader = kha.Shaders.getFragment(raw.fragment_shader);
							 | 
						||
| 
								 | 
							
											pipeState.vertexShader = kha.Shaders.getVertex(raw.vertex_shader);
							 | 
						||
| 
								 | 
							
											if (raw.geometry_shader != null) {
							 | 
						||
| 
								 | 
							
												pipeState.geometryShader = kha.Shaders.getGeometry(raw.geometry_shader);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											finishCompile(done);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											pipeState.fragmentShader = Reflect.field(kha.Shaders, raw.fragment_shader.replace(".", "_"));
							 | 
						||
| 
								 | 
							
											pipeState.vertexShader = Reflect.field(kha.Shaders, raw.vertex_shader.replace(".", "_"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (raw.geometry_shader != null) {
							 | 
						||
| 
								 | 
							
												pipeState.geometryShader = Reflect.field(kha.Shaders, raw.geometry_shader.replace(".", "_"));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (raw.tesscontrol_shader != null) {
							 | 
						||
| 
								 | 
							
												pipeState.tessellationControlShader = Reflect.field(kha.Shaders, raw.tesscontrol_shader.replace(".", "_"));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (raw.tesseval_shader != null) {
							 | 
						||
| 
								 | 
							
												pipeState.tessellationEvaluationShader = Reflect.field(kha.Shaders, raw.tesseval_shader.replace(".", "_"));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											finishCompile(done);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											#end
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function finishCompile(done: ShaderContext->Void) {
							 | 
						||
| 
								 | 
							
										// Override specified values
							 | 
						||
| 
								 | 
							
										if (overrideContext != null) {
							 | 
						||
| 
								 | 
							
											if (overrideContext.cull_mode != null) {
							 | 
						||
| 
								 | 
							
												pipeState.cullMode = getCullMode(overrideContext.cull_mode);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										pipeState.compile();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (raw.constants != null) {
							 | 
						||
| 
								 | 
							
											for (c in raw.constants) addConstant(c);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (raw.texture_units != null) {
							 | 
						||
| 
								 | 
							
											for (tu in raw.texture_units) addTexture(tu);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										done(this);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public static function parseData(data: String): VertexData {
							 | 
						||
| 
								 | 
							
										if (data == "float1") return VertexData.Float1;
							 | 
						||
| 
								 | 
							
										else if (data == "float2") return VertexData.Float2;
							 | 
						||
| 
								 | 
							
										else if (data == "float3") return VertexData.Float3;
							 | 
						||
| 
								 | 
							
										else if (data == "float4") return VertexData.Float4;
							 | 
						||
| 
								 | 
							
										else if (data == "short2norm") return VertexData.Short2Norm;
							 | 
						||
| 
								 | 
							
										else if (data == "short4norm") return VertexData.Short4Norm;
							 | 
						||
| 
								 | 
							
										return VertexData.Float1;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function parseVertexStructure() {
							 | 
						||
| 
								 | 
							
										structure = new VertexStructure();
							 | 
						||
| 
								 | 
							
										var ipos = false;
							 | 
						||
| 
								 | 
							
										var irot = false;
							 | 
						||
| 
								 | 
							
										var iscl = false;
							 | 
						||
| 
								 | 
							
										for (elem in raw.vertex_elements) {
							 | 
						||
| 
								 | 
							
											#if cpp
							 | 
						||
| 
								 | 
							
											if (Reflect.field(elem, "name") == "ipos") { ipos = true; continue; }
							 | 
						||
| 
								 | 
							
											if (Reflect.field(elem, "name") == "irot") { irot = true; continue; }
							 | 
						||
| 
								 | 
							
											if (Reflect.field(elem, "name") == "iscl") { iscl = true; continue; }
							 | 
						||
| 
								 | 
							
											#else
							 | 
						||
| 
								 | 
							
											if (elem.name == "ipos") { ipos = true; continue; }
							 | 
						||
| 
								 | 
							
											if (elem.name == "irot") { irot = true; continue; }
							 | 
						||
| 
								 | 
							
											if (elem.name == "iscl") { iscl = true; continue; }
							 | 
						||
| 
								 | 
							
											#end
							 | 
						||
| 
								 | 
							
											structure.add(elem.name, parseData(elem.data));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (ipos && !irot && !iscl) instancingType = 1;
							 | 
						||
| 
								 | 
							
										else if (ipos && irot && !iscl) instancingType = 2;
							 | 
						||
| 
								 | 
							
										else if (ipos && !irot && iscl) instancingType = 3;
							 | 
						||
| 
								 | 
							
										else if (ipos && irot && iscl) instancingType = 4;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function delete() {
							 | 
						||
| 
								 | 
							
										if (pipeState.fragmentShader != null) pipeState.fragmentShader.delete();
							 | 
						||
| 
								 | 
							
										if (pipeState.vertexShader != null) pipeState.vertexShader.delete();
							 | 
						||
| 
								 | 
							
										if (pipeState.geometryShader != null) pipeState.geometryShader.delete();
							 | 
						||
| 
								 | 
							
										if (pipeState.tessellationControlShader != null) pipeState.tessellationControlShader.delete();
							 | 
						||
| 
								 | 
							
										if (pipeState.tessellationEvaluationShader != null) pipeState.tessellationEvaluationShader.delete();
							 | 
						||
| 
								 | 
							
										pipeState.delete();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getCompareMode(s: String): CompareMode {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "always": return CompareMode.Always;
							 | 
						||
| 
								 | 
							
											case "never": return CompareMode.Never;
							 | 
						||
| 
								 | 
							
											case "less": return CompareMode.Less;
							 | 
						||
| 
								 | 
							
											case "less_equal": return CompareMode.LessEqual;
							 | 
						||
| 
								 | 
							
											case "greater": return CompareMode.Greater;
							 | 
						||
| 
								 | 
							
											case "greater_equal": return CompareMode.GreaterEqual;
							 | 
						||
| 
								 | 
							
											case "equal": return CompareMode.Equal;
							 | 
						||
| 
								 | 
							
											case "not_equal": return CompareMode.NotEqual;
							 | 
						||
| 
								 | 
							
											default: return CompareMode.Less;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getCullMode(s: String): CullMode {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "none": return CullMode.None;
							 | 
						||
| 
								 | 
							
											case "clockwise": return CullMode.Clockwise;
							 | 
						||
| 
								 | 
							
											default: return CullMode.CounterClockwise;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getBlendingOperation(s: String): BlendingOperation {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "add": return BlendingOperation.Add;
							 | 
						||
| 
								 | 
							
											case "subtract": return BlendingOperation.Subtract;
							 | 
						||
| 
								 | 
							
											case "reverse_subtract": return BlendingOperation.ReverseSubtract;
							 | 
						||
| 
								 | 
							
											case "min": return BlendingOperation.Min;
							 | 
						||
| 
								 | 
							
											case "max": return BlendingOperation.Max;
							 | 
						||
| 
								 | 
							
											default: return BlendingOperation.Add;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getBlendingFactor(s: String): BlendingFactor {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "blend_one": return BlendingFactor.BlendOne;
							 | 
						||
| 
								 | 
							
											case "blend_zero": return BlendingFactor.BlendZero;
							 | 
						||
| 
								 | 
							
											case "source_alpha": return BlendingFactor.SourceAlpha;
							 | 
						||
| 
								 | 
							
											case "destination_alpha": return BlendingFactor.DestinationAlpha;
							 | 
						||
| 
								 | 
							
											case "inverse_source_alpha": return BlendingFactor.InverseSourceAlpha;
							 | 
						||
| 
								 | 
							
											case "inverse_destination_alpha": return BlendingFactor.InverseDestinationAlpha;
							 | 
						||
| 
								 | 
							
											case "source_color": return BlendingFactor.SourceColor;
							 | 
						||
| 
								 | 
							
											case "destination_color": return BlendingFactor.DestinationColor;
							 | 
						||
| 
								 | 
							
											case "inverse_source_color": return BlendingFactor.InverseSourceColor;
							 | 
						||
| 
								 | 
							
											case "inverse_destination_color": return BlendingFactor.InverseDestinationColor;
							 | 
						||
| 
								 | 
							
											default: return BlendingFactor.Undefined;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getTextureAddresing(s: String): TextureAddressing {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "repeat": return TextureAddressing.Repeat;
							 | 
						||
| 
								 | 
							
											case "mirror": return TextureAddressing.Mirror;
							 | 
						||
| 
								 | 
							
											default: return TextureAddressing.Clamp;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getTextureFilter(s: String): TextureFilter {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "point": return TextureFilter.PointFilter;
							 | 
						||
| 
								 | 
							
											case "linear": return TextureFilter.LinearFilter;
							 | 
						||
| 
								 | 
							
											default: return TextureFilter.AnisotropicFilter;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getMipmapFilter(s: String): MipMapFilter {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "no": return MipMapFilter.NoMipFilter;
							 | 
						||
| 
								 | 
							
											case "point": return MipMapFilter.PointMipFilter;
							 | 
						||
| 
								 | 
							
											default: return MipMapFilter.LinearMipFilter;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getTextureFormat(s: String): TextureFormat {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "RGBA32": return TextureFormat.RGBA32;
							 | 
						||
| 
								 | 
							
											case "RGBA64": return TextureFormat.RGBA64;
							 | 
						||
| 
								 | 
							
											case "RGBA128": return TextureFormat.RGBA128;
							 | 
						||
| 
								 | 
							
											case "DEPTH16": return TextureFormat.DEPTH16;
							 | 
						||
| 
								 | 
							
											case "R32": return TextureFormat.A32;
							 | 
						||
| 
								 | 
							
											case "R16": return TextureFormat.A16;
							 | 
						||
| 
								 | 
							
											case "R8": return TextureFormat.L8;
							 | 
						||
| 
								 | 
							
											default: return TextureFormat.RGBA32;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function getDepthStencilFormat(s: String): DepthStencilFormat {
							 | 
						||
| 
								 | 
							
										switch (s) {
							 | 
						||
| 
								 | 
							
											case "DEPTH32": return DepthStencilFormat.DepthOnly;
							 | 
						||
| 
								 | 
							
											case "NONE": return DepthStencilFormat.NoDepthAndStencil;
							 | 
						||
| 
								 | 
							
											default: return DepthStencilFormat.DepthOnly;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function addConstant(c: TShaderConstant) {
							 | 
						||
| 
								 | 
							
										constants.push(pipeState.getConstantLocation(c.name));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function addTexture(tu: TTextureUnit) {
							 | 
						||
| 
								 | 
							
										var unit = pipeState.getTextureUnit(tu.name);
							 | 
						||
| 
								 | 
							
										textureUnits.push(unit);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setTextureParameters(g: kha.graphics4.Graphics, unitIndex: Int, tex: TBindTexture) {
							 | 
						||
| 
								 | 
							
										// This function is called for samplers set using material context
							 | 
						||
| 
								 | 
							
										var unit = textureUnits[unitIndex];
							 | 
						||
| 
								 | 
							
										g.setTextureParameters(unit,
							 | 
						||
| 
								 | 
							
											tex.u_addressing == null ? TextureAddressing.Repeat : getTextureAddresing(tex.u_addressing),
							 | 
						||
| 
								 | 
							
											tex.v_addressing == null ? TextureAddressing.Repeat : getTextureAddresing(tex.v_addressing),
							 | 
						||
| 
								 | 
							
											tex.min_filter == null ? TextureFilter.LinearFilter : getTextureFilter(tex.min_filter),
							 | 
						||
| 
								 | 
							
											tex.mag_filter == null ? TextureFilter.LinearFilter : getTextureFilter(tex.mag_filter),
							 | 
						||
| 
								 | 
							
											tex.mipmap_filter == null ? MipMapFilter.NoMipFilter : getMipmapFilter(tex.mipmap_filter));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |