forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			739 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			739 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package kha.js.graphics4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import js.html.webgl.GL2;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.StencilValue;
							 | 
						||
| 
								 | 
							
								import kha.arrays.Float32Array;
							 | 
						||
| 
								 | 
							
								import kha.arrays.Int32Array;
							 | 
						||
| 
								 | 
							
								import js.html.webgl.GL;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.BlendingFactor;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.BlendingOperation;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.CompareMode;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.CubeMap;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.CullMode;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.IndexBuffer;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.MipMapFilter;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.PipelineState;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.StencilAction;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.TextureAddressing;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.TextureFilter;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.Usage;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.VertexBuffer;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.VertexStructure;
							 | 
						||
| 
								 | 
							
								import kha.Image;
							 | 
						||
| 
								 | 
							
								import kha.math.FastMatrix3;
							 | 
						||
| 
								 | 
							
								import kha.math.FastMatrix4;
							 | 
						||
| 
								 | 
							
								import kha.math.FastVector2;
							 | 
						||
| 
								 | 
							
								import kha.math.FastVector3;
							 | 
						||
| 
								 | 
							
								import kha.math.FastVector4;
							 | 
						||
| 
								 | 
							
								import kha.WebGLImage;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class Graphics implements kha.graphics4.Graphics {
							 | 
						||
| 
								 | 
							
									var currentPipeline: PipelineState = null;
							 | 
						||
| 
								 | 
							
									var depthTest: Bool = false;
							 | 
						||
| 
								 | 
							
									var depthMask: Bool = false;
							 | 
						||
| 
								 | 
							
									var colorMaskRed: Bool = true;
							 | 
						||
| 
								 | 
							
									var colorMaskGreen: Bool = true;
							 | 
						||
| 
								 | 
							
									var colorMaskBlue: Bool = true;
							 | 
						||
| 
								 | 
							
									var colorMaskAlpha: Bool = true;
							 | 
						||
| 
								 | 
							
									var indicesCount: Int;
							 | 
						||
| 
								 | 
							
									var renderTarget: Canvas;
							 | 
						||
| 
								 | 
							
									var renderTargetFrameBuffer: Dynamic;
							 | 
						||
| 
								 | 
							
									var renderTargetMSAA: Dynamic;
							 | 
						||
| 
								 | 
							
									var renderTargetTexture: Dynamic;
							 | 
						||
| 
								 | 
							
									var isCubeMap: Bool = false;
							 | 
						||
| 
								 | 
							
									var isDepthAttachment: Bool = false;
							 | 
						||
| 
								 | 
							
									var instancedExtension: Dynamic;
							 | 
						||
| 
								 | 
							
									var blendMinMaxExtension: Dynamic;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static var current: Graphics = null;
							 | 
						||
| 
								 | 
							
									static var useVertexAttributes: Int = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(renderTarget: Canvas = null) {
							 | 
						||
| 
								 | 
							
										this.renderTarget = renderTarget;
							 | 
						||
| 
								 | 
							
										init();
							 | 
						||
| 
								 | 
							
										if (SystemImpl.gl2) {
							 | 
						||
| 
								 | 
							
											instancedExtension = true;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											instancedExtension = SystemImpl.gl.getExtension("ANGLE_instanced_arrays");
							 | 
						||
| 
								 | 
							
											blendMinMaxExtension = SystemImpl.gl.getExtension("EXT_blend_minmax");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function init() {
							 | 
						||
| 
								 | 
							
										if (renderTarget == null)
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										isCubeMap = Std.isOfType(renderTarget, CubeMap);
							 | 
						||
| 
								 | 
							
										if (isCubeMap) {
							 | 
						||
| 
								 | 
							
											var cubeMap: CubeMap = cast(renderTarget, CubeMap);
							 | 
						||
| 
								 | 
							
											renderTargetFrameBuffer = cubeMap.frameBuffer;
							 | 
						||
| 
								 | 
							
											renderTargetTexture = cubeMap.texture;
							 | 
						||
| 
								 | 
							
											isDepthAttachment = cubeMap.isDepthAttachment;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											var image: WebGLImage = cast(renderTarget, WebGLImage);
							 | 
						||
| 
								 | 
							
											renderTargetFrameBuffer = image.frameBuffer;
							 | 
						||
| 
								 | 
							
											renderTargetMSAA = image.MSAAFrameBuffer;
							 | 
						||
| 
								 | 
							
											renderTargetTexture = image.texture;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function begin(additionalRenderTargets: Array<Canvas> = null): Void {
							 | 
						||
| 
								 | 
							
										if (current == null) {
							 | 
						||
| 
								 | 
							
											current = this;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											throw "End before you begin";
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.enable(GL.BLEND);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
							 | 
						||
| 
								 | 
							
										if (renderTarget == null) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.viewport(0, 0, System.windowWidth(), System.windowHeight());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, renderTargetFrameBuffer);
							 | 
						||
| 
								 | 
							
											// if (isCubeMap) SystemImpl.gl.framebufferTexture(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_CUBE_MAP, renderTargetTexture, 0); // Layered
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.viewport(0, 0, renderTarget.width, renderTarget.height);
							 | 
						||
| 
								 | 
							
											if (additionalRenderTargets != null) {
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL, GL.TEXTURE_2D, renderTargetTexture, 0);
							 | 
						||
| 
								 | 
							
												for (i in 0...additionalRenderTargets.length) {
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL + i + 1, GL.TEXTURE_2D,
							 | 
						||
| 
								 | 
							
														cast(additionalRenderTargets[i], WebGLImage).texture, 0);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												var attachments = [SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL];
							 | 
						||
| 
								 | 
							
												for (i in 0...additionalRenderTargets.length) {
							 | 
						||
| 
								 | 
							
													attachments.push(SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL + i + 1);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												SystemImpl.gl2 ? untyped SystemImpl.gl.drawBuffers(attachments) : SystemImpl.drawBuffers.drawBuffersWEBGL(attachments);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function beginFace(face: Int): Void {
							 | 
						||
| 
								 | 
							
										if (current == null) {
							 | 
						||
| 
								 | 
							
											current = this;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											throw "End before you begin";
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.enable(GL.BLEND);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, renderTargetFrameBuffer);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, isDepthAttachment ? GL.DEPTH_ATTACHMENT : GL.COLOR_ATTACHMENT0,
							 | 
						||
| 
								 | 
							
											GL.TEXTURE_CUBE_MAP_POSITIVE_X + face, renderTargetTexture, 0);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.viewport(0, 0, renderTarget.width, renderTarget.height);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function beginEye(eye: Int): Void {
							 | 
						||
| 
								 | 
							
										if (current == null) {
							 | 
						||
| 
								 | 
							
											current = this;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											throw "End before you begin";
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.enable(GL.BLEND);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
							 | 
						||
| 
								 | 
							
										if (eye == 0) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.viewport(0, 0, Std.int(System.windowWidth() * 0.5), System.windowHeight());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.viewport(Std.int(System.windowWidth() * 0.5), 0, Std.int(System.windowWidth() * 0.5), System.windowHeight());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function end(): Void {
							 | 
						||
| 
								 | 
							
										if (current == this) {
							 | 
						||
| 
								 | 
							
											current = null;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											throw "Begin before you end";
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (renderTargetMSAA != null) {
							 | 
						||
| 
								 | 
							
											untyped SystemImpl.gl.bindFramebuffer(SystemImpl.gl.READ_FRAMEBUFFER, renderTargetFrameBuffer);
							 | 
						||
| 
								 | 
							
											untyped SystemImpl.gl.bindFramebuffer(SystemImpl.gl.DRAW_FRAMEBUFFER, renderTargetMSAA);
							 | 
						||
| 
								 | 
							
											untyped SystemImpl.gl.blitFramebuffer(0, 0, renderTarget.width, renderTarget.height, 0, 0, renderTarget.width, renderTarget.height,
							 | 
						||
| 
								 | 
							
												GL.COLOR_BUFFER_BIT, GL.NEAREST);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										#if (debug || kha_debug_html5)
							 | 
						||
| 
								 | 
							
										var error = SystemImpl.gl.getError();
							 | 
						||
| 
								 | 
							
										switch (error) {
							 | 
						||
| 
								 | 
							
											case GL.NO_ERROR:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											case GL.INVALID_ENUM:
							 | 
						||
| 
								 | 
							
												trace("WebGL error: Invalid enum");
							 | 
						||
| 
								 | 
							
											case GL.INVALID_VALUE:
							 | 
						||
| 
								 | 
							
												trace("WebGL error: Invalid value");
							 | 
						||
| 
								 | 
							
											case GL.INVALID_OPERATION:
							 | 
						||
| 
								 | 
							
												trace("WebGL error: Invalid operation");
							 | 
						||
| 
								 | 
							
											case GL.INVALID_FRAMEBUFFER_OPERATION:
							 | 
						||
| 
								 | 
							
												trace("WebGL error: Invalid framebuffer operation");
							 | 
						||
| 
								 | 
							
											case GL.OUT_OF_MEMORY:
							 | 
						||
| 
								 | 
							
												trace("WebGL error: Out of memory");
							 | 
						||
| 
								 | 
							
											case GL.CONTEXT_LOST_WEBGL:
							 | 
						||
| 
								 | 
							
												trace("WebGL error: Context lost");
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												trace("Unknown WebGL error");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function flush(): Void {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function vsynced(): Bool {
							 | 
						||
| 
								 | 
							
										return true;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function refreshRate(): Int {
							 | 
						||
| 
								 | 
							
										return 60;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function clear(?color: Color, ?depth: Float, ?stencil: Int): Void {
							 | 
						||
| 
								 | 
							
										var clearMask: Int = 0;
							 | 
						||
| 
								 | 
							
										if (color != null) {
							 | 
						||
| 
								 | 
							
											clearMask |= GL.COLOR_BUFFER_BIT;
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.colorMask(true, true, true, true);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.clearColor(color.R, color.G, color.B, color.A);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (depth != null) {
							 | 
						||
| 
								 | 
							
											clearMask |= GL.DEPTH_BUFFER_BIT;
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.depthMask(true);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.clearDepth(depth);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (stencil != null) {
							 | 
						||
| 
								 | 
							
											clearMask |= GL.STENCIL_BUFFER_BIT;
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.enable(GL.STENCIL_TEST);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.stencilMask(0xff);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.clearStencil(stencil);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.clear(clearMask);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.colorMask(colorMaskRed, colorMaskGreen, colorMaskBlue, colorMaskAlpha);
							 | 
						||
| 
								 | 
							
										if (depthTest) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.disable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.depthMask(depthMask);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function viewport(x: Int, y: Int, width: Int, height: Int): Void {
							 | 
						||
| 
								 | 
							
										if (renderTarget == null) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.viewport(x, System.windowHeight(0) - y - height, width, height);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.viewport(x, y, width, height);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function scissor(x: Int, y: Int, width: Int, height: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.enable(GL.SCISSOR_TEST);
							 | 
						||
| 
								 | 
							
										if (renderTarget == null) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.scissor(x, System.windowHeight(0) - y - height, width, height);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.scissor(x, y, width, height);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function disableScissor(): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.disable(GL.SCISSOR_TEST);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setDepthMode(write: Bool, mode: CompareMode): Void {
							 | 
						||
| 
								 | 
							
										switch (mode) {
							 | 
						||
| 
								 | 
							
											case Always:
							 | 
						||
| 
								 | 
							
												write ? SystemImpl.gl.enable(GL.DEPTH_TEST) : SystemImpl.gl.disable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = write;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.ALWAYS);
							 | 
						||
| 
								 | 
							
											case Never:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = true;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.NEVER);
							 | 
						||
| 
								 | 
							
											case Equal:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = true;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.EQUAL);
							 | 
						||
| 
								 | 
							
											case NotEqual:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = true;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.NOTEQUAL);
							 | 
						||
| 
								 | 
							
											case Less:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = true;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.LESS);
							 | 
						||
| 
								 | 
							
											case LessEqual:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = true;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.LEQUAL);
							 | 
						||
| 
								 | 
							
											case Greater:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = true;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.GREATER);
							 | 
						||
| 
								 | 
							
											case GreaterEqual:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.DEPTH_TEST);
							 | 
						||
| 
								 | 
							
												depthTest = true;
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.depthFunc(GL.GEQUAL);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.depthMask(write);
							 | 
						||
| 
								 | 
							
										depthMask = write;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static function getBlendFunc(factor: BlendingFactor): Int {
							 | 
						||
| 
								 | 
							
										switch (factor) {
							 | 
						||
| 
								 | 
							
											case BlendZero, Undefined:
							 | 
						||
| 
								 | 
							
												return GL.ZERO;
							 | 
						||
| 
								 | 
							
											case BlendOne:
							 | 
						||
| 
								 | 
							
												return GL.ONE;
							 | 
						||
| 
								 | 
							
											case SourceAlpha:
							 | 
						||
| 
								 | 
							
												return GL.SRC_ALPHA;
							 | 
						||
| 
								 | 
							
											case DestinationAlpha:
							 | 
						||
| 
								 | 
							
												return GL.DST_ALPHA;
							 | 
						||
| 
								 | 
							
											case InverseSourceAlpha:
							 | 
						||
| 
								 | 
							
												return GL.ONE_MINUS_SRC_ALPHA;
							 | 
						||
| 
								 | 
							
											case InverseDestinationAlpha:
							 | 
						||
| 
								 | 
							
												return GL.ONE_MINUS_DST_ALPHA;
							 | 
						||
| 
								 | 
							
											case SourceColor:
							 | 
						||
| 
								 | 
							
												return GL.SRC_COLOR;
							 | 
						||
| 
								 | 
							
											case DestinationColor:
							 | 
						||
| 
								 | 
							
												return GL.DST_COLOR;
							 | 
						||
| 
								 | 
							
											case InverseSourceColor:
							 | 
						||
| 
								 | 
							
												return GL.ONE_MINUS_SRC_COLOR;
							 | 
						||
| 
								 | 
							
											case InverseDestinationColor:
							 | 
						||
| 
								 | 
							
												return GL.ONE_MINUS_DST_COLOR;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static function getBlendOp(op: BlendingOperation): Int {
							 | 
						||
| 
								 | 
							
										switch (op) {
							 | 
						||
| 
								 | 
							
											case Add:
							 | 
						||
| 
								 | 
							
												return GL.FUNC_ADD;
							 | 
						||
| 
								 | 
							
											case Subtract:
							 | 
						||
| 
								 | 
							
												return GL.FUNC_SUBTRACT;
							 | 
						||
| 
								 | 
							
											case ReverseSubtract:
							 | 
						||
| 
								 | 
							
												return GL.FUNC_REVERSE_SUBTRACT;
							 | 
						||
| 
								 | 
							
											case Min:
							 | 
						||
| 
								 | 
							
												return 0x8007;
							 | 
						||
| 
								 | 
							
											case Max:
							 | 
						||
| 
								 | 
							
												return 0x8008;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setBlendingMode(source: BlendingFactor, destination: BlendingFactor, operation: BlendingOperation, alphaSource: BlendingFactor,
							 | 
						||
| 
								 | 
							
											alphaDestination: BlendingFactor, alphaOperation: BlendingOperation): Void {
							 | 
						||
| 
								 | 
							
										if (source == BlendOne && destination == BlendZero) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.disable(GL.BLEND);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.enable(GL.BLEND);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.blendFuncSeparate(getBlendFunc(source), getBlendFunc(destination), getBlendFunc(alphaSource), getBlendFunc(alphaDestination));
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.blendEquationSeparate(getBlendOp(operation), getBlendOp(alphaOperation));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function createVertexBuffer(vertexCount: Int, structure: VertexStructure, usage: Usage, canRead: Bool = false): kha.graphics4.VertexBuffer {
							 | 
						||
| 
								 | 
							
										return new VertexBuffer(vertexCount, structure, usage);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setVertexBuffer(vertexBuffer: kha.graphics4.VertexBuffer): Void {
							 | 
						||
| 
								 | 
							
										for (i in 0...useVertexAttributes) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.disableVertexAttribArray(i);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										useVertexAttributes = vertexBuffer.set(0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setVertexBuffers(vertexBuffers: Array<kha.graphics4.VertexBuffer>): Void {
							 | 
						||
| 
								 | 
							
										for (i in 0...useVertexAttributes) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.disableVertexAttribArray(i);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										var offset: Int = 0;
							 | 
						||
| 
								 | 
							
										for (vertexBuffer in vertexBuffers) {
							 | 
						||
| 
								 | 
							
											offset += vertexBuffer.set(offset);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										useVertexAttributes = offset;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function createIndexBuffer(indexCount: Int, usage: Usage, canRead: Bool = false): kha.graphics4.IndexBuffer {
							 | 
						||
| 
								 | 
							
										return new IndexBuffer(indexCount, usage);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setIndexBuffer(indexBuffer: kha.graphics4.IndexBuffer): Void {
							 | 
						||
| 
								 | 
							
										indicesCount = indexBuffer.count();
							 | 
						||
| 
								 | 
							
										indexBuffer.set();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// public function maxTextureSize(): Int {
							 | 
						||
| 
								 | 
							
									//	return Sys.gl == null ? 8192 : Sys.gl.getParameter(Sys.gl.MAX_TEXTURE_SIZE);
							 | 
						||
| 
								 | 
							
									// }
							 | 
						||
| 
								 | 
							
									// public function supportsNonPow2Textures(): Bool {
							 | 
						||
| 
								 | 
							
									//	return false;
							 | 
						||
| 
								 | 
							
									// }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setTexture(stage: kha.graphics4.TextureUnit, texture: kha.Image): Void {
							 | 
						||
| 
								 | 
							
										if (texture == null) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast stage : TextureUnit).value);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											cast(texture, WebGLImage).set((cast stage : TextureUnit).value);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setTextureDepth(stage: kha.graphics4.TextureUnit, texture: kha.Image): Void {
							 | 
						||
| 
								 | 
							
										cast(texture, WebGLImage).setDepth((cast stage : TextureUnit).value);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setTextureArray(unit: kha.graphics4.TextureUnit, texture: kha.Image): Void {
							 | 
						||
| 
								 | 
							
										// not implemented yet.
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setVideoTexture(unit: kha.graphics4.TextureUnit, texture: kha.Video): Void {
							 | 
						||
| 
								 | 
							
										if (texture == null) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast unit : TextureUnit).value);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											cast((cast texture : kha.js.Video).texture, WebGLImage).set((cast unit : TextureUnit).value);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setImageTexture(unit: kha.graphics4.TextureUnit, texture: kha.Image): Void {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setTextureParameters(texunit: kha.graphics4.TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
							 | 
						||
| 
								 | 
							
											minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast texunit : TextureUnit).value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch (uAddressing) {
							 | 
						||
| 
								 | 
							
											case Clamp:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
											case Repeat:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.REPEAT);
							 | 
						||
| 
								 | 
							
											case Mirror:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.MIRRORED_REPEAT);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch (vAddressing) {
							 | 
						||
| 
								 | 
							
											case Clamp:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
											case Repeat:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.REPEAT);
							 | 
						||
| 
								 | 
							
											case Mirror:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.MIRRORED_REPEAT);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch (minificationFilter) {
							 | 
						||
| 
								 | 
							
											case PointFilter:
							 | 
						||
| 
								 | 
							
												switch (mipmapFilter) {
							 | 
						||
| 
								 | 
							
													case NoMipFilter:
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
													case PointMipFilter:
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST_MIPMAP_NEAREST);
							 | 
						||
| 
								 | 
							
													case LinearMipFilter:
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST_MIPMAP_LINEAR);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case LinearFilter, AnisotropicFilter:
							 | 
						||
| 
								 | 
							
												switch (mipmapFilter) {
							 | 
						||
| 
								 | 
							
													case NoMipFilter:
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
							 | 
						||
| 
								 | 
							
													case PointMipFilter:
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR_MIPMAP_NEAREST);
							 | 
						||
| 
								 | 
							
													case LinearMipFilter:
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR_MIPMAP_LINEAR);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												if (minificationFilter == AnisotropicFilter) {
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texParameteri(GL.TEXTURE_2D, SystemImpl.anisotropicFilter.TEXTURE_MAX_ANISOTROPY_EXT, 4);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										switch (magnificationFilter) {
							 | 
						||
| 
								 | 
							
											case PointFilter:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
											case LinearFilter, AnisotropicFilter:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setTexture3DParameters(texunit: kha.graphics4.TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
							 | 
						||
| 
								 | 
							
										wAddressing: TextureAddressing, minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setTextureCompareMode(texunit: kha.graphics4.TextureUnit, enabled: Bool) {
							 | 
						||
| 
								 | 
							
										if (enabled) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL2.TEXTURE_COMPARE_MODE, GL2.COMPARE_REF_TO_TEXTURE);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL2.TEXTURE_COMPARE_FUNC, GL.LEQUAL);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL2.TEXTURE_COMPARE_MODE, GL.NONE);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setCubeMapCompareMode(texunit: kha.graphics4.TextureUnit, enabled: Bool) {
							 | 
						||
| 
								 | 
							
										if (enabled) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL2.TEXTURE_COMPARE_MODE, GL2.COMPARE_REF_TO_TEXTURE);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL2.TEXTURE_COMPARE_FUNC, GL.LEQUAL);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL2.TEXTURE_COMPARE_MODE, GL.NONE);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setCubeMap(stage: kha.graphics4.TextureUnit, cubeMap: kha.graphics4.CubeMap): Void {
							 | 
						||
| 
								 | 
							
										if (cubeMap == null) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast stage : TextureUnit).value);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, null);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											cubeMap.set((cast stage : TextureUnit).value);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setCubeMapDepth(stage: kha.graphics4.TextureUnit, cubeMap: kha.graphics4.CubeMap): Void {
							 | 
						||
| 
								 | 
							
										cubeMap.setDepth((cast stage : TextureUnit).value);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function maxBoundTextures(): Int {
							 | 
						||
| 
								 | 
							
										return SystemImpl.gl.getParameter(GL.MAX_TEXTURE_IMAGE_UNITS);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setCullMode(mode: CullMode): Void {
							 | 
						||
| 
								 | 
							
										switch (mode) {
							 | 
						||
| 
								 | 
							
											case None:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.disable(GL.CULL_FACE);
							 | 
						||
| 
								 | 
							
											case Clockwise:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.CULL_FACE);
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.cullFace(GL.BACK);
							 | 
						||
| 
								 | 
							
											case CounterClockwise:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.enable(GL.CULL_FACE);
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.cullFace(GL.FRONT);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setPipeline(pipe: PipelineState): Void {
							 | 
						||
| 
								 | 
							
										setCullMode(pipe.cullMode);
							 | 
						||
| 
								 | 
							
										setDepthMode(pipe.depthWrite, pipe.depthMode);
							 | 
						||
| 
								 | 
							
										if (pipe.stencilFrontMode == Always && pipe.stencilBackMode == Always && pipe.stencilFrontBothPass == Keep && pipe.stencilBackBothPass == Keep
							 | 
						||
| 
								 | 
							
											&& pipe.stencilFrontDepthFail == Keep && pipe.stencilBackDepthFail == Keep && pipe.stencilFrontFail == Keep && pipe.stencilBackFail == Keep) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.disable(GL.STENCIL_TEST);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.enable(GL.STENCIL_TEST);
							 | 
						||
| 
								 | 
							
											setStencilParameters(true, pipe.stencilFrontMode, pipe.stencilFrontBothPass, pipe.stencilFrontDepthFail, pipe.stencilFrontFail,
							 | 
						||
| 
								 | 
							
												pipe.stencilReferenceValue, pipe.stencilReadMask, pipe.stencilWriteMask);
							 | 
						||
| 
								 | 
							
											setStencilParameters(false, pipe.stencilBackMode, pipe.stencilBackBothPass, pipe.stencilBackDepthFail, pipe.stencilBackFail,
							 | 
						||
| 
								 | 
							
												pipe.stencilReferenceValue, pipe.stencilReadMask, pipe.stencilWriteMask);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										setBlendingMode(pipe.blendSource, pipe.blendDestination, pipe.blendOperation, pipe.alphaBlendSource, pipe.alphaBlendDestination,
							 | 
						||
| 
								 | 
							
											pipe.alphaBlendOperation);
							 | 
						||
| 
								 | 
							
										currentPipeline = pipe;
							 | 
						||
| 
								 | 
							
										pipe.set();
							 | 
						||
| 
								 | 
							
										colorMaskRed = pipe.colorWriteMaskRed;
							 | 
						||
| 
								 | 
							
										colorMaskGreen = pipe.colorWriteMaskGreen;
							 | 
						||
| 
								 | 
							
										colorMaskBlue = pipe.colorWriteMaskBlue;
							 | 
						||
| 
								 | 
							
										colorMaskAlpha = pipe.colorWriteMaskAlpha;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setStencilReferenceValue(value: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.stencilFuncSeparate(GL.FRONT, convertCompareMode(currentPipeline.stencilFrontMode), value, currentPipeline.stencilReadMask);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.stencilFuncSeparate(GL.BACK, convertCompareMode(currentPipeline.stencilBackMode), value, currentPipeline.stencilReadMask);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setBool(location: kha.graphics4.ConstantLocation, value: Bool): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform1i((cast location : ConstantLocation).value, value ? 1 : 0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setInt(location: kha.graphics4.ConstantLocation, value: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform1i((cast location : ConstantLocation).value, value);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setInt2(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform2i((cast location : ConstantLocation).value, value1, value2);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setInt3(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int, value3: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform3i((cast location : ConstantLocation).value, value1, value2, value3);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setInt4(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int, value3: Int, value4: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform4i((cast location : ConstantLocation).value, value1, value2, value3, value4);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setInts(location: kha.graphics4.ConstantLocation, values: Int32Array): Void {
							 | 
						||
| 
								 | 
							
										var webglLocation = (cast location : ConstantLocation);
							 | 
						||
| 
								 | 
							
										var rawValues = new js.lib.Int32Array(values.buffer, values.byteOffset, values.length);
							 | 
						||
| 
								 | 
							
										switch (webglLocation.type) {
							 | 
						||
| 
								 | 
							
											case GL.INT_VEC2:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform2iv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
											case GL.INT_VEC3:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform3iv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
											case GL.INT_VEC4:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform4iv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform1iv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setFloat(location: kha.graphics4.ConstantLocation, value: FastFloat): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform1f((cast location : ConstantLocation).value, value);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setFloat2(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform2f((cast location : ConstantLocation).value, value1, value2);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setFloat3(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform3f((cast location : ConstantLocation).value, value1, value2, value3);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setFloat4(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat, value4: FastFloat): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform4f((cast location : ConstantLocation).value, value1, value2, value3, value4);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setFloats(location: kha.graphics4.ConstantLocation, values: Float32Array): Void {
							 | 
						||
| 
								 | 
							
										var webglLocation = (cast location : ConstantLocation);
							 | 
						||
| 
								 | 
							
										var rawValues = new js.lib.Float32Array(values.buffer, values.byteOffset, values.length);
							 | 
						||
| 
								 | 
							
										switch (webglLocation.type) {
							 | 
						||
| 
								 | 
							
											case GL.FLOAT_VEC2:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform2fv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
											case GL.FLOAT_VEC3:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform3fv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
											case GL.FLOAT_VEC4:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform4fv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
											case GL.FLOAT_MAT4:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniformMatrix4fv(webglLocation.value, false, rawValues);
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.uniform1fv(webglLocation.value, rawValues);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setVector2(location: kha.graphics4.ConstantLocation, value: FastVector2): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform2f((cast location : ConstantLocation).value, value.x, value.y);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setVector3(location: kha.graphics4.ConstantLocation, value: FastVector3): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform3f((cast location : ConstantLocation).value, value.x, value.y, value.z);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setVector4(location: kha.graphics4.ConstantLocation, value: FastVector4): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniform4f((cast location : ConstantLocation).value, value.x, value.y, value.z, value.w);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static var matrixCache = new js.lib.Float32Array(16);
							 | 
						||
| 
								 | 
							
									public inline function setMatrix(location: kha.graphics4.ConstantLocation, matrix: FastMatrix4): Void {
							 | 
						||
| 
								 | 
							
										matrixCache[0] = matrix._00;
							 | 
						||
| 
								 | 
							
										matrixCache[1] = matrix._01;
							 | 
						||
| 
								 | 
							
										matrixCache[2] = matrix._02;
							 | 
						||
| 
								 | 
							
										matrixCache[3] = matrix._03;
							 | 
						||
| 
								 | 
							
										matrixCache[4] = matrix._10;
							 | 
						||
| 
								 | 
							
										matrixCache[5] = matrix._11;
							 | 
						||
| 
								 | 
							
										matrixCache[6] = matrix._12;
							 | 
						||
| 
								 | 
							
										matrixCache[7] = matrix._13;
							 | 
						||
| 
								 | 
							
										matrixCache[8] = matrix._20;
							 | 
						||
| 
								 | 
							
										matrixCache[9] = matrix._21;
							 | 
						||
| 
								 | 
							
										matrixCache[10] = matrix._22;
							 | 
						||
| 
								 | 
							
										matrixCache[11] = matrix._23;
							 | 
						||
| 
								 | 
							
										matrixCache[12] = matrix._30;
							 | 
						||
| 
								 | 
							
										matrixCache[13] = matrix._31;
							 | 
						||
| 
								 | 
							
										matrixCache[14] = matrix._32;
							 | 
						||
| 
								 | 
							
										matrixCache[15] = matrix._33;
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniformMatrix4fv((cast location : ConstantLocation).value, false, matrixCache);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static var matrix3Cache = new js.lib.Float32Array(9);
							 | 
						||
| 
								 | 
							
									public inline function setMatrix3(location: kha.graphics4.ConstantLocation, matrix: FastMatrix3): Void {
							 | 
						||
| 
								 | 
							
										matrix3Cache[0] = matrix._00;
							 | 
						||
| 
								 | 
							
										matrix3Cache[1] = matrix._01;
							 | 
						||
| 
								 | 
							
										matrix3Cache[2] = matrix._02;
							 | 
						||
| 
								 | 
							
										matrix3Cache[3] = matrix._10;
							 | 
						||
| 
								 | 
							
										matrix3Cache[4] = matrix._11;
							 | 
						||
| 
								 | 
							
										matrix3Cache[5] = matrix._12;
							 | 
						||
| 
								 | 
							
										matrix3Cache[6] = matrix._20;
							 | 
						||
| 
								 | 
							
										matrix3Cache[7] = matrix._21;
							 | 
						||
| 
								 | 
							
										matrix3Cache[8] = matrix._22;
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.uniformMatrix3fv((cast location : ConstantLocation).value, false, matrix3Cache);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function drawIndexedVertices(start: Int = 0, count: Int = -1): Void {
							 | 
						||
| 
								 | 
							
										var type = SystemImpl.elementIndexUint == null ? GL.UNSIGNED_SHORT : GL.UNSIGNED_INT;
							 | 
						||
| 
								 | 
							
										var size = type == GL.UNSIGNED_SHORT ? 2 : 4;
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.drawElements(GL.TRIANGLES, count == -1 ? indicesCount : count, type, start * size);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function convertStencilAction(action: StencilAction) {
							 | 
						||
| 
								 | 
							
										switch (action) {
							 | 
						||
| 
								 | 
							
											case StencilAction.Decrement:
							 | 
						||
| 
								 | 
							
												return GL.DECR;
							 | 
						||
| 
								 | 
							
											case StencilAction.DecrementWrap:
							 | 
						||
| 
								 | 
							
												return GL.DECR_WRAP;
							 | 
						||
| 
								 | 
							
											case StencilAction.Increment:
							 | 
						||
| 
								 | 
							
												return GL.INCR;
							 | 
						||
| 
								 | 
							
											case StencilAction.IncrementWrap:
							 | 
						||
| 
								 | 
							
												return GL.INCR_WRAP;
							 | 
						||
| 
								 | 
							
											case StencilAction.Invert:
							 | 
						||
| 
								 | 
							
												return GL.INVERT;
							 | 
						||
| 
								 | 
							
											case StencilAction.Keep:
							 | 
						||
| 
								 | 
							
												return GL.KEEP;
							 | 
						||
| 
								 | 
							
											case StencilAction.Replace:
							 | 
						||
| 
								 | 
							
												return GL.REPLACE;
							 | 
						||
| 
								 | 
							
											case StencilAction.Zero:
							 | 
						||
| 
								 | 
							
												return GL.ZERO;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function convertCompareMode(compareMode: CompareMode) {
							 | 
						||
| 
								 | 
							
										switch (compareMode) {
							 | 
						||
| 
								 | 
							
											case Always:
							 | 
						||
| 
								 | 
							
												return GL.ALWAYS;
							 | 
						||
| 
								 | 
							
											case Equal:
							 | 
						||
| 
								 | 
							
												return GL.EQUAL;
							 | 
						||
| 
								 | 
							
											case Greater:
							 | 
						||
| 
								 | 
							
												return GL.GREATER;
							 | 
						||
| 
								 | 
							
											case GreaterEqual:
							 | 
						||
| 
								 | 
							
												return GL.GEQUAL;
							 | 
						||
| 
								 | 
							
											case Less:
							 | 
						||
| 
								 | 
							
												return GL.LESS;
							 | 
						||
| 
								 | 
							
											case LessEqual:
							 | 
						||
| 
								 | 
							
												return GL.LEQUAL;
							 | 
						||
| 
								 | 
							
											case Never:
							 | 
						||
| 
								 | 
							
												return GL.NEVER;
							 | 
						||
| 
								 | 
							
											case NotEqual:
							 | 
						||
| 
								 | 
							
												return GL.NOTEQUAL;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setStencilParameters(front: Bool, compareMode: CompareMode, bothPass: StencilAction, depthFail: StencilAction, stencilFail: StencilAction,
							 | 
						||
| 
								 | 
							
											referenceValue: StencilValue, readMask: Int = 0xff, writeMask: Int = 0xff): Void {
							 | 
						||
| 
								 | 
							
										var stencilFunc = convertCompareMode(compareMode);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.stencilMaskSeparate(front ? GL.FRONT : GL.BACK, writeMask);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.stencilOpSeparate(front ? GL.FRONT : GL.BACK, convertStencilAction(stencilFail), convertStencilAction(depthFail),
							 | 
						||
| 
								 | 
							
											convertStencilAction(bothPass));
							 | 
						||
| 
								 | 
							
										switch (referenceValue) {
							 | 
						||
| 
								 | 
							
											case Static(value):
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.stencilFuncSeparate(front ? GL.FRONT : GL.BACK, stencilFunc, value, readMask);
							 | 
						||
| 
								 | 
							
											case Dynamic:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.stencilFuncSeparate(front ? GL.FRONT : GL.BACK, stencilFunc, 0, readMask);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function drawIndexedVerticesInstanced(instanceCount: Int, start: Int = 0, count: Int = -1) {
							 | 
						||
| 
								 | 
							
										if (instancedRenderingAvailable()) {
							 | 
						||
| 
								 | 
							
											var type = SystemImpl.elementIndexUint == null ? GL.UNSIGNED_SHORT : GL.UNSIGNED_INT;
							 | 
						||
| 
								 | 
							
											var typeSize = SystemImpl.elementIndexUint == null ? 2 : 4;
							 | 
						||
| 
								 | 
							
											if (SystemImpl.gl2) {
							 | 
						||
| 
								 | 
							
												untyped SystemImpl.gl.drawElementsInstanced(GL.TRIANGLES, count == -1 ? indicesCount : count, type, start * typeSize, instanceCount);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else {
							 | 
						||
| 
								 | 
							
												instancedExtension.drawElementsInstancedANGLE(GL.TRIANGLES, count == -1 ? indicesCount : count, type, start * typeSize, instanceCount);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function instancedRenderingAvailable(): Bool {
							 | 
						||
| 
								 | 
							
										return instancedExtension;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |