|
| 1 | +package openfl.display3D.textures; |
| 2 | + |
| 3 | +#if !flash |
| 4 | +import haxe.io.Bytes; |
| 5 | +import openfl.utils._internal.UInt8Array; |
| 6 | +import openfl.display.BlendMode; |
| 7 | +import openfl.utils.ByteArray; |
| 8 | +import openfl.Lib; |
| 9 | + |
| 10 | +/** |
| 11 | + The ASTCTexture class represents a 2-dimensional compressed ASTC texture uploaded to a rendering context. |
| 12 | +
|
| 13 | + Defines a 2D texture for use during rendering. |
| 14 | +
|
| 15 | + ASTCTexture cannot be instantiated directly. Create instances by using Context3D |
| 16 | + `createASTCTexture()` method. |
| 17 | +**/ |
| 18 | +#if !openfl_debug |
| 19 | +@:fileXml('tags="haxe,release"') |
| 20 | +@:noDebug |
| 21 | +#end |
| 22 | +@:access(openfl.display3D.Context3D) |
| 23 | +@:final class ASTCTexture extends TextureBase |
| 24 | +{ |
| 25 | + @:noCompletion private static var __lowMemoryMode:Bool = false; |
| 26 | + @:noCompletion private static var __warned:Bool = false; |
| 27 | + public static inline final IMAGE_DATA_OFFSET = 16; |
| 28 | + |
| 29 | + public var supported:Bool = true; |
| 30 | + public var imageSize(default, null):Int = 0; |
| 31 | + public var depth(default, null):Int = 0; |
| 32 | + |
| 33 | + @:noCompletion private function new(context:Context3D, data:ByteArray) |
| 34 | + { |
| 35 | + super(context); |
| 36 | + var gl = __context.gl; |
| 37 | + var astcExtension = gl.getExtension("KHR_texture_compression_astc_ldr"); |
| 38 | + |
| 39 | + if (astcExtension == null) |
| 40 | + { |
| 41 | + if (!__warned) |
| 42 | + { |
| 43 | + Lib.current.stage.window.alert("ASTC compression is not available on this device.", "Rendering Error!"); |
| 44 | + __warned = true; |
| 45 | + } |
| 46 | + |
| 47 | + supported = false; |
| 48 | + } |
| 49 | + |
| 50 | + if (supported) |
| 51 | + { |
| 52 | + var format = astcExtension.COMPRESSED_RGBA_ASTC_4x4_KHR; |
| 53 | + __format = format; |
| 54 | + __internalFormat = format; |
| 55 | + __optimizeForRenderToTexture = false; |
| 56 | + __streamingLevels = 0; |
| 57 | + |
| 58 | + __getImageSize(data); |
| 59 | + __getImageDimensions(data); |
| 60 | + |
| 61 | + __uploadASTCTextureFromByteArray(data); |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + @:noCompletion public function __uploadASTCTextureFromByteArray(data:ByteArray):Void |
| 66 | + { |
| 67 | + var context = __context; |
| 68 | + var gl = context.gl; |
| 69 | + |
| 70 | + __textureTarget = gl.TEXTURE_2D; |
| 71 | + __context.__bindGLTexture2D(__textureID); |
| 72 | + |
| 73 | + var bytes:Bytes = cast data; |
| 74 | + var textureBytes = new UInt8Array(#if js @:privateAccess bytes.b.buffer #else bytes #end, IMAGE_DATA_OFFSET, imageSize); |
| 75 | + gl.compressedTexImage2D(__textureTarget, 0, __internalFormat, __width, __height, 0, textureBytes); |
| 76 | + gl.texParameteri(__textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR); |
| 77 | + gl.texParameteri(__textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR); |
| 78 | + |
| 79 | + __context.__bindGLTexture2D(null); |
| 80 | + } |
| 81 | + |
| 82 | + @:noCompletion private function __getImageDimensions(bytes:ByteArray):Void |
| 83 | + { |
| 84 | + bytes.position = 7; |
| 85 | + |
| 86 | + __width = bytes.readUnsignedByte() | (bytes.readUnsignedByte() << 8) | (bytes.readUnsignedByte() << 16); |
| 87 | + __height = bytes.readUnsignedByte() | (bytes.readUnsignedByte() << 8) | (bytes.readUnsignedByte() << 16); |
| 88 | + depth = bytes.readUnsignedByte() | (bytes.readUnsignedByte() << 8) | (bytes.readUnsignedByte() << 16); |
| 89 | + } |
| 90 | + |
| 91 | + @:noCompletion private function __getImageSize(bytes:ByteArray):Void |
| 92 | + { |
| 93 | + bytes.position = 4; |
| 94 | + |
| 95 | + var blockDimX = bytes.readUnsignedByte(); |
| 96 | + var blockDimY = bytes.readUnsignedByte(); |
| 97 | + var blockDimZ = bytes.readUnsignedByte(); |
| 98 | + |
| 99 | + bytes.position = 7; |
| 100 | + |
| 101 | + var dimX = bytes.readUnsignedByte() | (bytes.readUnsignedByte() << 8) | (bytes.readUnsignedByte() << 16); |
| 102 | + var dimY = bytes.readUnsignedByte() | (bytes.readUnsignedByte() << 8) | (bytes.readUnsignedByte() << 16); |
| 103 | + var dimZ = bytes.readUnsignedByte() | (bytes.readUnsignedByte() << 8) | (bytes.readUnsignedByte() << 16); |
| 104 | + |
| 105 | + var blocksX = Math.ceil(dimX / blockDimX); |
| 106 | + var blocksY = Math.ceil(dimY / blockDimY); |
| 107 | + var blocksZ = Math.ceil(dimZ / blockDimZ); |
| 108 | + |
| 109 | + var totalBlocks = blocksX * blocksY * blocksZ; |
| 110 | + imageSize = totalBlocks * 16; |
| 111 | + } |
| 112 | +} |
| 113 | +#end |
0 commit comments