200 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| package kha.graphics4;
 | |
| 
 | |
| import js.html.webgl.GL;
 | |
| import haxe.io.Bytes;
 | |
| import kha.js.graphics4.Graphics;
 | |
| 
 | |
| class CubeMap implements Canvas implements Resource {
 | |
| 	var myWidth: Int;
 | |
| 	var myHeight: Int;
 | |
| 	var format: TextureFormat;
 | |
| 	var renderTarget: Bool;
 | |
| 	var depthStencilFormat: DepthStencilFormat;
 | |
| 	var graphics4: kha.graphics4.Graphics;
 | |
| 
 | |
| 	public var frameBuffer: Dynamic = null;
 | |
| 	public var texture: Dynamic = null;
 | |
| 	public var depthTexture: Dynamic = null;
 | |
| 	public var isDepthAttachment: Bool = false;
 | |
| 
 | |
| 	// 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_DEPTH_COMPONENT24 = 0x81A6;
 | |
| 	static inline var GL_DEPTH24_STENCIL8 = 0x88F0;
 | |
| 	static inline var GL_DEPTH32F_STENCIL8 = 0x8CAD;
 | |
| 
 | |
| 	function new(size: Int, format: TextureFormat, renderTarget: Bool, depthStencilFormat: DepthStencilFormat) {
 | |
| 		myWidth = size;
 | |
| 		myHeight = size;
 | |
| 		this.format = format;
 | |
| 		this.renderTarget = renderTarget;
 | |
| 		this.depthStencilFormat = depthStencilFormat;
 | |
| 		if (renderTarget)
 | |
| 			createTexture();
 | |
| 	}
 | |
| 
 | |
| 	public static function createRenderTarget(size: Int, format: TextureFormat = null, depthStencil: DepthStencilFormat = null): CubeMap {
 | |
| 		if (format == null)
 | |
| 			format = TextureFormat.RGBA32;
 | |
| 		if (depthStencil == null)
 | |
| 			depthStencil = NoDepthAndStencil;
 | |
| 		return new CubeMap(size, format, true, depthStencil);
 | |
| 	}
 | |
| 
 | |
| 	function createTexture() {
 | |
| 		if (SystemImpl.gl == null)
 | |
| 			return;
 | |
| 
 | |
| 		texture = SystemImpl.gl.createTexture();
 | |
| 		SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
 | |
| 
 | |
| 		SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
 | |
| 		SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
 | |
| 		SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
 | |
| 		SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
 | |
| 
 | |
| 		if (renderTarget) {
 | |
| 			frameBuffer = SystemImpl.gl.createFramebuffer();
 | |
| 			SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
 | |
| 
 | |
| 			switch (format) {
 | |
| 				case DEPTH16:
 | |
| 					for (i in 0...6)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, myWidth,
 | |
| 							myHeight, 0, GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
 | |
| 				case RGBA128:
 | |
| 					for (i in 0...6)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
 | |
| 							GL.FLOAT, null);
 | |
| 				case RGBA64:
 | |
| 					for (i in 0...6)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
 | |
| 							SystemImpl.halfFloat.HALF_FLOAT_OES, null);
 | |
| 				case RGBA32:
 | |
| 					for (i in 0...6)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
 | |
| 				case A32:
 | |
| 					for (i in 0...6)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, myWidth, myHeight, 0, GL.ALPHA,
 | |
| 							GL.FLOAT, null);
 | |
| 				case A16:
 | |
| 					for (i in 0...6)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, myWidth, myHeight, 0, GL.ALPHA,
 | |
| 							SystemImpl.halfFloat.HALF_FLOAT_OES, null);
 | |
| 				default:
 | |
| 					for (i in 0...6)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
 | |
| 			}
 | |
| 
 | |
| 			if (format == DEPTH16) {
 | |
| 				SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
 | |
| 				SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
 | |
| 				isDepthAttachment = true;
 | |
| 				// Some WebGL implementations throw incomplete framebuffer error, create color attachment
 | |
| 				if (!SystemImpl.gl2) {
 | |
| 					var colortex = SystemImpl.gl.createTexture();
 | |
| 					SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, colortex);
 | |
| 					for (i in 0...6) {
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
 | |
| 						SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, colortex, 0);
 | |
| 					}
 | |
| 					SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			initDepthStencilBuffer(depthStencilFormat);
 | |
| 			SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
 | |
| 		}
 | |
| 
 | |
| 		SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, null);
 | |
| 	}
 | |
| 
 | |
| 	function initDepthStencilBuffer(depthStencilFormat: DepthStencilFormat) {
 | |
| 		switch (depthStencilFormat) {
 | |
| 			case NoDepthAndStencil:
 | |
| 			case DepthOnly, Depth16:
 | |
| 				{
 | |
| 					depthTexture = SystemImpl.gl.createTexture();
 | |
| 					SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
 | |
| 					if (depthStencilFormat == DepthOnly)
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL_DEPTH_COMPONENT24 : GL.DEPTH_COMPONENT, myWidth, myHeight, 0,
 | |
| 							GL.DEPTH_COMPONENT, GL.UNSIGNED_INT, null);
 | |
| 					else
 | |
| 						SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, myWidth, myHeight, 0,
 | |
| 							GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
 | |
| 					SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
 | |
| 					SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
 | |
| 					SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
 | |
| 					SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
 | |
| 					SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
 | |
| 					SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_CUBE_MAP, depthTexture, 0);
 | |
| 				}
 | |
| 			case DepthAutoStencilAuto, Depth24Stencil8, Depth32Stencil8:
 | |
| 				depthTexture = SystemImpl.gl.createTexture();
 | |
| 				SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
 | |
| 				SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL_DEPTH24_STENCIL8 : GL.DEPTH_STENCIL, myWidth, myHeight, 0,
 | |
| 					GL.DEPTH_STENCIL, SystemImpl.depthTexture.UNSIGNED_INT_24_8_WEBGL, null);
 | |
| 				SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
 | |
| 				SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
 | |
| 				SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
 | |
| 				SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
 | |
| 				SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
 | |
| 				SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_CUBE_MAP, depthTexture, 0);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public function set(stage: Int): Void {
 | |
| 		SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
 | |
| 		SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
 | |
| 	}
 | |
| 
 | |
| 	public function setDepth(stage: Int): Void {
 | |
| 		SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
 | |
| 		SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
 | |
| 	}
 | |
| 
 | |
| 	public function unload(): Void {}
 | |
| 
 | |
| 	public function lock(level: Int = 0): Bytes {
 | |
| 		return null;
 | |
| 	}
 | |
| 
 | |
| 	public function unlock(): Void {}
 | |
| 
 | |
| 	public var width(get, never): Int;
 | |
| 
 | |
| 	function get_width(): Int {
 | |
| 		return myWidth;
 | |
| 	}
 | |
| 
 | |
| 	public var height(get, never): Int;
 | |
| 
 | |
| 	function get_height(): Int {
 | |
| 		return myHeight;
 | |
| 	}
 | |
| 
 | |
| 	public var g1(get, never): kha.graphics1.Graphics;
 | |
| 
 | |
| 	function get_g1(): kha.graphics1.Graphics {
 | |
| 		return null;
 | |
| 	}
 | |
| 
 | |
| 	public var g2(get, never): kha.graphics2.Graphics;
 | |
| 
 | |
| 	function get_g2(): kha.graphics2.Graphics {
 | |
| 		return null;
 | |
| 	}
 | |
| 
 | |
| 	public var g4(get, never): kha.graphics4.Graphics;
 | |
| 
 | |
| 	function get_g4(): kha.graphics4.Graphics {
 | |
| 		if (graphics4 == null) {
 | |
| 			graphics4 = new Graphics(this);
 | |
| 		}
 | |
| 		return graphics4;
 | |
| 	}
 | |
| }
 |