Skip to content

Commit 83b8361

Browse files
committed
Move texture loading out of graphics code
Currently the graphics code handles loading texture information and data but that should be done by bmpman itself. I removed two graphics API functions and added a new one which is called to notify the graphics code that a texture has been loaded.
1 parent be67793 commit 83b8361

File tree

7 files changed

+234
-770
lines changed

7 files changed

+234
-770
lines changed

code/bmpman/bmpman.cpp

Lines changed: 218 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,110 @@ int bm_is_valid(int handle) {
913913
return (bm_bitmaps[handle % MAX_BITMAPS].handle == handle);
914914
}
915915

916+
917+
// Load an image and validate it while retrieving information for later use
918+
// Input: type = current BM_TYPE_*
919+
// n = location in bm_bitmaps[]
920+
// filename = name of the current file
921+
// img_cfp = already open CFILE handle, if available
922+
//
923+
// Output: w = bmp width
924+
// h = bmp height
925+
// bpp = bmp bits per pixel
926+
// c_type = output for an updated BM_TYPE_*
927+
// mm_lvl = number of mipmap levels for the image
928+
// size = size of the data contained in the image
929+
static int bm_load_info(BM_TYPE type, int n, const char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, BM_TYPE *c_type, int *mm_lvl, int *size)
930+
{
931+
int dds_ct;
932+
933+
if (type == BM_TYPE_DDS) {
934+
int dds_error = dds_read_header(filename, img_cfp, w, h, bpp, &dds_ct, mm_lvl, size);
935+
936+
if (dds_error != DDS_ERROR_NONE) {
937+
mprintf(("DDS ERROR: Couldn't open '%s' -- %s\n", filename, dds_error_string(dds_error)));
938+
return -1;
939+
}
940+
941+
switch (dds_ct) {
942+
case DDS_DXT1:
943+
*c_type = BM_TYPE_DXT1;
944+
break;
945+
946+
case DDS_DXT3:
947+
*c_type = BM_TYPE_DXT3;
948+
break;
949+
950+
case DDS_DXT5:
951+
*c_type = BM_TYPE_DXT5;
952+
break;
953+
954+
case DDS_UNCOMPRESSED:
955+
*c_type = BM_TYPE_DDS;
956+
break;
957+
958+
case DDS_CUBEMAP_DXT1:
959+
*c_type = BM_TYPE_CUBEMAP_DXT1;
960+
break;
961+
962+
case DDS_CUBEMAP_DXT3:
963+
*c_type = BM_TYPE_CUBEMAP_DXT3;
964+
break;
965+
966+
case DDS_CUBEMAP_DXT5:
967+
*c_type = BM_TYPE_CUBEMAP_DXT5;
968+
break;
969+
970+
case DDS_CUBEMAP_UNCOMPRESSED:
971+
*c_type = BM_TYPE_CUBEMAP_DDS;
972+
break;
973+
974+
default:
975+
Error(LOCATION, "Bad DDS file compression! Not using DXT1,3,5: %s", filename);
976+
return -1;
977+
}
978+
}
979+
// if its a tga file
980+
else if (type == BM_TYPE_TGA) {
981+
int tga_error = targa_read_header(filename, img_cfp, w, h, bpp, NULL);
982+
if (tga_error != TARGA_ERROR_NONE) {
983+
mprintf(("tga: Couldn't open '%s'\n", filename));
984+
return -1;
985+
}
986+
}
987+
// if its a png file
988+
else if (type == BM_TYPE_PNG) {
989+
int png_error = png_read_header(filename, img_cfp, w, h, bpp, NULL);
990+
if (png_error != PNG_ERROR_NONE) {
991+
mprintf(("png: Couldn't open '%s'\n", filename));
992+
return -1;
993+
}
994+
}
995+
// if its a jpg file
996+
else if (type == BM_TYPE_JPG) {
997+
int jpg_error = jpeg_read_header(filename, img_cfp, w, h, bpp, NULL);
998+
if (jpg_error != JPEG_ERROR_NONE) {
999+
mprintf(("jpg: Couldn't open '%s'\n", filename));
1000+
return -1;
1001+
}
1002+
}
1003+
// if its a pcx file
1004+
else if (type == BM_TYPE_PCX) {
1005+
int pcx_error = pcx_read_header(filename, img_cfp, w, h, bpp, NULL);
1006+
if (pcx_error != PCX_ERROR_NONE) {
1007+
mprintf(("pcx: Couldn't open '%s'\n", filename));
1008+
return -1;
1009+
}
1010+
}
1011+
else {
1012+
Assert(0);
1013+
1014+
return -1;
1015+
}
1016+
1017+
return 0;
1018+
}
1019+
9161020
int bm_load(const char *real_filename) {
9171021
int i, free_slot = -1;
9181022
int w, h, bpp = 8;
@@ -985,7 +1089,7 @@ int bm_load(const char *real_filename) {
9851089
goto Done;
9861090
}
9871091

988-
rc = gr_bm_load(type, free_slot, filename, img_cfp, &w, &h, &bpp, &c_type, &mm_lvl, &bm_size);
1092+
rc = bm_load_info(type, free_slot, filename, img_cfp, &w, &h, &bpp, &c_type, &mm_lvl, &bm_size);
9891093

9901094
if (rc != 0)
9911095
goto Done;
@@ -1111,6 +1215,109 @@ bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
11111215
return true;
11121216
}
11131217

1218+
1219+
/**
1220+
* Lock an image files data into memory
1221+
*/
1222+
static int bm_load_image_data(const char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug)
1223+
{
1224+
BM_TYPE c_type = BM_TYPE_NONE;
1225+
ubyte true_bpp;
1226+
1227+
bitmap_entry *be = &bm_bitmaps[bitmapnum];
1228+
bitmap *bmp = &be->bm;
1229+
1230+
Assert(!Is_standalone);
1231+
1232+
if (bmp->true_bpp > bpp)
1233+
true_bpp = bmp->true_bpp;
1234+
else
1235+
true_bpp = bpp;
1236+
1237+
// don't do a bpp check here since it could be different in OGL - taylor
1238+
if (bmp->data == 0) {
1239+
Assert(be->ref_count == 1);
1240+
1241+
if (be->type != BM_TYPE_USER && !nodebug) {
1242+
if (bmp->data == 0)
1243+
nprintf(("BmpMan", "Loading %s for the first time.\n", be->filename));
1244+
}
1245+
1246+
if (!Bm_paging) {
1247+
if (be->type != BM_TYPE_USER && !nodebug)
1248+
nprintf(("Paging", "Loading %s (%dx%dx%d)\n", be->filename, bmp->w, bmp->h, true_bpp));
1249+
}
1250+
1251+
// select proper format
1252+
if (flags & BMP_AABITMAP)
1253+
BM_SELECT_ALPHA_TEX_FORMAT();
1254+
else if (flags & BMP_TEX_ANY)
1255+
BM_SELECT_TEX_FORMAT();
1256+
else
1257+
BM_SELECT_SCREEN_FORMAT();
1258+
1259+
// make sure we use the real graphic type for EFFs
1260+
if (be->type == BM_TYPE_EFF) {
1261+
c_type = be->info.ani.eff.type;
1262+
}
1263+
else {
1264+
c_type = be->type;
1265+
}
1266+
1267+
switch (c_type)
1268+
{
1269+
case BM_TYPE_PCX:
1270+
bm_lock_pcx(handle, bitmapnum, be, bmp, true_bpp, flags);
1271+
break;
1272+
1273+
case BM_TYPE_ANI:
1274+
bm_lock_ani(handle, bitmapnum, be, bmp, true_bpp, flags);
1275+
break;
1276+
1277+
case BM_TYPE_TGA:
1278+
bm_lock_tga(handle, bitmapnum, be, bmp, true_bpp, flags);
1279+
break;
1280+
1281+
case BM_TYPE_PNG:
1282+
//libpng handles compression with zlib
1283+
bm_lock_png(handle, bitmapnum, be, bmp, true_bpp, flags);
1284+
break;
1285+
1286+
case BM_TYPE_JPG:
1287+
bm_lock_jpg(handle, bitmapnum, be, bmp, true_bpp, flags);
1288+
break;
1289+
1290+
case BM_TYPE_DDS:
1291+
case BM_TYPE_DXT1:
1292+
case BM_TYPE_DXT3:
1293+
case BM_TYPE_DXT5:
1294+
case BM_TYPE_CUBEMAP_DDS:
1295+
case BM_TYPE_CUBEMAP_DXT1:
1296+
case BM_TYPE_CUBEMAP_DXT3:
1297+
case BM_TYPE_CUBEMAP_DXT5:
1298+
bm_lock_dds(handle, bitmapnum, be, bmp, true_bpp, flags);
1299+
break;
1300+
1301+
case BM_TYPE_USER:
1302+
bm_lock_user(handle, bitmapnum, be, bmp, true_bpp, flags);
1303+
break;
1304+
1305+
default:
1306+
Warning(LOCATION, "Unsupported type in bm_lock -- %d\n", c_type);
1307+
return -1;
1308+
}
1309+
1310+
// always go back to screen format
1311+
BM_SELECT_SCREEN_FORMAT();
1312+
1313+
// make sure we actually did something
1314+
if (!(bmp->data))
1315+
return -1;
1316+
}
1317+
1318+
return 0;
1319+
}
1320+
11141321
int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type) {
11151322
int i, n;
11161323
anim the_anim;
@@ -1279,7 +1486,7 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
12791486
sprintf(bm_bitmaps[n + i].info.ani.eff.filename, "%s_%.4d", clean_name, i);
12801487

12811488
// gr_bm_load() returns non-0 on failure
1282-
if (gr_bm_load(eff_type, n + i, bm_bitmaps[n + i].info.ani.eff.filename, NULL, &anim_width, &anim_height, &bpp, &c_type, &mm_lvl, &img_size)) {
1489+
if (bm_load_info(eff_type, n + i, bm_bitmaps[n + i].info.ani.eff.filename, NULL, &anim_width, &anim_height, &bpp, &c_type, &mm_lvl, &img_size)) {
12831490
// if we didn't get anything then bail out now
12841491
if (i == 0) {
12851492
Warning(LOCATION, "EFF: No frame images were found. EFF, %s, is invalid.\n", filename);
@@ -1504,13 +1711,21 @@ bitmap * bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug) {
15041711
#endif
15051712

15061713
// read the file data
1507-
if (gr_bm_lock(be->filename, handle, bitmapnum, bpp, flags, nodebug) == -1) {
1714+
if (bm_load_image_data(be->filename, handle, bitmapnum, bpp, flags, nodebug) == -1) {
15081715
// oops, this isn't good - reset and return NULL
15091716
bm_unlock( handle );
15101717
bm_unload( handle );
15111718

15121719
return NULL;
15131720
}
1721+
1722+
if (!gr_bm_data(bitmapnum, bmp)) {
1723+
// graphics subsystem failed, reset and return NULL
1724+
bm_unlock( handle );
1725+
bm_unload( handle );
1726+
1727+
return NULL;
1728+
}
15141729

15151730
MONITOR_INC(NumBitmapPage, 1);
15161731
MONITOR_INC(SizeBitmapPage, bmp->w*bmp->h);

code/graphics/2d.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,9 @@ typedef struct screen {
557557
// Here be the bitmap functions
558558
void (*gf_bm_free_data)(int n, bool release);
559559
void (*gf_bm_create)(int n);
560-
int(*gf_bm_load)(BM_TYPE type, int n, const char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, BM_TYPE *c_type, int *mm_lvl, int *size);
561560
void (*gf_bm_init)(int n);
562561
void (*gf_bm_page_in_start)();
563-
int (*gf_bm_lock)(const char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug);
562+
bool (*gf_bm_data)(int n, bitmap* bm);
564563

565564
int (*gf_bm_make_render_target)(int n, int *width, int *height, ubyte *bpp, int *mm_lvl, int flags );
566565
int (*gf_bm_set_render_target)(int n, int face);
@@ -891,12 +890,8 @@ __inline int gr_tcache_set(int bitmap_id, int bitmap_type, float *u_scale, float
891890
#define gr_bm_free_data GR_CALL(*gr_screen.gf_bm_free_data)
892891
#define gr_bm_create GR_CALL(*gr_screen.gf_bm_create)
893892
#define gr_bm_init GR_CALL(*gr_screen.gf_bm_init)
894-
__inline int gr_bm_load(BM_TYPE type, int n, const char *filename, CFILE *img_cfp = NULL, int *w = 0, int *h = 0, int *bpp = 0, BM_TYPE *c_type = 0, int *mm_lvl = 0, int *size = 0)
895-
{
896-
return (*gr_screen.gf_bm_load)(type, n, filename, img_cfp, w, h, bpp, c_type, mm_lvl, size);
897-
}
898893
#define gr_bm_page_in_start GR_CALL(*gr_screen.gf_bm_page_in_start)
899-
#define gr_bm_lock GR_CALL(*gr_screen.gf_bm_lock)
894+
#define gr_bm_data GR_CALL(*gr_screen.gf_bm_data)
900895

901896
#define gr_bm_make_render_target GR_CALL(*gr_screen.gf_bm_make_render_target)
902897

code/graphics/gropengl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,9 +1831,8 @@ void opengl_setup_function_pointers()
18311831
gr_screen.gf_bm_free_data = gr_opengl_bm_free_data;
18321832
gr_screen.gf_bm_create = gr_opengl_bm_create;
18331833
gr_screen.gf_bm_init = gr_opengl_bm_init;
1834-
gr_screen.gf_bm_load = gr_opengl_bm_load;
18351834
gr_screen.gf_bm_page_in_start = gr_opengl_bm_page_in_start;
1836-
gr_screen.gf_bm_lock = gr_opengl_bm_lock;
1835+
gr_screen.gf_bm_data = gr_opengl_bm_data;
18371836
gr_screen.gf_bm_make_render_target = gr_opengl_bm_make_render_target;
18381837
gr_screen.gf_bm_set_render_target = gr_opengl_bm_set_render_target;
18391838

0 commit comments

Comments
 (0)