2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
12 #include "gropengl1.h"
13 #include "gropenglinternal.h"
15 #include "grinternal.h"
16 #include "systemvars.h"
21 typedef struct tcache_slot_opengl {
22 GLuint texture_handle;
23 float u_scale, v_scale;
31 tcache_slot_opengl *data_sections[MAX_BMAP_SECTIONS_X][MAX_BMAP_SECTIONS_Y];
32 tcache_slot_opengl *parent;
34 gr_texture_source texture_mode;
37 static void *Texture_sections = NULL;
38 static tcache_slot_opengl *Textures = NULL;
40 static tcache_slot_opengl *GL_bound_texture;
42 static int GL_frame_count = 0;
43 static int GL_textures_in_frame = 0;
44 static int GL_last_bitmap_id = -1;
45 static int GL_last_detail = -1;
46 static int GL_last_bitmap_type = -1;
47 static int GL_last_section_x = -1;
48 static int GL_last_section_y = -1;
49 static int GL_should_preload = 0;
51 int GL_textures_in = 0;
53 static gr_texture_source GL_current_texture_source = (gr_texture_source) -1;
55 static ubyte GL_xlat[256] = { 0 };
58 void gr_opengl1_set_gamma(float gamma)
61 Gr_gamma_int = int (Gr_gamma*10);
63 // Create the Gamma lookup table
65 for (i=0;i<256; i++) {
66 int v = fl2i(pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f);
72 Gr_gamma_lookup[i] = v;
75 // set the alpha gamma settings (for fonts)
76 for (i=0; i<16; i++) {
77 GL_xlat[i] = (ubyte)Gr_gamma_lookup[(i*255)/15];
80 GL_xlat[15] = GL_xlat[1];
83 GL_xlat[i] = GL_xlat[0];
86 // Flush any existing textures
87 opengl1_tcache_flush();
90 void opengl1_set_texture_state(gr_texture_source ts)
92 if (ts == TEXTURE_SOURCE_NONE) {
93 GL_bound_texture = NULL;
95 glBindTexture(GL_TEXTURE_2D, 0);
96 opengl1_tcache_set(-1, -1, NULL, NULL, 0, -1, -1, 0 );
97 } else if (GL_bound_texture &&
98 GL_bound_texture->texture_mode != ts) {
100 case TEXTURE_SOURCE_DECAL:
101 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
102 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
104 case TEXTURE_SOURCE_NO_FILTERING:
105 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
106 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
112 GL_bound_texture->texture_mode = ts;
115 GL_current_texture_source = ts;
119 void opengl1_tcache_init (int use_sections)
123 // DDOI - FIXME skipped a lot of stuff here
124 GL_should_preload = 0;
126 //uint tmp_pl = os_config_read_uint( NULL, NOX("D3DPreloadTextures"), 255 );
130 GL_should_preload = 0;
131 } else if ( tmp_pl == 1 ) {
132 GL_should_preload = 1;
134 GL_should_preload = 1;
139 Textures = (tcache_slot_opengl *)malloc(MAX_BITMAPS*sizeof(tcache_slot_opengl));
144 if (gr_screen.use_sections) {
145 Texture_sections = (tcache_slot_opengl*)malloc(MAX_BITMAPS * MAX_BMAP_SECTIONS_X * MAX_BMAP_SECTIONS_Y * sizeof(tcache_slot_opengl));
146 if(!Texture_sections){
149 memset(Texture_sections, 0, MAX_BITMAPS * MAX_BMAP_SECTIONS_X * MAX_BMAP_SECTIONS_Y * sizeof(tcache_slot_opengl));
152 // Init the texture structures
153 int section_count = 0;
154 for( i=0; i<MAX_BITMAPS; i++ ) {
156 Textures[i].vram_texture = NULL;
157 Textures[i].vram_texture_surface = NULL;
159 Textures[i].texture_handle = 0;
161 Textures[i].bitmap_id = -1;
162 Textures[i].size = 0;
163 Textures[i].used_this_frame = 0;
165 Textures[i].parent = NULL;
168 if (gr_screen.use_sections) {
169 for(idx=0; idx<MAX_BMAP_SECTIONS_X; idx++){
170 for(s_idx=0; s_idx<MAX_BMAP_SECTIONS_Y; s_idx++){
171 Textures[i].data_sections[idx][s_idx] = &((tcache_slot_opengl*)Texture_sections)[section_count++];
172 Textures[i].data_sections[idx][s_idx]->parent = &Textures[i];
174 Textures[i].data_sections[idx][s_idx]->vram_texture = NULL;
175 Textures[i].data_sections[idx][s_idx]->vram_texture_surface = NULL;
177 Textures[i].data_sections[idx][s_idx]->texture_handle = 0;
178 Textures[i].data_sections[idx][s_idx]->bitmap_id = -1;
179 Textures[i].data_sections[idx][s_idx]->size = 0;
180 Textures[i].data_sections[idx][s_idx]->used_this_frame = 0;
184 for(idx=0; idx<MAX_BMAP_SECTIONS_X; idx++){
185 for(s_idx=0; s_idx<MAX_BMAP_SECTIONS_Y; s_idx++){
186 Textures[i].data_sections[idx][s_idx] = NULL;
192 GL_last_detail = Detail.hardware_textures;
193 GL_last_bitmap_id = -1;
194 GL_last_bitmap_type = -1;
196 GL_last_section_x = -1;
197 GL_last_section_y = -1;
200 GL_textures_in_frame = 0;
203 static int opengl1_free_texture (tcache_slot_opengl *t);
205 void opengl1_free_texture_with_handle(int handle)
207 for(int i=0; i<MAX_BITMAPS; i++ ) {
208 if (Textures[i].bitmap_id == handle) {
209 Textures[i].used_this_frame = 0; // this bmp doesn't even exist any longer...
210 opengl1_free_texture ( &Textures[i] );
215 void opengl1_tcache_flush()
219 for( i=0; i<MAX_BITMAPS; i++ ) {
220 opengl1_free_texture ( &Textures[i] );
222 if (GL_textures_in != 0) {
223 mprintf(( "WARNING: VRAM is at %d instead of zero after flushing!\n", GL_textures_in ));
227 GL_last_bitmap_id = -1;
228 GL_last_section_x = -1;
229 GL_last_section_y = -1;
232 void opengl1_tcache_cleanup()
234 opengl1_tcache_flush ();
237 GL_textures_in_frame = 0;
244 if( Texture_sections != NULL ){
245 free(Texture_sections);
246 Texture_sections = NULL;
250 void opengl1_tcache_frame()
252 GL_last_bitmap_id = -1;
253 GL_textures_in_frame = 0;
260 for( i=0; i<MAX_BITMAPS; i++ ) {
261 Textures[i].used_this_frame = 0;
264 if(Textures[i].data_sections[0][0] != NULL){
265 Assert(GL_texture_sections);
266 if(GL_texture_sections){
267 for(idx=0; idx<MAX_BMAP_SECTIONS_X; idx++){
268 for(s_idx=0; s_idx<MAX_BMAP_SECTIONS_Y; s_idx++){
269 if(Textures[i].data_sections[idx][s_idx] != NULL){
270 Textures[i].data_sections[idx][s_idx]->used_this_frame = 0;
280 opengl1_tcache_flush();
285 static int opengl1_free_texture ( tcache_slot_opengl *t )
291 if ( t->bitmap_id > -1 ) {
292 // if I, or any of my children have been used this frame, bail
293 if(t->used_this_frame == GL_frame_count){
297 if (gr_screen.use_sections) {
298 for(idx=0; idx<MAX_BMAP_SECTIONS_X; idx++){
299 for(s_idx=0; s_idx<MAX_BMAP_SECTIONS_Y; s_idx++){
300 if((t->data_sections[idx][s_idx] != NULL) && (t->data_sections[idx][s_idx]->used_this_frame == GL_frame_count)){
307 // ok, now we know its legal to free everything safely
308 t->texture_mode = (gr_texture_source) -1;
309 glDeleteTextures (1, &t->texture_handle);
310 t->texture_handle = 0;
312 if ( GL_last_bitmap_id == t->bitmap_id ) {
313 GL_last_bitmap_id = -1;
316 // if this guy has children, free them too, since the children
317 // actually make up his size
318 if (gr_screen.use_sections) {
319 for(idx=0; idx<MAX_BMAP_SECTIONS_X; idx++){
320 for(s_idx=0; s_idx<MAX_BMAP_SECTIONS_Y; s_idx++){
321 if(t->data_sections[idx][s_idx] != NULL){
322 opengl1_free_texture(t->data_sections[idx][s_idx]);
329 t->used_this_frame = 0;
330 GL_textures_in -= t->size;
337 static void opengl1_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out)
343 if((w_out == NULL) || (h_out == NULL)){
351 // set height and width to a power of 2
352 for (i=0; i<16; i++ ) {
353 if ( (tex_w > (1<<i)) && (tex_w <= (1<<(i+1))) ) {
359 for (i=0; i<16; i++ ) {
360 if ( (tex_h > (1<<i)) && (tex_h <= (1<<(i+1))) ) {
366 // try to keep an 8:1 size ratio
372 if ( tex_w < GL_min_texture_width ) {
373 tex_w = GL_min_texture_width;
374 } else if ( tex_w > GL_max_texture_width ) {
375 tex_w = GL_max_texture_width;
378 if ( tex_h < GL_min_texture_height ) {
379 tex_h = GL_min_texture_height;
380 } else if ( tex_h > GL_max_texture_height ) {
381 tex_h = GL_max_texture_height;
384 // store the outgoing size
389 // data == start of bitmap data
390 // sx == x offset into bitmap
391 // sy == y offset into bitmap
392 // src_w == absolute width of section on source bitmap
393 // src_h == absolute height of section on source bitmap
394 // bmap_w == width of source bitmap
395 // bmap_h == height of source bitmap
396 // tex_w == width of final texture
397 // tex_h == height of final texture
398 static int opengl1_create_texture_sub(int bitmap_type, int texture_handle, ushort *data, int sx, int sy, int src_w, int src_h, int bmap_w, int bmap_h, int tex_w, int tex_h, tcache_slot_opengl *t, int reload, int resize, int fail_on_full)
403 ubyte *bmp_data = ((ubyte*)data);
404 ubyte *texmem = NULL, *texmemp;
407 if((t == NULL) || (bmp_data == NULL)){
411 if ( t->used_this_frame == GL_frame_count ) {
412 mprintf(( "ARGHH!!! Texture already used this frame! Cannot free it!\n" ));
417 if(!opengl1_free_texture(t)){
422 switch (bitmap_type) {
423 case TCACHE_TYPE_AABITMAP:
424 t->u_scale = (float)bmap_w / (float)tex_w;
425 t->v_scale = (float)bmap_h / (float)tex_h;
428 case TCACHE_TYPE_BITMAP_INTERFACE:
429 case TCACHE_TYPE_BITMAP_SECTION:
430 t->u_scale = (float)src_w / (float)tex_w;
431 t->v_scale = (float)src_h / (float)tex_h;
441 glGenTextures (1, &t->texture_handle);
444 if (t->texture_handle == 0) {
445 nprintf(("Error", "!!DEBUG!! t->texture_handle == 0"));
449 GL_bound_texture = t;
451 GL_bound_texture->texture_mode = (gr_texture_source) -1;
453 glBindTexture (GL_TEXTURE_2D, t->texture_handle);
455 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
456 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
457 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
459 /* this should be set next anyway */
460 // if (GL_current_texture_source != TEXTURE_SOURCE_NONE) {
461 // gr_opengl_set_texture_state(GL_current_texture_source);
466 switch (bitmap_type) {
467 case TCACHE_TYPE_AABITMAP:
469 texmem = (ubyte *) malloc (tex_w*tex_h);
472 for (i=0;i<tex_h;i++)
474 for (j=0;j<tex_w;j++)
476 if (i < bmap_h && j < bmap_w) {
477 *texmemp++ = GL_xlat[bmp_data[i*bmap_w+j]];
487 glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, tex_w, tex_h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texmem);
489 glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, tex_w, tex_h, GL_ALPHA, GL_UNSIGNED_BYTE, texmem);
497 case TCACHE_TYPE_BITMAP_INTERFACE:
498 case TCACHE_TYPE_BITMAP_SECTION:
500 // if we aren't resizing in any way then we can just use bmp_data directly
502 texmem = (ubyte *) malloc (tex_w*tex_h*2);
505 for (i=0;i<tex_h;i++) {
506 for (j=0;j<tex_w;j++) {
507 if (i < src_h && j < src_w) {
508 *texmemp++ = bmp_data[((i+sy)*bmap_w+(j+sx))*2+0];
509 *texmemp++ = bmp_data[((i+sy)*bmap_w+(j+sx))*2+1];
518 size = tex_w*tex_h*2;
521 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB5_A1, tex_w, tex_h, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (resize) ? texmem : bmp_data);
523 glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, tex_w, tex_h, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (resize) ? texmem : bmp_data);
534 // if we aren't resizing then we can just use bmp_data directly
536 texmem = (ubyte *) malloc (tex_w*tex_h*2);
539 Assert( texmem != NULL );
541 fix u, utmp, v, du, dv;
545 du = ( (bmap_w-1)*F1_0 ) / tex_w;
546 dv = ( (bmap_h-1)*F1_0 ) / tex_h;
548 for (j=0;j<tex_h;j++) {
550 for (i=0;i<tex_w;i++) {
551 *texmemp++ = bmp_data[(f2i(v)*bmap_w+f2i(utmp))*2+0];
552 *texmemp++ = bmp_data[(f2i(v)*bmap_w+f2i(utmp))*2+1];
559 size = tex_w*tex_h*2;
562 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB5_A1, tex_w, tex_h, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (resize) ? texmem : bmp_data);
564 glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, tex_w, tex_h, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (resize) ? texmem : bmp_data);
574 t->bitmap_id = texture_handle;
575 t->time_created = GL_frame_count;
576 t->used_this_frame = 0;
578 t->w = (ushort)tex_w;
579 t->h = (ushort)tex_h;
581 GL_textures_in_frame += t->size;
583 GL_textures_in += t->size;
589 static int opengl1_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl *tslot, int fail_on_full)
593 int final_w, final_h;
599 // setup texture/bitmap flags
602 case TCACHE_TYPE_AABITMAP:
603 flags |= BMP_AABITMAP;
606 case TCACHE_TYPE_NORMAL:
607 flags |= BMP_TEX_OTHER;
610 case TCACHE_TYPE_BITMAP_INTERFACE:
611 case TCACHE_TYPE_XPARENT:
612 flags |= BMP_TEX_XPARENT;
619 // lock the bitmap into the proper format
620 bmp = bm_lock(bitmap_handle, bpp, flags);
622 mprintf(("Couldn't lock bitmap %d.\n", bitmap_handle ));
632 // max_w /= D3D_texture_divider;
633 // max_h /= D3D_texture_divider;
635 // if we are going to cull the size then we need to force a resize
636 if (Detail.hardware_textures < 4) {
639 // Detail.debris_culling goes from 0 to 4.
640 max_w /= (16 >> Detail.hardware_textures);
641 max_h /= (16 >> Detail.hardware_textures);
646 // get final texture size as it will be allocated as a DD surface
647 opengl1_tcache_get_adjusted_texture_size(max_w, max_h, &final_w, &final_h);
649 if ( (final_w < 1) || (final_h < 1) ) {
650 mprintf(("Bitmap is too small at %dx%d.\n", final_w, final_h));
654 // if we don't have to resize the image (to get power of 2, etc.) then skip that extra work
655 if ( (max_w != final_w) || (max_h != final_h) ) {
659 // if this tcache slot has no bitmap
660 if ( tslot->bitmap_id < 0) {
663 // different bitmap altogether - determine if the new one can use the old one's slot
664 else if (tslot->bitmap_id != bitmap_handle) {
665 if((final_w == tslot->w) && (final_h == tslot->h)){
667 //ml_printf("Reloading texture %d\n", bitmap_handle);
674 int ret_val = opengl1_create_texture_sub(bitmap_type, bitmap_handle, (ushort*)bmp->data, 0, 0, bmp->w, bmp->h, bmp->w, bmp->h, final_w, final_h, tslot, reload, resize, fail_on_full);
677 bm_unlock(bitmap_handle);
682 static int opengl1_create_texture_sectioned(int bitmap_handle, int bitmap_type, tcache_slot_opengl *tslot, int sx, int sy, int fail_on_full)
686 int final_w, final_h;
687 int section_x, section_y;
691 Assert( gr_screen.use_sections );
693 // setup texture/bitmap flags
694 Assert(bitmap_type == TCACHE_TYPE_BITMAP_SECTION);
695 if(bitmap_type != TCACHE_TYPE_BITMAP_SECTION){
696 bitmap_type = TCACHE_TYPE_BITMAP_SECTION;
698 flags = BMP_TEX_XPARENT;
700 // lock the bitmap in the proper format
701 bmp = bm_lock(bitmap_handle, 16, flags);
703 mprintf(("Couldn't lock bitmap %d.\n", bitmap_handle ));
706 // determine the width and height of this section
707 bm_get_section_size(bitmap_handle, sx, sy, §ion_x, §ion_y);
709 // get final texture size as it will be allocated as an opengl texture
710 opengl1_tcache_get_adjusted_texture_size(section_x, section_y, &final_w, &final_h);
712 if ( (final_w < 1) || (final_h < 1) ) {
713 mprintf(("Bitmap is too small at %dx%d.\n", final_w, final_h));
717 // if we don't have to resize the image (to get power of 2, etc.) then skip that extra work
718 if ( (bmp->sections.num_x == 1) && (bmp->sections.num_y == 1) && (section_x == final_w) && (section_y == final_h) ) {
722 // if this tcache slot has no bitmap
723 if ( tslot->bitmap_id < 0) {
726 // different bitmap altogether - determine if the new one can use the old one's slot
727 else if (tslot->bitmap_id != bitmap_handle) {
728 if((final_w == tslot->w) && (final_h == tslot->h)){
736 int ret_val = opengl1_create_texture_sub(bitmap_type, bitmap_handle, (ushort*)bmp->data, bmp->sections.sx[sx], bmp->sections.sy[sy], section_x, section_y, bmp->w, bmp->h, final_w, final_h, tslot, reload, resize, fail_on_full);
739 bm_unlock(bitmap_handle);
744 extern int bm_get_cache_slot( int bitmap_id, int separate_ani_frames );
746 int opengl1_tcache_set(int bitmap_id, int bitmap_type, float *u_scale, float *v_scale, int fail_on_full, int sx, int sy, int force)
755 GL_last_bitmap_id = -1;
759 if ( GL_last_detail != Detail.hardware_textures ) {
760 GL_last_detail = Detail.hardware_textures;
761 opengl1_tcache_flush();
768 int n = bm_get_cache_slot (bitmap_id, 1);
769 tcache_slot_opengl *t = &Textures[n];
771 if ( (GL_last_bitmap_id == bitmap_id) && (GL_last_bitmap_type==bitmap_type) && (t->bitmap_id == bitmap_id) && (GL_last_section_x == sx) && (GL_last_section_y == sy)) {
772 t->used_this_frame = GL_frame_count;
774 // mark all children as used
775 if (gr_screen.use_sections) {
776 for(idx=0; idx<MAX_BMAP_SECTIONS_X; idx++){
777 for(s_idx=0; s_idx<MAX_BMAP_SECTIONS_Y; s_idx++){
778 if(t->data_sections[idx][s_idx] != NULL){
779 t->data_sections[idx][s_idx]->used_this_frame = GL_frame_count;
785 *u_scale = t->u_scale;
786 *v_scale = t->v_scale;
790 if (bitmap_type == TCACHE_TYPE_BITMAP_SECTION){
791 Assert( gr_screen.use_sections );
792 Assert((sx >= 0) && (sy >= 0) && (sx < MAX_BMAP_SECTIONS_X) && (sy < MAX_BMAP_SECTIONS_Y));
793 if(!((sx >= 0) && (sy >= 0) && (sx < MAX_BMAP_SECTIONS_X) && (sy < MAX_BMAP_SECTIONS_Y))){
799 // if the texture sections haven't been created yet
800 if((t->bitmap_id < 0) || (t->bitmap_id != bitmap_id)){
802 // lock the bitmap in the proper format
803 bmp = bm_lock(bitmap_id, 16, BMP_TEX_XPARENT);
804 bm_unlock(bitmap_id);
806 // now lets do something for each texture
808 for(idx=0; idx<bmp->sections.num_x; idx++){
809 for(s_idx=0; s_idx<bmp->sections.num_y; s_idx++){
810 // hmm. i'd rather we didn't have to do it this way...
811 if(!opengl1_create_texture_sectioned(bitmap_id, bitmap_type, t->data_sections[idx][s_idx], idx, s_idx, fail_on_full)){
815 // not used this frame
816 t->data_sections[idx][s_idx]->used_this_frame = 0;
820 // zero out pretty much everything in the parent struct since he's just the root
821 t->bitmap_id = bitmap_id;
822 t->texture_handle = 0;
823 t->time_created = t->data_sections[sx][sy]->time_created;
824 t->used_this_frame = 0;
826 t->vram_texture = NULL;
827 t->vram_texture_surface = NULL
831 // argh. we failed to upload. free anything we can
833 opengl1_free_texture(t);
835 // swap in the texture we want
837 t = t->data_sections[sx][sy];
840 // all other "normal" textures
841 else if((bitmap_id < 0) || (bitmap_id != t->bitmap_id)){
842 ret_val = opengl1_create_texture( bitmap_id, bitmap_type, t, fail_on_full );
845 // everything went ok
846 if(ret_val && (t->texture_handle) && !vram_full){
847 *u_scale = t->u_scale;
848 *v_scale = t->v_scale;
850 GL_bound_texture = t;
852 glBindTexture (GL_TEXTURE_2D, t->texture_handle );
854 /* this should be set next anyway */
855 // if (GL_current_texture_source != TEXTURE_SOURCE_NONE) {
856 // gr_opengl_set_texture_state(GL_current_texture_source);
859 GL_last_bitmap_id = t->bitmap_id;
860 GL_last_bitmap_type = bitmap_type;
861 GL_last_section_x = sx;
862 GL_last_section_y = sy;
864 t->used_this_frame = GL_frame_count;
868 GL_last_bitmap_id = -1;
869 GL_last_bitmap_type = -1;
871 GL_last_section_x = -1;
872 GL_last_section_y = -1;
874 GL_bound_texture = NULL;
876 glBindTexture (GL_TEXTURE_2D, 0); // test - DDOI
883 void gr_opengl1_preload_init()
885 if (gr_screen.mode != GR_OPENGL) {
889 opengl1_tcache_flush();
892 int gr_opengl1_preload(int bitmap_num, int is_aabitmap)
894 if ( gr_screen.mode != GR_OPENGL) {
898 if ( !GL_should_preload ) {
902 float u_scale, v_scale;
904 int bitmap_type = TCACHE_TYPE_NORMAL;
907 bitmap_type = TCACHE_TYPE_AABITMAP;
910 retval = opengl1_tcache_set(bitmap_num, bitmap_type, &u_scale, &v_scale, 1, -1, -1, 0 );
913 mprintf(("Texture upload failed!\n" ));