Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ktx2 compressed textures support #1254

Closed
wants to merge 87 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
0f5ecf6
WIP: Basis support
lbergman Oct 31, 2019
e6f75d9
Add all compressed texture formats to isSupportedFormat
lbergman Oct 31, 2019
c8b85c4
Remove unused pattern for supported format
lbergman Oct 31, 2019
1f50d20
Make BasisTextureLoader js only
lbergman Oct 31, 2019
599adb5
Add bsis support
lbergman Nov 18, 2019
0d4b759
Get image width/height from basis bytes
lbergman Nov 18, 2019
d3fc2f7
Throw when basis texture on non-js target
lbergman Nov 18, 2019
3bb8c54
Cleanup basis width detection
lbergman Nov 20, 2019
49d6a2d
Remove duplicate compressed texture detection
lbergman Nov 20, 2019
7779b53
Use stride 1 with ETC and PBRTC
lbergman Nov 20, 2019
42fa2b7
Prioritize ETC textures last
lbergman Nov 20, 2019
1c6f8ed
Remove unused import
lbergman Nov 20, 2019
e8067c3
Support non alpha PVRTC
lbergman Nov 20, 2019
4c91180
Merge pull request #4 from HacksawStudios/basis_support
lbergman Mar 9, 2020
eb65cd6
chore: Add util files
lbergman Mar 25, 2020
1ee5cd1
Merge remote-tracking branch 'upstream/master'
lbergman Mar 25, 2020
6cdee26
fix: Flickering due to incorrect timing of clear https://github.com/…
lbergman Mar 25, 2020
3a00b7f
Merge pull request #5 from HacksawStudios/clear_background_fix
lbergman Mar 25, 2020
b83bdbd
Merge pull request #6 from HacksawStudios/engine_clear_fix
lbergman Mar 25, 2020
34c18e4
fix; Making separate alpha handling configurable in h2d.RenderContex…
lbergman Apr 6, 2020
3c9b5b8
Merge pull request #7 from HacksawStudios/separate_alpha_handling_in_…
lbergman Apr 6, 2020
08597ae
Enable high precision shaders if supported
lbergman Apr 21, 2020
4784fd2
Merge pull request #8 from HacksawStudios/enable_highp_when_available
lbergman Apr 21, 2020
0d61641
chore: Merge latest heaps master
lbergman Aug 17, 2020
b1a1bd4
Merge pull request #9 from HacksawStudios/update_from_master
lbergman Aug 17, 2020
7ee2110
chore: Update package version
lbergman Aug 17, 2020
3f6dc7e
Merge branch 'master' of https://github.com/HacksawStudios/heaps
lbergman Aug 17, 2020
713cad9
Merge remote-tracking branch 'upstream/master' into update_from_upstream
lbergman Mar 2, 2021
438e64c
fix: Merge issues
lbergman Mar 2, 2021
9e4a14a
feat: Add 'addTangent' to HMDModel
lbergman Mar 2, 2021
702b50d
fix: Formatting
lbergman Mar 2, 2021
75d0407
Merge pull request #10 from HacksawStudios/update_from_upstream
lbergman Mar 2, 2021
7baf553
chore: Update version
lbergman Mar 2, 2021
ae4a753
Merge remote-tracking branch 'upstream/master' into update_from_upstream
tkwiatek Nov 22, 2022
ae0329a
Merge pull request #11 from HacksawStudios/update_from_upstream
tkwiatek Nov 23, 2022
a652075
chore: Add Basis condition to fix compilation issue
tkwiatek Nov 23, 2022
5865e61
Merge pull request #12 from HacksawStudios/add_missing_condition_to_i…
lbergman Nov 23, 2022
8ac0833
Merge branch 'HeapsIO:master' into master
lbergman Feb 16, 2023
e1c9372
Revert unnecessary changes
lbergman Feb 16, 2023
258ad00
chore: Remove unneccessary changes
lbergman Feb 17, 2023
42ca30e
chore: Update npmrc
lbergman Feb 17, 2023
b10ed37
fix: Add missing brace
lbergman Feb 17, 2023
53ed8cf
style: Use correct indenting
lbergman Feb 17, 2023
479ad86
style: Add ending linebreak
lbergman Feb 17, 2023
91c1d68
style: Remove unnecessary whitespace changes
lbergman Feb 17, 2023
4929a10
fix: Add missing return definitions for hxsl setParamIndexValue and s…
lbergman Feb 17, 2023
f116fe8
Merge pull request #14 from HacksawStudios/fix_merge
tkwiatek Feb 20, 2023
b099063
chore: Update version
lbergman Feb 20, 2023
433ebca
chore: Update version
lbergman Feb 20, 2023
dff1eba
chore: Set haxe-module-installer as dev dependency
lbergman Feb 20, 2023
4e10301
chore: Exectute toString function on transcoder bytes
tkwiatek May 12, 2023
306a104
chore: Fix haxe 4.3.1 warnings
tkwiatek May 19, 2023
b7f9c71
Merge pull request #15 from HacksawStudios/haxe_4.3.1_compability
lbergman May 25, 2023
a7956d2
chore: Update version
lbergman May 25, 2023
e9e43e6
Merge branch 'master' of https://github.com/HacksawStudios/heaps
Jan 17, 2024
048826f
Merge pull request #16 from Vekzzor/master
lbergman Feb 6, 2024
9c21164
Adding metadata for SDF
Aug 30, 2024
ce4cdb5
fix: Restore use of initSize
Aug 30, 2024
9f95949
Merge pull request #17 from HacksawStudios/addSdfFontMetadata2
lbergman Aug 30, 2024
0563d7e
chore: Update package version
lbergman Sep 2, 2024
7f0c8b4
Merge changes from upstream
lbergman Nov 14, 2024
cf4437f
Merge pull request #19 from HacksawStudios/update_from_upstream
lbergman Nov 14, 2024
00dfde3
Add precision declaration for int, not just float, in GlslOut
Sechgulo Nov 15, 2024
d63fc8b
Merge pull request #21 from Sechgulo/add-int-precision-declaration
lbergman Nov 15, 2024
45e43d9
chore: Update version
lbergman Nov 15, 2024
a91dcdf
Fix missing condition wrapping
Sechgulo Nov 15, 2024
3984614
Merge pull request #22 from Sechgulo/add-int-precision-declaration
lbergman Nov 15, 2024
dc17d15
Merge branch 'master' of https://github.com/HacksawStudios/heaps
lbergman Nov 15, 2024
6e64fcd
chore: Update version
lbergman Nov 15, 2024
1e185a0
refactor: Remove old not used MAX_PRECISION
Sechgulo Nov 18, 2024
cb020bb
Merge pull request #25 from HacksawStudios/rework-max-precision
lbergman Nov 19, 2024
7de7b5c
Add MAX_PRECISION for JS target
Sechgulo Nov 19, 2024
9b3a094
Merge branch 'master' into custom-max-precision
Sechgulo Nov 19, 2024
241b10d
Merge pull request #26 from Sechgulo/custom-max-precision
lbergman Nov 19, 2024
a743874
chore: Update version
lbergman Nov 19, 2024
c5c4d96
feat: Support ktx2 with compressed textures, but without res system i…
lbergman Jan 2, 2025
9d379b1
feat: Ktx2 support without res integration
lbergman Jan 2, 2025
fca380b
chore: Set flag for bptc texture support
lbergman Jan 3, 2025
3524cc0
Merge branch 'HeapsIO:master' into upstream_master
lbergman Jan 3, 2025
a28f251
chore: Get tile size from texture directly instead of info
lbergman Jan 3, 2025
b96b6f8
Merge branch 'upstream_master' of https://github.com/HacksawStudios/h…
lbergman Jan 3, 2025
1c3840f
feat: Add working bptc support
lbergman Jan 7, 2025
cdcae08
chore: Remove unneccesary changes
lbergman Jan 7, 2025
6dacc57
chore: Move constants for compressed textures to own file
lbergman Jan 7, 2025
0a34c0d
Merge branch 'master' into upstream_master
lbergman Jan 7, 2025
abfe146
Revert "Merge branch 'master' into upstream_master"
lbergman Jan 7, 2025
1dc0707
fix: Ensure basis transcoder files only load once
lbergman Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 44 additions & 12 deletions h3d/impl/GlDriver.hx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package h3d.impl;
import h3d.impl.Driver;
import h3d.mat.Data;
import h3d.mat.Pass;
import h3d.mat.Stencil;
import h3d.mat.Data;

#if (js||hlsdl||usegl)

Expand Down Expand Up @@ -87,6 +87,7 @@ class GlDriver extends Driver {
static var UID = 0;
public var gl : GL;
public static var ALLOW_WEBGL2 = true;
public var textureSupport:{astc:Bool, astcHDR:Bool, etc1:Bool, etc2:Bool, dxt:Bool, bptc:Bool};
#end

#if (hlsdl||usegl)
Expand Down Expand Up @@ -992,8 +993,9 @@ class GlDriver extends Driver {
case GL.RGB10_A2: GL.RGBA;
case GL.RED, GL.R8, GL.R16F, GL.R32F, 0x822A: GL.RED;
case GL.RG, GL.RG8, GL.RG16F, GL.RG32F, 0x822C: GL.RG;
case GL.RGB16F, GL.RGB32F, 0x8054, 0x8E8F: GL.RGB;
case 0x83F1, 0x83F2, 0x83F3, 0x805B, 0x8E8C: GL.RGBA;
case GL.RGB16F, GL.RGB32F, 0x8054, 0x8E8F, hxd.PixelFormat.ETC_FORMAT.RGB_ETC1: GL.RGB;
case 0x805B, hxd.PixelFormat.DXT_FORMAT.RGBA_DXT1,hxd.PixelFormat.DXT_FORMAT.RGBA_DXT3,
hxd.PixelFormat.DXT_FORMAT.RGBA_DXT5,hxd.PixelFormat.ASTC_FORMAT.RGBA_4x4, hxd.PixelFormat.BPTC_FORMAT.RGBA_BPTC : GL.RGBA;
default: throw "Invalid format " + t.internalFmt;
}
}
Expand All @@ -1005,6 +1007,7 @@ class GlDriver extends Driver {
case SRGB, SRGB_ALPHA: hasFeature(SRGBTextures);
case R8, RG8, RGB8, R16F, RG16F, RGB16F, R32F, RG32F, RGB32F, RG11B10UF, RGB10A2: #if js glES >= 3 #else true #end;
case S3TC(n): n <= maxCompressedTexturesSupport;
case ASTC(_), ETC(_): #if js true #else false #end;
default: false;
}
}
Expand Down Expand Up @@ -1083,8 +1086,7 @@ class GlDriver extends Driver {
tt.internalFmt = GL.R11F_G11F_B10F;
tt.pixelFmt = GL.UNSIGNED_INT_10F_11F_11F_REV;
case S3TC(n) if( n <= maxCompressedTexturesSupport ):
if( t.width&3 != 0 || t.height&3 != 0 )
throw "Compressed texture "+t+" has size "+t.width+"x"+t.height+" - must be a multiple of 4";
checkMult4(t);
switch( n ) {
case 1: tt.internalFmt = 0x83F1; // COMPRESSED_RGBA_S3TC_DXT1_EXT
case 2: tt.internalFmt = 0x83F2; // COMPRESSED_RGBA_S3TC_DXT3_EXT
Expand All @@ -1093,6 +1095,18 @@ class GlDriver extends Driver {
case 7: tt.internalFmt = 0x8E8C; // COMPRESSED_RGBA_BPTC_UNORM
default: throw "Unsupported texture format "+t.format;
}
case ASTC(n):
checkMult4(t);
switch( n ) {
case 10: tt.internalFmt = hxd.PixelFormat.ASTC_FORMAT.RGBA_4x4;
default: throw "Unsupported texture format "+t.format;
}
case ETC(n):
checkMult4(t);
switch( n ) {
case 0: tt.internalFmt = hxd.PixelFormat.ETC_FORMAT.RGB_ETC1;
case 1: tt.internalFmt = hxd.PixelFormat.ETC_FORMAT.RGBA_ETC2;
}
default:
throw "Unsupported texture format "+t.format;
}
Expand Down Expand Up @@ -1169,6 +1183,11 @@ class GlDriver extends Driver {
return tt;
}

inline function checkMult4(t:h3d.mat.Texture) {
if( t.width&3 != 0 || t.height&3 != 0 )
throw "Compressed texture "+t+" has size "+t.width+"x"+t.height+" - must be a multiple of 4";
}

function restoreBind() {
var t = boundTextures[lastActiveIndex];
if( t == null )
Expand Down Expand Up @@ -1409,12 +1428,13 @@ class GlDriver extends Driver {
case RGB10A2, RG11B10UF: new Uint32Array(@:privateAccess pixels.bytes.b.buffer, pixels.offset, dataLen>>2);
default: new Uint8Array(@:privateAccess pixels.bytes.b.buffer, pixels.offset, dataLen);
}
if( t.format.match(S3TC(_)) ) {
switch (t.format) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use match(S3TC()|STC()|ETC(_)) instead ?

case S3TC(_), ASTC(_), ETC(_):
if( t.flags.has(IsArray) || t.flags.has(Is3D) )
gl.compressedTexSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, t.t.internalFmt, buffer);
else
gl.compressedTexSubImage2D(face, mipLevel, 0, 0, pixels.width, pixels.height, t.t.internalFmt, buffer);
} else {
default:
if( t.flags.has(IsArray) || t.flags.has(Is3D) )
gl.texSubImage3D(face, mipLevel, 0, 0, side, pixels.width, pixels.height, 1, getChannels(t.t), t.t.pixelFmt, buffer);
else
Expand Down Expand Up @@ -1893,16 +1913,28 @@ class GlDriver extends Driver {
}

#if js
public function checkTextureSupport() {
final checkExtension = ext -> {
gl.getExtension(ext) != null;
}
return {
astc: checkExtension('WEBGL_compressed_texture_astc'),
astcHDR: checkExtension( 'WEBGL_compressed_texture_astc' )
&& gl.getExtension( 'WEBGL_compressed_texture_astc' ).getSupportedProfiles().includes( 'hdr' ),
etc1: false, // Not supported on WebGL2 (https://registry.khronos.org/OpenGL-Refpages/es3/html/glCompressedTexSubImage2D.xhtml); checkExtension('WEBGL_compressed_texture_etc1'),
etc2: checkExtension('WEBGL_compressed_texture_etc'),
dxt: checkExtension('WEBGL_compressed_texture_s3tc'),
bptc: checkExtension('EXT_texture_compression_bptc'),
}
}

var features : Map<Feature,Bool> = new Map();
var has16Bits : Bool;
function makeFeatures() {
for( f in Type.allEnums(Feature) )
features.set(f,checkFeature(f));
if( gl.getExtension("WEBGL_compressed_texture_s3tc") != null ) {
maxCompressedTexturesSupport = 3;
if( gl.getExtension("EXT_texture_compression_bptc") != null )
maxCompressedTexturesSupport = 7;
}
textureSupport = checkTextureSupport();
maxCompressedTexturesSupport = textureSupport.bptc ? 7 : 3;
if( glES < 3 )
gl.getExtension("WEBGL_depth_texture");
has16Bits = gl.getExtension("EXT_texture_norm16") != null; // 16 bit textures
Expand Down
28 changes: 26 additions & 2 deletions hxd/PixelFormat.hx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,33 @@ enum PixelFormat {
RG16U;
RGB16U;
RGBA16U;
S3TC( v : Int );
ASTC( ?v : Int );
ETC( ?v : Int );
S3TC( ?v : Int );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is v optional ? it shouldn't be for S3TC

Depth16;
Depth24;
Depth24Stencil8;
Depth32;
}
}

enum abstract ASTC_FORMAT(Int) from Int to Int {
final RGBA_4x4 = 0x93B0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These constants are for GL and should not be in PixelFormat

}

enum abstract DXT_FORMAT(Int) from Int to Int {
final RGB_DXT1 = 0x83F0;
final RGBA_DXT1 = 0x83F1;
final RGBA_DXT3 = 0x83F2;
final RGBA_DXT5 = 0x83F3;
}

enum abstract ETC_FORMAT(Int) from Int to Int {
final RGB_ETC1 = 0x8D64;
final RGBA_ETC2 = 0x9278;
}

enum abstract BPTC_FORMAT(Int) from Int to Int {
final RGB_BPTC_UNSIGNED = 0x8E8F;
final RGBA_BPTC = 0x8E8C;
}

56 changes: 49 additions & 7 deletions hxd/Pixels.hx
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ class Pixels {
this.bytes = nbytes;

case [S3TC(a),S3TC(b)] if( a == b ):
case [ASTC(a),ASTC(b)] if( a == b ):
case [ETC(a),ETC(b)] if( a == b ):
// nothing

#if (hl && hl_ver >= "1.10")
Expand Down Expand Up @@ -536,8 +538,33 @@ class Pixels {

public static function calcDataSize( width : Int, height : Int, format : PixelFormat ) {
return switch( format ) {
case S3TC(_):
(((height + 3) >> 2) << 2) * calcStride(width, format);
case S3TC(n):
var w = ((width + 3) >> 2) << 2; // Round up width to next multiple of 4
var h = ((height + 3) >> 2) << 2; // Round up height to next multiple of 4
var blocks = (w >> 2) * (h >> 2); // Total number of blocks
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be simplified without <<2 and blocks = w*h (same for other formats)

if (n == 3) { // DXT5
blocks * 16; // 16 bytes per block
} else if (n == 1 || n == 4) {
blocks * 8; // DXT1 or BC4, 8 bytes per block
} else {
blocks * 16; // DXT3 or BC5, 16 bytes per block, but handling like DXT5 for simplicity
}
case ASTC(n):
var w = ((width + 3) >> 2) << 2;
var h = ((height + 3) >> 2) << 2;
(w >> 2) * (h >> 2) * 16;
case ETC(n):
if (n == 0) { // RGB_ETC1_Format or RGB_ETC2_Format
var w = ((width + 3) >> 2) << 2;
var h = ((height + 3) >> 2) << 2;
(w >> 2) * (h >> 2) * 8;
} else if (n == 1 || n == 2) { // RGBA_ETC2_EAC_Format
var w = ((width + 3) >> 2) << 2;
var h = ((height + 3) >> 2) << 2;
(w >> 2) * (h >> 2) * 16;
} else {
throw "Unsupported ETC format";
}
default:
height * calcStride(width, format);
}
Expand All @@ -559,11 +586,26 @@ class Pixels {
case RGB32F: 12;
case RGB10A2: 4;
case RG11B10UF: 4;
case ASTC(n):
var blocks = ((width + 3) >> 2) * 16;
blocks << 4;
case ETC(n):
if (n == 0) { // ETC1 and ETC2 RGB
((width + 3) >> 2) << 3;
} else if (n == 1) { // ETC2 EAC RGBA
((width + 3) >> 2) << 4;
} else {
throw "Unsupported ETC format";
}
case S3TC(n):
var blocks = (width + 3) >> 2;
if( n == 1 || n == 4 )
return blocks << 1;
return blocks << 2;
if (n == 3) { // DXT5
blocks << 4; // 16 bytes per block
} else if (n == 1 || n == 4) {
blocks << 1; // DXT1 or BC4, 8 bytes per block
} else {
blocks << 2; // DXT3 or BC5, 16 bytes per block, but handling like DXT5 for simplicity
}
case Depth16: 2;
case Depth24: 3;
case Depth24Stencil8, Depth32: 4;
Expand Down Expand Up @@ -605,13 +647,13 @@ class Pixels {
channel.toInt() * 4;
case RGB10A2, RG11B10UF:
throw "Bit packed format";
case S3TC(_), Depth16, Depth24, Depth24Stencil8, Depth32:
case S3TC(_), ASTC(_), ETC(_), Depth16, Depth24, Depth24Stencil8, Depth32:
throw "Not supported";
}
}

public static function alloc( width, height, format : PixelFormat ) {
return new Pixels(width, height, haxe.io.Bytes.alloc(calcDataSize(width, height, format)), format);
return new Pixels(width, height, haxe.io.Bytes.alloc(calcDataSize(width, height, format)), format);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions hxd/net/BinaryLoader.hx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class BinaryLoader {
throw msg;
}

public function load() {
public function load(raw = false) {
#if js

var xhr = new js.html.XMLHttpRequest();
Expand All @@ -32,7 +32,7 @@ class BinaryLoader {
onError(xhr.statusText);
return;
}
onLoaded(haxe.io.Bytes.ofData(xhr.response));
onLoaded(raw ? xhr.response : haxe.io.Bytes.ofData(xhr.response));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unrelated to the PR. Please submit separately

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used by Ktx2Decoder.initTranscoder when loading the wasm module.

}

xhr.onprogress = function(e) {
Expand Down
27 changes: 24 additions & 3 deletions hxd/res/Image.hx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum abstract ImageFormat(Int) {
var Dds = 4;
var Raw = 5;
var Hdr = 6;
var Ktx2 = 7;

/*
Tells if we might not be able to directly decode the image without going through a loadBitmap async call.
Expand Down Expand Up @@ -35,6 +36,7 @@ enum abstract ImageFormat(Int) {
case Dds: "DDS";
case Raw: "RAW";
case Hdr: "HDR";
case Ktx2: "KTX2";
};
}
}
Expand Down Expand Up @@ -241,7 +243,21 @@ class Image extends Resource {
fid = "" + fourCC;
throw entry.path + " has unsupported 4CC " + fid;
}

#if js
case 0x4273:
throw 'Use .ktx2 files for GPU compressed textures instead of .basis';
case 0x4BAB:
final ktx2 = hxd.res.Ktx2.readFile(new haxe.io.BytesInput(@:privateAccess f.cache));
inf.pixelFormat = switch ktx2.dfd.colorModel {
case hxd.res.Ktx2.DFDModel.ETC1S: ETC(hxd.res.Ktx2.TranscoderFormat.ETC1);
case hxd.res.Ktx2.DFDModel.UASTC: ASTC(hxd.res.Ktx2.TranscoderFormat.ASTC_4x4);
default: throw 'Unsupported colorModel in ktx2 file ${ktx2.dfd.colorModel}';
}
inf.mipLevels = ktx2.header.levelCount;
inf.width = ktx2.header.pixelWidth;
inf.height = ktx2.header.pixelHeight;
inf.dataFormat = Ktx2;
#end
case 0x3F23: // HDR RADIANCE

inf.dataFormat = Hdr;
Expand Down Expand Up @@ -435,6 +451,9 @@ class Image extends Resource {
case Hdr:
var data = hxd.fmt.hdr.Reader.decode(entry.getBytes(), false);
pixels = new hxd.Pixels(data.width, data.height, data.bytes, inf.pixelFormat);
case Ktx2:
var bytes = entry.getBytes();
pixels = new hxd.Pixels(inf.width, inf.height, bytes, inf.pixelFormat);
}
if (fmt != null)
pixels.convert(fmt);
Expand Down Expand Up @@ -610,6 +629,8 @@ class Image extends Resource {
pos += size;
}
}
case Ktx2:
throw 'Ktx2 loading using heaps resource system not implemented';
default:
for (layer in 0...tex.layerCount) {
for (mip in 0...inf.mipLevels) {
Expand Down Expand Up @@ -668,8 +689,8 @@ class Image extends Resource {
}

public function toTile():h2d.Tile {
getInfo();
return h2d.Tile.fromTexture(toTexture()).sub(0, 0, inf.width, inf.height);
final tex = toTexture();
return h2d.Tile.fromTexture(tex).sub(0, 0, tex.width, tex.height);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unrelated to the PR. Please submit separately

}

public static dynamic function setupTextureFlags(tex:h3d.mat.Texture) {}
Expand Down
Loading