Skip to content

Commit f06070e

Browse files
committed
Initial KTX1/ETC2 support
1 parent 1197a19 commit f06070e

8 files changed

Lines changed: 572 additions & 40 deletions

File tree

code/bmpman/bm_internal.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct bitmap_entry {
7070
// Stuff to keep track of usage
7171
ubyte preloaded; //!< If set, then this was loaded from the lst file
7272
int preload_count; //!< how many times this gets used in game, for unlocking
73-
ushort used_flags; //!< What flags it was accessed thru
73+
uint used_flags; //!< What flags it was accessed thru
7474
int load_count;
7575

7676
bitmap bm; //!< Bitmap info
@@ -93,14 +93,15 @@ struct bitmap_slot {
9393
};
9494

9595
// image specific lock functions
96-
void bm_lock_ani( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
97-
void bm_lock_dds( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
98-
void bm_lock_png( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
99-
void bm_lock_apng( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
100-
void bm_lock_jpg( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
101-
void bm_lock_pcx( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
102-
void bm_lock_tga( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags );
103-
void bm_lock_user( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags, bool convert = true );
96+
void bm_lock_ani( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
97+
void bm_lock_dds( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
98+
void bm_lock_png( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
99+
void bm_lock_apng( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
100+
void bm_lock_jpg( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
101+
void bm_lock_pcx( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
102+
void bm_lock_tga( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags );
103+
void bm_lock_user( int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags, bool convert = true );
104+
void bm_lock_ktx1(int handle, bitmap_slot* bs, bitmap* bmp, int bpp, uint flags);
104105

105106
const size_t BM_BLOCK_SIZE = 4096;
106107

code/bmpman/bmpman.cpp

Lines changed: 120 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "tgautils/tgautils.h"
3333
#include "tracing/Monitor.h"
3434
#include "tracing/tracing.h"
35+
#include "ktxutils/ktxutils.h"
3536

3637
#include <cctype>
3738
#include <climits>
@@ -59,8 +60,8 @@ size_t bm_texture_ram = 0;
5960
int Bm_paging = 0;
6061

6162
// Extension type lists
62-
const BM_TYPE bm_type_list[] = { BM_TYPE_DDS, BM_TYPE_TGA, BM_TYPE_PNG, BM_TYPE_JPG, BM_TYPE_PCX };
63-
const char *bm_ext_list[] = { ".dds", ".tga", ".png", ".jpg", ".pcx" };
63+
const BM_TYPE bm_type_list[] = { BM_TYPE_DDS, BM_TYPE_TGA, BM_TYPE_PNG, BM_TYPE_JPG, BM_TYPE_PCX, BM_TYPE_KTX };
64+
const char* bm_ext_list[] = { ".dds", ".tga", ".png", ".jpg", ".pcx", ".ktx" };
6465
const int BM_NUM_TYPES = sizeof(bm_type_list) / sizeof(bm_type_list[0]);
6566

6667
const BM_TYPE bm_ani_type_list[] = { BM_TYPE_EFF, BM_TYPE_ANI, BM_TYPE_PNG };
@@ -205,7 +206,7 @@ void clear_bm_lookup_cache() {
205206
/**
206207
* Converts the bitmap referenced by bmp to the type specified by flags
207208
*/
208-
static void bm_convert_format(bitmap *bmp, ushort flags);
209+
static void bm_convert_format(bitmap *bmp, uint flags);
209210

210211
/**
211212
* Frees a bitmap's data if it can
@@ -639,7 +640,7 @@ int bm_create_3d(int bpp, int w, int h, int d, void* data) {
639640
return n;
640641
}
641642

642-
void bm_convert_format(bitmap *bmp, ushort flags) {
643+
void bm_convert_format(bitmap *bmp, uint flags) {
643644
int idx;
644645

645646
// no transparency for 24 bpp images
@@ -901,7 +902,7 @@ void bm_get_frame_usage(int *ntotal, int *nnew) {
901902
#endif
902903
}
903904

904-
int bm_get_info(int handle, int *w, int * h, ushort* flags, int *nframes, int *fps) {
905+
int bm_get_info(int handle, int *w, int * h, uint* flags, int *nframes, int *fps) {
905906
bitmap * bmp;
906907

907908
if (!bm_inited) return -1;
@@ -1055,6 +1056,18 @@ int bm_is_compressed(int num) {
10551056
case BM_TYPE_CUBEMAP_DXT5:
10561057
return DDS_CUBEMAP_DXT5;
10571058

1059+
case BM_TYPE_ETC2_RGB:
1060+
return KTX_ETC2_RGB;
1061+
1062+
case BM_TYPE_ETC2_RGBA_EAC:
1063+
return KTX_ETC2_RGBA_EAC;
1064+
1065+
case BM_TYPE_EAC_R11:
1066+
return KTX_EAC_R11;
1067+
1068+
case BM_TYPE_EAC_RG11:
1069+
return KTX_EAC_RG11;
1070+
10581071
default:
10591072
return 0;
10601073
}
@@ -1148,6 +1161,16 @@ static int bm_load_info(BM_TYPE type, const char *filename, CFILE *img_cfp, int
11481161
return -1;
11491162
}
11501163
}
1164+
// its a KTX file
1165+
else if (type == BM_TYPE_KTX) {
1166+
int ktx_ct;
1167+
int ktx_error = ktx1_read_header(filename, img_cfp, w, h, bpp, &ktx_ct, mm_lvl, size);
1168+
if (ktx_error != KTX1_ERROR_NONE) {
1169+
mprintf(("ktx: could not open '%s'\n", filename));
1170+
return -1;
1171+
}
1172+
*c_type = (BM_TYPE)ktx_ct;
1173+
}
11511174
// if its a tga file
11521175
else if (type == BM_TYPE_TGA) {
11531176
int tga_error = targa_read_header(filename, img_cfp, w, h, bpp, NULL);
@@ -1361,6 +1384,8 @@ bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
13611384
c_type = BM_TYPE_JPG;
13621385
} else if (!stricmp(NOX("pcx"), ext)) {
13631386
c_type = BM_TYPE_PCX;
1387+
} else if (!stricmp(NOX("ktx"), ext)) {
1388+
c_type = BM_TYPE_KTX;
13641389
} else {
13651390
mprintf(("BMPMAN: Unknown file type in EFF parse!\n"));
13661391
return false;
@@ -1390,7 +1415,7 @@ bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
13901415
/**
13911416
* Lock an image files data into memory
13921417
*/
1393-
static int bm_load_image_data(int handle, int bpp, ushort flags, bool nodebug)
1418+
static int bm_load_image_data(int handle, int bpp, uint flags, bool nodebug)
13941419
{
13951420
BM_TYPE c_type = BM_TYPE_NONE;
13961421
int true_bpp;
@@ -1482,6 +1507,10 @@ static int bm_load_image_data(int handle, int bpp, ushort flags, bool nodebug)
14821507
bm_lock_user(handle, bs, bmp, true_bpp, flags, false);
14831508
break;
14841509

1510+
case BM_TYPE_KTX:
1511+
bm_lock_ktx1(handle, bs, bmp, true_bpp, flags);
1512+
break;
1513+
14851514
default:
14861515
Warning(LOCATION, "Unsupported type in bm_lock -- %d\n", c_type);
14871516
return -1;
@@ -1941,7 +1970,7 @@ int bm_load_sub_slow(const char *real_filename, const int num_ext, const char **
19411970
return -1;
19421971
}
19431972

1944-
bitmap * bm_lock(int handle, int bpp, ushort flags, bool nodebug) {
1973+
bitmap * bm_lock(int handle, int bpp, uint flags, bool nodebug) {
19451974
bitmap *bmp;
19461975

19471976
Assertion(bm_inited, "bmpman must be initialized before this function can be called!");
@@ -2038,7 +2067,7 @@ bitmap * bm_lock(int handle, int bpp, ushort flags, bool nodebug) {
20382067
return bmp;
20392068
}
20402069

2041-
void bm_lock_ani(int /*handle*/, bitmap_slot *bs, bitmap* /*bmp*/, int bpp, ushort flags) {
2070+
void bm_lock_ani(int /*handle*/, bitmap_slot *bs, bitmap* /*bmp*/, int bpp, uint flags) {
20422071
anim *the_anim;
20432072
anim_instance *the_anim_instance;
20442073
bitmap *bm;
@@ -2164,7 +2193,7 @@ void bm_lock_ani(int /*handle*/, bitmap_slot *bs, bitmap* /*bmp*/, int bpp, usho
21642193
}
21652194

21662195

2167-
void bm_lock_apng(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort /*flags*/) {
2196+
void bm_lock_apng(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, uint /*flags*/) {
21682197
auto be = &bs->entry;
21692198
int first_frame = be->info.ani.first_frame;
21702199
auto first_entry = bm_get_entry(first_frame);
@@ -2214,7 +2243,7 @@ void bm_lock_apng(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort
22142243
}
22152244

22162245

2217-
void bm_lock_dds(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, ushort /*flags*/) {
2246+
void bm_lock_dds(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, uint /*flags*/) {
22182247
ubyte *data = NULL;
22192248
int error;
22202249
ubyte dds_bpp = 0;
@@ -2278,7 +2307,7 @@ void bm_lock_dds(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, ushort /
22782307
#endif
22792308
}
22802309

2281-
void bm_lock_jpg(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort /*flags*/) {
2310+
void bm_lock_jpg(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint /*flags*/) {
22822311
ubyte *data = NULL;
22832312
int d_size = 0;
22842313
int jpg_error = JPEG_ERROR_INVALID;
@@ -2325,7 +2354,7 @@ void bm_lock_jpg(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort /*fla
23252354
#endif
23262355
}
23272356

2328-
void bm_lock_pcx(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags) {
2357+
void bm_lock_pcx(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags) {
23292358
ubyte *data;
23302359
int pcx_error;
23312360
char filename[MAX_FILENAME_LEN];
@@ -2370,7 +2399,7 @@ void bm_lock_pcx(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags
23702399
bm_convert_format(bmp, flags);
23712400
}
23722401

2373-
void bm_lock_png(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, ushort /*flags*/) {
2402+
void bm_lock_png(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, uint /*flags*/) {
23742403
ubyte *data = NULL;
23752404
//assume 32 bit - libpng should expand everything
23762405
int d_size;
@@ -2415,7 +2444,7 @@ void bm_lock_png(int handle, bitmap_slot *bs, bitmap *bmp, int /*bpp*/, ushort /
24152444
#endif
24162445
}
24172446

2418-
void bm_lock_tga(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags) {
2447+
void bm_lock_tga(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags) {
24192448
ubyte *data = NULL;
24202449
int byte_size;
24212450
char filename[MAX_FILENAME_LEN];
@@ -2474,7 +2503,7 @@ void bm_lock_tga(int handle, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags
24742503
bm_convert_format(bmp, flags);
24752504
}
24762505

2477-
void bm_lock_user(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, ushort flags, bool convert) {
2506+
void bm_lock_user(int /*handle*/, bitmap_slot *bs, bitmap *bmp, int bpp, uint flags, bool convert) {
24782507
auto be = &bs->entry;
24792508

24802509
// Unload any existing data
@@ -2767,6 +2796,22 @@ void bm_page_in_texture(int bitmapnum, int nframes) {
27672796
frame_entry->used_flags = BMP_TEX_CUBEMAP;
27682797
continue;
27692798

2799+
case BM_TYPE_ETC2_RGB:
2800+
frame_entry->used_flags = BMP_TEX_ETC2_RGB;
2801+
continue;
2802+
2803+
case BM_TYPE_ETC2_RGBA_EAC:
2804+
frame_entry->used_flags = BMP_TEX_ETC2_RGBA_EAC;
2805+
continue;
2806+
2807+
case BM_TYPE_EAC_R11:
2808+
frame_entry->used_flags = BMP_TEX_EAC_R11;
2809+
continue;
2810+
2811+
case BM_TYPE_EAC_RG11:
2812+
frame_entry->used_flags = BMP_TEX_EAC_RG11;
2813+
continue;
2814+
27702815
default:
27712816
continue;
27722817
}
@@ -2812,6 +2857,22 @@ void bm_page_in_xparent_texture(int bitmapnum, int nframes) {
28122857
entry->used_flags = BMP_TEX_CUBEMAP;
28132858
continue;
28142859

2860+
case BM_TYPE_ETC2_RGB:
2861+
entry->used_flags = BMP_TEX_ETC2_RGB;
2862+
continue;
2863+
2864+
case BM_TYPE_ETC2_RGBA_EAC:
2865+
entry->used_flags = BMP_TEX_ETC2_RGBA_EAC;
2866+
continue;
2867+
2868+
case BM_TYPE_EAC_R11:
2869+
entry->used_flags = BMP_TEX_EAC_R11;
2870+
continue;
2871+
2872+
case BM_TYPE_EAC_RG11:
2873+
entry->used_flags = BMP_TEX_EAC_RG11;
2874+
continue;
2875+
28152876
default:
28162877
continue;
28172878
}
@@ -3432,3 +3493,47 @@ SDL_Surface* bm_to_sdl_surface(int handle) {
34323493
return bitmapSurface;
34333494

34343495
}
3496+
3497+
// copied bm_lock_dds and adjusted for ktx. missing BIG_ENDIAN
3498+
void bm_lock_ktx1(int handle, bitmap_slot* bs, bitmap* bmp, int bpp, uint flags)
3499+
{
3500+
(void)bpp;
3501+
(void)flags;
3502+
ubyte* data = nullptr;
3503+
ubyte ktx_bpp = 0;
3504+
int ktx_error = KTX1_ERROR_NONE;
3505+
char filename[MAX_FILENAME_LEN];
3506+
3507+
auto be = &bs->entry;
3508+
3509+
bm_free_data(bs);
3510+
3511+
Assert(be->mem_taken > 0);
3512+
Assert(&be->bm == bmp);
3513+
3514+
data = (ubyte*)bm_malloc(handle, be->mem_taken);
3515+
if (!data)
3516+
return;
3517+
memset(data, 0, be->mem_taken);
3518+
3519+
// make sure we are using the correct filename in the case of an EFF.
3520+
// this will populate filename[] whether it's EFF or not
3521+
EFF_FILENAME_CHECK;
3522+
3523+
ktx_error = ktx1_read_bitmap(filename, data, &ktx_bpp, be->dir_type);
3524+
3525+
if (ktx_error != KTX1_ERROR_NONE)
3526+
{
3527+
mprintf(("KTX: read_bitmap error=%d file='%s'\n", ktx_error, filename));
3528+
bm_free_data(bs);
3529+
return;
3530+
}
3531+
3532+
bmp->bpp = ktx_bpp;
3533+
bmp->data = (ptr_u)data;
3534+
bmp->flags = 0;
3535+
3536+
#ifdef BMPMAN_NDEBUG
3537+
Assert(be->data_size > 0);
3538+
#endif
3539+
}

code/bmpman/bmpman.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
// Flag positions for bitmap.flags
3636
// ***** NOTE: bitmap.flags is an 8-bit value, no more BMP_TEX_* flags can be added unless the type is changed!! ******
37+
// Update: type changed to 16-bit
3738
#define BMP_AABITMAP (1<<0) //!< antialiased bitmap
3839
#define BMP_TEX_XPARENT (1<<1) //!< transparent texture
3940
#define BMP_TEX_OTHER (1<<2) //!< so we can identify all "normal" textures
@@ -43,9 +44,14 @@
4344
#define BMP_TEX_BC7 (1<<6) //!< BC7 compressed 8r8g8b8a (32bit)
4445
#define BMP_TEX_CUBEMAP (1<<7) //!< a texture made for cubic environment map
4546
#define BMP_MASK_BITMAP (1<<8) //!< a bitmap that will be used for masking mouse interaction. Typically not used in render operations
47+
#define BMP_TEX_ETC2_RGB (1 << 9)
48+
#define BMP_TEX_ETC2_RGBA_EAC (1 << 10)
49+
#define BMP_TEX_EAC_R11 (1 << 11)
50+
#define BMP_TEX_EAC_RG11 (1 << 12)
4651

4752
// Combined flags
48-
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 | BMP_TEX_BC7 ) //!< Compressed textures
53+
#define BMP_TEX_COMP ( BMP_TEX_DXT1 | BMP_TEX_DXT3 | BMP_TEX_DXT5 | BMP_TEX_BC7 | BMP_TEX_ETC2_RGB |\
54+
BMP_TEX_ETC2_RGBA_EAC | BMP_TEX_EAC_R11 | BMP_TEX_EAC_RG11 ) //!< Compressed textures
4955
#define BMP_TEX_NONCOMP ( BMP_TEX_XPARENT | BMP_TEX_OTHER ) //!< Non-compressed textures
5056
#define BMP_TEX_ANY ( BMP_TEX_COMP | BMP_TEX_NONCOMP ) //!< Any texture
5157

@@ -81,7 +87,12 @@ enum BM_TYPE
8187
BM_TYPE_CUBEMAP_DXT3, //!< 32-bit cubemap (compressed cubemap surface)
8288
BM_TYPE_CUBEMAP_DXT5, //!< 32-bit cubemap (compressed cubemap surface)
8389

84-
BM_TYPE_3D //!< 3D in-memory
90+
BM_TYPE_3D, //!< 3D in-memory
91+
BM_TYPE_KTX, //!< generic identifier for KTX
92+
BM_TYPE_ETC2_RGB, //!< 24 bit without alpha
93+
BM_TYPE_ETC2_RGBA_EAC, //!< 32 bit with alpha
94+
BM_TYPE_EAC_R11, //!< BC4 equivalent
95+
BM_TYPE_EAC_RG11 //!< BC5 equivalent
8596
};
8697

8798
/**
@@ -96,7 +107,7 @@ struct bitmap
96107
short rowsize; //!< What you need to add to go to next row
97108
int bpp; //!< Requested bitdepth of each pixel. ( 7, 8, 15, 16, 24, 32)
98109
int true_bpp; //!< The image's actual bitdepth
99-
ushort flags; //!< Various texture type flags. @see BMPMAN_CONSTANTS
110+
uint flags; //!< Various texture type flags. @see BMPMAN_CONSTANTS
100111
ptr_u data; //!< Pointer to data, or maybe offset into VRAM.
101112
ubyte *palette; /**< @brief Pointer to this bitmap's palette (if it has one).
102113
* @details If BMP_NO_PALETTE_MAP flag is cleared, this palette just points to the screen palette. (gr_palette)
@@ -344,7 +355,7 @@ int bm_load_either(const char *filename, int *nframes = NULL, int *fps = NULL, i
344355
* @returns A pointer to the bitmap that's valid until bm_unlock is called if successful, or
345356
* @returns NULL if unsuccessful
346357
*/
347-
bitmap* bm_lock(int handle, int bpp, ushort flags, bool nodebug = false);
358+
bitmap* bm_lock(int handle, int bpp, uint flags, bool nodebug = false);
348359

349360
/**
350361
* @brief Returns the image type of the given bitmap handle
@@ -387,7 +398,7 @@ int bm_is_valid(int handle);
387398
* @returns The handle to the first frame on success, or
388399
* @returns -1 on failure
389400
*/
390-
int bm_get_info(int handle, int *w = nullptr, int * h = nullptr, ushort* flags = nullptr, int *nframes = nullptr, int *fps = nullptr);
401+
int bm_get_info(int handle, int *w = nullptr, int * h = nullptr, uint* flags = nullptr, int *nframes = nullptr, int *fps = nullptr);
391402

392403
/**
393404
* @brief Gets 3D info on the bitmap indexed by handle.

0 commit comments

Comments
 (0)