forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			585 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			585 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								package kha;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import haxe.io.Bytes;
							 | 
						||
| 
								 | 
							
								import js.Browser;
							 | 
						||
| 
								 | 
							
								import js.lib.Uint8Array;
							 | 
						||
| 
								 | 
							
								import js.lib.Uint16Array;
							 | 
						||
| 
								 | 
							
								import js.lib.Float32Array;
							 | 
						||
| 
								 | 
							
								import js.html.VideoElement;
							 | 
						||
| 
								 | 
							
								import js.html.webgl.GL;
							 | 
						||
| 
								 | 
							
								import js.html.webgl.Framebuffer;
							 | 
						||
| 
								 | 
							
								import js.html.webgl.Renderbuffer;
							 | 
						||
| 
								 | 
							
								import js.html.webgl.Texture;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.TextureFormat;
							 | 
						||
| 
								 | 
							
								import kha.graphics4.DepthStencilFormat;
							 | 
						||
| 
								 | 
							
								import kha.js.graphics4.Graphics;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class WebGLImage extends Image {
							 | 
						||
| 
								 | 
							
									public var image: Dynamic;
							 | 
						||
| 
								 | 
							
									public var video: VideoElement;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static var context: js.html.CanvasRenderingContext2D;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var data: js.html.ImageData;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var myWidth: Int;
							 | 
						||
| 
								 | 
							
									var myHeight: Int;
							 | 
						||
| 
								 | 
							
									var myFormat: TextureFormat;
							 | 
						||
| 
								 | 
							
									var renderTarget: Bool;
							 | 
						||
| 
								 | 
							
									var samples: Int;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var frameBuffer: Framebuffer = null;
							 | 
						||
| 
								 | 
							
									public var renderBuffer: Renderbuffer = null;
							 | 
						||
| 
								 | 
							
									public var texture: Texture = null;
							 | 
						||
| 
								 | 
							
									public var depthTexture: Texture = null;
							 | 
						||
| 
								 | 
							
									public var MSAAFrameBuffer: Framebuffer = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var MSAAColorBuffer: Renderbuffer;
							 | 
						||
| 
								 | 
							
									var MSAADepthBuffer: Renderbuffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var graphics1: kha.graphics1.Graphics;
							 | 
						||
| 
								 | 
							
									var graphics2: kha.graphics2.Graphics;
							 | 
						||
| 
								 | 
							
									var graphics4: kha.graphics4.Graphics;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var depthStencilFormat: DepthStencilFormat;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var readable: Bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// WebGL2 constants
							 | 
						||
| 
								 | 
							
									static inline var GL_RGBA16F = 0x881A;
							 | 
						||
| 
								 | 
							
									static inline var GL_RGBA32F = 0x8814;
							 | 
						||
| 
								 | 
							
									static inline var GL_R16F = 0x822D;
							 | 
						||
| 
								 | 
							
									static inline var GL_R32F = 0x822E;
							 | 
						||
| 
								 | 
							
									static inline var GL_RED = 0x1903;
							 | 
						||
| 
								 | 
							
									static inline var GL_DEPTH_COMPONENT24 = 0x81A6;
							 | 
						||
| 
								 | 
							
									static inline var GL_DEPTH24_STENCIL8 = 0x88F0;
							 | 
						||
| 
								 | 
							
									static inline var GL_DEPTH32F_STENCIL8 = 0x8CAD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static var canvas: js.html.CanvasElement;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public static function init() {
							 | 
						||
| 
								 | 
							
										if (context == null) {
							 | 
						||
| 
								 | 
							
											// create only once
							 | 
						||
| 
								 | 
							
											canvas = Browser.document.createCanvasElement();
							 | 
						||
| 
								 | 
							
											if (canvas != null) {
							 | 
						||
| 
								 | 
							
												context = canvas.getContext("2d");
							 | 
						||
| 
								 | 
							
												canvas.width = 4096;
							 | 
						||
| 
								 | 
							
												canvas.height = 4096;
							 | 
						||
| 
								 | 
							
												context.globalCompositeOperation = "copy";
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(width: Int, height: Int, format: TextureFormat, renderTarget: Bool, depthStencilFormat: DepthStencilFormat, samples: Int,
							 | 
						||
| 
								 | 
							
											readable: Bool) {
							 | 
						||
| 
								 | 
							
										myWidth = width;
							 | 
						||
| 
								 | 
							
										myHeight = height;
							 | 
						||
| 
								 | 
							
										myFormat = format;
							 | 
						||
| 
								 | 
							
										this.renderTarget = renderTarget;
							 | 
						||
| 
								 | 
							
										this.samples = samples;
							 | 
						||
| 
								 | 
							
										this.readable = readable;
							 | 
						||
| 
								 | 
							
										image = null;
							 | 
						||
| 
								 | 
							
										video = null;
							 | 
						||
| 
								 | 
							
										this.depthStencilFormat = depthStencilFormat;
							 | 
						||
| 
								 | 
							
										init();
							 | 
						||
| 
								 | 
							
										if (renderTarget)
							 | 
						||
| 
								 | 
							
											createTexture();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_g1(): kha.graphics1.Graphics {
							 | 
						||
| 
								 | 
							
										if (graphics1 == null) {
							 | 
						||
| 
								 | 
							
											graphics1 = new kha.graphics2.Graphics1(this);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return graphics1;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_g2(): kha.graphics2.Graphics {
							 | 
						||
| 
								 | 
							
										if (graphics2 == null) {
							 | 
						||
| 
								 | 
							
											graphics2 = new kha.js.graphics4.Graphics2(this);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return graphics2;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_g4(): kha.graphics4.Graphics {
							 | 
						||
| 
								 | 
							
										if (graphics4 == null) {
							 | 
						||
| 
								 | 
							
											graphics4 = new Graphics(this);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return graphics4;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_width(): Int {
							 | 
						||
| 
								 | 
							
										return myWidth;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_height(): Int {
							 | 
						||
| 
								 | 
							
										return myHeight;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_format(): TextureFormat {
							 | 
						||
| 
								 | 
							
										return myFormat;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_realWidth(): Int {
							 | 
						||
| 
								 | 
							
										return myWidth;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_realHeight(): Int {
							 | 
						||
| 
								 | 
							
										return myHeight;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override function get_stride(): Int {
							 | 
						||
| 
								 | 
							
										return formatByteSize(myFormat) * width;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function isOpaque(x: Int, y: Int): Bool {
							 | 
						||
| 
								 | 
							
										if (data == null) {
							 | 
						||
| 
								 | 
							
											if (context == null)
							 | 
						||
| 
								 | 
							
												return true;
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
												createImageData();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return (data.data[y * Std.int(image.width) * 4 + x * 4 + 3] != 0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function at(x: Int, y: Int): Color {
							 | 
						||
| 
								 | 
							
										if (bytes != null) {
							 | 
						||
| 
								 | 
							
											var r = bytes.get(y * width * 4 + x * 4);
							 | 
						||
| 
								 | 
							
											var g = bytes.get(y * width * 4 + x * 4 + 1);
							 | 
						||
| 
								 | 
							
											var b = bytes.get(y * width * 4 + x * 4 + 2);
							 | 
						||
| 
								 | 
							
											var a = bytes.get(y * width * 4 + x * 4 + 3);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return Color.fromValue((a << 24) | (r << 16) | (g << 8) | b);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											if (data == null) {
							 | 
						||
| 
								 | 
							
												if (context == null)
							 | 
						||
| 
								 | 
							
													return Color.Black;
							 | 
						||
| 
								 | 
							
												else
							 | 
						||
| 
								 | 
							
													createImageData();
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var r = data.data[y * width * 4 + x * 4];
							 | 
						||
| 
								 | 
							
											var g = data.data[y * width * 4 + x * 4 + 1];
							 | 
						||
| 
								 | 
							
											var b = data.data[y * width * 4 + x * 4 + 2];
							 | 
						||
| 
								 | 
							
											var a = data.data[y * width * 4 + x * 4 + 3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return Color.fromValue((a << 24) | (r << 16) | (g << 8) | b);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function createImageData() {
							 | 
						||
| 
								 | 
							
										if (Std.isOfType(image, Uint8Array)) {
							 | 
						||
| 
								 | 
							
											data = new js.html.ImageData(new js.lib.Uint8ClampedArray(image.buffer), this.width, this.height);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											if (this.width > canvas.width || this.height > canvas.height) {
							 | 
						||
| 
								 | 
							
												var cw = canvas.width;
							 | 
						||
| 
								 | 
							
												var ch = canvas.height;
							 | 
						||
| 
								 | 
							
												while (this.width > cw || this.height > ch) {
							 | 
						||
| 
								 | 
							
													cw *= 2;
							 | 
						||
| 
								 | 
							
													ch *= 2;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												canvas.width = cw;
							 | 
						||
| 
								 | 
							
												canvas.height = ch;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											context.strokeStyle = "rgba(0,0,0,0)";
							 | 
						||
| 
								 | 
							
											context.fillStyle = "rgba(0,0,0,0)";
							 | 
						||
| 
								 | 
							
											context.fillRect(0, 0, image.width, image.height);
							 | 
						||
| 
								 | 
							
											context.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
							 | 
						||
| 
								 | 
							
											data = context.getImageData(0, 0, image.width, image.height);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static function upperPowerOfTwo(v: Int): Int {
							 | 
						||
| 
								 | 
							
										v--;
							 | 
						||
| 
								 | 
							
										v |= v >>> 1;
							 | 
						||
| 
								 | 
							
										v |= v >>> 2;
							 | 
						||
| 
								 | 
							
										v |= v >>> 4;
							 | 
						||
| 
								 | 
							
										v |= v >>> 8;
							 | 
						||
| 
								 | 
							
										v |= v >>> 16;
							 | 
						||
| 
								 | 
							
										v++;
							 | 
						||
| 
								 | 
							
										return v;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function createTexture(): Void {
							 | 
						||
| 
								 | 
							
										if (SystemImpl.gl == null)
							 | 
						||
| 
								 | 
							
											return;
							 | 
						||
| 
								 | 
							
										texture = SystemImpl.gl.createTexture();
							 | 
						||
| 
								 | 
							
										// texture.image = image;
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
										// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
										if (renderTarget) {
							 | 
						||
| 
								 | 
							
											frameBuffer = SystemImpl.gl.createFramebuffer();
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
											switch (myFormat) {
							 | 
						||
| 
								 | 
							
												case DEPTH16:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, realWidth, realHeight, 0,
							 | 
						||
| 
								 | 
							
														GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
							 | 
						||
| 
								 | 
							
												case RGBA128:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.FLOAT, null);
							 | 
						||
| 
								 | 
							
												case RGBA64:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, realWidth, realHeight, 0, GL.RGBA,
							 | 
						||
| 
								 | 
							
														SystemImpl.halfFloat.HALF_FLOAT_OES, null);
							 | 
						||
| 
								 | 
							
												case RGBA32:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
							 | 
						||
| 
								 | 
							
												case A32:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, realWidth, realHeight, 0,
							 | 
						||
| 
								 | 
							
														SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.FLOAT, null);
							 | 
						||
| 
								 | 
							
												case A16:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, realWidth, realHeight, 0,
							 | 
						||
| 
								 | 
							
														SystemImpl.gl2 ? GL_RED : GL.ALPHA, SystemImpl.halfFloat.HALF_FLOAT_OES, null);
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (myFormat == DEPTH16) {
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_2D, texture, 0);
							 | 
						||
| 
								 | 
							
												// Some WebGL implementations throw incomplete framebuffer error, create color attachment
							 | 
						||
| 
								 | 
							
												if (!SystemImpl.gl2) {
							 | 
						||
| 
								 | 
							
													var colortex = SystemImpl.gl.createTexture();
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindTexture(GL.TEXTURE_2D, colortex);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, colortex, 0);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else {
							 | 
						||
| 
								 | 
							
												if (samples > 1 && SystemImpl.gl2) {
							 | 
						||
| 
								 | 
							
													MSAAFrameBuffer = SystemImpl.gl.createFramebuffer();
							 | 
						||
| 
								 | 
							
													MSAAColorBuffer = SystemImpl.gl.createRenderbuffer();
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, MSAAColorBuffer);
							 | 
						||
| 
								 | 
							
													var MSAAFormat = switch (myFormat) {
							 | 
						||
| 
								 | 
							
														case RGBA128:
							 | 
						||
| 
								 | 
							
															untyped SystemImpl.gl.RGBA32F;
							 | 
						||
| 
								 | 
							
														case RGBA64:
							 | 
						||
| 
								 | 
							
															untyped SystemImpl.gl.RGBA16F;
							 | 
						||
| 
								 | 
							
														case RGBA32:
							 | 
						||
| 
								 | 
							
															untyped SystemImpl.gl.RGBA8;
							 | 
						||
| 
								 | 
							
														case A32:
							 | 
						||
| 
								 | 
							
															GL_R32F;
							 | 
						||
| 
								 | 
							
														case A16:
							 | 
						||
| 
								 | 
							
															GL_R16F;
							 | 
						||
| 
								 | 
							
														default:
							 | 
						||
| 
								 | 
							
															untyped SystemImpl.gl.RGBA8;
							 | 
						||
| 
								 | 
							
													};
							 | 
						||
| 
								 | 
							
													untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, MSAAFormat, realWidth, realHeight);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.RENDERBUFFER, MSAAColorBuffer);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, MSAAFrameBuffer);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, texture, 0);
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											initDepthStencilBuffer(depthStencilFormat);
							 | 
						||
| 
								 | 
							
											var e = SystemImpl.gl.checkFramebufferStatus(GL.FRAMEBUFFER);
							 | 
						||
| 
								 | 
							
											if (e != GL.FRAMEBUFFER_COMPLETE) {
							 | 
						||
| 
								 | 
							
												trace("checkframebufferStatus error " + e);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, null);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else if (video != null) {
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, video);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											switch (myFormat) {
							 | 
						||
| 
								 | 
							
												case RGBA128:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.FLOAT, image);
							 | 
						||
| 
								 | 
							
												case RGBA64:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
							 | 
						||
| 
								 | 
							
														SystemImpl.halfFloat.HALF_FLOAT_OES, image);
							 | 
						||
| 
								 | 
							
												case RGBA32:
							 | 
						||
| 
								 | 
							
													if (Std.isOfType(image, Uint8Array)) {
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, image);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else {
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, image);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												case A32:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, myWidth, myHeight, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
							 | 
						||
| 
								 | 
							
														GL.FLOAT, image);
							 | 
						||
| 
								 | 
							
												case A16:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, myWidth, myHeight, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
							 | 
						||
| 
								 | 
							
														SystemImpl.halfFloat.HALF_FLOAT_OES, image);
							 | 
						||
| 
								 | 
							
												case L8:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.LUMINANCE, myWidth, myHeight, 0, GL.LUMINANCE, GL.UNSIGNED_BYTE, image);
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, image);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									function initDepthStencilBuffer(depthStencilFormat: DepthStencilFormat) {
							 | 
						||
| 
								 | 
							
										switch (depthStencilFormat) {
							 | 
						||
| 
								 | 
							
											case NoDepthAndStencil:
							 | 
						||
| 
								 | 
							
											case DepthOnly, Depth16:
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													if (SystemImpl.depthTexture == null) {
							 | 
						||
| 
								 | 
							
														renderBuffer = SystemImpl.gl.createRenderbuffer();
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, renderBuffer);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.renderbufferStorage(GL.RENDERBUFFER, GL.DEPTH_COMPONENT16, realWidth, realHeight);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, renderBuffer);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else {
							 | 
						||
| 
								 | 
							
														depthTexture = SystemImpl.gl.createTexture();
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.bindTexture(GL.TEXTURE_2D, depthTexture);
							 | 
						||
| 
								 | 
							
														if (depthStencilFormat == DepthOnly)
							 | 
						||
| 
								 | 
							
															SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_DEPTH_COMPONENT24 : GL.DEPTH_COMPONENT, realWidth, realHeight, 0,
							 | 
						||
| 
								 | 
							
																GL.DEPTH_COMPONENT, GL.UNSIGNED_INT, null);
							 | 
						||
| 
								 | 
							
														else
							 | 
						||
| 
								 | 
							
															SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, realWidth, realHeight, 0,
							 | 
						||
| 
								 | 
							
																GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														if (samples > 1 && SystemImpl.gl2) {
							 | 
						||
| 
								 | 
							
															MSAADepthBuffer = SystemImpl.gl.createRenderbuffer();
							 | 
						||
| 
								 | 
							
															SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, MSAADepthBuffer);
							 | 
						||
| 
								 | 
							
															if (depthStencilFormat == DepthOnly)
							 | 
						||
| 
								 | 
							
																untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, realWidth, realHeight);
							 | 
						||
| 
								 | 
							
															else
							 | 
						||
| 
								 | 
							
																untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, GL.DEPTH_COMPONENT16, realWidth, realHeight);
							 | 
						||
| 
								 | 
							
															SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
															SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, MSAADepthBuffer);
							 | 
						||
| 
								 | 
							
															SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, MSAAFrameBuffer);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_2D, depthTexture, 0);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case DepthAutoStencilAuto, Depth24Stencil8, Depth32Stencil8:
							 | 
						||
| 
								 | 
							
												if (SystemImpl.depthTexture == null) {
							 | 
						||
| 
								 | 
							
													renderBuffer = SystemImpl.gl.createRenderbuffer();
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, renderBuffer);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.renderbufferStorage(GL.RENDERBUFFER, GL.DEPTH_STENCIL, realWidth, realHeight);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.RENDERBUFFER, renderBuffer);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else {
							 | 
						||
| 
								 | 
							
													depthTexture = SystemImpl.gl.createTexture();
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindTexture(GL.TEXTURE_2D, depthTexture);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_DEPTH24_STENCIL8 : GL.DEPTH_STENCIL, realWidth, realHeight, 0,
							 | 
						||
| 
								 | 
							
														GL.DEPTH_STENCIL, SystemImpl.depthTexture.UNSIGNED_INT_24_8_WEBGL, null);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
													if (samples > 1 && SystemImpl.gl2) {
							 | 
						||
| 
								 | 
							
														MSAADepthBuffer = SystemImpl.gl.createRenderbuffer();
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, MSAADepthBuffer);
							 | 
						||
| 
								 | 
							
														untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, realWidth, realHeight);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.RENDERBUFFER, MSAADepthBuffer);
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, MSAAFrameBuffer);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_2D, depthTexture, 0);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function set(stage: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
										if (video != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, video);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function setDepth(stage: Int): Void {
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindTexture(GL.TEXTURE_2D, depthTexture);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function setDepthStencilFrom(image: Image): Void {
							 | 
						||
| 
								 | 
							
										depthTexture = cast(image, WebGLImage).depthTexture;
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_2D, depthTexture, 0);
							 | 
						||
| 
								 | 
							
										if (samples > 1 && SystemImpl.gl2) {
							 | 
						||
| 
								 | 
							
											MSAADepthBuffer = cast(image, WebGLImage).MSAADepthBuffer;
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, MSAADepthBuffer);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static function formatByteSize(format: TextureFormat): Int {
							 | 
						||
| 
								 | 
							
										return switch (format) {
							 | 
						||
| 
								 | 
							
											case RGBA32: 4;
							 | 
						||
| 
								 | 
							
											case L8: 1;
							 | 
						||
| 
								 | 
							
											case RGBA128: 16;
							 | 
						||
| 
								 | 
							
											case DEPTH16: 2;
							 | 
						||
| 
								 | 
							
											case RGBA64: 8;
							 | 
						||
| 
								 | 
							
											case A32: 4;
							 | 
						||
| 
								 | 
							
											case A16: 2;
							 | 
						||
| 
								 | 
							
											default: 4;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function bytesToArray(bytes: Bytes): js.lib.ArrayBufferView {
							 | 
						||
| 
								 | 
							
										return switch (myFormat) {
							 | 
						||
| 
								 | 
							
											case RGBA32, L8:
							 | 
						||
| 
								 | 
							
												new Uint8Array(bytes.getData());
							 | 
						||
| 
								 | 
							
											case RGBA128, RGBA64, A32, A16:
							 | 
						||
| 
								 | 
							
												new Float32Array(bytes.getData());
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												new Uint8Array(bytes.getData());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var bytes: Bytes;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function lock(level: Int = 0): Bytes {
							 | 
						||
| 
								 | 
							
										bytes = Bytes.alloc(formatByteSize(myFormat) * width * height);
							 | 
						||
| 
								 | 
							
										return bytes;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function unlock(): Void {
							 | 
						||
| 
								 | 
							
										data = null;
							 | 
						||
| 
								 | 
							
										image = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (SystemImpl.gl != null) {
							 | 
						||
| 
								 | 
							
											texture = SystemImpl.gl.createTexture();
							 | 
						||
| 
								 | 
							
											// texture.image = image;
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
											// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											switch (myFormat) {
							 | 
						||
| 
								 | 
							
												case L8:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.LUMINANCE, width, height, 0, GL.LUMINANCE, GL.UNSIGNED_BYTE, bytesToArray(bytes));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													if (SystemImpl.ie && SystemImpl.gl.getError() == 1282) { // no LUMINANCE support in IE11
							 | 
						||
| 
								 | 
							
														var rgbaBytes = Bytes.alloc(width * height * 4);
							 | 
						||
| 
								 | 
							
														for (y in 0...height)
							 | 
						||
| 
								 | 
							
															for (x in 0...width) {
							 | 
						||
| 
								 | 
							
																var value = bytes.get(y * width + x);
							 | 
						||
| 
								 | 
							
																rgbaBytes.set(y * width * 4 + x * 4 + 0, value);
							 | 
						||
| 
								 | 
							
																rgbaBytes.set(y * width * 4 + x * 4 + 1, value);
							 | 
						||
| 
								 | 
							
																rgbaBytes.set(y * width * 4 + x * 4 + 2, value);
							 | 
						||
| 
								 | 
							
																rgbaBytes.set(y * width * 4 + x * 4 + 3, 255);
							 | 
						||
| 
								 | 
							
															}
							 | 
						||
| 
								 | 
							
														SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(rgbaBytes));
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												case RGBA128:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, width, height, 0, GL.RGBA, GL.FLOAT,
							 | 
						||
| 
								 | 
							
														bytesToArray(bytes));
							 | 
						||
| 
								 | 
							
												case RGBA64:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, width, height, 0, GL.RGBA,
							 | 
						||
| 
								 | 
							
														SystemImpl.halfFloat.HALF_FLOAT_OES, bytesToArray(bytes));
							 | 
						||
| 
								 | 
							
												case A32:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, width, height, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
							 | 
						||
| 
								 | 
							
														GL.FLOAT, bytesToArray(bytes));
							 | 
						||
| 
								 | 
							
												case A16:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, width, height, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
							 | 
						||
| 
								 | 
							
														SystemImpl.halfFloat.HALF_FLOAT_OES, bytesToArray(bytes));
							 | 
						||
| 
								 | 
							
												case RGBA32:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(bytes));
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(bytes));
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (!readable) {
							 | 
						||
| 
								 | 
							
												bytes = null;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var pixels: js.lib.ArrayBufferView = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function getPixels(): Bytes {
							 | 
						||
| 
								 | 
							
										if (frameBuffer == null)
							 | 
						||
| 
								 | 
							
											return null;
							 | 
						||
| 
								 | 
							
										if (pixels == null) {
							 | 
						||
| 
								 | 
							
											switch (myFormat) {
							 | 
						||
| 
								 | 
							
												case RGBA128, A32:
							 | 
						||
| 
								 | 
							
													pixels = new Float32Array(Std.int(formatByteSize(myFormat) / 4) * width * height);
							 | 
						||
| 
								 | 
							
												case RGBA64, A16:
							 | 
						||
| 
								 | 
							
													pixels = new Uint16Array(Std.int(formatByteSize(myFormat) / 2) * width * height);
							 | 
						||
| 
								 | 
							
												case RGBA32, L8:
							 | 
						||
| 
								 | 
							
													pixels = new Uint8Array(formatByteSize(myFormat) * width * height);
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													pixels = new Uint8Array(formatByteSize(myFormat) * width * height);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
							 | 
						||
| 
								 | 
							
										switch (myFormat) {
							 | 
						||
| 
								 | 
							
											case RGBA128:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, GL.FLOAT, pixels);
							 | 
						||
| 
								 | 
							
											case RGBA64:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, SystemImpl.halfFloat.HALF_FLOAT_OES, pixels);
							 | 
						||
| 
								 | 
							
											case RGBA32:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, GL.UNSIGNED_BYTE, pixels);
							 | 
						||
| 
								 | 
							
											case A32:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.FLOAT, pixels);
							 | 
						||
| 
								 | 
							
											case A16:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, SystemImpl.gl2 ? GL_RED : GL.ALPHA, SystemImpl.halfFloat.HALF_FLOAT_OES, pixels);
							 | 
						||
| 
								 | 
							
											case L8:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.UNSIGNED_BYTE, pixels);
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, GL.UNSIGNED_BYTE, pixels);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return Bytes.ofData(pixels.buffer);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function unload(): Void {
							 | 
						||
| 
								 | 
							
										if (texture != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.deleteTexture(texture);
							 | 
						||
| 
								 | 
							
										if (depthTexture != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.deleteTexture(depthTexture);
							 | 
						||
| 
								 | 
							
										if (frameBuffer != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.deleteFramebuffer(frameBuffer);
							 | 
						||
| 
								 | 
							
										if (renderBuffer != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.deleteRenderbuffer(renderBuffer);
							 | 
						||
| 
								 | 
							
										if (MSAAFrameBuffer != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.deleteFramebuffer(MSAAFrameBuffer);
							 | 
						||
| 
								 | 
							
										if (MSAAColorBuffer != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.deleteRenderbuffer(MSAAColorBuffer);
							 | 
						||
| 
								 | 
							
										if (MSAADepthBuffer != null)
							 | 
						||
| 
								 | 
							
											SystemImpl.gl.deleteRenderbuffer(MSAADepthBuffer);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function generateMipmaps(levels: Int): Void {
							 | 
						||
| 
								 | 
							
										// WebGL requires to generate all mipmaps down to 1x1 size, ignoring levels for now
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.generateMipmap(GL.TEXTURE_2D);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									override public function setMipmaps(mipmaps: Array<Image>): Void {
							 | 
						||
| 
								 | 
							
										// Similar to generateMipmaps, specify all the levels down to 1x1 size
							 | 
						||
| 
								 | 
							
										SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
										if (myFormat == TextureFormat.RGBA128) {
							 | 
						||
| 
								 | 
							
											for (i in 0...mipmaps.length) {
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, mipmaps[i].width, mipmaps[i].height, 0, GL.RGBA,
							 | 
						||
| 
								 | 
							
													GL.FLOAT, cast(mipmaps[i], WebGLImage).image);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else if (myFormat == TextureFormat.RGBA64) {
							 | 
						||
| 
								 | 
							
											for (i in 0...mipmaps.length) {
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, mipmaps[i].width, mipmaps[i].height, 0, GL.RGBA,
							 | 
						||
| 
								 | 
							
													SystemImpl.halfFloat.HALF_FLOAT_OES, cast(mipmaps[i], WebGLImage).image);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											for (i in 0...mipmaps.length) {
							 | 
						||
| 
								 | 
							
												SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, cast(mipmaps[i], WebGLImage).image);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |