-
Notifications
You must be signed in to change notification settings - Fork 345
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
Changes from 8 commits
0f5ecf6
e6f75d9
c8b85c4
1f50d20
599adb5
0d4b759
d3fc2f7
3bb8c54
49d6a2d
7779b53
42fa2b7
1c6f8ed
e8067c3
4c91180
eb65cd6
1ee5cd1
6cdee26
3a00b7f
b83bdbd
34c18e4
3c9b5b8
08597ae
4784fd2
0d61641
b1a1bd4
7ee2110
3f6dc7e
713cad9
438e64c
9e4a14a
702b50d
75d0407
7baf553
ae4a753
ae0329a
a652075
5865e61
8ac0833
e1c9372
258ad00
42ca30e
b10ed37
53ed8cf
479ad86
91c1d68
4929a10
f116fe8
b099063
433ebca
dff1eba
4e10301
306a104
b7f9c71
a7956d2
e9e43e6
048826f
9c21164
ce4cdb5
9f95949
0563d7e
7f0c8b4
cf4437f
00dfde3
d63fc8b
45e43d9
a91dcdf
3984614
dc17d15
6e64fcd
1e185a0
cb020bb
7de7b5c
9b3a094
241b10d
a743874
c5c4d96
9d379b1
fca380b
3524cc0
a28f251
b96b6f8
1c3840f
cdcae08
6dacc57
0a34c0d
abfe146
1dc0707
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,9 +23,33 @@ enum PixelFormat { | |
RG16U; | ||
RGB16U; | ||
RGBA16U; | ||
S3TC( v : Int ); | ||
ASTC( ?v : Int ); | ||
ETC( ?v : Int ); | ||
S3TC( ?v : Int ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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") | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
} | ||
|
@@ -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; | ||
|
@@ -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); | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ class BinaryLoader { | |
throw msg; | ||
} | ||
|
||
public function load() { | ||
public function load(raw = false) { | ||
#if js | ||
|
||
var xhr = new js.html.XMLHttpRequest(); | ||
|
@@ -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)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems unrelated to the PR. Please submit separately There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
|
@@ -35,6 +36,7 @@ enum abstract ImageFormat(Int) { | |
case Dds: "DDS"; | ||
case Raw: "RAW"; | ||
case Hdr: "HDR"; | ||
case Ktx2: "KTX2"; | ||
}; | ||
} | ||
} | ||
|
@@ -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; | ||
|
@@ -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); | ||
|
@@ -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) { | ||
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) {} | ||
|
There was a problem hiding this comment.
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 ?