From a8cee89f567a35026a1a6a829cf09a26cf68ca33 Mon Sep 17 00:00:00 2001 From: Taylor Richards Date: Sat, 26 Oct 2013 02:08:39 -0400 Subject: [PATCH] initial graphics system update - separate OpenGL version code - prep for Glide/D3D/Soft removal - bitmap sections optional --- include/2d.h | 41 +- include/bmpman.h | 8 +- include/grinternal.h | 4 +- include/gropengl.h | 4 - include/gropengl1.h | 69 + include/gropenglinternal.h | 60 + include/pstypes.h | 5 +- include/tmapper.h | 2 + src/asteroid/asteroid.cpp | 8 +- src/bmpman/bmpman.cpp | 293 +-- src/freespace2/freespace.cpp | 57 +- src/graphics/2d.cpp | 123 +- src/graphics/gropengl.cpp | 3410 +++-------------------------- src/graphics/gropengl1.cpp | 763 +++++++ src/graphics/gropengl1render.cpp | 1071 +++++++++ src/graphics/gropengl1texture.cpp | 917 ++++++++ src/menuui/credits.cpp | 10 +- src/menuui/mainhallmenu.cpp | 41 +- src/model/modelinterp.cpp | 36 +- src/nebula/neb.cpp | 129 +- src/render/3ddraw.cpp | 2 +- src/render/3dlaser.cpp | 12 +- src/render/3dmath.cpp | 7 +- src/ship/ship.cpp | 7 +- src/weapon/weapons.cpp | 19 +- 25 files changed, 3374 insertions(+), 3724 deletions(-) create mode 100644 include/gropengl1.h create mode 100644 include/gropenglinternal.h create mode 100644 src/graphics/gropengl1.cpp create mode 100644 src/graphics/gropengl1render.cpp create mode 100644 src/graphics/gropengl1texture.cpp diff --git a/include/2d.h b/include/2d.h index fcb4900..bb60121 100644 --- a/include/2d.h +++ b/include/2d.h @@ -376,6 +376,7 @@ typedef struct screen { int max_w, max_h; // Width and height int res; // GR_640 or GR_1024 int mode; // What mode gr_init was called with. + int use_sections; // whether to use bitmap sections or not float aspect; // Aspect ratio int rowsize; // What you need to add to go to next row (includes bytes_per_pixel) int bits_per_pixel; // How many bits per pixel it is. (7,8,15,16,24,32) @@ -406,7 +407,6 @@ typedef struct screen { //switch onscreen, offscreen void (*gf_flip)(); - void (*gf_flip_window)(uint _hdc, int x, int y, int w, int h ); // Sets the current palette void (*gf_set_palette)(ubyte * new_pal, int restrict_alphacolor); @@ -457,9 +457,6 @@ typedef struct screen { // clears entire clipping region to current color void (*gf_clear)(); - // void (*gf_bitmap)(int x,int y); - // void (*gf_bitmap_ex)(int x,int y,int w,int h,int sx,int sy); - void (*gf_aabitmap)(int x, int y); void (*gf_aabitmap_ex)(int x, int y, int w, int h, int sx, int sy); @@ -556,11 +553,18 @@ typedef struct screen { // filtering void (*gf_filter_set)(int filter); - // set a texture into cache. for sectioned bitmaps, pass in sx and sy to set that particular section of the bitmap - int (*gf_tcache_set)(int bitmap_id, int bitmap_type, float *u_scale, float *v_scale, int fail_on_full, int sx, int sy, int force); - // set the color to be used when clearing the background void (*gf_set_clear_color)(int r, int g, int b); + + void (*gf_preload_init)(); + int (*gf_preload)(int bitmap_num, int is_aabitmap); + + void (*gf_zbias)(int bias); + + void (*gf_force_windowed)(); + void (*gf_force_fullscreen)(); + + void (*gf_activate)(int active); } screen; // cpu types @@ -576,11 +580,8 @@ extern int Gr_mmx; //-------------------------------------- // Call this at application startup -#define GR_SOFTWARE (100) // Software renderer using standard Win32 functions in a window. -#define GR_DIRECTDRAW (101) // Software renderer using DirectDraw fullscreen. -#define GR_DIRECT3D (102) // Use Direct3d hardware renderer -#define GR_GLIDE (103) // Use Glide hardware renderer -#define GR_OPENGL (104) // Use OpenGl hardware renderer +#define GR_SDL (100) // SDL2 renderer +#define GR_OPENGL (101) // OpenGL (generic) // resolution constants - always keep resolutions in ascending order and starting from 0 #define GR_NUM_RESOLUTIONS 2 @@ -642,7 +643,6 @@ extern void gr_activate(int active); #define gr_print_screen GR_CALL(gr_screen.gf_print_screen) #define gr_flip GR_CALL(gr_screen.gf_flip) -#define gr_flip_window GR_CALL(gr_screen.gf_flip_window) #define gr_set_clip GR_CALL(gr_screen.gf_set_clip) #define gr_reset_clip GR_CALL(gr_screen.gf_reset_clip) @@ -660,11 +660,15 @@ __inline void gr_set_bitmap( int bitmap_num, int alphablend=GR_ALPHABLEND_NONE, (*gr_screen.gf_set_bitmap)(bitmap_num, alphablend, bitbltmode, alpha, sx, sy); } +__inline bool gr_is_32bit() +{ + return (gr_screen.bytes_per_pixel == 4); +} + #define gr_create_shader GR_CALL(gr_screen.gf_create_shader) #define gr_set_shader GR_CALL(gr_screen.gf_set_shader) #define gr_clear GR_CALL(gr_screen.gf_clear) -// #define gr_bitmap GR_CALL(gr_screen.gf_bitmap) -// #define gr_bitmap_ex GR_CALL(gr_screen.gf_bitmap_ex) + #define gr_aabitmap GR_CALL(gr_screen.gf_aabitmap) #define gr_aabitmap_ex GR_CALL(gr_screen.gf_aabitmap_ex) #define gr_rect GR_CALL(gr_screen.gf_rect) @@ -716,10 +720,13 @@ __inline void gr_set_bitmap( int bitmap_num, int alphablend=GR_ALPHABLEND_NONE, #define gr_filter_set GR_CALL(gr_screen.gf_filter_set) -#define gr_tcache_set GR_CALL(gr_screen.gf_tcache_set) - #define gr_set_clear_color GR_CALL(gr_screen.gf_set_clear_color) +#define gr_preload_init GR_CALL(gr_screen.gf_preload_init) +#define gr_preload GR_CALL(gr_screen.gf_preload) + +#define gr_zbias GR_CALL(gr_screen.gf_zbias) + // new bitmap functions extern int Gr_bitmap_poly; void gr_bitmap(int x, int y); diff --git a/include/bmpman.h b/include/bmpman.h index ecae27d..300892e 100644 --- a/include/bmpman.h +++ b/include/bmpman.h @@ -168,9 +168,7 @@ #endif // 16 bit pixel formats -#define BM_PIXEL_FORMAT_ARGB 0 // for glide - can assume certain things, like 1555 LFB writes, whee! -#define BM_PIXEL_FORMAT_D3D 1 // d3d - card dependant. booo! -#define BM_PIXEL_FORMAT_ARGB_D3D 2 // this card has nice 1555 textures like Glide - ahhhhh! +#define BM_PIXEL_FORMAT_ARGB 0 // can assume certain things, like 1555 LFB writes, whee! // 16 bit pixel formats extern int Bm_pixel_format; @@ -311,10 +309,6 @@ void bm_page_in_stop(); // If num_frames is passed, assume this is an animation void bm_page_in_texture( int bitmapnum, int num_frames=1 ); -// Marks a texture as being used for this level -// If num_frames is passed, assume this is an animation -void bm_page_in_nondarkening_texture( int bitmap, int num_frames=1 ); - // marks a texture as being a transparent textyre used for this level // Marks a texture as being used for this level // If num_frames is passed, assume this is an animation diff --git a/include/grinternal.h b/include/grinternal.h index 9d21808..58a02d8 100644 --- a/include/grinternal.h +++ b/include/grinternal.h @@ -217,8 +217,8 @@ extern int Gr_gamma_lookup[256]; #define TCACHE_TYPE_AABITMAP 0 // HUD bitmap. All Alpha. #define TCACHE_TYPE_NORMAL 1 // Normal bitmap. Alpha = 0. #define TCACHE_TYPE_XPARENT 2 // Bitmap with 0,255,0 = transparent. Alpha=0 if transparent, 1 if not. -#define TCACHE_TYPE_NONDARKENING 3 // Bitmap with 255,255,255 = non-darkening. Alpha=1 if non-darkening, 0 if not. -#define TCACHE_TYPE_BITMAP_SECTION 4 // section of a bitmap +#define TCACHE_TYPE_BITMAP_SECTION 3 // section of a bitmap +#define TCACHE_TYPE_BITMAP_INTERFACE 4 // bitmap used for UI #endif diff --git a/include/gropengl.h b/include/gropengl.h index 80638c7..34dc2e1 100644 --- a/include/gropengl.h +++ b/include/gropengl.h @@ -47,10 +47,6 @@ void gr_opengl_init(); void gr_opengl_cleanup(); -void gr_opengl_force_windowed(); - -void gr_opengl_bitmap(int x, int y); -void gr_opengl_bitmap_ex(int x, int y, int w, int h, int sx, int sy); #endif diff --git a/include/gropengl1.h b/include/gropengl1.h new file mode 100644 index 0000000..84f7a53 --- /dev/null +++ b/include/gropengl1.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) Volition, Inc. 1999. All rights reserved. + * + * All source code herein is the property of Volition, Inc. You may not sell + * or otherwise commercially exploit the source or things you created based on + * the source. + */ + +#ifndef _GROPENGL1_H +#define _GROPENGL1_H + +#include "pstypes.h" + + +typedef enum gr_texture_source { + TEXTURE_SOURCE_NONE, + TEXTURE_SOURCE_DECAL, + TEXTURE_SOURCE_NO_FILTERING, +} gr_texture_source; + +typedef enum gr_alpha_blend { + ALPHA_BLEND_NONE, // 1*SrcPixel + 0*DestPixel + ALPHA_BLEND_ADDITIVE, // 1*SrcPixel + 1*DestPixel + ALPHA_BLEND_ALPHA_ADDITIVE, // Alpha*SrcPixel + 1*DestPixel + ALPHA_BLEND_ALPHA_BLEND_ALPHA, // Alpha*SrcPixel + (1-Alpha)*DestPixel + ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR, // Alpha*SrcPixel + (1-SrcPixel)*DestPixel +} gr_alpha_blend; + +typedef enum gr_zbuffer_type { + ZBUFFER_TYPE_NONE, + ZBUFFER_TYPE_READ, + ZBUFFER_TYPE_WRITE, + ZBUFFER_TYPE_FULL, +} gr_zbuffer_type; + +extern PFNGLSECONDARYCOLORPOINTEREXTPROC vglSecondaryColorPointerEXT; + +void opengl1_init(); +void opengl1_cleanup(); + +void opengl1_set_state(gr_texture_source ts, gr_alpha_blend ab, gr_zbuffer_type zt); +void opengl1_set_texture_state(gr_texture_source ts); + +void opengl1_tcache_init (int use_sections); +void opengl1_tcache_cleanup(); +void opengl1_tcache_flush(); +void opengl1_tcache_frame(); +int opengl1_tcache_set(int bitmap_id, int bitmap_type, float *u_scale, float *v_scale, int fail_on_full = 0, int sx = -1, int sy = -1, int force = 0); + +void gr_opengl1_rect(int x,int y,int w,int h); +void gr_opengl1_shade(int x,int y,int w,int h); +void gr_opengl1_aabitmap_ex(int x,int y,int w,int h,int sx,int sy); +void gr_opengl1_aabitmap(int x, int y); +void gr_opengl1_string( int sx, int sy, const char *s ); +void gr_opengl1_line(int x1,int y1,int x2,int y2); +void gr_opengl1_aaline(vertex *v1, vertex *v2); +void gr_opengl1_gradient(int x1,int y1,int x2,int y2); +void gr_opengl1_circle( int xc, int yc, int d ); +void gr_opengl1_pixel(int x, int y); +void gr_opengl1_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct); +void gr_opengl1_flash(int r, int g, int b); +void gr_opengl1_tmapper( int nverts, vertex **verts, uint flags ); +void gr_opengl1_scaler(vertex *va, vertex *vb ); +void gr_opengl1_save_mouse_area(int x, int y, int w, int h); +void gr_opengl1_set_gamma(float gamma); +void gr_opengl1_preload_init(); +int gr_opengl1_preload(int bitmap_num, int is_aabitmap); + +#endif // _GROPENGL1_H diff --git a/include/gropenglinternal.h b/include/gropenglinternal.h new file mode 100644 index 0000000..4674f24 --- /dev/null +++ b/include/gropenglinternal.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) Volition, Inc. 1999. All rights reserved. + * + * All source code herein is the property of Volition, Inc. You may not sell + * or otherwise commercially exploit the source or things you created based on + * the source. + */ + +#ifndef _OPENGLINTERNAL_H +#define _OPENGLINTERNAL_H + +#include "2d.h" + + +extern SDL_Window *GL_window; + +extern int GL_version; + +extern int GL_viewport_x; +extern int GL_viewport_y; +extern int GL_viewport_w; +extern int GL_viewport_h; +extern float GL_viewport_scale_w; +extern float GL_viewport_scale_h; +extern int GL_min_texture_width; +extern int GL_max_texture_width; +extern int GL_min_texture_height; +extern int GL_max_texture_height; + + +void opengl_alloc_render_buffer(unsigned int nelems); +void opengl_free_render_buffer(); + +typedef struct rb_t { + float x, y, z, w; + float u, v; + ubyte r, g, b, a; + ubyte sr, sg, sb, sa; +} rb_t; + +extern rb_t *render_buffer; + + +// gr_* pointer functions +void gr_opengl_set_shader( shader * shade ); +void gr_opengl_create_shader(shader * shade, float r, float g, float b, float c ); +void gr_opengl_set_bitmap( int bitmap_num, int alphablend_mode = GR_ALPHABLEND_NONE, int bitblt_mode = GR_BITBLT_MODE_NORMAL, float alpha = 1.0f, int sx = -1, int sy = -1 ); +void gr_opengl_set_clear_color(int r, int g, int b); +void gr_opengl_set_color( int r, int g, int b ); +void gr_opengl_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type ); +void gr_opengl_init_color(color *c, int r, int g, int b); +void gr_opengl_get_color( int * r, int * g, int * b ); +void gr_opengl_set_color_fast(color *dst); +void gr_opengl_force_fullscreen(); +void gr_opengl_force_windowed(); +void gr_opengl_set_viewport(int width, int height); +int gr_opengl_zbuffer_get(); +int gr_opengl_zbuffer_set(int mode); + +#endif // _OPENGLINTERNAL_H diff --git a/include/pstypes.h b/include/pstypes.h index a642f4a..a8a841a 100644 --- a/include/pstypes.h +++ b/include/pstypes.h @@ -371,11 +371,10 @@ typedef struct vertex { #define BMP_AABITMAP (1<<0) // antialiased bitmap #define BMP_TEX_XPARENT (1<<1) // transparent texture -#define BMP_TEX_NONDARK (1<<2) // nondarkening texture -#define BMP_TEX_OTHER (1<<3) // so we can identify all "normal" textures +#define BMP_TEX_OTHER (1<<2) // so we can identify all "normal" textures // any texture type -#define BMP_TEX_ANY ( BMP_TEX_XPARENT | BMP_TEX_NONDARK | BMP_TEX_OTHER ) +#define BMP_TEX_ANY ( BMP_TEX_XPARENT | BMP_TEX_OTHER ) // max res == 1024x768. max texture size == 256 #define MAX_BMAP_SECTIONS_X 4 diff --git a/include/tmapper.h b/include/tmapper.h index 2298086..ec80533 100644 --- a/include/tmapper.h +++ b/include/tmapper.h @@ -128,6 +128,8 @@ extern void grx_tmapper( int nv, vertex * verts[], uint flags ); // bitmap section #define TMAP_FLAG_BITMAP_SECTION (1<<11) +// user interface bitmap +#define TMAP_FLAG_BITMAP_INTERFACE (1<<12) #endif diff --git a/src/asteroid/asteroid.cpp b/src/asteroid/asteroid.cpp index af5c281..dd74bbe 100644 --- a/src/asteroid/asteroid.cpp +++ b/src/asteroid/asteroid.cpp @@ -2263,14 +2263,8 @@ void asteroid_page_in() for (j=0; jmodelp[k]->n_textures; j++ ) { int bitmap_num = asip->modelp[k]->original_textures[j]; - - // if we're in Glide (and maybe later with D3D), use nondarkening textures if ( bitmap_num > -1 ) { - if(gr_screen.mode == GR_GLIDE){ - bm_page_in_nondarkening_texture( bitmap_num ); - } else { - bm_page_in_texture( bitmap_num ); - } + bm_page_in_texture( bitmap_num ); } } diff --git a/src/bmpman/bmpman.cpp b/src/bmpman/bmpman.cpp index a151677..ed51d8f 100644 --- a/src/bmpman/bmpman.cpp +++ b/src/bmpman/bmpman.cpp @@ -818,22 +818,30 @@ void bm_calc_sections(bitmap *be) { int idx; - // number of x and y sections - be->sections.num_x = (ubyte)(be->w / MAX_BMAP_SECTION_SIZE); - if((be->sections.num_x * MAX_BMAP_SECTION_SIZE) < be->w){ - be->sections.num_x++; - } - be->sections.num_y = (ubyte)(be->h / MAX_BMAP_SECTION_SIZE); - if((be->sections.num_y * MAX_BMAP_SECTION_SIZE) < be->h){ - be->sections.num_y++; - } + if (gr_screen.use_sections) { + // number of x and y sections + be->sections.num_x = (ubyte)(be->w / MAX_BMAP_SECTION_SIZE); + if((be->sections.num_x * MAX_BMAP_SECTION_SIZE) < be->w){ + be->sections.num_x++; + } + be->sections.num_y = (ubyte)(be->h / MAX_BMAP_SECTION_SIZE); + if((be->sections.num_y * MAX_BMAP_SECTION_SIZE) < be->h){ + be->sections.num_y++; + } - // calculate the offsets for each section - for(idx=0; idxsections.num_x; idx++){ - be->sections.sx[idx] = (ushort)(MAX_BMAP_SECTION_SIZE * idx); - } - for(idx=0; idxsections.num_y; idx++){ - be->sections.sy[idx] = (ushort)(MAX_BMAP_SECTION_SIZE * idx); + // calculate the offsets for each section + for(idx=0; idxsections.num_x; idx++){ + be->sections.sx[idx] = (ushort)(MAX_BMAP_SECTION_SIZE * idx); + } + for(idx=0; idxsections.num_y; idx++){ + be->sections.sy[idx] = (ushort)(MAX_BMAP_SECTION_SIZE * idx); + } + } else { + be->sections.num_x = 1; + be->sections.num_y = 1; + + be->sections.sx[0] = 0; + be->sections.sy[0] = 0; } } @@ -1351,18 +1359,8 @@ static void bm_convert_format( int bitmapnum, bitmap *bmp, ubyte bpp, ubyte flag switch(Bm_pixel_format){ // 1555, all we need to do is zero the whole thing case BM_PIXEL_FORMAT_ARGB: - case BM_PIXEL_FORMAT_ARGB_D3D: ((ushort*)bmp->data)[idx] = 0; break; - // d3d format - case BM_PIXEL_FORMAT_D3D: - r = g = b = a = 0; - r /= Gr_t_red.scale; - g /= Gr_t_green.scale; - b /= Gr_t_blue.scale; - a /= Gr_t_alpha.scale; - ((ushort*)bmp->data)[idx] = (unsigned short)((a<filename, data, palette ); @@ -1457,8 +1453,6 @@ void bm_lock_pcx( int handle, int bitmapnum, bitmap_entry *be, bitmap *bmp, ubyt // load types if(flags & BMP_AABITMAP){ pcx_error = pcx_read_bitmap_16bpp_aabitmap( be->filename, data ); - } else if(flags & BMP_TEX_NONDARK){ - pcx_error = pcx_read_bitmap_16bpp_nondark( be->filename, data ); } else { pcx_error = pcx_read_bitmap_16bpp( be->filename, data ); } @@ -1923,7 +1917,7 @@ void bm_get_palette(int handle, ubyte *pal, char *name) // returns: nothing // opengl hack -void opengl_free_texture_with_handle(int handle); +void opengl1_free_texture_with_handle(int handle); void bm_release(int handle) { bitmap_entry *be; @@ -1951,7 +1945,7 @@ void bm_release(int handle) // until opengl mode gets a proper texture manager, this will have to do #ifdef PLAT_UNIX - opengl_free_texture_with_handle(handle); + opengl1_free_texture_with_handle(handle); #endif bm_free_data(n); @@ -2099,29 +2093,7 @@ void bm_page_in_texture( int bitmapnum, int nframes ) bm_bitmaps[n+i].preloaded = 1; - if ( D3D_enabled ) { - bm_bitmaps[n+i].used_flags = BMP_TEX_OTHER; - } else { - bm_bitmaps[n+i].used_flags = 0; - } - } -} - -// Marks a texture as being used for this level -// If num_frames is passed, assume this is an animation -void bm_page_in_nondarkening_texture( int bitmapnum, int nframes ) -{ - int i; - for (i=0; iscale ) << Gr_current_red->shift); - *((ushort*)pixel) |= (ushort)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); - *((ushort*)pixel) |= (ushort)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); - *((ushort*)pixel) &= ~(0x8000); - if (*((ushort*)pixel) == (ushort)Gr_current_green->mask) { - *((ushort*)pixel) = 0; - } else { - if(*av){ - *((ushort*)pixel) |= 0x8000; - } - } -} - -void bm_set_components_d3d(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) -{ - // rgba - *((ushort*)pixel) |= (ushort)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); - *((ushort*)pixel) |= (ushort)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); - *((ushort*)pixel) |= (ushort)(( (int)*bv / Gr_current_blue->scale ) << Gr_current_blue->shift); - if(*av == 0){ - *((ushort*)pixel) = (ushort)Gr_current_green->mask; - } -} - -void bm_set_components_argb_d3d_16_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) +void bm_set_components_argb_16_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { *((ushort*)pixel) |= (ushort)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); *((ushort*)pixel) |= (ushort)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); @@ -2356,7 +2267,7 @@ void bm_set_components_argb_d3d_16_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ub } } -void bm_set_components_argb_d3d_32_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) +void bm_set_components_argb_32_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { *((uint*)pixel) |= (uint)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); *((uint*)pixel) |= (uint)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); @@ -2366,7 +2277,7 @@ void bm_set_components_argb_d3d_32_screen(ubyte *pixel, ubyte *rv, ubyte *gv, ub } } -void bm_set_components_argb_d3d_16_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) +void bm_set_components_argb_16_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { *((ushort*)pixel) |= (ushort)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); *((ushort*)pixel) |= (ushort)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); @@ -2379,7 +2290,7 @@ void bm_set_components_argb_d3d_16_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte } } -void bm_set_components_argb_d3d_32_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) +void bm_set_components_argb_32_tex(ubyte *pixel, ubyte *rv, ubyte *gv, ubyte *bv, ubyte *av) { *((ushort*)pixel) |= (ushort)(( (int)*rv / Gr_current_red->scale ) << Gr_current_red->shift); *((ushort*)pixel) |= (ushort)(( (int)*gv / Gr_current_green->scale ) << Gr_current_green->shift); @@ -2401,24 +2312,10 @@ void BM_SELECT_SCREEN_FORMAT() Gr_current_alpha = &Gr_alpha; // setup pointers - if(gr_screen.mode == GR_GLIDE){ -#ifndef PLAT_UNIX - bm_set_components = bm_set_components_argb; -#endif - } else if(gr_screen.mode == GR_DIRECT3D){ - if(Bm_pixel_format == BM_PIXEL_FORMAT_D3D){ - bm_set_components = bm_set_components_d3d; - } else { - if(D3D_32bit){ - bm_set_components = bm_set_components_argb_d3d_32_screen; - } else { - bm_set_components = bm_set_components_argb_d3d_16_screen; - } - } - } else if(gr_screen.mode == GR_SOFTWARE){ - bm_set_components = bm_set_components_argb; - } else if(gr_screen.mode == GR_OPENGL){ - bm_set_components = bm_set_components_argb_d3d_32_screen; + if ( gr_is_32bit() ) { + bm_set_components = bm_set_components_argb_32_screen; + } else { + bm_set_components = bm_set_components_argb_16_screen; } } @@ -2430,22 +2327,10 @@ void BM_SELECT_TEX_FORMAT() Gr_current_alpha = &Gr_t_alpha; // setup pointers - if(gr_screen.mode == GR_GLIDE){ - bm_set_components = bm_set_components_argb; - } else if(gr_screen.mode == GR_DIRECT3D){ - if(Bm_pixel_format == BM_PIXEL_FORMAT_D3D){ - bm_set_components = bm_set_components_d3d; - } else { - if(D3D_32bit){ - bm_set_components = bm_set_components_argb_d3d_32_tex; - } else { - bm_set_components = bm_set_components_argb_d3d_16_tex; - } - } - } else if(gr_screen.mode == GR_SOFTWARE){ - bm_set_components = bm_set_components_argb; - } else if(gr_screen.mode == GR_OPENGL){ - bm_set_components = bm_set_components_argb_d3d_32_tex; + if ( gr_is_32bit() ) { + bm_set_components = bm_set_components_argb_32_tex; + } else { + bm_set_components = bm_set_components_argb_16_tex; } } @@ -2457,22 +2342,10 @@ void BM_SELECT_ALPHA_TEX_FORMAT() Gr_current_alpha = &Gr_ta_alpha; // setup pointers - if(gr_screen.mode == GR_GLIDE){ - bm_set_components = bm_set_components_argb; - } else if(gr_screen.mode == GR_DIRECT3D){ - if(Bm_pixel_format == BM_PIXEL_FORMAT_D3D){ - bm_set_components = bm_set_components_d3d; - } else { - if(D3D_32bit){ - bm_set_components = bm_set_components_argb_d3d_32_tex; - } else { - bm_set_components = bm_set_components_argb_d3d_16_tex; - } - } - } else if(gr_screen.mode == GR_SOFTWARE){ - bm_set_components = bm_set_components_argb; - } else if(gr_screen.mode == GR_OPENGL){ - bm_set_components = bm_set_components_argb_d3d_32_tex; + if ( gr_is_32bit() ) { + bm_set_components = bm_set_components_argb_32_tex; + } else { + bm_set_components = bm_set_components_argb_16_tex; } } @@ -2556,7 +2429,7 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) int bit_32 = 0; // pick a byte size - 32 bits only if 32 bit mode d3d and screen format - if(D3D_32bit && (Gr_current_red == &Gr_red)){ + if ( gr_is_32bit() && (Gr_current_red == &Gr_red) ) { bit_32 = 1; } @@ -2586,45 +2459,34 @@ void bm_get_components(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a) if(a != NULL){ *a = 1; - switch(Bm_pixel_format){ - // glide has an alpha channel so we have to unset ir or set it each time - case BM_PIXEL_FORMAT_ARGB: - SDL_assert(!bit_32); - if(!( ((ushort*)pixel)[0] & 0x8000)){ - *a = 0; - } - break; - - // this d3d format has no alpha channel, so only make it "transparent", never make it "non-transparent" - case BM_PIXEL_FORMAT_D3D: - SDL_assert(!bit_32); - if( *((ushort*)pixel) == Gr_current_green->mask){ - *a = 0; - } - break; - - // nice 1555 texture format mode - case BM_PIXEL_FORMAT_ARGB_D3D: - // if we're writing to a normal texture, use nice alpha bits - if(Gr_current_red == &Gr_t_red){ + switch (Bm_pixel_format) { + // nice 1555 texture format mode + case BM_PIXEL_FORMAT_ARGB: + // if we're writing to a normal texture, use nice alpha bits + if(Gr_current_red == &Gr_t_red){ SDL_assert(!bit_32); - if(!(*((ushort*)pixel) & Gr_current_alpha->mask)){ - *a = 0; - } - } - // otherwise do it as normal - else { - if(bit_32){ - if(*((int*)pixel) == Gr_current_green->mask){ + if(!(*((ushort*)pixel) & Gr_current_alpha->mask)){ *a = 0; } - } else { - if(*((ushort*)pixel) == Gr_current_green->mask){ - *a = 0; + } + // otherwise do it as normal + else { + if(bit_32){ + if(*((int*)pixel) == Gr_current_green->mask){ + *a = 0; + } + } else { + if(*((ushort*)pixel) == Gr_current_green->mask){ + *a = 0; + } } } - } + break; + + default: + Int3(); + break; } } } @@ -2654,7 +2516,12 @@ void bm_get_section_size(int bitmapnum, int sx, int sy, int *w, int *h) bm_get_info(bitmapnum, &bw, &bh, NULL, NULL, NULL, §ions); // determine the width and height of this section - *w = sx < (sections->num_x - 1) ? MAX_BMAP_SECTION_SIZE : bw - sections->sx[sx]; - *h = sy < (sections->num_y - 1) ? MAX_BMAP_SECTION_SIZE : bh - sections->sy[sy]; + if (gr_screen.use_sections) { + *w = sx < (sections->num_x - 1) ? MAX_BMAP_SECTION_SIZE : bw - sections->sx[sx]; + *h = sy < (sections->num_y - 1) ? MAX_BMAP_SECTION_SIZE : bh - sections->sy[sy]; + } else { + *w = bw; + *h = bh; + } } diff --git a/src/freespace2/freespace.cpp b/src/freespace2/freespace.cpp index e276146..1596f8c 100644 --- a/src/freespace2/freespace.cpp +++ b/src/freespace2/freespace.cpp @@ -1336,53 +1336,9 @@ void game_framerate_check_init() // nebula missions if(The_mission.flags & MISSION_FLAG_FULLNEB){ - // if this is a glide card - if(gr_screen.mode == GR_GLIDE){ -#ifndef PLAT_UNIX - extern GrHwConfiguration hwconfig; - - // voodoo 2/3 - if(hwconfig.SSTs[0].sstBoard.VoodooConfig.fbRam >= 4){ - Gf_critical = 15.0f; - } - // voodoo 1 - else { - Gf_critical = 10.0f; - } -#else - STUB_FUNCTION; - - Gf_critical = 15.0f; -#endif - } - // d3d. only care about good cards here I guess (TNT) - else { - Gf_critical = 15.0f; - } + Gf_critical = 15.0f; } else { - // if this is a glide card - if(gr_screen.mode == GR_GLIDE){ -#ifndef PLAT_UNIX - extern GrHwConfiguration hwconfig; - - // voodoo 2/3 - if(hwconfig.SSTs[0].sstBoard.VoodooConfig.fbRam >= 4){ - Gf_critical = 25.0f; - } - // voodoo 1 - else { - Gf_critical = 20.0f; - } -#else - STUB_FUNCTION; - - Gf_critical = 25.0f; -#endif - } - // d3d. only care about good cards here I guess (TNT) - else { - Gf_critical = 25.0f; - } + Gf_critical = 25.0f; } } @@ -2579,7 +2535,7 @@ void game_init() } } else { STUB_FUNCTION; - gr_init(GR_640, GR_SOFTWARE); + gr_init(GR_640, GR_SDL); } #endif // !PLAT_UNIX @@ -5366,13 +5322,6 @@ void game_process_event( int current_state, int event ) break; case GS_EVENT_TOGGLE_GLIDE: - #ifndef NDEBUG - if ( gr_screen.mode != GR_GLIDE ) { - gr_init( GR_640, GR_GLIDE ); - } else { - gr_init( GR_640, GR_SOFTWARE ); - } - #endif break; case GS_EVENT_LOAD_MISSION_MENU: diff --git a/src/graphics/2d.cpp b/src/graphics/2d.cpp index 07ac1bd..1e7308c 100644 --- a/src/graphics/2d.cpp +++ b/src/graphics/2d.cpp @@ -967,6 +967,7 @@ int gr_init(int res, int mode, int depth, int fred_x, int fred_y) gr_screen.res = res; gr_screen.max_w = max_w; gr_screen.max_h = max_h; + gr_screen.use_sections = 1; gr_screen.aspect = 1.0f; // Normal PC screen gr_screen.offset_x = 0; gr_screen.offset_y = 0; @@ -1047,90 +1048,28 @@ int gr_init(int res, int mode, int depth, int fred_x, int fred_y) void gr_force_windowed() { - if ( !Gr_inited ) return; + if ( !Gr_inited ) { + return; + } - switch( gr_screen.mode ) { -#ifndef PLAT_UNIX - case GR_SOFTWARE: - { - extern void gr_soft_force_windowed(); - gr_soft_force_windowed(); - } - break; - case GR_DIRECTDRAW: - { - Int3(); - extern void gr_directdraw_force_windowed(); - gr_directdraw_force_windowed(); - } - break; - case GR_DIRECT3D: - break; - case GR_GLIDE: - { - extern void gr_glide_force_windowed(); - gr_glide_force_windowed(); - } - break; -#endif - case GR_OPENGL: - gr_opengl_force_windowed(); - break; - default: - Int3(); // Invalid graphics mode + if (gr_screen.gf_force_windowed) { + (*gr_screen.gf_force_windowed)(); } - if ( Os_debugger_running ) + if (Os_debugger_running) { SDL_Delay(1000); + } } void gr_activate(int active) { - if ( !Gr_inited ) return; - - switch( gr_screen.mode ) { -#ifndef PLAT_UNIX - case GR_SOFTWARE: - { - extern void gr_soft_activate(int active); - gr_soft_activate(active); - return; - } - break; - case GR_DIRECTDRAW: - { - Int3(); - extern void gr_dd_activate(int active); - gr_dd_activate(active); - return; - } - break; - case GR_DIRECT3D: - { - extern void gr_d3d_activate(int active); - gr_d3d_activate(active); - return; - } - break; - case GR_GLIDE: - { - extern void gr_glide_activate(int active); - gr_glide_activate(active); - return; - } - break; -#endif - case GR_OPENGL: - { - extern void gr_opengl_activate(int active); - gr_opengl_activate(active); - return; - } - break; - default: - Int3(); // Invalid graphics mode + if ( !Gr_inited ) { + return; } + if (gr_screen.gf_activate) { + (*gr_screen.gf_activate)(active); + } } // ----------------------------------------------------------------------- @@ -1188,7 +1127,7 @@ void gr_bitmap(int x, int y) int w, h; // d3d and glide support texture poly shiz - if(((gr_screen.mode == GR_DIRECT3D) || (gr_screen.mode == GR_GLIDE) || (gr_screen.mode == GR_OPENGL)) && Gr_bitmap_poly){ + if((gr_screen.mode == GR_OPENGL) && Gr_bitmap_poly){ int idx, s_idx; // float u_scale, v_scale; bitmap_section_info *sections; @@ -1197,20 +1136,28 @@ void gr_bitmap(int x, int y) bm_get_info(gr_screen.current_bitmap, &w, &h, NULL, NULL, NULL, §ions); y_line = 0; section_y = 0; - for(idx=0; idxnum_y; idx++){ - x_line = 0; - for(s_idx=0; s_idxnum_x; s_idx++){ - // get the section as a texture in vram - gr_set_bitmap(gr_screen.current_bitmap, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, gr_screen.current_alpha, s_idx, idx); - - // determine the width and height of this section - bm_get_section_size(gr_screen.current_bitmap, s_idx, idx, §ion_x, §ion_y); - - // draw as a poly - g3_draw_2d_poly_bitmap(x + x_line, y + y_line, section_x, section_y, TMAP_FLAG_BITMAP_SECTION); - x_line += section_x; + + if (gr_screen.use_sections) { + for(idx=0; idxnum_y; idx++){ + x_line = 0; + for(s_idx=0; s_idxnum_x; s_idx++){ + // get the section as a texture in vram + gr_set_bitmap(gr_screen.current_bitmap, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, gr_screen.current_alpha, s_idx, idx); + + // determine the width and height of this section + bm_get_section_size(gr_screen.current_bitmap, s_idx, idx, §ion_x, §ion_y); + + // draw as a poly + g3_draw_2d_poly_bitmap(x + x_line, y + y_line, section_x, section_y, TMAP_FLAG_BITMAP_SECTION); + x_line += section_x; + } + y_line += section_y; } - y_line += section_y; + } else { + gr_set_bitmap(gr_screen.current_bitmap, gr_screen.current_alphablend_mode, + gr_screen.current_bitblt_mode, gr_screen.current_alpha); + g3_draw_2d_poly_bitmap(x, y, w, h, TMAP_FLAG_BITMAP_INTERFACE); + } // done. whee! diff --git a/src/graphics/gropengl.cpp b/src/graphics/gropengl.cpp index b42e036..6049c14 100644 --- a/src/graphics/gropengl.cpp +++ b/src/graphics/gropengl.cpp @@ -1,2950 +1,74 @@ /* * Copyright (C) Volition, Inc. 1999. All rights reserved. * - * All source code herein is the property of Volition, Inc. You may not sell + * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on * the source. */ -/* - * $Logfile: /Freespace2/code/Graphics/GrOpenGL.cpp $ - * $Revision$ - * $Date$ - * $Author$ - * - * Code that uses the OpenGL graphics library - * - * $Log$ - * Revision 1.76 2005/10/01 21:44:43 taylor - * slight speedup to font rendering by not doing something that should be global for each letter - * little cleanup to better deal with FS2_Open related changes - * don't deal with the extra texmem stuff if we don't have to, saves on temporary memory usage and speed - * - * Revision 1.75 2005/08/12 20:24:31 taylor - * some OSX GCC4 fixin (LEgregius) - * - * Revision 1.74 2005/08/12 08:57:20 taylor - * don't show hardware S-RAM value on HUD in debug - * do show in use GL texture memory - * have an actual fade effect for the credits screen artwork - * - * Revision 1.73 2005/04/02 18:58:08 taylor - * attempt to fix garbage at end of GL extension string - * - * Revision 1.72 2005/03/30 01:20:12 taylor - * Screenshot function filled, will output into ~/.freespace(2)/Data - * Use glTexSubImage2D on reloaded texture slots, this is only used by ANIs - * - * Revision 1.71 2004/12/15 04:10:45 taylor - * outwnd_unix.cpp from fs2_open for logging to file in debug mode - * fixes for default function values - * always use vm_* functions for sanity sake - * make cfilearchiver 64-bit compatible - * fix crash on exit from double free() - * fix crash on startup from extra long GL extension string in debug - * - * Revision 1.70 2004/09/20 01:31:44 theoddone33 - * GCC 3.4 fixes. - * - * Revision 1.69 2004/07/04 11:31:43 taylor - * amd64 support, compiler warning fixes, don't use software rendering - * - * Revision 1.68 2004/06/11 01:01:07 tigital - * added FSAA support: switched on in .ini - * - * Revision 1.67 2003/08/03 15:59:40 taylor - * GL_RGB5_A1 as TexImage internal format; cleaner input grab; min window title; cleanup - * - * Revision 1.66 2003/06/22 12:52:34 taylor - * more texture size fixin - * - * Revision 1.65 2003/06/19 11:52:47 taylor - * fix texture size issue with lower detail settings - * - * Revision 1.64 2003/05/28 06:02:04 taylor - * fix transparency in green weapon blobs - * - * Revision 1.63 2003/05/09 05:05:52 taylor - * improve gr_(de)activate, mouse grab, default fullscreen - * - * Revision 1.62 2003/05/04 04:56:53 taylor - * move SDL_Quit to os_deinit to fix fonttool segfault - * - * Revision 1.61 2003/02/02 21:13:27 relnev - * minor updates (made functions static, tried to improve texture sizes) - * - * Revision 1.60 2003/02/02 20:20:03 relnev - * add large texture support (Taylor Richards) - * - * Revision 1.59 2002/09/04 01:38:09 relnev - * revert - * - * Revision 1.57 2002/08/31 01:39:13 theoddone33 - * Speed up the renderer a tad - * - * Revision 1.56 2002/08/01 05:03:11 relnev - * minor change - * - * Revision 1.55 2002/08/01 04:55:45 relnev - * experimenting with texture state - * - * Revision 1.54 2002/07/30 15:00:15 relnev - * not use luminance alpha by default - * - * Revision 1.53 2002/06/22 17:08:16 relnev - * more fixes to unused alpha code - * - * Revision 1.52 2002/06/21 23:59:14 relnev - * moved a gr_opengl_set_state to after the gr_tcache_set - * - * Revision 1.51 2002/06/19 04:52:45 relnev - * MacOS X updates (Ryan) - * - * Revision 1.50 2002/06/18 23:20:44 relnev - * fixed _splitpath. - * - * adjusted line offsets. - * - * Revision 1.49 2002/06/17 23:11:39 relnev - * enable sdl key repeating. - * - * swap '/` keys. - * - * Revision 1.48 2002/06/09 04:41:17 relnev - * added copyright header - * - * Revision 1.47 2002/06/09 03:16:04 relnev - * added _splitpath. - * - * removed unneeded asm, old sdl 2d setup. - * - * fixed crash caused by opengl_get_region. - * - * Revision 1.46 2002/06/05 04:03:32 relnev - * finished cfilesystem. - * - * removed some old code. - * - * fixed mouse save off-by-one. - * - * sound cleanups. - * - * Revision 1.45 2002/06/03 09:25:37 relnev - * implement mouse cursor and screen save/restore - * - * Revision 1.44 2002/06/02 18:46:59 relnev - * updated - * - * Revision 1.43 2002/06/02 11:34:00 relnev - * adjust z coords - * - * Revision 1.42 2002/06/02 10:28:17 relnev - * fix texture handle leak - * - * Revision 1.41 2002/06/01 09:00:34 relnev - * silly debug memmanager - * - * Revision 1.40 2002/06/01 07:12:33 relnev - * a few NDEBUG updates. - * - * removed a few warnings. - * - * Revision 1.39 2002/06/01 05:33:15 relnev - * copied more code over. - * - * added scissor clipping. - * - * Revision 1.38 2002/06/01 03:35:27 relnev - * fix typo - * - * Revision 1.37 2002/06/01 03:32:00 relnev - * fix texture loading mistake. - * - * enable some d3d stuff for opengl also - * - * Revision 1.36 2002/05/31 23:25:03 relnev - * line fixes - * - * Revision 1.34 2002/05/31 22:15:22 relnev - * BGRA - * - * Revision 1.33 2002/05/31 22:04:55 relnev - * use d3d rect_internal - * - * Revision 1.32 2002/05/31 06:28:23 relnev - * more stuff - * - * Revision 1.31 2002/05/31 06:04:39 relnev - * fog - * - * Revision 1.30 2002/05/31 03:56:11 theoddone33 - * Change tmapper polygon winding and enable culling - * - * Revision 1.29 2002/05/31 03:34:02 theoddone33 - * Fix Keyboard - * Add titlebar - * - * Revision 1.28 2002/05/31 00:06:59 relnev - * minor change - * - * Revision 1.27 2002/05/30 23:46:29 theoddone33 - * some minor key changes (not necessarily fixes) - * - * Revision 1.26 2002/05/30 23:33:12 relnev - * implemented a few more functions. - * - * Revision 1.25 2002/05/30 23:01:16 relnev - * implement gr_opengl_set_state. - * - * Revision 1.24 2002/05/30 22:12:57 relnev - * finish default texture case - * - * Revision 1.23 2002/05/30 22:02:30 theoddone33 - * More gl changes - * - * Revision 1.22 2002/05/30 21:44:48 relnev - * implemented some missing texture stuff. - * - * enable bitmap polys for opengl. - * - * work around greenness in bitmaps. - * - * Revision 1.21 2002/05/30 17:29:30 theoddone33 - * Fix some more stubs, change at least one polygon winding since culling is now - * enabled. - * - * Revision 1.20 2002/05/30 16:50:24 theoddone33 - * Keyboard partially fixed - * - * Revision 1.19 2002/05/30 08:13:14 relnev - * fonts are fixed - * - * Revision 1.18 2002/05/29 23:37:36 relnev - * fix bitmap bug - * - * Revision 1.17 2002/05/29 23:17:49 theoddone33 - * Non working text code and fixed keys - * - * Revision 1.16 2002/05/29 19:45:13 theoddone33 - * More changes on texture loading - * - * Revision 1.15 2002/05/29 19:06:48 theoddone33 - * Enable string printing. Enable texture mapping - * - * Revision 1.14 2002/05/29 08:54:40 relnev - * "fixed" bitmap drawing. - * - * copied more d3d code over. - * - * Revision 1.13 2002/05/29 06:25:13 theoddone33 - * Keyboard input, mouse tracking now work - * - * Revision 1.12 2002/05/29 04:52:45 relnev - * bitmap - * - * Revision 1.11 2002/05/29 04:29:56 relnev - * removed some unncessary stubbing, implemented opengl rect - * - * Revision 1.10 2002/05/29 04:13:27 theoddone33 - * enable opengl_line - * - * Revision 1.9 2002/05/29 03:35:51 relnev - * added rest of init - * - * Revision 1.8 2002/05/29 03:30:05 relnev - * update opengl stubs - * - * Revision 1.7 2002/05/29 02:52:32 theoddone33 - * Enable OpenGL renderer - * - * Revision 1.6 2002/05/28 04:56:51 theoddone33 - * runs a little bit now - * - * Revision 1.5 2002/05/28 04:07:28 theoddone33 - * New graphics stubbing arrangement - * - * Revision 1.4 2002/05/27 23:39:34 relnev - * 0 - * - * Revision 1.3 2002/05/27 22:35:01 theoddone33 - * more symbols - * - * Revision 1.2 2002/05/27 22:32:02 theoddone33 - * throw all d3d stuff at opengl - * - * Revision 1.1.1.1 2002/05/03 03:28:09 root - * Initial import. - * - * - * 10 7/14/99 9:42a Dave - * Put in clear_color debug function. Put in base for 3dnow stuff / P3 - * stuff - * - * 9 7/09/99 9:51a Dave - * Added thick polyline code. - * - * 8 6/29/99 10:35a Dave - * Interface polygon bitmaps! Whee! - * - * 7 2/03/99 11:44a Dave - * Fixed d3d transparent textures. - * - * 6 1/24/99 11:37p Dave - * First full rev of beam weapons. Very customizable. Removed some bogus - * Int3()'s in low level net code. - * - * 5 12/18/98 1:13a Dave - * Rough 1024x768 support for Direct3D. Proper detection and usage through - * the launcher. - * - * 4 12/06/98 2:36p Dave - * Drastically improved nebula fogging. - * - * 3 11/11/98 5:37p Dave - * Checkin for multiplayer testing. - * - * 2 10/07/98 10:53a Dave - * Initial checkin. - * - * 1 10/07/98 10:49a Dave - * - * 14 5/20/98 9:46p John - * added code so the places in code that change half the palette don't - * have to clear the screen. - * - * 13 5/06/98 5:30p John - * Removed unused cfilearchiver. Removed/replaced some unused/little used - * graphics functions, namely gradient_h and _v and pixel_sp. Put in new - * DirectX header files and libs that fixed the Direct3D alpha blending - * problems. - * - * 12 4/14/98 12:15p John - * Made 16-bpp movies work. - * - * 11 3/12/98 5:36p John - * Took out any unused shaders. Made shader code take rgbc instead of - * matrix and vector since noone used it like a matrix and it would have - * been impossible to do in hardware. Made Glide implement a basic - * shader for online help. - * - * 10 3/10/98 4:18p John - * Cleaned up graphics lib. Took out most unused gr functions. Made D3D - * & Glide have popups and print screen. Took out all >8bpp software - * support. Made Fred zbuffer. Made zbuffer allocate dynamically to - * support Fred. Made zbuffering key off of functions rather than one - * global variable. - * - * 9 12/02/97 4:00p John - * Added first rev of thruster glow, along with variable levels of - * translucency, which retquired some restructing of palman. - * - * 8 10/03/97 9:10a John - * added better antialiased line drawer - * - * 7 9/23/97 10:45a John - * made so you can tell bitblt code to rle a bitmap by passing flag to - * gr_set_bitmap - * - * 6 9/09/97 11:01a Sandeep - * fixed warning level 4 bugs - * - * 5 7/10/97 2:06p John - * added code to specify alphablending type for bitmaps. - * - * 4 6/17/97 7:04p John - * added d3d support for gradients. - * fixed some color bugs by adding screen signatures instead of watching - * flags and palette changes. - * - * 3 6/12/97 2:50a Lawrance - * bm_unlock() now passed bitmap number, not pointer - * - * 2 6/11/97 1:12p John - * Started fixing all the text colors in the game. - * - * 1 5/12/97 12:14p John - * - * $NoKeywords: $ - */ - -#ifndef PLAT_UNIX -#include -#include -#endif - -#include "pstypes.h" -#include "osapi.h" -#include "2d.h" -#include "3d.h" -#include "bmpman.h" -#include "floating.h" -#include "palman.h" -#include "systemvars.h" -#include "grinternal.h" -#include "gropengl.h" -#include "line.h" -#include "neb.h" -#include "mouse.h" -#include "osregistry.h" -#include "cmdline.h" -#include "cfile.h" - -static int Inited = 0; - -typedef enum gr_texture_source { - TEXTURE_SOURCE_NONE, - TEXTURE_SOURCE_DECAL, - TEXTURE_SOURCE_NO_FILTERING, -} gr_texture_source; - -typedef enum gr_alpha_blend { - ALPHA_BLEND_NONE, // 1*SrcPixel + 0*DestPixel - ALPHA_BLEND_ADDITIVE, // 1*SrcPixel + 1*DestPixel - ALPHA_BLEND_ALPHA_ADDITIVE, // Alpha*SrcPixel + 1*DestPixel - ALPHA_BLEND_ALPHA_BLEND_ALPHA, // Alpha*SrcPixel + (1-Alpha)*DestPixel - ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR, // Alpha*SrcPixel + (1-SrcPixel)*DestPixel -} gr_alpha_blend; - -typedef enum gr_zbuffer_type { - ZBUFFER_TYPE_NONE, - ZBUFFER_TYPE_READ, - ZBUFFER_TYPE_WRITE, - ZBUFFER_TYPE_FULL, -} gr_zbuffer_type; - -#define NEBULA_COLORS 20 - -volatile int GL_activate = 0; -volatile int GL_deactivate = 0; - -static int FSAA; -static ubyte GL_xlat[256] = { 0 }; - -static GLuint Gr_saved_screen_tex = 0; - -static int Gr_opengl_mouse_saved = 0; -static int Gr_opengl_mouse_saved_x = 0; -static int Gr_opengl_mouse_saved_y = 0; -static int Gr_opengl_mouse_saved_w = 0; -static int Gr_opengl_mouse_saved_h = 0; -static ubyte *Gr_opengl_mouse_saved_data = NULL; - -#define CLAMP(x,r1,r2) do { if ( (x) < (r1) ) (x) = (r1); else if ((x) > (r2)) (x) = (r2); } while(0) - -SDL_Window *GL_window = NULL; -SDL_GLContext GL_context; - -static int GL_viewport_x = 0; -static int GL_viewport_y = 0; -static int GL_viewport_w = 640; -static int GL_viewport_h = 480; -static float GL_viewport_scale_w = 1.0f; -static float GL_viewport_scale_h = 1.0f; - -PFNGLSECONDARYCOLOR3FEXTPROC glSecondaryColor3fEXT = NULL; - -#ifdef PLAT_UNIX -// Throw in some dummy functions - DDOI - -int D3D_32bit = 0; // grd3d.cpp -int D3D_fog_mode = -1; // grd3d.cpp -int D3D_inited = 0; // grd3d.cpp -int D3D_zbias = 1; // grd3d.cpp -int D3d_rendition_uvs = 0; // grd3d.cpp - -void d3d_flush () -{ - STUB_FUNCTION; -} - -void d3d_zbias (int a) -{ - STUB_FUNCTION; -} -#endif - -static void gr_opengl_set_texture_state(gr_texture_source ts); - -static gr_alpha_blend GL_current_alpha_blend = (gr_alpha_blend) -1; -static gr_zbuffer_type GL_current_zbuffer_type = (gr_zbuffer_type) -1; - -static void gr_opengl_set_state(gr_texture_source ts, gr_alpha_blend ab, gr_zbuffer_type zt) -{ - gr_opengl_set_texture_state(ts); - - if (ab != GL_current_alpha_blend) { - switch (ab) { - case ALPHA_BLEND_NONE: // 1*SrcPixel + 0*DestPixel - glBlendFunc(GL_ONE, GL_ZERO); - break; - case ALPHA_BLEND_ADDITIVE: // 1*SrcPixel + 1*DestPixel - glBlendFunc(GL_ONE, GL_ONE); - break; - case ALPHA_BLEND_ALPHA_ADDITIVE: // Alpha*SrcPixel + 1*DestPixel - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - break; - case ALPHA_BLEND_ALPHA_BLEND_ALPHA: // Alpha*SrcPixel + (1-Alpha)*DestPixel - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - case ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR: // Alpha*SrcPixel + (1-SrcPixel)*DestPixel - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR); - break; - default: - break; - } - - GL_current_alpha_blend = ab; - } - - if (zt != GL_current_zbuffer_type) { - switch (zt) { - case ZBUFFER_TYPE_NONE: - glDepthFunc(GL_ALWAYS); - glDepthMask(GL_FALSE); - break; - case ZBUFFER_TYPE_READ: - glDepthFunc(GL_LESS); - glDepthMask(GL_FALSE); - break; - case ZBUFFER_TYPE_WRITE: - glDepthFunc(GL_ALWAYS); - glDepthMask(GL_TRUE); - break; - case ZBUFFER_TYPE_FULL: - glDepthFunc(GL_LESS); - glDepthMask(GL_TRUE); - break; - default: - break; - } - - GL_current_zbuffer_type = zt; - } -} - -void gr_opengl_activate(int active) -{ - if (active) { - GL_activate++; - - // don't grab key/mouse if cmdline says so or if we're fullscreen - // if(!Cmdline_no_grab && !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN)) { - // SDL_WM_GrabInput(SDL_GRAB_ON); - // } - } else { - GL_deactivate++; - - // let go of mouse/keyboard - // SDL_WM_GrabInput(SDL_GRAB_OFF); - } -} - - -static void opengl_tcache_flush (); - -void gr_opengl_preload_init() -{ - if (gr_screen.mode != GR_OPENGL) { - return; - } - - opengl_tcache_flush (); -} - -int GL_should_preload = 0; -int gr_opengl_preload(int bitmap_num, int is_aabitmap) -{ - if ( gr_screen.mode != GR_OPENGL) { - return 0; - } - - if ( !GL_should_preload ) { - return 0; - } - - float u_scale, v_scale; - - int retval; - if ( is_aabitmap ) { - retval = gr_tcache_set(bitmap_num, TCACHE_TYPE_AABITMAP, &u_scale, &v_scale, 1, -1, -1, 0 ); - } else { - retval = gr_tcache_set(bitmap_num, TCACHE_TYPE_NORMAL, &u_scale, &v_scale, 1, -1, -1, 0 ); - } - - if ( !retval ) { - mprintf(("Texture upload failed!\n" )); - } - - return retval; -} - -void gr_opengl_pixel(int x, int y) -{ - gr_line(x,y,x,y); -} - -void gr_opengl_clear() -{ - glClearColor(gr_screen.current_clear_color.red / 255.0, - gr_screen.current_clear_color.green / 255.0, - gr_screen.current_clear_color.blue / 255.0, 1.0); - - glClear ( GL_COLOR_BUFFER_BIT ); -} - -void gr_opengl_save_mouse_area(int x, int y, int w, int h); -static void opengl_tcache_frame (); - -void gr_opengl_flip() -{ - if (!Inited) return; - - gr_reset_clip(); - - mouse_eval_deltas(); - - Gr_opengl_mouse_saved = 0; - - if ( mouse_is_visible() ) { - int mx, my; - - gr_reset_clip(); - mouse_get_pos( &mx, &my ); - - gr_opengl_save_mouse_area(mx,my,32,32); - - if ( Gr_cursor == -1 ) { - // stuff - } else { - gr_set_bitmap(Gr_cursor, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1); - gr_bitmap( mx, my ); - } - } - -#ifndef NDEBUG - GLenum error = glGetError(); - int ic = 0; - do { - error = glGetError(); - - if (error != GL_NO_ERROR) { - nprintf(("Warning", "!!DEBUG!! OpenGL Error: %d (%d this frame)\n", error, ic)); - } - ic++; - } while (error != GL_NO_ERROR); -#endif - - SDL_GL_SwapWindow(GL_window); - - opengl_tcache_frame (); - - int cnt = GL_activate; - if ( cnt ) { - GL_activate-=cnt; - opengl_tcache_flush(); - // gr_opengl_clip_cursor(1); /* mouse grab, see opengl_activate */ - } - - cnt = GL_deactivate; - if ( cnt ) { - GL_deactivate-=cnt; - // gr_opengl_clip_cursor(0); /* mouse grab, see opengl_activate */ - } -} - -void gr_opengl_flip_window(uint _hdc, int x, int y, int w, int h ) -{ - // Not used. -} - -void gr_opengl_set_clip(int x,int y,int w,int h) -{ - // check for sanity of parameters - if (x < 0) - x = 0; - if (y < 0) - y = 0; - - if (x >= gr_screen.max_w) - x = gr_screen.max_w - 1; - if (y >= gr_screen.max_h) - y = gr_screen.max_h - 1; - - if (x + w > gr_screen.max_w) - w = gr_screen.max_w - x; - if (y + h > gr_screen.max_h) - h = gr_screen.max_h - y; - - if (w > gr_screen.max_w) - w = gr_screen.max_w; - if (h > gr_screen.max_h) - h = gr_screen.max_h; - - gr_screen.offset_x = x; - gr_screen.offset_y = y; - gr_screen.clip_left = 0; - gr_screen.clip_right = w-1; - gr_screen.clip_top = 0; - gr_screen.clip_bottom = h-1; - gr_screen.clip_width = w; - gr_screen.clip_height = h; - - x = fl2i((x * GL_viewport_scale_w) + 0.5f) + GL_viewport_x; - y = fl2i((y * GL_viewport_scale_h) + 0.5f) + GL_viewport_y; - w = fl2i((w * GL_viewport_scale_w) + 0.5f); - h = fl2i((h * GL_viewport_scale_h) + 0.5f); - - glEnable(GL_SCISSOR_TEST); - glScissor(x, GL_viewport_h-y-h, w, h); -} - -void gr_opengl_reset_clip() -{ - gr_screen.offset_x = 0; - gr_screen.offset_y = 0; - gr_screen.clip_left = 0; - gr_screen.clip_top = 0; - gr_screen.clip_right = gr_screen.max_w - 1; - gr_screen.clip_bottom = gr_screen.max_h - 1; - gr_screen.clip_width = gr_screen.max_w; - gr_screen.clip_height = gr_screen.max_h; - - glDisable(GL_SCISSOR_TEST); -// glScissor(0, 0, gr_screen.max_w, gr_screen.max_h); -} - -void gr_opengl_set_bitmap( int bitmap_num, int alphablend_mode = GR_ALPHABLEND_NONE, int bitblt_mode = GR_BITBLT_MODE_NORMAL, float alpha = 1.0f, int sx = -1, int sy = -1 ) -{ - gr_screen.current_alpha = alpha; - gr_screen.current_alphablend_mode = alphablend_mode; - gr_screen.current_bitblt_mode = bitblt_mode; - gr_screen.current_bitmap = bitmap_num; - - gr_screen.current_bitmap_sx = sx; - gr_screen.current_bitmap_sy = sy; -} - -void gr_opengl_create_shader(shader * shade, float r, float g, float b, float c ) -{ - shade->screen_sig = gr_screen.signature; - shade->r = r; - shade->g = g; - shade->b = b; - shade->c = c; -} - -void gr_opengl_set_shader( shader * shade ) -{ - if ( shade ) { - if (shade->screen_sig != gr_screen.signature) { - gr_create_shader( shade, shade->r, shade->g, shade->b, shade->c ); - } - gr_screen.current_shader = *shade; - } else { - gr_create_shader( &gr_screen.current_shader, 0.0f, 0.0f, 0.0f, 0.0f ); - } -} - - -void gr_opengl_bitmap_ex(int x,int y,int w,int h,int sx,int sy) -{ - STUB_FUNCTION; /* who called me? */ -} - -void gr_opengl_bitmap(int x, int y) -{ - STUB_FUNCTION; /* who called me? */ -} - -static void gr_opengl_rect_internal(int x, int y, int w, int h, int r, int g, int b, int a) -{ - int saved_zbuf; - vertex v[4]; - vertex *verts[4] = {&v[0], &v[1], &v[2], &v[3]}; - - saved_zbuf = gr_zbuffer_get(); - - // start the frame, no zbuffering, no culling - g3_start_frame(1); - gr_zbuffer_set(GR_ZBUFF_NONE); - gr_set_cull(0); - - // stuff coords - v[0].sx = i2fl(x); - v[0].sy = i2fl(y); - v[0].sw = 0.0f; - v[0].u = 0.0f; - v[0].v = 0.0f; - v[0].flags = PF_PROJECTED; - v[0].codes = 0; - v[0].r = (ubyte)r; - v[0].g = (ubyte)g; - v[0].b = (ubyte)b; - v[0].a = (ubyte)a; - - v[1].sx = i2fl(x + w); - v[1].sy = i2fl(y); - v[1].sw = 0.0f; - v[1].u = 0.0f; - v[1].v = 0.0f; - v[1].flags = PF_PROJECTED; - v[1].codes = 0; - v[1].r = (ubyte)r; - v[1].g = (ubyte)g; - v[1].b = (ubyte)b; - v[1].a = (ubyte)a; - - v[2].sx = i2fl(x + w); - v[2].sy = i2fl(y + h); - v[2].sw = 0.0f; - v[2].u = 0.0f; - v[2].v = 0.0f; - v[2].flags = PF_PROJECTED; - v[2].codes = 0; - v[2].r = (ubyte)r; - v[2].g = (ubyte)g; - v[2].b = (ubyte)b; - v[2].a = (ubyte)a; - - v[3].sx = i2fl(x); - v[3].sy = i2fl(y + h); - v[3].sw = 0.0f; - v[3].u = 0.0f; - v[3].v = 0.0f; - v[3].flags = PF_PROJECTED; - v[3].codes = 0; - v[3].r = (ubyte)r; - v[3].g = (ubyte)g; - v[3].b = (ubyte)b; - v[3].a = (ubyte)a; - - // draw the polys - g3_draw_poly_constant_sw(4, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_ALPHA, 0.1f); - - g3_end_frame(); - - // restore zbuffer and culling - gr_zbuffer_set(saved_zbuf); - gr_set_cull(1); -} - -void gr_opengl_rect(int x,int y,int w,int h) -{ - gr_opengl_rect_internal(x, y, w, h, gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue, gr_screen.current_color.alpha); -} - -void gr_opengl_shade(int x,int y,int w,int h) -{ - int r,g,b,a; - - float shade1 = 1.0f; - float shade2 = 6.0f; - - r = fl2i(gr_screen.current_shader.r*255.0f*shade1); - if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255; - g = fl2i(gr_screen.current_shader.g*255.0f*shade1); - if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255; - b = fl2i(gr_screen.current_shader.b*255.0f*shade1); - if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255; - a = fl2i(gr_screen.current_shader.c*255.0f*shade2); - if ( a < 0 ) a = 0; else if ( a > 255 ) a = 255; - - gr_opengl_rect_internal(x, y, w, h, r, g, b, a); -} - -static void gr_opengl_aabitmap_ex_internal(int x,int y,int w,int h,int sx,int sy) -{ - if ( w < 1 ) return; - if ( h < 1 ) return; - - if ( !gr_screen.current_color.is_alphacolor ) return; - - float u_scale, v_scale; - - if ( !gr_tcache_set( gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &u_scale, &v_scale, 0, -1, -1, 0 ) ) { - // Couldn't set texture - mprintf(( "WARNING: Error setting aabitmap texture!\n" )); - return; - } - - gr_opengl_set_state( TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE ); - - float u0, u1, v0, v1; - float x1, x2, y1, y2; - int bw, bh; - - bm_get_info( gr_screen.current_bitmap, &bw, &bh ); - - u0 = u_scale*i2fl(sx)/i2fl(bw); - v0 = v_scale*i2fl(sy)/i2fl(bh); - - u1 = u_scale*i2fl(sx+w)/i2fl(bw); - v1 = v_scale*i2fl(sy+h)/i2fl(bh); - - x1 = i2fl(x+gr_screen.offset_x); - y1 = i2fl(y+gr_screen.offset_y); - x2 = i2fl(x+w+gr_screen.offset_x); - y2 = i2fl(y+h+gr_screen.offset_y); - - if ( gr_screen.current_color.is_alphacolor ) { - glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue,gr_screen.current_color.alpha); - } else { - glColor3ub(gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue); - } - - glBegin (GL_QUADS); - glTexCoord2f (u0, v1); - glVertex3f (x1, y2, -0.99); - - glTexCoord2f (u1, v1); - glVertex3f (x2, y2, -0.99); - - glTexCoord2f (u1, v0); - glVertex3f (x2, y1, -0.99); - - glTexCoord2f (u0, v0); - glVertex3f (x1, y1, -0.99); - glEnd (); -} - -void gr_opengl_aabitmap_ex(int x,int y,int w,int h,int sx,int sy) -{ - int reclip; - #ifndef NDEBUG - int count = 0; - #endif - - int dx1=x, dx2=x+w-1; - int dy1=y, dy2=y+h-1; - - int bw, bh; - bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL ); - - do { - reclip = 0; - #ifndef NDEBUG - if ( count > 1 ) Int3(); - count++; - #endif - - if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return; - if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return; - if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; } - if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; } - if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; } - if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; } - - if ( sx < 0 ) { - dx1 -= sx; - sx = 0; - reclip = 1; - } - - if ( sy < 0 ) { - dy1 -= sy; - sy = 0; - reclip = 1; - } - - w = dx2-dx1+1; - h = dy2-dy1+1; - - if ( sx + w > bw ) { - w = bw - sx; - dx2 = dx1 + w - 1; - } - - if ( sy + h > bh ) { - h = bh - sy; - dy2 = dy1 + h - 1; - } - - if ( w < 1 ) return; // clipped away! - if ( h < 1 ) return; // clipped away! - - } while (reclip); - - // Make sure clipping algorithm works - #ifndef NDEBUG - SDL_assert( w > 0 ); - SDL_assert( h > 0 ); - SDL_assert( w == (dx2-dx1+1) ); - SDL_assert( h == (dy2-dy1+1) ); - SDL_assert( sx >= 0 ); - SDL_assert( sy >= 0 ); - SDL_assert( sx+w <= bw ); - SDL_assert( sy+h <= bh ); - SDL_assert( dx2 >= dx1 ); - SDL_assert( dy2 >= dy1 ); - SDL_assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) ); - SDL_assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) ); - SDL_assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) ); - SDL_assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) ); - #endif - - // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions. - gr_opengl_aabitmap_ex_internal(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy); -} - -void gr_opengl_aabitmap(int x, int y) -{ - int w, h; - - bm_get_info( gr_screen.current_bitmap, &w, &h, NULL ); - int dx1=x, dx2=x+w-1; - int dy1=y, dy2=y+h-1; - int sx=0, sy=0; - - if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return; - if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return; - if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; } - if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; } - if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; } - if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; } - - if ( sx < 0 ) return; - if ( sy < 0 ) return; - if ( sx >= w ) return; - if ( sy >= h ) return; - - // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2) - gr_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy); -} - -void gr_opengl_string( int sx, int sy, const char *s ) -{ - int width, spacing, letter; - int x, y; - - if ( !Current_font ) { - return; - } - - gr_set_bitmap(Current_font->bitmap_id, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1); - - x = sx; - y = sy; - - if (sx==0x8000) { //centered - x = get_centered_x(s); - } else { - x = sx; - } - - spacing = 0; - - while (*s) { - x += spacing; - - while (*s== '\n' ) { - s++; - y += Current_font->h; - if (sx==0x8000) { //centered - x = get_centered_x(s); - } else { - x = sx; - } - } - if (*s == 0 ) break; - - letter = get_char_width(s[0],s[1],&width,&spacing); - s++; - - //not in font, draw as space - if (letter<0) { - continue; - } - - int xd, yd, xc, yc; - int wc, hc; - - // Check if this character is totally clipped - if ( x + width < gr_screen.clip_left ) continue; - if ( y + Current_font->h < gr_screen.clip_top ) continue; - if ( x > gr_screen.clip_right ) continue; - if ( y > gr_screen.clip_bottom ) continue; - - xd = yd = 0; - if ( x < gr_screen.clip_left ) xd = gr_screen.clip_left - x; - if ( y < gr_screen.clip_top ) yd = gr_screen.clip_top - y; - xc = x+xd; - yc = y+yd; - - wc = width - xd; hc = Current_font->h - yd; - if ( xc + wc > gr_screen.clip_right ) wc = gr_screen.clip_right - xc; - if ( yc + hc > gr_screen.clip_bottom ) hc = gr_screen.clip_bottom - yc; - - if ( wc < 1 ) continue; - if ( hc < 1 ) continue; - - int u = Current_font->bm_u[letter]; - int v = Current_font->bm_v[letter]; - - gr_opengl_aabitmap_ex_internal( xc, yc, wc, hc, u+xd, v+yd ); - } -} - -void gr_opengl_line(int x1,int y1,int x2,int y2) -{ - int clipped = 0, swapped=0; - - gr_opengl_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE ); - - INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,gr_screen.clip_right,gr_screen.clip_bottom,return,clipped=1,swapped=1); - - float sx1, sy1; - float sx2, sy2; - - sx1 = i2fl(x1 + gr_screen.offset_x)+0.5; - sy1 = i2fl(y1 + gr_screen.offset_y)+0.5; - sx2 = i2fl(x2 + gr_screen.offset_x)+0.5; - sy2 = i2fl(y2 + gr_screen.offset_y)+0.5; - - if ( x1 == x2 && y1 == y2 ) { - glBegin (GL_POINTS); - glColor4ub (gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue, gr_screen.current_color.alpha); - glVertex3f (sx1, sy1, -0.99f); - glEnd (); - - return; - } - - if ( x1 == x2 ) { - if ( sy1 < sy2 ) { - sy2 += 0.5f; - } else { - sy1 += 0.5f; - } - } else if ( y1 == y2 ) { - if ( sx1 < sx2 ) { - sx2 += 0.5f; - } else { - sx1 += 0.5f; - } - } - - glBegin (GL_LINES); - glColor4ub (gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue, gr_screen.current_color.alpha); - glVertex3f (sx2, sy2, -0.99f); - glVertex3f (sx1, sy1, -0.99f); - glEnd (); -} - -void gr_opengl_aaline(vertex *v1, vertex *v2) -{ - gr_opengl_line( fl2i(v1->sx), fl2i(v1->sy), fl2i(v2->sx), fl2i(v2->sy) ); -} - -void gr_opengl_gradient(int x1,int y1,int x2,int y2) -{ - int clipped = 0, swapped=0; - - if ( !gr_screen.current_color.is_alphacolor ) { - gr_line( x1, y1, x2, y2 ); - return; - } - - INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,gr_screen.clip_right,gr_screen.clip_bottom,return,clipped=1,swapped=1); - - gr_opengl_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE ); - - int aa = swapped ? 0 : gr_screen.current_color.alpha; - int ba = swapped ? gr_screen.current_color.alpha : 0; - - float sx1, sy1; - float sx2, sy2; - - sx1 = i2fl(x1 + gr_screen.offset_x)+0.5; - sy1 = i2fl(y1 + gr_screen.offset_y)+0.5; - sx2 = i2fl(x2 + gr_screen.offset_x)+0.5; - sy2 = i2fl(y2 + gr_screen.offset_y)+0.5; - - if ( x1 == x2 ) { - if ( sy1 < sy2 ) { - sy2 += 0.5f; - } else { - sy1 += 0.5f; - } - } else if ( y1 == y2 ) { - if ( sx1 < sx2 ) { - sx2 += 0.5f; - } else { - sx1 += 0.5f; - } - } - - glBegin (GL_LINES); - glColor4ub (gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue, ba); - glVertex3f (sx2, sy2, -0.99f); - glColor4ub (gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue, aa); - glVertex3f (sx1, sy1, -0.99f); - glEnd (); -} - -void gr_opengl_circle( int xc, int yc, int d ) -{ - int p,x, y, r; - - r = d/2; - p=3-d; - x=0; - y=r; - - // Big clip - if ( (xc+r) < gr_screen.clip_left ) return; - if ( (xc-r) > gr_screen.clip_right ) return; - if ( (yc+r) < gr_screen.clip_top ) return; - if ( (yc-r) > gr_screen.clip_bottom ) return; - - while(x 1.0f) { - f_float = 1.0f; - } - - *f_val = f_float; -} - -static void gr_opengl_tmapper_internal( int nv, vertex ** verts, uint flags, int is_scaler ) -{ - int i; - float u_scale = 1.0f, v_scale = 1.0f; - - // Make nebula use the texture mapper... this blends the colors better. - if ( flags & TMAP_FLAG_NEBULA ){ - Int3 (); - } - - gr_texture_source texture_source = (gr_texture_source)-1; - gr_alpha_blend alpha_blend = (gr_alpha_blend)-1; - gr_zbuffer_type zbuffer_type = (gr_zbuffer_type)-1; - - if ( gr_zbuffering ) { - if ( is_scaler || (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) ) { - zbuffer_type = ZBUFFER_TYPE_READ; - } else { - zbuffer_type = ZBUFFER_TYPE_FULL; - } - } else { - zbuffer_type = ZBUFFER_TYPE_NONE; - } - - int alpha; - - int tmap_type = TCACHE_TYPE_NORMAL; - - int r, g, b; - - if ( flags & TMAP_FLAG_TEXTURED ) { - r = g = b = 255; - } else { - r = gr_screen.current_color.red; - g = gr_screen.current_color.green; - b = gr_screen.current_color.blue; - } - - if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) - { - if (1) { - tmap_type = TCACHE_TYPE_NORMAL; - alpha_blend = ALPHA_BLEND_ALPHA_ADDITIVE; - - // Blend with screen pixel using src*alpha+dst - float factor = gr_screen.current_alpha; - - alpha = 255; - - if ( factor <= 1.0f ) { - int tmp_alpha = fl2i(gr_screen.current_alpha*255.0f); - r = (r*tmp_alpha)/255; - g = (g*tmp_alpha)/255; - b = (b*tmp_alpha)/255; - } - } else { - tmap_type = TCACHE_TYPE_XPARENT; - - alpha_blend = ALPHA_BLEND_ALPHA_BLEND_ALPHA; - - // Blend with screen pixel using src*alpha+dst - float factor = gr_screen.current_alpha; - - if ( factor > 1.0f ) { - alpha = 255; - } else { - alpha = fl2i(gr_screen.current_alpha*255.0f); - } - } - } else { - if(Bm_pixel_format == BM_PIXEL_FORMAT_ARGB) { - alpha_blend = ALPHA_BLEND_ALPHA_BLEND_ALPHA; - } else { - alpha_blend = ALPHA_BLEND_NONE; - } - alpha = 255; - } - - if(flags & TMAP_FLAG_BITMAP_SECTION){ - tmap_type = TCACHE_TYPE_BITMAP_SECTION; - } - - texture_source = TEXTURE_SOURCE_NONE; - - if ( flags & TMAP_FLAG_TEXTURED ) { - if ( !gr_tcache_set(gr_screen.current_bitmap, tmap_type, &u_scale, &v_scale, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, 0 )) - { - mprintf(( "Not rendering a texture because it didn't fit in VRAM!\n" )); - return; - } - - // use nonfiltered textures for bitmap sections - if(flags & TMAP_FLAG_BITMAP_SECTION){ - texture_source = TEXTURE_SOURCE_NO_FILTERING; - } else { - texture_source = TEXTURE_SOURCE_DECAL; - } - } - - - gr_opengl_set_state( texture_source, alpha_blend, zbuffer_type ); - - if ( flags & TMAP_FLAG_TEXTURED ) - { - // rendition junk - // STUB_FUNCTION; - } - - float fr = 1.0f, fg = 1.0f, fb = 1.0f; - - if (flags & TMAP_FLAG_PIXEL_FOG) { - int r, g, b; - int ra, ga, ba; - ra = ga = ba = 0; - - /* argh */ - for (i=nv-1;i>=0;i--) // DDOI - change polygon winding - { - vertex * va = verts[i]; - float sx, sy; - - int x, y; - x = fl2i(va->sx*16.0f); - y = fl2i(va->sy*16.0f); - - x += gr_screen.offset_x*16; - y += gr_screen.offset_y*16; - - sx = i2fl(x) / 16.0f; - sy = i2fl(y) / 16.0f; - - neb2_get_pixel((int)sx, (int)sy, &r, &g, &b); - - ra += r; - ga += g; - ba += b; - } - - ra /= nv; - ga /= nv; - ba /= nv; - - gr_fog_set(GR_FOGMODE_FOG, ra, ga, ba, -1.0f, -1.0f); - - fr = ra / 255.0f; - fg = ga / 255.0f; - fb = ba / 255.0f; - } - - glBegin(GL_TRIANGLE_FAN); - for (i = nv-1; i >= 0; i--) { - vertex * va = verts[i]; - float sx, sy, sz; - float tu, tv; - float rhw; - int a; - - if ( gr_zbuffering || (flags & TMAP_FLAG_NEBULA) ) { - sz = 1.0 - 1.0 / (1.0 + va->z / (32768.0 / 256.0)); - - if ( sz > 0.98f ) { - sz = 0.98f; - } - } else { - sz = 0.99f; - } - - if ( flags & TMAP_FLAG_CORRECT ) { - rhw = va->sw; - } else { - rhw = 1.0f; - } - - if (flags & TMAP_FLAG_ALPHA) { - a = verts[i]->a; - } else { - a = alpha; - } - - if (flags & TMAP_FLAG_NEBULA ) { - int pal = (verts[i]->b*(NEBULA_COLORS-1))/255; - r = gr_palette[pal*3+0]; - g = gr_palette[pal*3+1]; - b = gr_palette[pal*3+2]; - } else if ( (flags & TMAP_FLAG_RAMP) && (flags & TMAP_FLAG_GOURAUD) ) { - r = Gr_gamma_lookup[verts[i]->b]; - g = Gr_gamma_lookup[verts[i]->b]; - b = Gr_gamma_lookup[verts[i]->b]; - } else if ( (flags & TMAP_FLAG_RGB) && (flags & TMAP_FLAG_GOURAUD) ) { - // Make 0.75 be 256.0f - r = Gr_gamma_lookup[verts[i]->r]; - g = Gr_gamma_lookup[verts[i]->g]; - b = Gr_gamma_lookup[verts[i]->b]; - } else { - // use constant RGB values... - } - glColor4ub (r,g,b,a); - - if((gr_screen.current_fog_mode != GR_FOGMODE_NONE) && (D3D_fog_mode == 1)){ - float f_val; - - gr_opengl_stuff_fog_value(va->z, &f_val); - - glSecondaryColor3fEXT(fr * f_val, fg * f_val, fb * f_val); - } - - int x, y; - x = fl2i(va->sx*16.0f); - y = fl2i(va->sy*16.0f); - - x += gr_screen.offset_x*16; - y += gr_screen.offset_y*16; - - sx = i2fl(x) / 16.0f; - sy = i2fl(y) / 16.0f; - - if ( flags & TMAP_FLAG_TEXTURED ) { - tu = va->u*u_scale; - tv = va->v*v_scale; - glTexCoord2f(tu, tv); - } - - glVertex4f(sx/rhw, sy/rhw, -sz/rhw, 1.0/rhw); - } - glEnd(); -} - -void gr_opengl_tmapper( int nverts, vertex **verts, uint flags ) -{ - gr_opengl_tmapper_internal( nverts, verts, flags, 0 ); -} - -#define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0)) - -void gr_opengl_scaler(vertex *va, vertex *vb ) -{ - float x0, y0, x1, y1; - float u0, v0, u1, v1; - float clipped_x0, clipped_y0, clipped_x1, clipped_y1; - float clipped_u0, clipped_v0, clipped_u1, clipped_v1; - float xmin, xmax, ymin, ymax; - int dx0, dy0, dx1, dy1; - - //============= CLIP IT ===================== - - x0 = va->sx; y0 = va->sy; - x1 = vb->sx; y1 = vb->sy; - - xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top); - xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom); - - u0 = va->u; v0 = va->v; - u1 = vb->u; v1 = vb->v; - - // Check for obviously offscreen bitmaps... - if ( (y1<=y0) || (x1<=x0) ) return; - if ( (x1xmax) ) return; - if ( (y1ymax) ) return; - - clipped_u0 = u0; clipped_v0 = v0; - clipped_u1 = u1; clipped_v1 = v1; - - clipped_x0 = x0; clipped_y0 = y0; - clipped_x1 = x1; clipped_y1 = y1; - - // Clip the left, moving u0 right as necessary - if ( x0 < xmin ) { - clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1); - clipped_x0 = xmin; - } - - // Clip the right, moving u1 left as necessary - if ( x1 > xmax ) { - clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1); - clipped_x1 = xmax; - } - - // Clip the top, moving v0 down as necessary - if ( y0 < ymin ) { - clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1); - clipped_y0 = ymin; - } - - // Clip the bottom, moving v1 up as necessary - if ( y1 > ymax ) { - clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1); - clipped_y1 = ymax; - } - - dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1); - dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1); - - if (dx1<=dx0) return; - if (dy1<=dy0) return; - - //============= DRAW IT ===================== - - vertex v[4]; - vertex *vl[4]; - - vl[0] = &v[0]; - v[0].sx = clipped_x0; - v[0].sy = clipped_y0; - v[0].sw = va->sw; - v[0].z = va->z; - v[0].u = clipped_u0; - v[0].v = clipped_v0; - - vl[1] = &v[1]; - v[1].sx = clipped_x1; - v[1].sy = clipped_y0; - v[1].sw = va->sw; - v[1].z = va->z; - v[1].u = clipped_u1; - v[1].v = clipped_v0; - - vl[2] = &v[2]; - v[2].sx = clipped_x1; - v[2].sy = clipped_y1; - v[2].sw = va->sw; - v[2].z = va->z; - v[2].u = clipped_u1; - v[2].v = clipped_v1; - - vl[3] = &v[3]; - v[3].sx = clipped_x0; - v[3].sy = clipped_y1; - v[3].sw = va->sw; - v[3].z = va->z; - v[3].u = clipped_u0; - v[3].v = clipped_v1; - - gr_opengl_tmapper_internal( 4, vl, TMAP_FLAG_TEXTURED, 1 ); -} - -void gr_opengl_set_palette(ubyte *new_palette, int is_alphacolor) -{ -} - -void gr_opengl_get_color( int * r, int * g, int * b ) -{ - if (r) *r = gr_screen.current_color.red; - if (g) *g = gr_screen.current_color.green; - if (b) *b = gr_screen.current_color.blue; -} - -void gr_opengl_init_color(color *c, int r, int g, int b) -{ - c->screen_sig = gr_screen.signature; - c->red = (unsigned char)r; - c->green = (unsigned char)g; - c->blue = (unsigned char)b; - c->alpha = 255; - c->ac_type = AC_TYPE_NONE; - c->alphacolor = -1; - c->is_alphacolor = 0; - c->magic = 0xAC01; -} - -void gr_opengl_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type ) -{ - if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255; - if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255; - if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255; - if ( alpha < 0 ) alpha = 0; else if ( alpha > 255 ) alpha = 255; - - gr_opengl_init_color( clr, r, g, b ); - - clr->alpha = (unsigned char)alpha; - clr->ac_type = (ubyte)type; - clr->alphacolor = -1; - clr->is_alphacolor = 1; -} - -void gr_opengl_set_color( int r, int g, int b ) -{ - SDL_assert((r >= 0) && (r < 256)); - SDL_assert((g >= 0) && (g < 256)); - SDL_assert((b >= 0) && (b < 256)); - - gr_opengl_init_color( &gr_screen.current_color, r, g, b ); -} - -void gr_opengl_set_color_fast(color *dst) -{ - if ( dst->screen_sig != gr_screen.signature ) { - if ( dst->is_alphacolor ) { - gr_opengl_init_alphacolor( dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type ); - } else { - gr_opengl_init_color( dst, dst->red, dst->green, dst->blue ); - } - } - gr_screen.current_color = *dst; -} - -void gr_opengl_print_screen(const char *filename) -{ - char tmp[MAX_FILENAME_LEN]; - ubyte *buf = NULL; - - strcpy( tmp, filename ); - strcat( tmp, NOX(".tga")); - - buf = (ubyte*)malloc(GL_viewport_w * GL_viewport_h * 3); - - if (buf == NULL) { - return; - } - - CFILE *f = cfopen(tmp, "wb", CFILE_NORMAL, CF_TYPE_ROOT); - - if (f == NULL) { - free(buf); - return; - } - - // Write the TGA header - cfwrite_ubyte( 0, f ); // IDLength; - cfwrite_ubyte( 0, f ); // ColorMapType; - cfwrite_ubyte( 2, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed - cfwrite_ushort( 0, f ); // CMapStart; - cfwrite_ushort( 0, f ); // CMapLength; - cfwrite_ubyte( 0, f ); // CMapDepth; - cfwrite_ushort( 0, f ); // XOffset; - cfwrite_ushort( 0, f ); // YOffset; - cfwrite_ushort( (ushort)GL_viewport_w, f ); // Width; - cfwrite_ushort( (ushort)GL_viewport_h, f ); // Height; - cfwrite_ubyte( 24, f ); //PixelDepth; - cfwrite_ubyte( 0, f ); //ImageDesc; - - memset(buf, 0, GL_viewport_w * GL_viewport_h * 3); - - glReadPixels(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h, GL_BGR, GL_UNSIGNED_BYTE, buf); - - cfwrite(buf, GL_viewport_w * GL_viewport_h * 3, 1, f); - - cfclose(f); - - free(buf); -} - -int gr_opengl_supports_res_ingame(int res) -{ - return 1; -} - -int gr_opengl_supports_res_interface(int res) -{ - return 1; -} - -static void opengl_tcache_cleanup (); - -void gr_opengl_cleanup() -{ - if ( !Inited ) return; - - - gr_reset_clip(); - gr_clear(); - gr_flip(); - - opengl_tcache_cleanup (); - - SDL_GL_DeleteContext(GL_context); - - Inited = 0; -} - -void gr_opengl_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far) -{ - SDL_assert((r >= 0) && (r < 256)); - SDL_assert((g >= 0) && (g < 256)); - SDL_assert((b >= 0) && (b < 256)); - - if (fog_mode == GR_FOGMODE_NONE) { - if (gr_screen.current_fog_mode != fog_mode) { - glDisable(GL_FOG); - - if (D3D_fog_mode == 1) { - glDisable(GL_COLOR_SUM); - } - } - - gr_screen.current_fog_mode = fog_mode; - - return; - } - - if (gr_screen.current_fog_mode != fog_mode) { - glEnable(GL_FOG); - - if (D3D_fog_mode == 1) { - glEnable(GL_COLOR_SUM); - } else if (D3D_fog_mode == 2) { - glFogi(GL_FOG_MODE, GL_LINEAR); - } - - gr_screen.current_fog_mode = fog_mode; - } - - if ( (gr_screen.current_fog_color.red != r) || - (gr_screen.current_fog_color.green != g) || - (gr_screen.current_fog_color.blue != b) ) { - GLfloat fc[4]; - - gr_opengl_init_color( &gr_screen.current_fog_color, r, g, b ); - - fc[0] = (float)r/255.0; - fc[1] = (float)g/255.0; - fc[2] = (float)b/255.0; - fc[3] = 1.0; - - glFogfv(GL_FOG_COLOR, fc); - } - - if( (fog_near >= 0.0f) && (fog_far >= 0.0f) && - ((fog_near != gr_screen.fog_near) || - (fog_far != gr_screen.fog_far)) ) { - gr_screen.fog_near = fog_near; - gr_screen.fog_far = fog_far; - - if (D3D_fog_mode == 2) { - glFogf(GL_FOG_START, fog_near); - glFogf(GL_FOG_END, fog_far); - } - } -} - -void gr_opengl_get_pixel(int x, int y, int *r, int *g, int *b) -{ - // Not used. -} - -void gr_opengl_set_cull(int cull) -{ - if (cull) { - glEnable (GL_CULL_FACE); - glFrontFace (GL_CCW); - } else { - glDisable (GL_CULL_FACE); - } -} - -void gr_opengl_filter_set(int filter) -{ -} - -// cross fade -void gr_opengl_cross_fade(int bmap1, int bmap2, int x1, int y1, int x2, int y2, float pct) -{ - gr_set_bitmap(bmap1, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 1.0f - pct ); - gr_bitmap(x1, y1); - - gr_set_bitmap(bmap2, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, pct ); - gr_bitmap(x2, y2); -} - - -typedef struct tcache_slot_opengl { - GLuint texture_handle; - float u_scale, v_scale; - int bitmap_id; - int size; - int used_this_frame; - int time_created; - ushort w,h; - - // sections - tcache_slot_opengl *data_sections[MAX_BMAP_SECTIONS_X][MAX_BMAP_SECTIONS_Y]; - tcache_slot_opengl *parent; - - gr_texture_source texture_mode; -} tcache_slot_opengl; - -static void *Texture_sections = NULL; -static tcache_slot_opengl *Textures = NULL; - -static tcache_slot_opengl *GL_bound_texture; - -int GL_texture_sections = 0; -int GL_texture_ram = 0; -int GL_frame_count = 0; -int GL_min_texture_width = 0; -int GL_max_texture_width = 0; -int GL_min_texture_height = 0; -int GL_max_texture_height = 0; -int GL_square_textures = 0; -int GL_textures_in = 0; -int GL_textures_in_frame = 0; -int GL_last_bitmap_id = -1; -int GL_last_detail = -1; -int GL_last_bitmap_type = -1; -int GL_last_section_x = -1; -int GL_last_section_y = -1; - -int vram_full = 0; - -static gr_texture_source GL_current_texture_source = (gr_texture_source) -1; - -static void gr_opengl_set_texture_state(gr_texture_source ts) -{ - if (ts == TEXTURE_SOURCE_NONE) { - GL_bound_texture = NULL; - - glBindTexture(GL_TEXTURE_2D, 0); - gr_tcache_set(-1, -1, NULL, NULL, 0, -1, -1, 0 ); - } else if (GL_bound_texture && - GL_bound_texture->texture_mode != ts) { - switch (ts) { - case TEXTURE_SOURCE_DECAL: - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - case TEXTURE_SOURCE_NO_FILTERING: - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - default: - break; - } - - GL_bound_texture->texture_mode = ts; - } - - GL_current_texture_source = ts; -} - -static int opengl_max_tex_size_get() -{ - GLint max_texture_size = 0; - - glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max_texture_size ); - return max_texture_size; -} - -static void opengl_tcache_init (int use_sections) -{ - int i, idx, s_idx; - - // DDOI - FIXME skipped a lot of stuff here - GL_should_preload = 0; - - //uint tmp_pl = os_config_read_uint( NULL, NOX("D3DPreloadTextures"), 255 ); - uint tmp_pl = 1; - - if ( tmp_pl == 0 ) { - GL_should_preload = 0; - } else if ( tmp_pl == 1 ) { - GL_should_preload = 1; - } else { - GL_should_preload = 1; - } - - STUB_FUNCTION; - - GL_min_texture_width = 16; - GL_min_texture_height = 16; - - GL_max_texture_width = opengl_max_tex_size_get(); - GL_max_texture_height = opengl_max_tex_size_get(); - - Textures = (tcache_slot_opengl *)malloc(MAX_BITMAPS*sizeof(tcache_slot_opengl)); - if ( !Textures ) { - exit(1); - } - - if(use_sections){ - Texture_sections = (tcache_slot_opengl*)malloc(MAX_BITMAPS * MAX_BMAP_SECTIONS_X * MAX_BMAP_SECTIONS_Y * sizeof(tcache_slot_opengl)); - if(!Texture_sections){ - exit(1); - } - memset(Texture_sections, 0, MAX_BITMAPS * MAX_BMAP_SECTIONS_X * MAX_BMAP_SECTIONS_Y * sizeof(tcache_slot_opengl)); - } - - // Init the texture structures - int section_count = 0; - for( i=0; iparent = &Textures[i]; - /* - Textures[i].data_sections[idx][s_idx]->vram_texture = NULL; - Textures[i].data_sections[idx][s_idx]->vram_texture_surface = NULL; - */ - Textures[i].data_sections[idx][s_idx]->texture_handle = 0; - Textures[i].data_sections[idx][s_idx]->bitmap_id = -1; - Textures[i].data_sections[idx][s_idx]->size = 0; - Textures[i].data_sections[idx][s_idx]->used_this_frame = 0; - } - } - } else { - for(idx=0; idxused_this_frame = 0; - } - } - } - } - } - } - */ - - if ( vram_full ) { - opengl_tcache_flush(); - vram_full = 0; - } -} - -static int opengl_free_texture ( tcache_slot_opengl *t ) -{ - int idx, s_idx; - - - // Bitmap changed!! - if ( t->bitmap_id > -1 ) { - // if I, or any of my children have been used this frame, bail - if(t->used_this_frame == GL_frame_count){ - return 0; - } - for(idx=0; idxdata_sections[idx][s_idx] != NULL) && (t->data_sections[idx][s_idx]->used_this_frame == GL_frame_count)){ - return 0; - } - } - } - - // ok, now we know its legal to free everything safely - t->texture_mode = (gr_texture_source) -1; - glDeleteTextures (1, &t->texture_handle); - t->texture_handle = 0; - - if ( GL_last_bitmap_id == t->bitmap_id ) { - GL_last_bitmap_id = -1; - } - - // if this guy has children, free them too, since the children - // actually make up his size - for(idx=0; idxdata_sections[idx][s_idx] != NULL){ - opengl_free_texture(t->data_sections[idx][s_idx]); - } - } - } - - t->bitmap_id = -1; - t->used_this_frame = 0; - GL_textures_in -= t->size; - t->size = 0; - } - - return 1; -} - -static void opengl_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out) -{ - int tex_w, tex_h; - int i; - - // bogus - if((w_out == NULL) || (h_out == NULL)){ - return; - } - - // starting size - tex_w = w_in; - tex_h = h_in; - - // set height and width to a power of 2 - for (i=0; i<16; i++ ) { - if ( (tex_w > (1< (1< 8) - tex_h = tex_w/8; - if (tex_h/tex_w > 8) - tex_w = tex_h/8; - - if ( tex_w < GL_min_texture_width ) { - tex_w = GL_min_texture_width; - } else if ( tex_w > GL_max_texture_width ) { - tex_w = GL_max_texture_width; - } - - if ( tex_h < GL_min_texture_height ) { - tex_h = GL_min_texture_height; - } else if ( tex_h > GL_max_texture_height ) { - tex_h = GL_max_texture_height; - } - - if ( GL_square_textures) { - int new_size; - // Make the both be equal to larger of the two - new_size = max(tex_w, tex_h); - tex_w = new_size; - tex_h = new_size; - } - - // store the outgoing size - *w_out = tex_w; - *h_out = tex_h; -} - -// data == start of bitmap data -// sx == x offset into bitmap -// sy == y offset into bitmap -// src_w == absolute width of section on source bitmap -// src_h == absolute height of section on source bitmap -// bmap_w == width of source bitmap -// bmap_h == height of source bitmap -// tex_w == width of final texture -// tex_h == height of final texture -static int opengl_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) -{ - int ret_val = 1; - int size; - int i, j; - ubyte *bmp_data = ((ubyte*)data); - ubyte *texmem = NULL, *texmemp; - - // bogus - if((t == NULL) || (bmp_data == NULL)){ - return 0; - } - - if ( t->used_this_frame == GL_frame_count ) { - mprintf(( "ARGHH!!! Texture already used this frame! Cannot free it!\n" )); - return 0; - } - if ( !reload ) { - // gah - if(!opengl_free_texture(t)){ - return 0; - } - } - - if ( bitmap_type == TCACHE_TYPE_AABITMAP ) { - t->u_scale = (float)bmap_w / (float)tex_w; - t->v_scale = (float)bmap_h / (float)tex_h; - } else if(bitmap_type == TCACHE_TYPE_BITMAP_SECTION){ - t->u_scale = (float)src_w / (float)tex_w; - t->v_scale = (float)src_h / (float)tex_h; - } else { - t->u_scale = 1.0f; - t->v_scale = 1.0f; - } - - if (!reload) { - glGenTextures (1, &t->texture_handle); - } - - if (t->texture_handle == 0) { - nprintf(("Error", "!!DEBUG!! t->texture_handle == 0")); - return 0; - } - - GL_bound_texture = t; - - GL_bound_texture->texture_mode = (gr_texture_source) -1; - - glBindTexture (GL_TEXTURE_2D, t->texture_handle); - - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - /* this should be set next anyway */ -// if (GL_current_texture_source != TEXTURE_SOURCE_NONE) { -// gr_opengl_set_texture_state(GL_current_texture_source); -// } - - size = 0; - - switch (bitmap_type) { - - case TCACHE_TYPE_AABITMAP: - { - texmem = (ubyte *) malloc (tex_w*tex_h); - texmemp = texmem; - - for (i=0;ibitmap_id = texture_handle; - t->time_created = GL_frame_count; - t->used_this_frame = 0; - t->size = size; - t->w = (ushort)tex_w; - t->h = (ushort)tex_h; - - GL_textures_in_frame += t->size; - if (!reload) { - GL_textures_in += t->size; - } - - return ret_val; -} - -static int opengl_create_texture (int bitmap_handle, int bitmap_type, tcache_slot_opengl *tslot, int fail_on_full) -{ - ubyte flags; - bitmap *bmp; - int final_w, final_h; - ubyte bpp = 16; - int reload = 0; - int resize = 0; - - // setup texture/bitmap flags - flags = 0; - switch(bitmap_type){ - case TCACHE_TYPE_AABITMAP: - flags |= BMP_AABITMAP; - bpp = 8; - break; - case TCACHE_TYPE_NORMAL: - flags |= BMP_TEX_OTHER; - case TCACHE_TYPE_XPARENT: - flags |= BMP_TEX_XPARENT; - break; - case TCACHE_TYPE_NONDARKENING: - Int3(); - flags |= BMP_TEX_NONDARK; - break; - } - - // lock the bitmap into the proper format - bmp = bm_lock(bitmap_handle, bpp, flags); - if ( bmp == NULL ) { - mprintf(("Couldn't lock bitmap %d.\n", bitmap_handle )); - return 0; - } - - int max_w = bmp->w; - int max_h = bmp->h; - - - // DDOI - TODO - if ( bitmap_type != TCACHE_TYPE_AABITMAP ) { - // max_w /= D3D_texture_divider; - // max_h /= D3D_texture_divider; - - // if we are going to cull the size then we need to force a resize - if (Detail.hardware_textures < 4) { - resize = 1; - } - - // Detail.debris_culling goes from 0 to 4. - max_w /= (16 >> Detail.hardware_textures); - max_h /= (16 >> Detail.hardware_textures); - } - - - // get final texture size as it will be allocated as a DD surface - opengl_tcache_get_adjusted_texture_size(max_w, max_h, &final_w, &final_h); - - if ( (final_w < 1) || (final_h < 1) ) { - mprintf(("Bitmap is too small at %dx%d.\n", final_w, final_h)); - return 0; - } - - // if we don't have to resize the image (to get power of 2, etc.) then skip that extra work - if ( (max_w != final_w) || (max_h != final_h) ) { - resize = 1; - } - - // if this tcache slot has no bitmap - if ( tslot->bitmap_id < 0) { - reload = 0; - } - // different bitmap altogether - determine if the new one can use the old one's slot - else if (tslot->bitmap_id != bitmap_handle) { - if((final_w == tslot->w) && (final_h == tslot->h)){ - reload = 1; - //ml_printf("Reloading texture %d\n", bitmap_handle); - } else { - reload = 0; - } - } - - // call the helper - int ret_val = opengl_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); - - // unlock the bitmap - bm_unlock(bitmap_handle); - - return ret_val; -} - -static int opengl_create_texture_sectioned(int bitmap_handle, int bitmap_type, tcache_slot_opengl *tslot, int sx, int sy, int fail_on_full) -{ - ubyte flags; - bitmap *bmp; - int final_w, final_h; - int section_x, section_y; - int reload = 0; - int resize = 1; - - // setup texture/bitmap flags - SDL_assert(bitmap_type == TCACHE_TYPE_BITMAP_SECTION); - if(bitmap_type != TCACHE_TYPE_BITMAP_SECTION){ - bitmap_type = TCACHE_TYPE_BITMAP_SECTION; - } - flags = BMP_TEX_XPARENT; - - // lock the bitmap in the proper format - bmp = bm_lock(bitmap_handle, 16, flags); - if ( bmp == NULL ) { - mprintf(("Couldn't lock bitmap %d.\n", bitmap_handle )); - return 0; - } - // determine the width and height of this section - bm_get_section_size(bitmap_handle, sx, sy, §ion_x, §ion_y); - - // get final texture size as it will be allocated as an opengl texture - opengl_tcache_get_adjusted_texture_size(section_x, section_y, &final_w, &final_h); - - if ( (final_w < 1) || (final_h < 1) ) { - mprintf(("Bitmap is too small at %dx%d.\n", final_w, final_h)); - return 0; - } - - // if we don't have to resize the image (to get power of 2, etc.) then skip that extra work - if ( (bmp->sections.num_x == 1) && (bmp->sections.num_y == 1) && (section_x == final_w) && (section_y == final_h) ) { - resize = 0; - } - - // if this tcache slot has no bitmap - if ( tslot->bitmap_id < 0) { - reload = 0; - } - // different bitmap altogether - determine if the new one can use the old one's slot - else if (tslot->bitmap_id != bitmap_handle) { - if((final_w == tslot->w) && (final_h == tslot->h)){ - reload = 1; - } else { - reload = 0; - } - } - - // call the helper - int ret_val = opengl_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); - - // unlock the bitmap - bm_unlock(bitmap_handle); - - return ret_val; -} - - -extern int bm_get_cache_slot( int bitmap_id, int separate_ani_frames ); -static int gr_opengl_tcache_set(int bitmap_id, int bitmap_type, float *u_scale, float *v_scale, int fail_on_full = 0, int sx = -1, int sy = -1, int force = 0) -{ - bitmap *bmp = NULL; - - int idx, s_idx; - int ret_val = 1; - - if (bitmap_id < 0) - { - GL_last_bitmap_id = -1; - return 0; - } - - if ( GL_last_detail != Detail.hardware_textures ) { - GL_last_detail = Detail.hardware_textures; - opengl_tcache_flush(); - } - - if (vram_full) { - return 0; - } - - int n = bm_get_cache_slot (bitmap_id, 1); - tcache_slot_opengl *t = &Textures[n]; - - 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)) { - t->used_this_frame = GL_frame_count; - - // mark all children as used - if(GL_texture_sections){ - for(idx=0; idxdata_sections[idx][s_idx] != NULL){ - t->data_sections[idx][s_idx]->used_this_frame = GL_frame_count; - } - } - } - } - - *u_scale = t->u_scale; - *v_scale = t->v_scale; - return 1; - } - - if (bitmap_type == TCACHE_TYPE_BITMAP_SECTION){ - SDL_assert((sx >= 0) && (sy >= 0) && (sx < MAX_BMAP_SECTIONS_X) && (sy < MAX_BMAP_SECTIONS_Y)); - if(!((sx >= 0) && (sy >= 0) && (sx < MAX_BMAP_SECTIONS_X) && (sy < MAX_BMAP_SECTIONS_Y))){ - return 0; - } - - ret_val = 1; - - // if the texture sections haven't been created yet - if((t->bitmap_id < 0) || (t->bitmap_id != bitmap_id)){ - - // lock the bitmap in the proper format - bmp = bm_lock(bitmap_id, 16, BMP_TEX_XPARENT); - bm_unlock(bitmap_id); - - // now lets do something for each texture - - for(idx=0; idxsections.num_x; idx++){ - for(s_idx=0; s_idxsections.num_y; s_idx++){ - // hmm. i'd rather we didn't have to do it this way... - if(!opengl_create_texture_sectioned(bitmap_id, bitmap_type, t->data_sections[idx][s_idx], idx, s_idx, fail_on_full)){ - ret_val = 0; - } - - // not used this frame - t->data_sections[idx][s_idx]->used_this_frame = 0; - } - } - - // zero out pretty much everything in the parent struct since he's just the root - t->bitmap_id = bitmap_id; - t->texture_handle = 0; - t->time_created = t->data_sections[sx][sy]->time_created; - t->used_this_frame = 0; - /* - t->vram_texture = NULL; - t->vram_texture_surface = NULL - */ - } - - // argh. we failed to upload. free anything we can - if(!ret_val){ - opengl_free_texture(t); - } - // swap in the texture we want - else { - t = t->data_sections[sx][sy]; - } - } - // all other "normal" textures - else if((bitmap_id < 0) || (bitmap_id != t->bitmap_id)){ - ret_val = opengl_create_texture( bitmap_id, bitmap_type, t, fail_on_full ); - } - - // everything went ok - if(ret_val && (t->texture_handle) && !vram_full){ - *u_scale = t->u_scale; - *v_scale = t->v_scale; - - GL_bound_texture = t; - - glBindTexture (GL_TEXTURE_2D, t->texture_handle ); - - /* this should be set next anyway */ -// if (GL_current_texture_source != TEXTURE_SOURCE_NONE) { -// gr_opengl_set_texture_state(GL_current_texture_source); -// } - - GL_last_bitmap_id = t->bitmap_id; - GL_last_bitmap_type = bitmap_type; - GL_last_section_x = sx; - GL_last_section_y = sy; - - t->used_this_frame = GL_frame_count; - } - // gah - else { - GL_last_bitmap_id = -1; - GL_last_bitmap_type = -1; - - GL_last_section_x = -1; - GL_last_section_y = -1; - - GL_bound_texture = NULL; - - glBindTexture (GL_TEXTURE_2D, 0); // test - DDOI - return 0; - } - - return 1; -} - -void gr_opengl_set_clear_color(int r, int g, int b) -{ - gr_init_color (&gr_screen.current_clear_color, r, g, b); -} - -void gr_opengl_flash(int r, int g, int b) -{ - CAP(r,0,255); - CAP(g,0,255); - CAP(b,0,255); - - if ( r || g || b ) { - gr_opengl_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_ADDITIVE, ZBUFFER_TYPE_NONE ); - - float x1, x2, y1, y2; - x1 = i2fl(gr_screen.clip_left+gr_screen.offset_x); - y1 = i2fl(gr_screen.clip_top+gr_screen.offset_y); - x2 = i2fl(gr_screen.clip_right+gr_screen.offset_x); - y2 = i2fl(gr_screen.clip_bottom+gr_screen.offset_y); - - glColor4ub(r, g, b, 255); - glBegin (GL_QUADS); - glVertex3f (x1, y2, -0.99); - - glVertex3f (x2, y2, -0.99); - - glVertex3f (x2, y1, -0.99); - - glVertex3f (x1, y1, -0.99); - glEnd (); - } -} - -int gr_opengl_zbuffer_get() -{ - if ( !gr_global_zbuffering ) { - return GR_ZBUFF_NONE; - } - return gr_zbuffering_mode; -} - -int gr_opengl_zbuffer_set(int mode) -{ - int tmp = gr_zbuffering_mode; - - gr_zbuffering_mode = mode; - - if (gr_zbuffering_mode == GR_ZBUFF_NONE ) { - gr_zbuffering = 0; - } else { - gr_zbuffering = 1; - } - return tmp; -} - -void gr_opengl_zbuffer_clear(int mode) -{ - if (mode) { - gr_zbuffering = 1; - gr_zbuffering_mode = GR_ZBUFF_FULL; - gr_global_zbuffering = 1; - - gr_opengl_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_NONE, ZBUFFER_TYPE_FULL ); - glClear ( GL_DEPTH_BUFFER_BIT ); - } else { - gr_zbuffering = 0; - gr_zbuffering_mode = GR_ZBUFF_NONE; - gr_global_zbuffering = 0; - } -} - -void gr_opengl_set_gamma(float gamma) -{ - Gr_gamma = gamma; - Gr_gamma_int = int (Gr_gamma*10); - - // Create the Gamma lookup table - int i; - for (i=0;i<256; i++) { - int v = fl2i(pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f); - if ( v > 255 ) { - v = 255; - } else if ( v < 0 ) { - v = 0; - } - Gr_gamma_lookup[i] = v; - } - - // set the alpha gamma settings (for fonts) - for (i=0; i<16; i++) { - GL_xlat[i] = (ubyte)Gr_gamma_lookup[(i*255)/15]; - } - - GL_xlat[15] = GL_xlat[1]; - - for (; i<256; i++) { - GL_xlat[i] = GL_xlat[0]; - } - - // Flush any existing textures - opengl_tcache_flush(); -} - -void gr_opengl_fade_in(int instantaneous) -{ - // Empty - DDOI -} - -void gr_opengl_fade_out(int instantaneous) -{ - // Empty - DDOI -} - -void gr_opengl_get_region(int front, int w, int h, ubyte *data) -{ - if (front) { - glReadBuffer(GL_FRONT); - } else { - glReadBuffer(GL_BACK); - } - - gr_opengl_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE); - - glPixelStorei(GL_UNPACK_ROW_LENGTH, GL_viewport_w); - - int x = GL_viewport_x; - int y = (GL_viewport_y+GL_viewport_h)-h-1; - - if (gr_screen.bits_per_pixel == 15) { - glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, data); - } else if (gr_screen.bits_per_pixel == 32) { - glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data); - } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); -} - -void gr_opengl_save_mouse_area(int x, int y, int w, int h) -{ - int x1, y1, x2, y2; - - w = fl2i((w * GL_viewport_scale_w) + 0.5f); - h = fl2i((h * GL_viewport_scale_h) + 0.5f); - - x1 = x; - y1 = y; - x2 = x+w-1; - y2 = y+h-1; - - CLAMP(x1, 0, GL_viewport_w); - CLAMP(x2, 0, GL_viewport_w); - CLAMP(y1, 0, GL_viewport_h); - CLAMP(y2, 0, GL_viewport_h); - - Gr_opengl_mouse_saved_x = x1; - Gr_opengl_mouse_saved_y = y1; - Gr_opengl_mouse_saved_w = x2 - x1 + 1; - Gr_opengl_mouse_saved_h = y2 - y1 + 1; - - if ( (Gr_opengl_mouse_saved_w < 1) || (Gr_opengl_mouse_saved_h < 1) ) { - return; - } +#include "pstypes.h" +#include "osregistry.h" +#include "gropengl.h" +#include "gropengl1.h" +#include "gropengl2.h" +#include "gropenglinternal.h" +#include "2d.h" +#include "bmpman.h" +#include "grinternal.h" +#include "cmdline.h" +#include "mouse.h" - if (Gr_opengl_mouse_saved_data == NULL) { - Gr_opengl_mouse_saved_data = (ubyte*)malloc(w * h * gr_screen.bytes_per_pixel); - if ( !Gr_opengl_mouse_saved_data ) { - return; - } - } +bool OGL_inited = false; +int GL_version = 0; - gr_opengl_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE); +SDL_Window *GL_window = NULL; +SDL_GLContext GL_context; - x1 = GL_viewport_x+Gr_opengl_mouse_saved_x; - y1 = (GL_viewport_y+GL_viewport_h)-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h; +static int FSAA = 0; - glReadBuffer(GL_BACK); - glReadPixels(x1, y1, Gr_opengl_mouse_saved_w, Gr_opengl_mouse_saved_h, - GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, Gr_opengl_mouse_saved_data); +int GL_viewport_x = 0; +int GL_viewport_y = 0; +int GL_viewport_w = 640; +int GL_viewport_h = 480; +float GL_viewport_scale_w = 1.0f; +float GL_viewport_scale_h = 1.0f; +int GL_min_texture_width = 0; +int GL_max_texture_width = 0; +int GL_min_texture_height = 0; +int GL_max_texture_height = 0; - Gr_opengl_mouse_saved = 1; -} +rb_t *render_buffer = NULL; +static size_t render_buffer_size = 0; -int gr_opengl_save_screen() +void opengl_alloc_render_buffer(unsigned int nelems) { - gr_reset_clip(); - - if (Gr_saved_screen_tex) { - mprintf(( "Screen already saved!\n" )); - return -1; - } - - glGenTextures(1, &Gr_saved_screen_tex); - - if ( !Gr_saved_screen_tex ) { - mprintf(( "Couldn't create texture for saved screen!\n" )); - return -1; - } - - gr_opengl_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE); - - glBindTexture(GL_TEXTURE_2D, Gr_saved_screen_tex); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glReadBuffer(GL_FRONT); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, GL_viewport_x, GL_viewport_y, - GL_viewport_w, GL_viewport_h, 0); - - if (Gr_opengl_mouse_saved) { - int x = Gr_opengl_mouse_saved_x; - int y = GL_viewport_h-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h; - - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, Gr_opengl_mouse_saved_w, - Gr_opengl_mouse_saved_h, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, - Gr_opengl_mouse_saved_data); + if (nelems < 0) { + nelems = 1; } - glBindTexture(GL_TEXTURE_2D, 0); - - return 0; -} - -void gr_opengl_restore_screen(int id) -{ - gr_reset_clip(); - - if ( !Gr_saved_screen_tex ) { - gr_clear(); + if ( render_buffer && (nelems <= render_buffer_size) ) { return; } - glBindTexture(GL_TEXTURE_2D, Gr_saved_screen_tex); - - if (Gr_opengl_mouse_saved) { - int x = Gr_opengl_mouse_saved_x; - int y = GL_viewport_h-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h; - - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, Gr_opengl_mouse_saved_w, - Gr_opengl_mouse_saved_h, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, - Gr_opengl_mouse_saved_data); + if (render_buffer) { + free(render_buffer); } - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glScalef(1.0f, -1.0f, 1.0f); - - glBegin(GL_QUADS); - glTexCoord2i(0, 0); - glVertex2i(GL_viewport_x, GL_viewport_y); - - glTexCoord2i(0, 1); - glVertex2i(GL_viewport_x, GL_viewport_h); - - glTexCoord2i(1, 1); - glVertex2f(GL_viewport_w, GL_viewport_h); - - glTexCoord2i(1, 0); - glVertex2i(GL_viewport_w, GL_viewport_y); - glEnd(); - - glPopMatrix(); - - glBindTexture(GL_TEXTURE_2D, 0); + render_buffer = (rb_t*) malloc(sizeof(rb_t) * nelems); + render_buffer_size = nelems; +printf("render_buffer_size: %d\n", render_buffer_size); } -void gr_opengl_free_screen(int id) +void opengl_free_render_buffer() { - if (Gr_saved_screen_tex) { - glDeleteTextures(1, &Gr_saved_screen_tex); - Gr_saved_screen_tex = 0; + if (render_buffer) { + free(render_buffer); + render_buffer = NULL; + render_buffer_size = 0; } } -void gr_opengl_dump_frame_start(int first_frame, int frames_between_dumps) -{ - STUB_FUNCTION; -} - -void gr_opengl_dump_frame_stop() -{ - STUB_FUNCTION; -} - -void gr_opengl_dump_frame() -{ - STUB_FUNCTION; -} - -uint gr_opengl_lock() -{ - STUB_FUNCTION; - - return 1; -} - -void gr_opengl_unlock() -{ -} - - void gr_opengl_set_viewport(int width, int height) { int w, h, x, y; @@ -2996,37 +120,163 @@ void gr_opengl_force_fullscreen() SDL_SetWindowFullscreen(GL_window, flag); } -void opengl_zbias(int bias) +void gr_opengl_set_color_fast(color *dst) +{ + if ( dst->screen_sig != gr_screen.signature ) { + if ( dst->is_alphacolor ) { + gr_opengl_init_alphacolor( dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type ); + } else { + gr_opengl_init_color( dst, dst->red, dst->green, dst->blue ); + } + } + gr_screen.current_color = *dst; +} + +void gr_opengl_get_color( int * r, int * g, int * b ) +{ + if (r) *r = gr_screen.current_color.red; + if (g) *g = gr_screen.current_color.green; + if (b) *b = gr_screen.current_color.blue; +} + +void gr_opengl_init_color(color *c, int r, int g, int b) +{ + c->screen_sig = gr_screen.signature; + c->red = (unsigned char)r; + c->green = (unsigned char)g; + c->blue = (unsigned char)b; + c->alpha = 255; + c->ac_type = AC_TYPE_NONE; + c->alphacolor = -1; + c->is_alphacolor = 0; + c->magic = 0xAC01; +} + +void gr_opengl_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type ) +{ + if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255; + if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255; + if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255; + if ( alpha < 0 ) alpha = 0; else if ( alpha > 255 ) alpha = 255; + + gr_opengl_init_color( clr, r, g, b ); + + clr->alpha = (unsigned char)alpha; + clr->ac_type = (ubyte)type; + clr->alphacolor = -1; + clr->is_alphacolor = 1; +} + +void gr_opengl_set_color( int r, int g, int b ) +{ + SDL_assert((r >= 0) && (r < 256)); + SDL_assert((g >= 0) && (g < 256)); + SDL_assert((b >= 0) && (b < 256)); + + gr_opengl_init_color( &gr_screen.current_color, r, g, b ); +} + +void gr_opengl_set_clear_color(int r, int g, int b) +{ + gr_opengl_init_color(&gr_screen.current_clear_color, r, g, b); +} + +void gr_opengl_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha, int sx, int sy) +{ + gr_screen.current_alpha = alpha; + gr_screen.current_alphablend_mode = alphablend_mode; + gr_screen.current_bitblt_mode = bitblt_mode; + gr_screen.current_bitmap = bitmap_num; + + gr_screen.current_bitmap_sx = sx; + gr_screen.current_bitmap_sy = sy; +} + +void gr_opengl_create_shader(shader * shade, float r, float g, float b, float c ) +{ + shade->screen_sig = gr_screen.signature; + shade->r = r; + shade->g = g; + shade->b = b; + shade->c = c; +} + +void gr_opengl_set_shader( shader * shade ) +{ + if ( shade ) { + if (shade->screen_sig != gr_screen.signature) { + gr_create_shader( shade, shade->r, shade->g, shade->b, shade->c ); + } + gr_screen.current_shader = *shade; + } else { + gr_create_shader( &gr_screen.current_shader, 0.0f, 0.0f, 0.0f, 0.0f ); + } +} + +int gr_opengl_zbuffer_get() +{ + if ( !gr_global_zbuffering ) { + return GR_ZBUFF_NONE; + } + return gr_zbuffering_mode; +} + +int gr_opengl_zbuffer_set(int mode) { - if (bias) { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(0.0, -bias); + int tmp = gr_zbuffering_mode; + + gr_zbuffering_mode = mode; + + if (gr_zbuffering_mode == GR_ZBUFF_NONE ) { + gr_zbuffering = 0; } else { - glDisable(GL_POLYGON_OFFSET_FILL); + gr_zbuffering = 1; + } + return tmp; +} + +void opengl_set_variables() +{ + GL_min_texture_height = 16; + GL_min_texture_width = 16; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GL_max_texture_width); + GL_max_texture_height = GL_max_texture_width; + + // no texture is larger than 1024, so maybe don't use sections + if (GL_max_texture_width >= 1024) { + gr_screen.use_sections = 0; } } - -extern const char *Osreg_title; + +void gr_opengl_cleanup() +{ + opengl1_cleanup(); + + opengl_free_render_buffer(); +} + void gr_opengl_init() { - if ( Inited ) { + if ( OGL_inited ) { gr_opengl_cleanup(); - Inited = 0; + OGL_inited = false; } mprintf(( "Initializing OpenGL graphics device...\n" )); - Inited = 1; + + OGL_inited = true; if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { - fprintf (stderr, "Couldn't init SDL: %s", SDL_GetError()); - exit(1); + Error(LOCATION, "Couldn't init SDL: %s", SDL_GetError()); } - int r = 5, g = 5, b = 5, bpp = 16, db = 1; + int a = 1, r = 5, g = 5, b = 5, bpp = 16, db = 1; SDL_GL_SetAttribute(SDL_GL_RED_SIZE, r); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, g); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, b); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, a); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bpp); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, db); @@ -3042,46 +292,39 @@ void gr_opengl_init() gr_screen.max_w, gr_screen.max_h, SDL_WINDOW_OPENGL); if ( !GL_window ) { - fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError()); - exit(1); + Error(LOCATION, "Couldn't create window: %s\n", SDL_GetError()); } GL_context = SDL_GL_CreateContext(GL_window); + const char *gl_version = (const char*)glGetString(GL_VERSION); + int v_major = 0, v_minor = 0; + + sscanf(gl_version, "%d.%d", &v_major, &v_minor); + + GL_version = (v_major * 10) + v_minor; + + // version check, require 1.2+ for sake of simplicity + if (GL_version < 12) { + Error(LOCATION, "Minimum OpenGL version is 1.2!"); + } + mprintf((" Vendor : %s\n", glGetString(GL_VENDOR))); mprintf((" Renderer : %s\n", glGetString(GL_RENDERER))); - mprintf((" Version : %s\n", glGetString(GL_VERSION))); + mprintf((" Version : %s\n", gl_version)); - mprintf((" Attributes requested: RGB %d%d%d, BPP %d, DB %d, AA %d\n", r, g, b, bpp, db, FSAA)); + mprintf((" Attributes requested: ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA)); SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b); + SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a); SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &FSAA); - mprintf((" Attributes received: RGB %d%d%d, BPP %d, DB %d, AA %d\n", r, g, b, bpp, db, FSAA)); - - - D3D_32bit = 1; // grd3d.cpp - extern int D3D_enabled; - D3D_enabled = 1; - - /* - 1 = use secondary color ext - 2 = use opengl linear fog - */ - D3D_fog_mode = 2; // grd3d.cpp - - if ( SDL_GL_ExtensionSupported("GL_EXT_secondary_color") ) { - glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)SDL_GL_GetProcAddress("glSecondaryColor3fEXT"); - SDL_assert( glSecondaryColor3fEXT != NULL ); - D3D_fog_mode = 1; - mprintf((" Using extension: GL_EXT_secondary_color\n")); - } + mprintf((" Attributes received: ARGB %d%d%d%d, BPP %d, DB %d, AA %d\n", a, r, g, b, bpp, db, FSAA)); - mprintf(("\n")); SDL_ShowCursor(0); @@ -3100,94 +343,82 @@ void gr_opengl_init() SDL_SetWindowFullscreen(GL_window, flag); } - glShadeModel(GL_SMOOTH); - glEnable(GL_DITHER); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glHint(GL_FOG_HINT, GL_NICEST); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - - glEnable(GL_TEXTURE_2D); - - glDepthRange(0.0, 1.0); - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glFlush(); - - + // set up generic variables before further init() calls + opengl_set_variables(); + +// if (v_major >= 2) { +// opengl2_init(); +// } else { + opengl1_init(); +// } + + mprintf(("\n")); + Bm_pixel_format = BM_PIXEL_FORMAT_ARGB; Gr_bitmap_poly = 1; - bpp = 15; - switch( bpp ) { - case 15: - gr_screen.bits_per_pixel = 15; - gr_screen.bytes_per_pixel = 2; - - Gr_red.bits = 5; - Gr_red.shift = 10; - Gr_red.scale = 8; - Gr_red.mask = 0x7C00; - - Gr_green.bits = 5; - Gr_green.shift = 5; - Gr_green.scale = 8; - Gr_green.mask = 0x3E0; - - Gr_blue.bits = 5; - Gr_blue.shift = 0; - Gr_blue.scale = 8; - Gr_blue.mask = 0x1F; - - break; - - case 16: - gr_screen.bits_per_pixel = 16; - gr_screen.bytes_per_pixel = 2; - - Gr_red.bits = 5; - Gr_red.shift = 11; - Gr_red.scale = 8; - Gr_red.mask = 0xF800; - - Gr_green.bits = 6; - Gr_green.shift = 5; - Gr_green.scale = 4; - Gr_green.mask = 0x7E0; - - Gr_blue.bits = 5; - Gr_blue.shift = 0; - Gr_blue.scale = 8; - Gr_blue.mask = 0x1F; - - break; - - case 32: - gr_screen.bits_per_pixel = 32; - gr_screen.bytes_per_pixel = 4; - - Gr_red.bits = 8; - Gr_red.shift = 16; - Gr_red.scale = 1; - Gr_red.mask = 0xff0000; - - Gr_green.bits = 8; - Gr_green.shift = 8; - Gr_green.scale = 1; - Gr_green.mask = 0xff00; - - Gr_blue.bits = 8; - Gr_blue.shift = 0; - Gr_blue.scale = 1; - Gr_blue.mask = 0xff; - - break; - - default: - Int3(); // Illegal bpp + extern int D3D_enabled; + D3D_enabled = 1; + +bpp = 16; + switch (bpp) { + case 15: + case 16: + gr_screen.bits_per_pixel = 16; + gr_screen.bytes_per_pixel = 2; + + Gr_red.bits = 5; + Gr_red.shift = 10; + Gr_red.scale = 8; + Gr_red.mask = 0x7C00; + + Gr_green.bits = 5; + Gr_green.shift = 5; + Gr_green.scale = 8; + Gr_green.mask = 0x3E0; + + Gr_blue.bits = 5; + Gr_blue.shift = 0; + Gr_blue.scale = 8; + Gr_blue.mask = 0x1F; + + Gr_alpha.bits = 1; + Gr_alpha.shift = 15; + Gr_alpha.scale = 255; + Gr_alpha.mask = 0x8000; + + break; + + case 24: + case 32: + gr_screen.bits_per_pixel = 32; + gr_screen.bytes_per_pixel = 4; + + Gr_red.bits = 8; + Gr_red.shift = 16; + Gr_red.scale = 1; + Gr_red.mask = 0xff0000; + + Gr_green.bits = 8; + Gr_green.shift = 8; + Gr_green.scale = 1; + Gr_green.mask = 0xff00; + + Gr_blue.bits = 8; + Gr_blue.shift = 0; + Gr_blue.scale = 1; + Gr_blue.mask = 0xff; + + Gr_alpha.bits = 8; + Gr_alpha.shift = 24; + Gr_alpha.scale = 1; + Gr_alpha.mask = 0xff000000; + + break; + + default: + Int3(); // Illegal bpp + break; } // DDOI - set these so no one else does! @@ -3198,14 +429,14 @@ void gr_opengl_init() Gr_t_green.mask = Gr_green.mask; Gr_t_green.shift = Gr_green.shift; Gr_t_green.scale = Gr_green.scale; - + Gr_t_blue.mask = Gr_blue.mask; Gr_t_blue.shift = Gr_blue.shift; Gr_t_blue.scale = Gr_blue.scale; - - Gr_t_alpha.mask = 0x8000; - Gr_t_alpha.scale = 255; - Gr_t_alpha.shift = 15; + + Gr_t_alpha.mask = Gr_alpha.mask; + Gr_t_alpha.scale = Gr_alpha.scale; + Gr_t_alpha.shift = Gr_alpha.shift; Gr_ta_red.mask = 0x0f00; Gr_ta_red.shift = 8; @@ -3214,7 +445,7 @@ void gr_opengl_init() Gr_ta_green.mask = 0x00f0; Gr_ta_green.shift = 4; Gr_ta_green.scale = 16; - + Gr_ta_blue.mask = 0x000f; Gr_ta_blue.shift = 0; Gr_ta_blue.scale = 16; @@ -3223,91 +454,22 @@ void gr_opengl_init() Gr_ta_alpha.shift = 12; Gr_ta_alpha.scale = 16; - - opengl_tcache_init (1); - gr_opengl_clear(); - Gr_current_red = &Gr_red; Gr_current_blue = &Gr_blue; Gr_current_green = &Gr_green; Gr_current_alpha = &Gr_alpha; - gr_screen.gf_flip = gr_opengl_flip; - gr_screen.gf_flip_window = gr_opengl_flip_window; - gr_screen.gf_set_clip = gr_opengl_set_clip; - gr_screen.gf_reset_clip = gr_opengl_reset_clip; - gr_screen.gf_set_font = grx_set_font; - - gr_screen.gf_set_color = gr_opengl_set_color; - gr_screen.gf_set_bitmap = gr_opengl_set_bitmap; - gr_screen.gf_create_shader = gr_opengl_create_shader; - gr_screen.gf_set_shader = gr_opengl_set_shader; - gr_screen.gf_clear = gr_opengl_clear; - // gr_screen.gf_bitmap = gr_opengl_bitmap; - // gr_screen.gf_bitmap_ex = gr_opengl_bitmap_ex; - gr_screen.gf_aabitmap = gr_opengl_aabitmap; - gr_screen.gf_aabitmap_ex = gr_opengl_aabitmap_ex; - - gr_screen.gf_rect = gr_opengl_rect; - gr_screen.gf_shade = gr_opengl_shade; - gr_screen.gf_string = gr_opengl_string; - gr_screen.gf_circle = gr_opengl_circle; - - gr_screen.gf_line = gr_opengl_line; - gr_screen.gf_aaline = gr_opengl_aaline; - gr_screen.gf_pixel = gr_opengl_pixel; - gr_screen.gf_scaler = gr_opengl_scaler; - gr_screen.gf_tmapper = gr_opengl_tmapper; - - gr_screen.gf_gradient = gr_opengl_gradient; - - gr_screen.gf_set_palette = gr_opengl_set_palette; - gr_screen.gf_get_color = gr_opengl_get_color; - gr_screen.gf_init_color = gr_opengl_init_color; - gr_screen.gf_init_alphacolor = gr_opengl_init_alphacolor; - gr_screen.gf_set_color_fast = gr_opengl_set_color_fast; - gr_screen.gf_print_screen = gr_opengl_print_screen; - - gr_screen.gf_fade_in = gr_opengl_fade_in; - gr_screen.gf_fade_out = gr_opengl_fade_out; - gr_screen.gf_flash = gr_opengl_flash; - - gr_screen.gf_zbuffer_get = gr_opengl_zbuffer_get; - gr_screen.gf_zbuffer_set = gr_opengl_zbuffer_set; - gr_screen.gf_zbuffer_clear = gr_opengl_zbuffer_clear; - - gr_screen.gf_save_screen = gr_opengl_save_screen; - gr_screen.gf_restore_screen = gr_opengl_restore_screen; - gr_screen.gf_free_screen = gr_opengl_free_screen; - - gr_screen.gf_dump_frame_start = gr_opengl_dump_frame_start; - gr_screen.gf_dump_frame_stop = gr_opengl_dump_frame_stop; - gr_screen.gf_dump_frame = gr_opengl_dump_frame; - - gr_screen.gf_set_gamma = gr_opengl_set_gamma; - - gr_screen.gf_lock = gr_opengl_lock; - gr_screen.gf_unlock = gr_opengl_unlock; - - gr_screen.gf_fog_set = gr_opengl_fog_set; - - gr_screen.gf_get_region = gr_opengl_get_region; - - gr_screen.gf_get_pixel = gr_opengl_get_pixel; - - gr_screen.gf_set_cull = gr_opengl_set_cull; - - gr_screen.gf_cross_fade = gr_opengl_cross_fade; - - gr_screen.gf_filter_set = gr_opengl_filter_set; - - gr_screen.gf_tcache_set = gr_opengl_tcache_set; - - gr_screen.gf_set_clear_color = gr_opengl_set_clear_color; - Mouse_hidden++; gr_reset_clip(); gr_clear(); gr_flip(); Mouse_hidden--; } + +int opengl_max_tex_size_get() +{ + GLint max_texture_size = 0; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + return max_texture_size; +} diff --git a/src/graphics/gropengl1.cpp b/src/graphics/gropengl1.cpp new file mode 100644 index 0000000..9519c1e --- /dev/null +++ b/src/graphics/gropengl1.cpp @@ -0,0 +1,763 @@ +/* + * Copyright (C) Volition, Inc. 1999. All rights reserved. + * + * All source code herein is the property of Volition, Inc. You may not sell + * or otherwise commercially exploit the source or things you created based on + * the source. + */ + +#include "gropengl.h" +#include "gropengl1.h" +#include "gropenglinternal.h" +#include "2d.h" +#include "mouse.h" +#include "pstypes.h" +#include "cfile.h" +#include "bmpman.h" +#include "grinternal.h" + + +int OGL_fog_mode = 0; + +static int Inited = 0; + + +volatile int GL_activate = 0; +volatile int GL_deactivate = 0; + +static GLuint Gr_saved_screen_tex = 0; + +static int Gr_opengl_mouse_saved = 0; +static int Gr_opengl_mouse_saved_x = 0; +static int Gr_opengl_mouse_saved_y = 0; +static int Gr_opengl_mouse_saved_w = 0; +static int Gr_opengl_mouse_saved_h = 0; +static ubyte *Gr_opengl_mouse_saved_data = NULL; + +#define CLAMP(x,r1,r2) do { if ( (x) < (r1) ) (x) = (r1); else if ((x) > (r2)) (x) = (r2); } while(0) + + +PFNGLSECONDARYCOLORPOINTEREXTPROC vglSecondaryColorPointerEXT = NULL; + + +static gr_alpha_blend GL_current_alpha_blend = (gr_alpha_blend) -1; +static gr_zbuffer_type GL_current_zbuffer_type = (gr_zbuffer_type) -1; + +void opengl1_set_state(gr_texture_source ts, gr_alpha_blend ab, gr_zbuffer_type zt) +{ + opengl1_set_texture_state(ts); + + if (ab != GL_current_alpha_blend) { + switch (ab) { + case ALPHA_BLEND_NONE: // 1*SrcPixel + 0*DestPixel + glBlendFunc(GL_ONE, GL_ZERO); + break; + case ALPHA_BLEND_ADDITIVE: // 1*SrcPixel + 1*DestPixel + glBlendFunc(GL_ONE, GL_ONE); + break; + case ALPHA_BLEND_ALPHA_ADDITIVE: // Alpha*SrcPixel + 1*DestPixel + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case ALPHA_BLEND_ALPHA_BLEND_ALPHA: // Alpha*SrcPixel + (1-Alpha)*DestPixel + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case ALPHA_BLEND_ALPHA_BLEND_SRC_COLOR: // Alpha*SrcPixel + (1-SrcPixel)*DestPixel + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR); + break; + default: + break; + } + + GL_current_alpha_blend = ab; + } + + if (zt != GL_current_zbuffer_type) { + switch (zt) { + case ZBUFFER_TYPE_NONE: + glDepthFunc(GL_ALWAYS); + glDepthMask(GL_FALSE); + break; + case ZBUFFER_TYPE_READ: + glDepthFunc(GL_LESS); + glDepthMask(GL_FALSE); + break; + case ZBUFFER_TYPE_WRITE: + glDepthFunc(GL_ALWAYS); + glDepthMask(GL_TRUE); + break; + case ZBUFFER_TYPE_FULL: + glDepthFunc(GL_LESS); + glDepthMask(GL_TRUE); + break; + default: + break; + } + + GL_current_zbuffer_type = zt; + } +} + +void gr_opengl1_activate(int active) +{ + if (active) { + GL_activate++; + + // don't grab key/mouse if cmdline says so or if we're fullscreen + // if(!Cmdline_no_grab && !(SDL_GetVideoSurface()->flags & SDL_FULLSCREEN)) { + // SDL_WM_GrabInput(SDL_GRAB_ON); + // } + } else { + GL_deactivate++; + + // let go of mouse/keyboard + // SDL_WM_GrabInput(SDL_GRAB_OFF); + } +} + +void gr_opengl1_clear() +{ + glClearColor(gr_screen.current_clear_color.red / 255.0, + gr_screen.current_clear_color.green / 255.0, + gr_screen.current_clear_color.blue / 255.0, 1.0); + + glClear ( GL_COLOR_BUFFER_BIT ); +} + +void gr_opengl1_flip() +{ + if (!Inited) return; + + gr_reset_clip(); + + mouse_eval_deltas(); + + Gr_opengl_mouse_saved = 0; + + if ( mouse_is_visible() ) { + int mx, my; + + gr_reset_clip(); + mouse_get_pos( &mx, &my ); + + gr_opengl1_save_mouse_area(mx,my,32,32); + + if (Gr_cursor == -1) { +#ifndef NDEBUG + gr_set_color(255,255,255); + gr_line(mx, my, mx+7, my + 7); + gr_line(mx, my, mx+5, my ); + gr_line(mx, my, mx, my+5); +#endif + } else { + gr_set_bitmap(Gr_cursor); + gr_bitmap(mx, my); + } + } + +#ifndef NDEBUG + GLenum error = GL_NO_ERROR; + int ic = 1; + do { + error = glGetError(); + + if (error != GL_NO_ERROR) { + nprintf(("Warning", "!!DEBUG!! OpenGL Error: %d (%d this frame)\n", error, ic)); + } + + ic++; + } while (error != GL_NO_ERROR); +#endif + + SDL_GL_SwapWindow(GL_window); + + opengl1_tcache_frame(); + + int cnt = GL_activate; + if ( cnt ) { + GL_activate-=cnt; + opengl1_tcache_flush(); + // gr_opengl_clip_cursor(1); /* mouse grab, see opengl_activate */ + } + + cnt = GL_deactivate; + if ( cnt ) { + GL_deactivate-=cnt; + // gr_opengl_clip_cursor(0); /* mouse grab, see opengl_activate */ + } +} + +void gr_opengl1_set_clip(int x,int y,int w,int h) +{ + // check for sanity of parameters + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + if (x >= gr_screen.max_w) + x = gr_screen.max_w - 1; + if (y >= gr_screen.max_h) + y = gr_screen.max_h - 1; + + if (x + w > gr_screen.max_w) + w = gr_screen.max_w - x; + if (y + h > gr_screen.max_h) + h = gr_screen.max_h - y; + + if (w > gr_screen.max_w) + w = gr_screen.max_w; + if (h > gr_screen.max_h) + h = gr_screen.max_h; + + gr_screen.offset_x = x; + gr_screen.offset_y = y; + gr_screen.clip_left = 0; + gr_screen.clip_right = w-1; + gr_screen.clip_top = 0; + gr_screen.clip_bottom = h-1; + gr_screen.clip_width = w; + gr_screen.clip_height = h; + + x = fl2i((x * GL_viewport_scale_w) + 0.5f) + GL_viewport_x; + y = fl2i((y * GL_viewport_scale_h) + 0.5f) + GL_viewport_y; + w = fl2i((w * GL_viewport_scale_w) + 0.5f); + h = fl2i((h * GL_viewport_scale_h) + 0.5f); + + glEnable(GL_SCISSOR_TEST); + glScissor(x, GL_viewport_h-y-h, w, h); +} + +void gr_opengl1_reset_clip() +{ + gr_screen.offset_x = 0; + gr_screen.offset_y = 0; + gr_screen.clip_left = 0; + gr_screen.clip_top = 0; + gr_screen.clip_right = gr_screen.max_w - 1; + gr_screen.clip_bottom = gr_screen.max_h - 1; + gr_screen.clip_width = gr_screen.max_w; + gr_screen.clip_height = gr_screen.max_h; + + glDisable(GL_SCISSOR_TEST); +// glScissor(0, 0, gr_screen.max_w, gr_screen.max_h); +} + + +void gr_opengl1_set_palette(ubyte *new_palette, int is_alphacolor) +{ +} + + +void gr_opengl1_print_screen(const char *filename) +{ + char tmp[MAX_FILENAME_LEN]; + ubyte *buf = NULL; + + strcpy( tmp, filename ); + strcat( tmp, NOX(".tga")); + + buf = (ubyte*)malloc(GL_viewport_w * GL_viewport_h * 3); + + if (buf == NULL) { + return; + } + + CFILE *f = cfopen(tmp, "wb", CFILE_NORMAL, CF_TYPE_ROOT); + + if (f == NULL) { + free(buf); + return; + } + + // Write the TGA header + cfwrite_ubyte( 0, f ); // IDLength; + cfwrite_ubyte( 0, f ); // ColorMapType; + cfwrite_ubyte( 2, f ); // ImageType; // 2 = 24bpp, uncompressed, 10=24bpp rle compressed + cfwrite_ushort( 0, f ); // CMapStart; + cfwrite_ushort( 0, f ); // CMapLength; + cfwrite_ubyte( 0, f ); // CMapDepth; + cfwrite_ushort( 0, f ); // XOffset; + cfwrite_ushort( 0, f ); // YOffset; + cfwrite_ushort( (ushort)GL_viewport_w, f ); // Width; + cfwrite_ushort( (ushort)GL_viewport_h, f ); // Height; + cfwrite_ubyte( 24, f ); //PixelDepth; + cfwrite_ubyte( 0, f ); //ImageDesc; + + memset(buf, 0, GL_viewport_w * GL_viewport_h * 3); + + glReadPixels(GL_viewport_x, GL_viewport_y, GL_viewport_w, GL_viewport_h, GL_BGR, GL_UNSIGNED_BYTE, buf); + + cfwrite(buf, GL_viewport_w * GL_viewport_h * 3, 1, f); + + cfclose(f); + + free(buf); +} + +int gr_opengl1_supports_res_ingame(int res) +{ + return 1; +} + +int gr_opengl1_supports_res_interface(int res) +{ + return 1; +} + +void opengl1_cleanup() +{ + if ( !Inited ) return; + + + gr_reset_clip(); + gr_clear(); + gr_flip(); + + opengl1_tcache_cleanup(); + + Inited = 0; +} + +void gr_opengl1_fog_set(int fog_mode, int r, int g, int b, float fog_near, float fog_far) +{ + Assert((r >= 0) && (r < 256)); + Assert((g >= 0) && (g < 256)); + Assert((b >= 0) && (b < 256)); + + if (fog_mode == GR_FOGMODE_NONE) { + if (gr_screen.current_fog_mode != fog_mode) { + glDisable(GL_FOG); + + if (OGL_fog_mode == 1) { + glDisable(GL_COLOR_SUM); + } + } + + gr_screen.current_fog_mode = fog_mode; + + return; + } + + if (gr_screen.current_fog_mode != fog_mode) { + glEnable(GL_FOG); + + if (OGL_fog_mode == 1) { + glEnable(GL_COLOR_SUM); + } else if (OGL_fog_mode == 2) { + glFogi(GL_FOG_MODE, GL_LINEAR); + } + + gr_screen.current_fog_mode = fog_mode; + } + + if ( (gr_screen.current_fog_color.red != r) || + (gr_screen.current_fog_color.green != g) || + (gr_screen.current_fog_color.blue != b) ) { + GLfloat fc[4]; + + gr_opengl_init_color( &gr_screen.current_fog_color, r, g, b ); + + fc[0] = (float)r/255.0; + fc[1] = (float)g/255.0; + fc[2] = (float)b/255.0; + fc[3] = 1.0; + + glFogfv(GL_FOG_COLOR, fc); + } + + if( (fog_near >= 0.0f) && (fog_far >= 0.0f) && + ((fog_near != gr_screen.fog_near) || + (fog_far != gr_screen.fog_far)) ) { + gr_screen.fog_near = fog_near; + gr_screen.fog_far = fog_far; + + if (OGL_fog_mode == 2) { + glFogf(GL_FOG_START, fog_near); + glFogf(GL_FOG_END, fog_far); + } + } +} + +void gr_opengl1_get_pixel(int x, int y, int *r, int *g, int *b) +{ + // Not used. +} + +void gr_opengl1_set_cull(int cull) +{ + if (cull) { + glEnable (GL_CULL_FACE); + glFrontFace (GL_CCW); + } else { + glDisable (GL_CULL_FACE); + } +} + +void gr_opengl1_filter_set(int filter) +{ +} + + +void gr_opengl1_zbuffer_clear(int mode) +{ + if (mode) { + gr_zbuffering = 1; + gr_zbuffering_mode = GR_ZBUFF_FULL; + gr_global_zbuffering = 1; + + opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_NONE, ZBUFFER_TYPE_FULL ); + glClear ( GL_DEPTH_BUFFER_BIT ); + } else { + gr_zbuffering = 0; + gr_zbuffering_mode = GR_ZBUFF_NONE; + gr_global_zbuffering = 0; + } +} + +void gr_opengl1_fade_in(int instantaneous) +{ + // Empty - DDOI +} + +void gr_opengl1_fade_out(int instantaneous) +{ + // Empty - DDOI +} + +void gr_opengl1_get_region(int front, int w, int h, ubyte *data) +{ + if (front) { + glReadBuffer(GL_FRONT); + } else { + glReadBuffer(GL_BACK); + } + + opengl1_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, GL_viewport_w); + + int x = GL_viewport_x; + int y = (GL_viewport_y+GL_viewport_h)-h-1; + + if (gr_screen.bytes_per_pixel == 2) { + glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, data); + } else if (gr_screen.bytes_per_pixel == 4) { + glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, data); + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); +} + +void gr_opengl1_save_mouse_area(int x, int y, int w, int h) +{ + int x1, y1, x2, y2; + + w = fl2i((w * GL_viewport_scale_w) + 0.5f); + h = fl2i((h * GL_viewport_scale_h) + 0.5f); + + x1 = x; + y1 = y; + x2 = x+w-1; + y2 = y+h-1; + + CLAMP(x1, 0, GL_viewport_w); + CLAMP(x2, 0, GL_viewport_w); + CLAMP(y1, 0, GL_viewport_h); + CLAMP(y2, 0, GL_viewport_h); + + Gr_opengl_mouse_saved_x = x1; + Gr_opengl_mouse_saved_y = y1; + Gr_opengl_mouse_saved_w = x2 - x1 + 1; + Gr_opengl_mouse_saved_h = y2 - y1 + 1; + + if ( (Gr_opengl_mouse_saved_w < 1) || (Gr_opengl_mouse_saved_h < 1) ) { + return; + } + + if (Gr_opengl_mouse_saved_data == NULL) { + Gr_opengl_mouse_saved_data = (ubyte*)malloc(w * h * gr_screen.bytes_per_pixel); + + if ( !Gr_opengl_mouse_saved_data ) { + return; + } + } + + opengl1_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE); + + x1 = GL_viewport_x+Gr_opengl_mouse_saved_x; + y1 = (GL_viewport_y+GL_viewport_h)-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h; + + glReadBuffer(GL_BACK); + glReadPixels(x1, y1, Gr_opengl_mouse_saved_w, Gr_opengl_mouse_saved_h, + GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, Gr_opengl_mouse_saved_data); + + Gr_opengl_mouse_saved = 1; +} + +int gr_opengl1_save_screen() +{ + gr_reset_clip(); + + if (Gr_saved_screen_tex) { + mprintf(( "Screen already saved!\n" )); + return -1; + } + + glGenTextures(1, &Gr_saved_screen_tex); + + if ( !Gr_saved_screen_tex ) { + mprintf(( "Couldn't create texture for saved screen!\n" )); + return -1; + } + + opengl1_set_state(TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_NONE, ZBUFFER_TYPE_NONE); + + glBindTexture(GL_TEXTURE_2D, Gr_saved_screen_tex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glReadBuffer(GL_FRONT); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_viewport_x, GL_viewport_y, + GL_viewport_w, GL_viewport_h, 0); + + if (Gr_opengl_mouse_saved) { + int x = Gr_opengl_mouse_saved_x; + int y = GL_viewport_h-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h; + + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, Gr_opengl_mouse_saved_w, + Gr_opengl_mouse_saved_h, GL_BGRA, GL_UNSIGNED_BYTE, + Gr_opengl_mouse_saved_data); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + return 0; +} + +void gr_opengl1_restore_screen(int id) +{ + gr_reset_clip(); + + if ( !Gr_saved_screen_tex ) { + gr_clear(); + return; + } + + glBindTexture(GL_TEXTURE_2D, Gr_saved_screen_tex); + + if (Gr_opengl_mouse_saved) { + int x = Gr_opengl_mouse_saved_x; + int y = GL_viewport_h-Gr_opengl_mouse_saved_y-Gr_opengl_mouse_saved_h; + + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, Gr_opengl_mouse_saved_w, + Gr_opengl_mouse_saved_h, GL_BGRA, GL_UNSIGNED_BYTE, + Gr_opengl_mouse_saved_data); + } + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glScalef(1.0f, -1.0f, 1.0f); + + int tex_coord[] = { 0, 0, 0, 1, 1, 1, 1, 0 }; + int ver_coord[] = { GL_viewport_x, GL_viewport_y, GL_viewport_x, + GL_viewport_h, GL_viewport_w, GL_viewport_h, GL_viewport_w, + GL_viewport_y + }; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + + glTexCoordPointer(2, GL_INT, 0, &tex_coord); + glVertexPointer(2, GL_INT, 0, &ver_coord); + + glDrawArrays(GL_QUADS, 0, 4); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +void gr_opengl1_free_screen(int id) +{ + if (Gr_saved_screen_tex) { + glDeleteTextures(1, &Gr_saved_screen_tex); + Gr_saved_screen_tex = 0; + } +} + +void gr_opengl1_dump_frame_start(int first_frame, int frames_between_dumps) +{ + STUB_FUNCTION; +} + +void gr_opengl1_dump_frame_stop() +{ + STUB_FUNCTION; +} + +void gr_opengl1_dump_frame() +{ + STUB_FUNCTION; +} + +uint gr_opengl1_lock() +{ + STUB_FUNCTION; + + return 1; +} + +void gr_opengl1_unlock() +{ +} + +void gr_opengl1_zbias(int bias) +{ + if (bias) { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0.0, -bias); + } else { + glDisable(GL_POLYGON_OFFSET_FILL); + } +} + +void opengl1_init_func_pointers() +{ + gr_screen.gf_flip = gr_opengl1_flip; + gr_screen.gf_set_clip = gr_opengl1_set_clip; + gr_screen.gf_reset_clip = gr_opengl1_reset_clip; + gr_screen.gf_set_font = grx_set_font; + + gr_screen.gf_set_color = gr_opengl_set_color; + gr_screen.gf_set_bitmap = gr_opengl_set_bitmap; + gr_screen.gf_create_shader = gr_opengl_create_shader; + gr_screen.gf_set_shader = gr_opengl_set_shader; + gr_screen.gf_clear = gr_opengl1_clear; + + gr_screen.gf_aabitmap = gr_opengl1_aabitmap; + gr_screen.gf_aabitmap_ex = gr_opengl1_aabitmap_ex; + + gr_screen.gf_rect = gr_opengl1_rect; + gr_screen.gf_shade = gr_opengl1_shade; + gr_screen.gf_string = gr_opengl1_string; + gr_screen.gf_circle = gr_opengl1_circle; + + gr_screen.gf_line = gr_opengl1_line; + gr_screen.gf_aaline = gr_opengl1_aaline; + gr_screen.gf_pixel = gr_opengl1_pixel; + gr_screen.gf_scaler = gr_opengl1_scaler; + gr_screen.gf_tmapper = gr_opengl1_tmapper; + + gr_screen.gf_gradient = gr_opengl1_gradient; + + gr_screen.gf_set_palette = gr_opengl1_set_palette; + gr_screen.gf_get_color = gr_opengl_get_color; + gr_screen.gf_init_color = gr_opengl_init_color; + gr_screen.gf_init_alphacolor = gr_opengl_init_alphacolor; + gr_screen.gf_set_color_fast = gr_opengl_set_color_fast; + gr_screen.gf_print_screen = gr_opengl1_print_screen; + + gr_screen.gf_fade_in = gr_opengl1_fade_in; + gr_screen.gf_fade_out = gr_opengl1_fade_out; + gr_screen.gf_flash = gr_opengl1_flash; + + gr_screen.gf_zbuffer_get = gr_opengl_zbuffer_get; + gr_screen.gf_zbuffer_set = gr_opengl_zbuffer_set; + gr_screen.gf_zbuffer_clear = gr_opengl1_zbuffer_clear; + + gr_screen.gf_save_screen = gr_opengl1_save_screen; + gr_screen.gf_restore_screen = gr_opengl1_restore_screen; + gr_screen.gf_free_screen = gr_opengl1_free_screen; + + gr_screen.gf_dump_frame_start = gr_opengl1_dump_frame_start; + gr_screen.gf_dump_frame_stop = gr_opengl1_dump_frame_stop; + gr_screen.gf_dump_frame = gr_opengl1_dump_frame; + + gr_screen.gf_set_gamma = gr_opengl1_set_gamma; + + gr_screen.gf_lock = gr_opengl1_lock; + gr_screen.gf_unlock = gr_opengl1_unlock; + + gr_screen.gf_fog_set = gr_opengl1_fog_set; + + gr_screen.gf_get_region = gr_opengl1_get_region; + + gr_screen.gf_get_pixel = gr_opengl1_get_pixel; + + gr_screen.gf_set_cull = gr_opengl1_set_cull; + + gr_screen.gf_cross_fade = gr_opengl1_cross_fade; + + gr_screen.gf_filter_set = gr_opengl1_filter_set; + + gr_screen.gf_set_clear_color = gr_opengl_set_clear_color; + + gr_screen.gf_preload_init = gr_opengl1_preload_init; + gr_screen.gf_preload = gr_opengl1_preload; + + gr_screen.gf_zbias = gr_opengl1_zbias; + + gr_screen.gf_force_windowed = gr_opengl_force_windowed; + gr_screen.gf_force_fullscreen = gr_opengl_force_fullscreen; + + gr_screen.gf_activate = gr_opengl1_activate; +} + +void opengl1_init() +{ + + if ( Inited ) { + return; + } + + /* + 1 = use secondary color ext + 2 = use opengl linear fog + */ + OGL_fog_mode = 2; + + if ( SDL_GL_ExtensionSupported("GL_EXT_secondary_color") ) { + vglSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)SDL_GL_GetProcAddress("glSecondaryColorPointerEXT"); + Assert( vglSecondaryColorPointerEXT != NULL ); + OGL_fog_mode = 1; + mprintf((" Using extension: GL_EXT_secondary_color\n")); + } + + mprintf(("\n")); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DITHER); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glHint(GL_FOG_HINT, GL_NICEST); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + + glEnable(GL_TEXTURE_2D); + + glDepthRange(0.0, 1.0); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glFlush(); + + + Bm_pixel_format = BM_PIXEL_FORMAT_ARGB; + Gr_bitmap_poly = 1; + + opengl1_init_func_pointers(); + opengl1_tcache_init(1); + + gr_opengl1_clear(); + + Inited = 1; +} diff --git a/src/graphics/gropengl1render.cpp b/src/graphics/gropengl1render.cpp new file mode 100644 index 0000000..dd79660 --- /dev/null +++ b/src/graphics/gropengl1render.cpp @@ -0,0 +1,1071 @@ +/* + * Copyright (C) Volition, Inc. 1999. All rights reserved. + * + * All source code herein is the property of Volition, Inc. You may not sell + * or otherwise commercially exploit the source or things you created based on + * the source. + */ + +#include "pstypes.h" +#include "2d.h" +#include "gropengl.h" +#include "gropengl1.h" +#include "gropenglinternal.h" +#include "bmpman.h" +#include "grinternal.h" +#include "3d.h" +#include "neb.h" +#include "line.h" +#include "palman.h" + + +extern int OGL_fog_mode; + +#define NEBULA_COLORS 20 + + +static void opengl1_rect_internal(int x, int y, int w, int h, int r, int g, int b, int a) +{ + int saved_zbuf; + vertex v[4]; + vertex *verts[4] = {&v[0], &v[1], &v[2], &v[3]}; + + saved_zbuf = gr_zbuffer_get(); + + // start the frame, no zbuffering, no culling + g3_start_frame(1); + gr_zbuffer_set(GR_ZBUFF_NONE); + gr_set_cull(0); + + // stuff coords + v[0].sx = i2fl(x); + v[0].sy = i2fl(y); + v[0].sw = 0.0f; + v[0].u = 0.0f; + v[0].v = 0.0f; + v[0].flags = PF_PROJECTED; + v[0].codes = 0; + v[0].r = (ubyte)r; + v[0].g = (ubyte)g; + v[0].b = (ubyte)b; + v[0].a = (ubyte)a; + + v[1].sx = i2fl(x + w); + v[1].sy = i2fl(y); + v[1].sw = 0.0f; + v[1].u = 0.0f; + v[1].v = 0.0f; + v[1].flags = PF_PROJECTED; + v[1].codes = 0; + v[1].r = (ubyte)r; + v[1].g = (ubyte)g; + v[1].b = (ubyte)b; + v[1].a = (ubyte)a; + + v[2].sx = i2fl(x + w); + v[2].sy = i2fl(y + h); + v[2].sw = 0.0f; + v[2].u = 0.0f; + v[2].v = 0.0f; + v[2].flags = PF_PROJECTED; + v[2].codes = 0; + v[2].r = (ubyte)r; + v[2].g = (ubyte)g; + v[2].b = (ubyte)b; + v[2].a = (ubyte)a; + + v[3].sx = i2fl(x); + v[3].sy = i2fl(y + h); + v[3].sw = 0.0f; + v[3].u = 0.0f; + v[3].v = 0.0f; + v[3].flags = PF_PROJECTED; + v[3].codes = 0; + v[3].r = (ubyte)r; + v[3].g = (ubyte)g; + v[3].b = (ubyte)b; + v[3].a = (ubyte)a; + + // draw the polys + g3_draw_poly_constant_sw(4, verts, TMAP_FLAG_GOURAUD | TMAP_FLAG_RGB | TMAP_FLAG_ALPHA, 0.1f); + + g3_end_frame(); + + // restore zbuffer and culling + gr_zbuffer_set(saved_zbuf); + gr_set_cull(1); +} + +void gr_opengl1_rect(int x,int y,int w,int h) +{ + opengl1_rect_internal(x, y, w, h, gr_screen.current_color.red, gr_screen.current_color.green, gr_screen.current_color.blue, gr_screen.current_color.alpha); +} + +void gr_opengl1_shade(int x,int y,int w,int h) +{ + int r,g,b,a; + + float shade1 = 1.0f; + float shade2 = 6.0f; + + r = fl2i(gr_screen.current_shader.r*255.0f*shade1); + if ( r < 0 ) r = 0; else if ( r > 255 ) r = 255; + g = fl2i(gr_screen.current_shader.g*255.0f*shade1); + if ( g < 0 ) g = 0; else if ( g > 255 ) g = 255; + b = fl2i(gr_screen.current_shader.b*255.0f*shade1); + if ( b < 0 ) b = 0; else if ( b > 255 ) b = 255; + a = fl2i(gr_screen.current_shader.c*255.0f*shade2); + if ( a < 0 ) a = 0; else if ( a > 255 ) a = 255; + + opengl1_rect_internal(x, y, w, h, r, g, b, a); +} + +static void opengl1_aabitmap_ex_internal(int x,int y,int w,int h,int sx,int sy) +{ + if ( w < 1 ) return; + if ( h < 1 ) return; + + if ( !gr_screen.current_color.is_alphacolor ) + return; + + float u_scale, v_scale; + + if ( !opengl1_tcache_set( gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &u_scale, &v_scale, 0, -1, -1, 0 ) ) { + // Couldn't set texture + mprintf(( "WARNING: Error setting aabitmap texture!\n" )); + return; + } + + opengl1_set_state( TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE ); + + float u0, u1, v0, v1; + float x1, x2, y1, y2; + int bw, bh; + + bm_get_info( gr_screen.current_bitmap, &bw, &bh ); + + u0 = u_scale*i2fl(sx)/i2fl(bw); + v0 = v_scale*i2fl(sy)/i2fl(bh); + + u1 = u_scale*i2fl(sx+w)/i2fl(bw); + v1 = v_scale*i2fl(sy+h)/i2fl(bh); + + x1 = i2fl(x+gr_screen.offset_x); + y1 = i2fl(y+gr_screen.offset_y); + x2 = i2fl(x+w+gr_screen.offset_x); + y2 = i2fl(y+h+gr_screen.offset_y); + + glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green, + gr_screen.current_color.blue,gr_screen.current_color.alpha); + + opengl_alloc_render_buffer(4); + + render_buffer[0].x = x1; + render_buffer[0].y = y2; + render_buffer[0].u = u0; + render_buffer[0].v = v1; + + render_buffer[1].x = x2; + render_buffer[1].y = y2; + render_buffer[1].u = u1; + render_buffer[1].v = v1; + + render_buffer[2].x = x2; + render_buffer[2].y = y1; + render_buffer[2].u = u1; + render_buffer[2].v = v0; + + render_buffer[3].x = x1; + render_buffer[3].y = y1; + render_buffer[3].u = u0; + render_buffer[3].v = v0; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + + glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u); + glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x); + + glDrawArrays(GL_QUADS, 0, 4); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); +} + +void gr_opengl1_aabitmap_ex(int x,int y,int w,int h,int sx,int sy) +{ + int reclip; + #ifndef NDEBUG + int count = 0; + #endif + + int dx1=x, dx2=x+w-1; + int dy1=y, dy2=y+h-1; + + int bw, bh; + bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL ); + + do { + reclip = 0; + #ifndef NDEBUG + if ( count > 1 ) Int3(); + count++; + #endif + + if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return; + if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return; + if ( dx1 < gr_screen.clip_left ) { sx += gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; } + if ( dy1 < gr_screen.clip_top ) { sy += gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; } + if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; } + if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; } + + if ( sx < 0 ) { + dx1 -= sx; + sx = 0; + reclip = 1; + } + + if ( sy < 0 ) { + dy1 -= sy; + sy = 0; + reclip = 1; + } + + w = dx2-dx1+1; + h = dy2-dy1+1; + + if ( sx + w > bw ) { + w = bw - sx; + dx2 = dx1 + w - 1; + } + + if ( sy + h > bh ) { + h = bh - sy; + dy2 = dy1 + h - 1; + } + + if ( w < 1 ) return; // clipped away! + if ( h < 1 ) return; // clipped away! + + } while (reclip); + + // Make sure clipping algorithm works + #ifndef NDEBUG + Assert( w > 0 ); + Assert( h > 0 ); + Assert( w == (dx2-dx1+1) ); + Assert( h == (dy2-dy1+1) ); + Assert( sx >= 0 ); + Assert( sy >= 0 ); + Assert( sx+w <= bw ); + Assert( sy+h <= bh ); + Assert( dx2 >= dx1 ); + Assert( dy2 >= dy1 ); + Assert( (dx1 >= gr_screen.clip_left ) && (dx1 <= gr_screen.clip_right) ); + Assert( (dx2 >= gr_screen.clip_left ) && (dx2 <= gr_screen.clip_right) ); + Assert( (dy1 >= gr_screen.clip_top ) && (dy1 <= gr_screen.clip_bottom) ); + Assert( (dy2 >= gr_screen.clip_top ) && (dy2 <= gr_screen.clip_bottom) ); + #endif + + // We now have dx1,dy1 and dx2,dy2 and sx, sy all set validly within clip regions. + opengl1_aabitmap_ex_internal(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy); +} + +void gr_opengl1_aabitmap(int x, int y) +{ + int w, h; + + bm_get_info( gr_screen.current_bitmap, &w, &h, NULL ); + int dx1=x, dx2=x+w-1; + int dy1=y, dy2=y+h-1; + int sx=0, sy=0; + + if ((dx1 > gr_screen.clip_right ) || (dx2 < gr_screen.clip_left)) return; + if ((dy1 > gr_screen.clip_bottom ) || (dy2 < gr_screen.clip_top)) return; + if ( dx1 < gr_screen.clip_left ) { sx = gr_screen.clip_left-dx1; dx1 = gr_screen.clip_left; } + if ( dy1 < gr_screen.clip_top ) { sy = gr_screen.clip_top-dy1; dy1 = gr_screen.clip_top; } + if ( dx2 > gr_screen.clip_right ) { dx2 = gr_screen.clip_right; } + if ( dy2 > gr_screen.clip_bottom ) { dy2 = gr_screen.clip_bottom; } + + if ( sx < 0 ) return; + if ( sy < 0 ) return; + if ( sx >= w ) return; + if ( sy >= h ) return; + + // Draw bitmap bm[sx,sy] into (dx1,dy1)-(dx2,dy2) + gr_opengl1_aabitmap_ex(dx1,dy1,dx2-dx1+1,dy2-dy1+1,sx,sy); +} + +void gr_opengl1_string( int sx, int sy, const char *s ) +{ + int width, spacing, letter; + int x, y; + int rb_offset; + float u_scale, v_scale; + float u0, u1, v0, v1; + float x1, x2, y1, y2; + int bw, bh; + + if ( !Current_font ) { + return; + } + + gr_set_bitmap(Current_font->bitmap_id, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1); + + if ( !opengl1_tcache_set( gr_screen.current_bitmap, TCACHE_TYPE_AABITMAP, &u_scale, &v_scale, 0, -1, -1, 0 ) ) { + // Couldn't set texture + mprintf(( "WARNING: Error setting aabitmap texture!\n" )); + return; + } + + bm_get_info( gr_screen.current_bitmap, &bw, &bh ); + + opengl1_set_state( TEXTURE_SOURCE_NO_FILTERING, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE ); + + opengl_alloc_render_buffer(strlen(s) * 4); + + x = sx; + y = sy; + + if (sx==0x8000) { //centered + x = get_centered_x(s); + } else { + x = sx; + } + + spacing = 0; + rb_offset = 0; + + while (*s) { + x += spacing; + + while (*s== '\n' ) { + s++; + y += Current_font->h; + if (sx==0x8000) { //centered + x = get_centered_x(s); + } else { + x = sx; + } + } + if (*s == 0 ) break; + + letter = get_char_width(s[0],s[1],&width,&spacing); + s++; + + //not in font, draw as space + if (letter<0) { + continue; + } + + int xd, yd, xc, yc; + int wc, hc; + + // Check if this character is totally clipped + if ( x + width < gr_screen.clip_left ) continue; + if ( y + Current_font->h < gr_screen.clip_top ) continue; + if ( x > gr_screen.clip_right ) continue; + if ( y > gr_screen.clip_bottom ) continue; + + xd = yd = 0; + if ( x < gr_screen.clip_left ) xd = gr_screen.clip_left - x; + if ( y < gr_screen.clip_top ) yd = gr_screen.clip_top - y; + xc = x+xd; + yc = y+yd; + + wc = width - xd; hc = Current_font->h - yd; + if ( xc + wc > gr_screen.clip_right ) wc = gr_screen.clip_right - xc; + if ( yc + hc > gr_screen.clip_bottom ) hc = gr_screen.clip_bottom - yc; + + if ( wc < 1 ) continue; + if ( hc < 1 ) continue; + + int u = Current_font->bm_u[letter]; + int v = Current_font->bm_v[letter]; + + x1 = i2fl(xc + gr_screen.offset_x); + y1 = i2fl(yc + gr_screen.offset_y); + x2 = i2fl(x1 + wc); + y2 = i2fl(y1 + hc); + + u0 = u_scale * (i2fl(u+xd) / bw); + v0 = v_scale * (i2fl(v+yd) / bh); + + u1 = u_scale * (i2fl((u+xd)+wc) / bw); + v1 = v_scale * (i2fl((v+yd)+hc) / bh); + + render_buffer[rb_offset].x = x1; + render_buffer[rb_offset].y = y2; + render_buffer[rb_offset].u = u0; + render_buffer[rb_offset].v = v1; + ++rb_offset; + + render_buffer[rb_offset].x = x2; + render_buffer[rb_offset].y = y2; + render_buffer[rb_offset].u = u1; + render_buffer[rb_offset].v = v1; + ++rb_offset; + + render_buffer[rb_offset].x = x2; + render_buffer[rb_offset].y = y1; + render_buffer[rb_offset].u = u1; + render_buffer[rb_offset].v = v0; + ++rb_offset; + + render_buffer[rb_offset].x = x1; + render_buffer[rb_offset].y = y1; + render_buffer[rb_offset].u = u0; + render_buffer[rb_offset].v = v0; + ++rb_offset; + } + + glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green, + gr_screen.current_color.blue,gr_screen.current_color.alpha); + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + + glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u); + glVertexPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x); + + glDrawArrays(GL_QUADS, 0, rb_offset); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); +} + +void gr_opengl1_line(int x1,int y1,int x2,int y2) +{ + int clipped = 0, swapped=0; + + opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE ); + + INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,gr_screen.clip_right,gr_screen.clip_bottom,return,clipped=1,swapped=1); + + float sx1, sy1; + float sx2, sy2; + + sx1 = i2fl(x1 + gr_screen.offset_x)+0.5; + sy1 = i2fl(y1 + gr_screen.offset_y)+0.5; + sx2 = i2fl(x2 + gr_screen.offset_x)+0.5; + sy2 = i2fl(y2 + gr_screen.offset_y)+0.5; + + opengl_alloc_render_buffer(2); + + if ( x1 == x2 && y1 == y2 ) { + render_buffer[0].x = sx1; + render_buffer[0].y = sy1; + render_buffer[0].z = -0.99f; + + glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green, + gr_screen.current_color.blue, gr_screen.current_color.alpha); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x); + + glDrawArrays(GL_POINTS, 0, 1); + + glDisableClientState(GL_VERTEX_ARRAY); + + return; + } + + if ( x1 == x2 ) { + if ( sy1 < sy2 ) { + sy2 += 0.5f; + } else { + sy1 += 0.5f; + } + } else if ( y1 == y2 ) { + if ( sx1 < sx2 ) { + sx2 += 0.5f; + } else { + sx1 += 0.5f; + } + } + + render_buffer[0].x = sx2; + render_buffer[0].y = sy2; + render_buffer[0].z = -0.99f; + + render_buffer[1].x = sx1; + render_buffer[1].y = sy1; + render_buffer[1].z = -0.99f; + + glColor4ub(gr_screen.current_color.red, gr_screen.current_color.green, + gr_screen.current_color.blue, gr_screen.current_color.alpha); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x); + + glDrawArrays(GL_LINES, 0, 2); + + glDisableClientState(GL_VERTEX_ARRAY); +} + +void gr_opengl1_aaline(vertex *v1, vertex *v2) +{ + gr_opengl1_line( fl2i(v1->sx), fl2i(v1->sy), fl2i(v2->sx), fl2i(v2->sy) ); +} + +void gr_opengl1_gradient(int x1,int y1,int x2,int y2) +{ + int clipped = 0, swapped=0; + + if ( !gr_screen.current_color.is_alphacolor ) { + gr_line( x1, y1, x2, y2 ); + return; + } + + INT_CLIPLINE(x1,y1,x2,y2,gr_screen.clip_left,gr_screen.clip_top,gr_screen.clip_right,gr_screen.clip_bottom,return,clipped=1,swapped=1); + + opengl1_set_state( TEXTURE_SOURCE_NONE, ALPHA_BLEND_ALPHA_BLEND_ALPHA, ZBUFFER_TYPE_NONE ); + + int aa = swapped ? 0 : gr_screen.current_color.alpha; + int ba = swapped ? gr_screen.current_color.alpha : 0; + + float sx1, sy1; + float sx2, sy2; + + sx1 = i2fl(x1 + gr_screen.offset_x)+0.5; + sy1 = i2fl(y1 + gr_screen.offset_y)+0.5; + sx2 = i2fl(x2 + gr_screen.offset_x)+0.5; + sy2 = i2fl(y2 + gr_screen.offset_y)+0.5; + + if ( x1 == x2 ) { + if ( sy1 < sy2 ) { + sy2 += 0.5f; + } else { + sy1 += 0.5f; + } + } else if ( y1 == y2 ) { + if ( sx1 < sx2 ) { + sx2 += 0.5f; + } else { + sx1 += 0.5f; + } + } + + opengl_alloc_render_buffer(2); + + render_buffer[0].r = gr_screen.current_color.red; + render_buffer[0].g = gr_screen.current_color.green; + render_buffer[0].b = gr_screen.current_color.blue; + render_buffer[0].a = ba; + render_buffer[0].x = sx2; + render_buffer[0].y = sy2; + render_buffer[0].z = -0.99f; + + render_buffer[1].r = gr_screen.current_color.red; + render_buffer[1].g = gr_screen.current_color.green; + render_buffer[1].b = gr_screen.current_color.blue; + render_buffer[1].a = aa; + render_buffer[1].x = sx1; + render_buffer[1].y = sy1; + render_buffer[1].z = -0.99f; + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].r); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x); + + glDrawArrays(GL_LINES, 0, 2); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); +} + +void gr_opengl1_circle( int xc, int yc, int d ) +{ + int p,x, y, r; + + r = d/2; + p=3-d; + x=0; + y=r; + + // Big clip + if ( (xc+r) < gr_screen.clip_left ) return; + if ( (xc-r) > gr_screen.clip_right ) return; + if ( (yc+r) < gr_screen.clip_top ) return; + if ( (yc-r) > gr_screen.clip_bottom ) return; + + while(x 1.0f) { + f_float = 1.0f; + } + + *f_val = f_float; +} + +void opengl1_tmapper_internal( int nv, vertex ** verts, uint flags, int is_scaler ) +{ + int i; + float u_scale = 1.0f, v_scale = 1.0f; + + // Make nebula use the texture mapper... this blends the colors better. + if ( flags & TMAP_FLAG_NEBULA ){ + Int3 (); + } + + gr_texture_source texture_source = (gr_texture_source)-1; + gr_alpha_blend alpha_blend = (gr_alpha_blend)-1; + gr_zbuffer_type zbuffer_type = (gr_zbuffer_type)-1; + + if ( gr_zbuffering ) { + if ( is_scaler || (gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER) ) { + zbuffer_type = ZBUFFER_TYPE_READ; + } else { + zbuffer_type = ZBUFFER_TYPE_FULL; + } + } else { + zbuffer_type = ZBUFFER_TYPE_NONE; + } + + int alpha; + + int tmap_type = TCACHE_TYPE_NORMAL; + + int r, g, b; + + if ( flags & TMAP_FLAG_TEXTURED ) { + r = g = b = 255; + } else { + r = gr_screen.current_color.red; + g = gr_screen.current_color.green; + b = gr_screen.current_color.blue; + } + + if ( gr_screen.current_alphablend_mode == GR_ALPHABLEND_FILTER ) + { + if (1) { + tmap_type = TCACHE_TYPE_NORMAL; + alpha_blend = ALPHA_BLEND_ALPHA_ADDITIVE; + + // Blend with screen pixel using src*alpha+dst + float factor = gr_screen.current_alpha; + + alpha = 255; + + if ( factor <= 1.0f ) { + int tmp_alpha = fl2i(gr_screen.current_alpha*255.0f); + r = (r*tmp_alpha)/255; + g = (g*tmp_alpha)/255; + b = (b*tmp_alpha)/255; + } + } else { + tmap_type = TCACHE_TYPE_XPARENT; + + alpha_blend = ALPHA_BLEND_ALPHA_BLEND_ALPHA; + + // Blend with screen pixel using src*alpha+dst + float factor = gr_screen.current_alpha; + + if ( factor > 1.0f ) { + alpha = 255; + } else { + alpha = fl2i(gr_screen.current_alpha*255.0f); + } + } + } else { + if(Bm_pixel_format == BM_PIXEL_FORMAT_ARGB) { + alpha_blend = ALPHA_BLEND_ALPHA_BLEND_ALPHA; + } else { + alpha_blend = ALPHA_BLEND_NONE; + } + alpha = 255; + } + + if (flags & TMAP_FLAG_BITMAP_SECTION) { + Assert( !(flags & TMAP_FLAG_BITMAP_INTERFACE) ); + tmap_type = TCACHE_TYPE_BITMAP_SECTION; + } else if (flags & TMAP_FLAG_BITMAP_INTERFACE) { + Assert( !(flags & TMAP_FLAG_BITMAP_SECTION) ); + tmap_type = TCACHE_TYPE_BITMAP_INTERFACE; + } + + texture_source = TEXTURE_SOURCE_NONE; + + if ( flags & TMAP_FLAG_TEXTURED ) { + if ( !opengl1_tcache_set(gr_screen.current_bitmap, tmap_type, &u_scale, &v_scale, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, 0 )) + { + mprintf(( "Not rendering a texture because it didn't fit in VRAM!\n" )); + return; + } + + // use nonfiltered textures for bitmap sections and UI graphics + switch (tmap_type) { + case TCACHE_TYPE_BITMAP_INTERFACE: + case TCACHE_TYPE_BITMAP_SECTION: + texture_source = TEXTURE_SOURCE_NO_FILTERING; + break; + + default: + texture_source = TEXTURE_SOURCE_DECAL; + break; + } + } + + + opengl1_set_state( texture_source, alpha_blend, zbuffer_type ); + + if ( flags & TMAP_FLAG_TEXTURED ) + { + // rendition junk + // STUB_FUNCTION; + } + + float fr = 1.0f, fg = 1.0f, fb = 1.0f; + + if (flags & TMAP_FLAG_PIXEL_FOG) { + int r, g, b; + int ra, ga, ba; + ra = ga = ba = 0; + + /* argh */ + for (i=nv-1;i>=0;i--) // DDOI - change polygon winding + { + vertex * va = verts[i]; + float sx, sy; + + int x, y; + x = fl2i(va->sx*16.0f); + y = fl2i(va->sy*16.0f); + + x += gr_screen.offset_x*16; + y += gr_screen.offset_y*16; + + sx = i2fl(x) / 16.0f; + sy = i2fl(y) / 16.0f; + + neb2_get_pixel((int)sx, (int)sy, &r, &g, &b); + + ra += r; + ga += g; + ba += b; + } + + ra /= nv; + ga /= nv; + ba /= nv; + + gr_fog_set(GR_FOGMODE_FOG, ra, ga, ba, -1.0f, -1.0f); + + fr = ra / 255.0f; + fg = ga / 255.0f; + fb = ba / 255.0f; + } + + opengl_alloc_render_buffer(nv); + + int rb_offset = 0; + + for (i = nv-1; i >= 0; i--) { + vertex * va = verts[i]; + float sx, sy, sz; + float rhw = 1.0f; + int a; + + if ( gr_zbuffering || (flags & TMAP_FLAG_NEBULA) ) { + sz = 1.0 - 1.0 / (1.0 + va->z / (32768.0 / 256.0)); + + if ( sz > 0.98f ) { + sz = 0.98f; + } + } else { + sz = 0.99f; + } + + if ( flags & TMAP_FLAG_CORRECT ) { + rhw /= va->sw; + } + + if (flags & TMAP_FLAG_ALPHA) { + a = verts[i]->a; + } else { + a = alpha; + } + + if (flags & TMAP_FLAG_NEBULA ) { + int pal = (verts[i]->b*(NEBULA_COLORS-1))/255; + r = gr_palette[pal*3+0]; + g = gr_palette[pal*3+1]; + b = gr_palette[pal*3+2]; + } else if ( (flags & TMAP_FLAG_RAMP) && (flags & TMAP_FLAG_GOURAUD) ) { + r = Gr_gamma_lookup[verts[i]->b]; + g = Gr_gamma_lookup[verts[i]->b]; + b = Gr_gamma_lookup[verts[i]->b]; + } else if ( (flags & TMAP_FLAG_RGB) && (flags & TMAP_FLAG_GOURAUD) ) { + // Make 0.75 be 256.0f + r = Gr_gamma_lookup[verts[i]->r]; + g = Gr_gamma_lookup[verts[i]->g]; + b = Gr_gamma_lookup[verts[i]->b]; + } else { + // use constant RGB values... + } + + render_buffer[rb_offset].r = r; + render_buffer[rb_offset].g = g; + render_buffer[rb_offset].b = b; + render_buffer[rb_offset].a = a; + + if((gr_screen.current_fog_mode != GR_FOGMODE_NONE) && (OGL_fog_mode == 1)){ + float f_val; + + opengl1_stuff_fog_value(va->z, &f_val); + + render_buffer[rb_offset].sr = fl2i(((fr * f_val) * 255.0f) + 0.5f); + render_buffer[rb_offset].sg = fl2i(((fg * f_val) * 255.0f) + 0.5f); + render_buffer[rb_offset].sb = fl2i(((fb * f_val) * 255.0f) + 0.5f); + } + + int x, y; + x = fl2i(va->sx*16.0f); + y = fl2i(va->sy*16.0f); + + x += gr_screen.offset_x*16; + y += gr_screen.offset_y*16; + + sx = i2fl(x) / 16.0f; + sy = i2fl(y) / 16.0f; + + if ( flags & TMAP_FLAG_TEXTURED ) { + render_buffer[rb_offset].u = va->u * u_scale; + render_buffer[rb_offset].v = va->v * v_scale; + } + + render_buffer[rb_offset].x = sx * rhw; + render_buffer[rb_offset].y = sy * rhw; + render_buffer[rb_offset].z = -sz * rhw; + render_buffer[rb_offset].w = rhw; + + ++rb_offset; + } + + if (flags & TMAP_FLAG_TEXTURED) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(rb_t), &render_buffer[0].u); + } + + if ( (gr_screen.current_fog_mode != GR_FOGMODE_NONE) && (OGL_fog_mode == 1) ) { + glEnableClientState(GL_SECONDARY_COLOR_ARRAY); + vglSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].sr); + } + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(rb_t), &render_buffer[0].r); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(4, GL_FLOAT, sizeof(rb_t), &render_buffer[0].x); + + glDrawArrays(GL_TRIANGLE_FAN, 0, rb_offset); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_SECONDARY_COLOR_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); +} + +void gr_opengl1_tmapper( int nverts, vertex **verts, uint flags ) +{ + opengl1_tmapper_internal( nverts, verts, flags, 0 ); +} + +#define FIND_SCALED_NUM(x,x0,x1,y0,y1) (((((x)-(x0))*((y1)-(y0)))/((x1)-(x0)))+(y0)) + +void gr_opengl1_scaler(vertex *va, vertex *vb ) +{ + float x0, y0, x1, y1; + float u0, v0, u1, v1; + float clipped_x0, clipped_y0, clipped_x1, clipped_y1; + float clipped_u0, clipped_v0, clipped_u1, clipped_v1; + float xmin, xmax, ymin, ymax; + int dx0, dy0, dx1, dy1; + + //============= CLIP IT ===================== + + x0 = va->sx; y0 = va->sy; + x1 = vb->sx; y1 = vb->sy; + + xmin = i2fl(gr_screen.clip_left); ymin = i2fl(gr_screen.clip_top); + xmax = i2fl(gr_screen.clip_right); ymax = i2fl(gr_screen.clip_bottom); + + u0 = va->u; v0 = va->v; + u1 = vb->u; v1 = vb->v; + + // Check for obviously offscreen bitmaps... + if ( (y1<=y0) || (x1<=x0) ) return; + if ( (x1xmax) ) return; + if ( (y1ymax) ) return; + + clipped_u0 = u0; clipped_v0 = v0; + clipped_u1 = u1; clipped_v1 = v1; + + clipped_x0 = x0; clipped_y0 = y0; + clipped_x1 = x1; clipped_y1 = y1; + + // Clip the left, moving u0 right as necessary + if ( x0 < xmin ) { + clipped_u0 = FIND_SCALED_NUM(xmin,x0,x1,u0,u1); + clipped_x0 = xmin; + } + + // Clip the right, moving u1 left as necessary + if ( x1 > xmax ) { + clipped_u1 = FIND_SCALED_NUM(xmax,x0,x1,u0,u1); + clipped_x1 = xmax; + } + + // Clip the top, moving v0 down as necessary + if ( y0 < ymin ) { + clipped_v0 = FIND_SCALED_NUM(ymin,y0,y1,v0,v1); + clipped_y0 = ymin; + } + + // Clip the bottom, moving v1 up as necessary + if ( y1 > ymax ) { + clipped_v1 = FIND_SCALED_NUM(ymax,y0,y1,v0,v1); + clipped_y1 = ymax; + } + + dx0 = fl2i(clipped_x0); dx1 = fl2i(clipped_x1); + dy0 = fl2i(clipped_y0); dy1 = fl2i(clipped_y1); + + if (dx1<=dx0) return; + if (dy1<=dy0) return; + + //============= DRAW IT ===================== + + vertex v[4]; + vertex *vl[4]; + + vl[0] = &v[0]; + v[0].sx = clipped_x0; + v[0].sy = clipped_y0; + v[0].sw = va->sw; + v[0].z = va->z; + v[0].u = clipped_u0; + v[0].v = clipped_v0; + + vl[1] = &v[1]; + v[1].sx = clipped_x1; + v[1].sy = clipped_y0; + v[1].sw = va->sw; + v[1].z = va->z; + v[1].u = clipped_u1; + v[1].v = clipped_v0; + + vl[2] = &v[2]; + v[2].sx = clipped_x1; + v[2].sy = clipped_y1; + v[2].sw = va->sw; + v[2].z = va->z; + v[2].u = clipped_u1; + v[2].v = clipped_v1; + + vl[3] = &v[3]; + v[3].sx = clipped_x0; + v[3].sy = clipped_y1; + v[3].sw = va->sw; + v[3].z = va->z; + v[3].u = clipped_u0; + v[3].v = clipped_v1; + + opengl1_tmapper_internal( 4, vl, TMAP_FLAG_TEXTURED, 1 ); +} diff --git a/src/graphics/gropengl1texture.cpp b/src/graphics/gropengl1texture.cpp new file mode 100644 index 0000000..e636c78 --- /dev/null +++ b/src/graphics/gropengl1texture.cpp @@ -0,0 +1,917 @@ +/* + * Copyright (C) Volition, Inc. 1999. All rights reserved. + * + * All source code herein is the property of Volition, Inc. You may not sell + * or otherwise commercially exploit the source or things you created based on + * the source. + */ + +#include "pstypes.h" +#include "2d.h" +#include "gropengl.h" +#include "gropengl1.h" +#include "gropenglinternal.h" +#include "bmpman.h" +#include "grinternal.h" +#include "systemvars.h" + + +int vram_full = 0; + +typedef struct tcache_slot_opengl { + GLuint texture_handle; + float u_scale, v_scale; + int bitmap_id; + int size; + int used_this_frame; + int time_created; + ushort w,h; + + // sections + tcache_slot_opengl *data_sections[MAX_BMAP_SECTIONS_X][MAX_BMAP_SECTIONS_Y]; + tcache_slot_opengl *parent; + + gr_texture_source texture_mode; +} tcache_slot_opengl; + +static void *Texture_sections = NULL; +static tcache_slot_opengl *Textures = NULL; + +static tcache_slot_opengl *GL_bound_texture; + +static int GL_frame_count = 0; +static int GL_textures_in_frame = 0; +static int GL_last_bitmap_id = -1; +static int GL_last_detail = -1; +static int GL_last_bitmap_type = -1; +static int GL_last_section_x = -1; +static int GL_last_section_y = -1; +static int GL_should_preload = 0; + +int GL_textures_in = 0; + +static gr_texture_source GL_current_texture_source = (gr_texture_source) -1; + +static ubyte GL_xlat[256] = { 0 }; + + +void gr_opengl1_set_gamma(float gamma) +{ + Gr_gamma = gamma; + Gr_gamma_int = int (Gr_gamma*10); + + // Create the Gamma lookup table + int i; + for (i=0;i<256; i++) { + int v = fl2i(pow(i2fl(i)/255.0f, 1.0f/Gr_gamma)*255.0f); + if ( v > 255 ) { + v = 255; + } else if ( v < 0 ) { + v = 0; + } + Gr_gamma_lookup[i] = v; + } + + // set the alpha gamma settings (for fonts) + for (i=0; i<16; i++) { + GL_xlat[i] = (ubyte)Gr_gamma_lookup[(i*255)/15]; + } + + GL_xlat[15] = GL_xlat[1]; + + for (; i<256; i++) { + GL_xlat[i] = GL_xlat[0]; + } + + // Flush any existing textures + opengl1_tcache_flush(); +} + +void opengl1_set_texture_state(gr_texture_source ts) +{ + if (ts == TEXTURE_SOURCE_NONE) { + GL_bound_texture = NULL; + + glBindTexture(GL_TEXTURE_2D, 0); + opengl1_tcache_set(-1, -1, NULL, NULL, 0, -1, -1, 0 ); + } else if (GL_bound_texture && + GL_bound_texture->texture_mode != ts) { + switch (ts) { + case TEXTURE_SOURCE_DECAL: + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + case TEXTURE_SOURCE_NO_FILTERING: + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + default: + break; + } + + GL_bound_texture->texture_mode = ts; + } + + GL_current_texture_source = ts; +} + + +void opengl1_tcache_init (int use_sections) +{ + int i, idx, s_idx; + + // DDOI - FIXME skipped a lot of stuff here + GL_should_preload = 0; + + //uint tmp_pl = os_config_read_uint( NULL, NOX("D3DPreloadTextures"), 255 ); + uint tmp_pl = 1; + + if ( tmp_pl == 0 ) { + GL_should_preload = 0; + } else if ( tmp_pl == 1 ) { + GL_should_preload = 1; + } else { + GL_should_preload = 1; + } + + STUB_FUNCTION; + + Textures = (tcache_slot_opengl *)malloc(MAX_BITMAPS*sizeof(tcache_slot_opengl)); + if ( !Textures ) { + exit(1); + } + + if (gr_screen.use_sections) { + Texture_sections = (tcache_slot_opengl*)malloc(MAX_BITMAPS * MAX_BMAP_SECTIONS_X * MAX_BMAP_SECTIONS_Y * sizeof(tcache_slot_opengl)); + if(!Texture_sections){ + exit(1); + } + memset(Texture_sections, 0, MAX_BITMAPS * MAX_BMAP_SECTIONS_X * MAX_BMAP_SECTIONS_Y * sizeof(tcache_slot_opengl)); + } + + // Init the texture structures + int section_count = 0; + for( i=0; iparent = &Textures[i]; + /* + Textures[i].data_sections[idx][s_idx]->vram_texture = NULL; + Textures[i].data_sections[idx][s_idx]->vram_texture_surface = NULL; + */ + Textures[i].data_sections[idx][s_idx]->texture_handle = 0; + Textures[i].data_sections[idx][s_idx]->bitmap_id = -1; + Textures[i].data_sections[idx][s_idx]->size = 0; + Textures[i].data_sections[idx][s_idx]->used_this_frame = 0; + } + } + } else { + for(idx=0; idxused_this_frame = 0; + } + } + } + } + } + } + */ + + if ( vram_full ) { + opengl1_tcache_flush(); + vram_full = 0; + } +} + +static int opengl1_free_texture ( tcache_slot_opengl *t ) +{ + int idx, s_idx; + + + // Bitmap changed!! + if ( t->bitmap_id > -1 ) { + // if I, or any of my children have been used this frame, bail + if(t->used_this_frame == GL_frame_count){ + return 0; + } + + if (gr_screen.use_sections) { + for(idx=0; idxdata_sections[idx][s_idx] != NULL) && (t->data_sections[idx][s_idx]->used_this_frame == GL_frame_count)){ + return 0; + } + } + } + } + + // ok, now we know its legal to free everything safely + t->texture_mode = (gr_texture_source) -1; + glDeleteTextures (1, &t->texture_handle); + t->texture_handle = 0; + + if ( GL_last_bitmap_id == t->bitmap_id ) { + GL_last_bitmap_id = -1; + } + + // if this guy has children, free them too, since the children + // actually make up his size + if (gr_screen.use_sections) { + for(idx=0; idxdata_sections[idx][s_idx] != NULL){ + opengl1_free_texture(t->data_sections[idx][s_idx]); + } + } + } + } + + t->bitmap_id = -1; + t->used_this_frame = 0; + GL_textures_in -= t->size; + t->size = 0; + } + + return 1; +} + +static void opengl1_tcache_get_adjusted_texture_size(int w_in, int h_in, int *w_out, int *h_out) +{ + int tex_w, tex_h; + int i; + + // bogus + if((w_out == NULL) || (h_out == NULL)){ + return; + } + + // starting size + tex_w = w_in; + tex_h = h_in; + + // set height and width to a power of 2 + for (i=0; i<16; i++ ) { + if ( (tex_w > (1< (1< 8) + tex_h = tex_w/8; + if (tex_h/tex_w > 8) + tex_w = tex_h/8; + + if ( tex_w < GL_min_texture_width ) { + tex_w = GL_min_texture_width; + } else if ( tex_w > GL_max_texture_width ) { + tex_w = GL_max_texture_width; + } + + if ( tex_h < GL_min_texture_height ) { + tex_h = GL_min_texture_height; + } else if ( tex_h > GL_max_texture_height ) { + tex_h = GL_max_texture_height; + } + + // store the outgoing size + *w_out = tex_w; + *h_out = tex_h; +} + +// data == start of bitmap data +// sx == x offset into bitmap +// sy == y offset into bitmap +// src_w == absolute width of section on source bitmap +// src_h == absolute height of section on source bitmap +// bmap_w == width of source bitmap +// bmap_h == height of source bitmap +// tex_w == width of final texture +// tex_h == height of final texture +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) +{ + int ret_val = 1; + int size; + int i, j; + ubyte *bmp_data = ((ubyte*)data); + ubyte *texmem = NULL, *texmemp; + + // bogus + if((t == NULL) || (bmp_data == NULL)){ + return 0; + } + + if ( t->used_this_frame == GL_frame_count ) { + mprintf(( "ARGHH!!! Texture already used this frame! Cannot free it!\n" )); + return 0; + } + if ( !reload ) { + // gah + if(!opengl1_free_texture(t)){ + return 0; + } + } + + switch (bitmap_type) { + case TCACHE_TYPE_AABITMAP: + t->u_scale = (float)bmap_w / (float)tex_w; + t->v_scale = (float)bmap_h / (float)tex_h; + break; + + case TCACHE_TYPE_BITMAP_INTERFACE: + case TCACHE_TYPE_BITMAP_SECTION: + t->u_scale = (float)src_w / (float)tex_w; + t->v_scale = (float)src_h / (float)tex_h; + break; + + default: + t->u_scale = 1.0f; + t->v_scale = 1.0f; + break; + } + + if (!reload) { + glGenTextures (1, &t->texture_handle); + } + + if (t->texture_handle == 0) { + nprintf(("Error", "!!DEBUG!! t->texture_handle == 0")); + return 0; + } + + GL_bound_texture = t; + + GL_bound_texture->texture_mode = (gr_texture_source) -1; + + glBindTexture (GL_TEXTURE_2D, t->texture_handle); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + /* this should be set next anyway */ +// if (GL_current_texture_source != TEXTURE_SOURCE_NONE) { +// gr_opengl_set_texture_state(GL_current_texture_source); +// } + + size = 0; + + switch (bitmap_type) { + case TCACHE_TYPE_AABITMAP: + { + texmem = (ubyte *) malloc (tex_w*tex_h); + texmemp = texmem; + + for (i=0;ibitmap_id = texture_handle; + t->time_created = GL_frame_count; + t->used_this_frame = 0; + t->size = size; + t->w = (ushort)tex_w; + t->h = (ushort)tex_h; + + GL_textures_in_frame += t->size; + if (!reload) { + GL_textures_in += t->size; + } + + return ret_val; +} + +static int opengl1_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl *tslot, int fail_on_full) +{ + ubyte flags; + bitmap *bmp; + int final_w, final_h; + ubyte bpp = 16; + int reload = 0; + int resize = 0; + int cull_size = 0; + + // setup texture/bitmap flags + flags = 0; + switch(bitmap_type){ + case TCACHE_TYPE_AABITMAP: + flags |= BMP_AABITMAP; + bpp = 8; + break; + case TCACHE_TYPE_NORMAL: + flags |= BMP_TEX_OTHER; + cull_size = 1; + break; + case TCACHE_TYPE_BITMAP_INTERFACE: + case TCACHE_TYPE_XPARENT: + flags |= BMP_TEX_XPARENT; + break; + default: + Int3(); + return 0; + } + + // lock the bitmap into the proper format + bmp = bm_lock(bitmap_handle, bpp, flags); + if ( bmp == NULL ) { + mprintf(("Couldn't lock bitmap %d.\n", bitmap_handle )); + return 0; + } + + int max_w = bmp->w; + int max_h = bmp->h; + + + // DDOI - TODO + if (cull_size) { + // max_w /= D3D_texture_divider; + // max_h /= D3D_texture_divider; + + // if we are going to cull the size then we need to force a resize + if (Detail.hardware_textures < 4) { + resize = 1; + + // Detail.debris_culling goes from 0 to 4. + max_w /= (16 >> Detail.hardware_textures); + max_h /= (16 >> Detail.hardware_textures); + } + } + + + // get final texture size as it will be allocated as a DD surface + opengl1_tcache_get_adjusted_texture_size(max_w, max_h, &final_w, &final_h); + + if ( (final_w < 1) || (final_h < 1) ) { + mprintf(("Bitmap is too small at %dx%d.\n", final_w, final_h)); + return 0; + } + + // if we don't have to resize the image (to get power of 2, etc.) then skip that extra work + if ( (max_w != final_w) || (max_h != final_h) ) { + resize = 1; + } + + // if this tcache slot has no bitmap + if ( tslot->bitmap_id < 0) { + reload = 0; + } + // different bitmap altogether - determine if the new one can use the old one's slot + else if (tslot->bitmap_id != bitmap_handle) { + if((final_w == tslot->w) && (final_h == tslot->h)){ + reload = 1; + //ml_printf("Reloading texture %d\n", bitmap_handle); + } else { + reload = 0; + } + } + + // call the helper + 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); + + // unlock the bitmap + bm_unlock(bitmap_handle); + + return ret_val; +} + +static int opengl1_create_texture_sectioned(int bitmap_handle, int bitmap_type, tcache_slot_opengl *tslot, int sx, int sy, int fail_on_full) +{ + ubyte flags; + bitmap *bmp; + int final_w, final_h; + int section_x, section_y; + int reload = 0; + int resize = 1; + + Assert( gr_screen.use_sections ); + + // setup texture/bitmap flags + Assert(bitmap_type == TCACHE_TYPE_BITMAP_SECTION); + if(bitmap_type != TCACHE_TYPE_BITMAP_SECTION){ + bitmap_type = TCACHE_TYPE_BITMAP_SECTION; + } + flags = BMP_TEX_XPARENT; + + // lock the bitmap in the proper format + bmp = bm_lock(bitmap_handle, 16, flags); + if ( bmp == NULL ) { + mprintf(("Couldn't lock bitmap %d.\n", bitmap_handle )); + return 0; + } + // determine the width and height of this section + bm_get_section_size(bitmap_handle, sx, sy, §ion_x, §ion_y); + + // get final texture size as it will be allocated as an opengl texture + opengl1_tcache_get_adjusted_texture_size(section_x, section_y, &final_w, &final_h); + + if ( (final_w < 1) || (final_h < 1) ) { + mprintf(("Bitmap is too small at %dx%d.\n", final_w, final_h)); + return 0; + } + + // if we don't have to resize the image (to get power of 2, etc.) then skip that extra work + if ( (bmp->sections.num_x == 1) && (bmp->sections.num_y == 1) && (section_x == final_w) && (section_y == final_h) ) { + resize = 0; + } + + // if this tcache slot has no bitmap + if ( tslot->bitmap_id < 0) { + reload = 0; + } + // different bitmap altogether - determine if the new one can use the old one's slot + else if (tslot->bitmap_id != bitmap_handle) { + if((final_w == tslot->w) && (final_h == tslot->h)){ + reload = 1; + } else { + reload = 0; + } + } + + // call the helper + 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); + + // unlock the bitmap + bm_unlock(bitmap_handle); + + return ret_val; +} + +extern int bm_get_cache_slot( int bitmap_id, int separate_ani_frames ); + +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) +{ + bitmap *bmp = NULL; + + int idx, s_idx; + int ret_val = 1; + + if (bitmap_id < 0) + { + GL_last_bitmap_id = -1; + return 0; + } + + if ( GL_last_detail != Detail.hardware_textures ) { + GL_last_detail = Detail.hardware_textures; + opengl1_tcache_flush(); + } + + if (vram_full) { + return 0; + } + + int n = bm_get_cache_slot (bitmap_id, 1); + tcache_slot_opengl *t = &Textures[n]; + + 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)) { + t->used_this_frame = GL_frame_count; + + // mark all children as used + if (gr_screen.use_sections) { + for(idx=0; idxdata_sections[idx][s_idx] != NULL){ + t->data_sections[idx][s_idx]->used_this_frame = GL_frame_count; + } + } + } + } + + *u_scale = t->u_scale; + *v_scale = t->v_scale; + return 1; + } + + if (bitmap_type == TCACHE_TYPE_BITMAP_SECTION){ + Assert( gr_screen.use_sections ); + Assert((sx >= 0) && (sy >= 0) && (sx < MAX_BMAP_SECTIONS_X) && (sy < MAX_BMAP_SECTIONS_Y)); + if(!((sx >= 0) && (sy >= 0) && (sx < MAX_BMAP_SECTIONS_X) && (sy < MAX_BMAP_SECTIONS_Y))){ + return 0; + } + + ret_val = 1; + + // if the texture sections haven't been created yet + if((t->bitmap_id < 0) || (t->bitmap_id != bitmap_id)){ + + // lock the bitmap in the proper format + bmp = bm_lock(bitmap_id, 16, BMP_TEX_XPARENT); + bm_unlock(bitmap_id); + + // now lets do something for each texture + + for(idx=0; idxsections.num_x; idx++){ + for(s_idx=0; s_idxsections.num_y; s_idx++){ + // hmm. i'd rather we didn't have to do it this way... + if(!opengl1_create_texture_sectioned(bitmap_id, bitmap_type, t->data_sections[idx][s_idx], idx, s_idx, fail_on_full)){ + ret_val = 0; + } + + // not used this frame + t->data_sections[idx][s_idx]->used_this_frame = 0; + } + } + + // zero out pretty much everything in the parent struct since he's just the root + t->bitmap_id = bitmap_id; + t->texture_handle = 0; + t->time_created = t->data_sections[sx][sy]->time_created; + t->used_this_frame = 0; + /* + t->vram_texture = NULL; + t->vram_texture_surface = NULL + */ + } + + // argh. we failed to upload. free anything we can + if(!ret_val){ + opengl1_free_texture(t); + } + // swap in the texture we want + else { + t = t->data_sections[sx][sy]; + } + } + // all other "normal" textures + else if((bitmap_id < 0) || (bitmap_id != t->bitmap_id)){ + ret_val = opengl1_create_texture( bitmap_id, bitmap_type, t, fail_on_full ); + } + + // everything went ok + if(ret_val && (t->texture_handle) && !vram_full){ + *u_scale = t->u_scale; + *v_scale = t->v_scale; + + GL_bound_texture = t; + + glBindTexture (GL_TEXTURE_2D, t->texture_handle ); + + /* this should be set next anyway */ +// if (GL_current_texture_source != TEXTURE_SOURCE_NONE) { +// gr_opengl_set_texture_state(GL_current_texture_source); +// } + + GL_last_bitmap_id = t->bitmap_id; + GL_last_bitmap_type = bitmap_type; + GL_last_section_x = sx; + GL_last_section_y = sy; + + t->used_this_frame = GL_frame_count; + } + // gah + else { + GL_last_bitmap_id = -1; + GL_last_bitmap_type = -1; + + GL_last_section_x = -1; + GL_last_section_y = -1; + + GL_bound_texture = NULL; + + glBindTexture (GL_TEXTURE_2D, 0); // test - DDOI + return 0; + } + + return 1; +} + +void gr_opengl1_preload_init() +{ + if (gr_screen.mode != GR_OPENGL) { + return; + } + + opengl1_tcache_flush(); +} + +int gr_opengl1_preload(int bitmap_num, int is_aabitmap) +{ + if ( gr_screen.mode != GR_OPENGL) { + return 0; + } + + if ( !GL_should_preload ) { + return 0; + } + + float u_scale, v_scale; + int retval; + int bitmap_type = TCACHE_TYPE_NORMAL; + + if ( is_aabitmap ) { + bitmap_type = TCACHE_TYPE_AABITMAP; + } + + retval = opengl1_tcache_set(bitmap_num, bitmap_type, &u_scale, &v_scale, 1, -1, -1, 0 ); + + if ( !retval ) { + mprintf(("Texture upload failed!\n" )); + } + + return retval; +} diff --git a/src/menuui/credits.cpp b/src/menuui/credits.cpp index ab82262..dbd4d43 100644 --- a/src/menuui/credits.cpp +++ b/src/menuui/credits.cpp @@ -806,15 +806,7 @@ void credits_do_frame(float frametime) sy = fl2i(Credit_position-0.5f); } - // HACK - I don't want to change the string code, so we'll just use a special version here - if(gr_screen.mode == GR_GLIDE){ -#ifndef PLAT_UNIX - extern void gr_glide_string_hack(int sx, int sy, char *s); - gr_glide_string_hack(0x8000, sy, Credit_text); -#endif - } else { - gr_string(0x8000, sy, Credit_text); - } + gr_string(0x8000, sy, Credit_text); int temp_time; temp_time = timer_get_milliseconds(); diff --git a/src/menuui/mainhallmenu.cpp b/src/menuui/mainhallmenu.cpp index 23b15fc..d865fc9 100644 --- a/src/menuui/mainhallmenu.cpp +++ b/src/menuui/mainhallmenu.cpp @@ -850,8 +850,8 @@ void main_hall_init(int main_hall_num) // init tooltip shader #ifndef MAKE_FS1 float gray_intensity = 0.02f; // nearly black - float c = (gr_screen.mode == GR_DIRECT3D || gr_screen.mode == GR_OPENGL) ? 0.11f : 0.07f; // adjust for renderer differences - gr_create_shader(&Main_hall_tooltip_shader, gray_intensity, gray_intensity, gray_intensity, c); +// float c = (gr_screen.mode == GR_DIRECT3D || gr_screen.mode == GR_OPENGL) ? 0.11f : 0.07f; // adjust for renderer differences + gr_create_shader(&Main_hall_tooltip_shader, gray_intensity, gray_intensity, gray_intensity, 0.11f); #endif // load the background bitmap @@ -1292,32 +1292,19 @@ void main_hall_do(float frametime) gr_set_color_fast(&Color_white); // d3d - if(gr_screen.mode == GR_DIRECT3D){ - if(Bm_pixel_format == BM_PIXEL_FORMAT_ARGB_D3D){ - gr_string(320, gr_screen.max_h - 10, "D3D ARGB"); - } - extern int D3d_rendition_uvs; - extern int D3D_32bit; - extern int D3D_fog_mode; - extern int D3D_zbias; - if(D3d_rendition_uvs){ - gr_string(320, gr_screen.max_h - 20, "D3D rendition"); - } - if(D3D_32bit){ - gr_string(320, gr_screen.max_h - 30, "D3D 32bit"); - } - gr_printf(320, gr_screen.max_h - 40, "Fog : %d", D3D_fog_mode); - gr_printf(320, gr_screen.max_h - 50, "Zbias : %d", D3D_zbias); - // extern void d3d_test(); - // d3d_test(); - } else if(gr_screen.mode == GR_GLIDE){ -#ifndef PLAT_UNIX - extern int Glide_voodoo3; - if(Glide_voodoo3){ - gr_string(320, gr_screen.max_h - 20, "VOODOO 3"); - } -#endif + if (Bm_pixel_format == BM_PIXEL_FORMAT_ARGB) { + gr_string(320, gr_screen.max_h - 10, "ARGB"); + } + // extern int D3D_fog_mode; + // extern int D3D_zbias; + + if ( gr_is_32bit() ) { + gr_string(320, gr_screen.max_h - 30, "32bit"); } + // gr_printf(320, gr_screen.max_h - 40, "Fog : %d", D3D_fog_mode); + // gr_printf(320, gr_screen.max_h - 50, "Zbias : %d", D3D_zbias); + // extern void d3d_test(); + // d3d_test(); #endif gr_flip(); diff --git a/src/model/modelinterp.cpp b/src/model/modelinterp.cpp index 0af9e31..63d94de 100644 --- a/src/model/modelinterp.cpp +++ b/src/model/modelinterp.cpp @@ -2699,11 +2699,7 @@ void model_really_render(int model_num, matrix *orient, vector * pos, uint flags g3_start_instance_matrix(&auto_back, NULL); } - if (gr_screen.mode == GR_DIRECT3D){ - d3d_zbias(1); - } else if (gr_screen.mode == GR_OPENGL) { - opengl_zbias(1); - } + gr_zbias(1); // Draw the subobjects i = pm->submodel[pm->detail[detail_level]].first_child; @@ -2741,12 +2737,8 @@ void model_really_render(int model_num, matrix *orient, vector * pos, uint flags gr_zbuffer_set(zbuf_mode); - if(gr_screen.mode == GR_DIRECT3D){ - d3d_zbias(0); - } else if (gr_screen.mode == GR_OPENGL) { - opengl_zbias(0); - } - + gr_zbias(0); + // draw the hull of the ship model_interp_sub( (ubyte *)pm->submodel[pm->detail[detail_level]].bsp_data, pm, &pm->submodel[pm->detail[detail_level]], 0 ); @@ -2769,21 +2761,13 @@ void model_really_render(int model_num, matrix *orient, vector * pos, uint flags } // render model insignias - if(gr_screen.mode == GR_DIRECT3D){ - d3d_zbias(1); - } else if (gr_screen.mode == GR_OPENGL) { - opengl_zbias(1); - } + gr_zbias(1); gr_zbuffer_set(GR_ZBUFF_READ); model_render_insignias(pm, detail_level); // zbias back to 0 - if(gr_screen.mode == GR_DIRECT3D){ - d3d_zbias(0); - } else if (gr_screen.mode == GR_OPENGL) { - opengl_zbias(0); - } + gr_zbias(0); // Draw the thruster glow #ifndef MAKE_FS1 @@ -3342,14 +3326,8 @@ void model_page_in_textures(int modelnum, int ship_info_index) int bitmap_num = pm->original_textures[idx]; if ( bitmap_num > -1 ) { - // if we're in Glide (and maybe later with D3D), use nondarkening textures - if(gr_screen.mode == GR_GLIDE){ - bm_lock(bitmap_num, 16, BMP_TEX_NONDARK); - bm_unlock(bitmap_num); - } else { - bm_lock(bitmap_num, 16, BMP_TEX_OTHER); - bm_unlock(bitmap_num); - } + bm_lock(bitmap_num, 16, BMP_TEX_OTHER); + bm_unlock(bitmap_num); } } } diff --git a/src/nebula/neb.cpp b/src/nebula/neb.cpp index 233a24d..f467b38 100644 --- a/src/nebula/neb.cpp +++ b/src/nebula/neb.cpp @@ -169,29 +169,7 @@ float max_rotation = 3.75f; float neb2_flash_fade = 0.3f; // fog values for different ship types -float Neb_ship_fog_vals_glide[MAX_SHIP_TYPE_COUNTS][2] = { - {0.0f, 0.0f}, // SHIP_TYPE_NONE - {10.0f, 500.0f}, // SHIP_TYPE_CARGO - {10.0f, 500.0f}, // SHIP_TYPE_FIGHTER_BOMBER - {10.0f, 600.0f}, // SHIP_TYPE_CRUISER - {10.0f, 600.0f}, // SHIP_TYPE_FREIGHTER - {10.0f, 750.0f}, // SHIP_TYPE_CAPITAL - {10.0f, 500.0f}, // SHIP_TYPE_TRANSPORT - {10.0f, 500.0f}, // SHIP_TYPE_REPAIR_REARM - {10.0f, 500.0f}, // SHIP_TYPE_NAVBUOY - {10.0f, 500.0f}, // SHIP_TYPE_SENTRYGUN - {10.0f, 600.0f}, // SHIP_TYPE_ESCAPEPOD - {10.0f, 1000.0f}, // SHIP_TYPE_SUPERCAP - {10.0f, 500.0f}, // SHIP_TYPE_STEALTH - {10.0f, 500.0f}, // SHIP_TYPE_FIGHTER - {10.0f, 500.0f}, // SHIP_TYPE_BOMBER - {10.0f, 750.0f}, // SHIP_TYPE_DRYDOCK - {10.0f, 600.0f}, // SHIP_TYPE_AWACS - {10.0f, 600.0f}, // SHIP_TYPE_GAS_MINER - {10.0f, 600.0f}, // SHIP_TYPE_CORVETTE - {10.0f, 1000.0f}, // SHIP_TYPE_KNOSSOS_DEVICE -}; -float Neb_ship_fog_vals_d3d[MAX_SHIP_TYPE_COUNTS][2] = { +float Neb_ship_fog_vals[MAX_SHIP_TYPE_COUNTS][2] = { {0.0f, 0.0f}, // SHIP_TYPE_NONE {10.0f, 500.0f}, // SHIP_TYPE_CARGO {10.0f, 500.0f}, // SHIP_TYPE_FIGHTER_BOMBER @@ -215,12 +193,10 @@ float Neb_ship_fog_vals_d3d[MAX_SHIP_TYPE_COUNTS][2] = { }; // fog near and far values for rendering the background nebula -#define NEB_BACKG_FOG_NEAR_GLIDE 2.5f -#define NEB_BACKG_FOG_NEAR_D3D 4.5f -#define NEB_BACKG_FOG_FAR_GLIDE 10.0f -#define NEB_BACKG_FOG_FAR_D3D 10.0f -float Neb_backg_fog_near = NEB_BACKG_FOG_NEAR_GLIDE; -float Neb_backg_fog_far = NEB_BACKG_FOG_FAR_GLIDE; +#define NEB_BACKG_FOG_NEAR 4.5f +#define NEB_BACKG_FOG_FAR 10.0f +float Neb_backg_fog_near = NEB_BACKG_FOG_NEAR; +float Neb_backg_fog_far = NEB_BACKG_FOG_FAR; // stats int pneb_tried = 0; // total pnebs tried to render @@ -437,22 +413,8 @@ void neb2_level_init() neb_tossed_count = 0; // setup proper fogging values - switch(gr_screen.mode){ - case GR_GLIDE: - Neb_backg_fog_near = NEB_BACKG_FOG_NEAR_GLIDE; - Neb_backg_fog_far = NEB_BACKG_FOG_FAR_GLIDE; - break; - case GR_OPENGL: - case GR_DIRECT3D: - Neb_backg_fog_near = NEB_BACKG_FOG_NEAR_D3D; - Neb_backg_fog_far = NEB_BACKG_FOG_FAR_D3D; - break; - case GR_SOFTWARE: - SDL_assert(Fred_running); - break; - default : - Int3(); - } + Neb_backg_fog_near = NEB_BACKG_FOG_NEAR; + Neb_backg_fog_far = NEB_BACKG_FOG_FAR; // regen the nebula neb2_eye_changed(); @@ -1153,21 +1115,8 @@ void neb2_get_fog_values(float *fnear, float *ffar, object *objp) } // get the values - switch(gr_screen.mode){ - case GR_GLIDE: - *fnear = Neb_ship_fog_vals_glide[fog_index][0]; - *ffar = Neb_ship_fog_vals_glide[fog_index][1]; - break; - - case GR_OPENGL: - case GR_DIRECT3D: - *fnear = Neb_ship_fog_vals_d3d[fog_index][0]; - *ffar = Neb_ship_fog_vals_d3d[fog_index][1]; - break; - - default: - Int3(); - } + *fnear = Neb_ship_fog_vals[fog_index][0]; + *ffar = Neb_ship_fog_vals[fog_index][1]; } // given a position in space, return a value from 0.0 to 1.0 representing the fog level @@ -1224,12 +1173,6 @@ void neb2_pre_render(vector *eye_pos, matrix *eye_orient) Neb2_render_mode = neb_save; - // HACK - flush d3d here so everything is rendered - if(gr_screen.mode == GR_DIRECT3D){ - extern void d3d_flush(); - d3d_flush(); - } - // grab the region gr_get_region(0, this_esize, this_esize, (ubyte*)tpixels); @@ -1248,12 +1191,6 @@ void neb2_pre_render(vector *eye_pos, matrix *eye_orient) gr_clear(); - // HACK - flush d3d here so everything is properly cleared - if(gr_screen.mode == GR_DIRECT3D){ - extern void d3d_flush(); - d3d_flush(); - } - // if the size has changed between frames, make a new bitmap if(this_esize != last_esize){ last_esize = this_esize; @@ -1513,14 +1450,8 @@ DCF(neb2_fog, "") Neb_backg_fog_near = fnear; Neb_backg_fog_far = ffar; } else { - if(gr_screen.mode == GR_GLIDE){ - Neb_ship_fog_vals_glide[index][0] = fnear; - Neb_ship_fog_vals_glide[index][1] = ffar; - } else { - SDL_assert(gr_screen.mode == GR_DIRECT3D || gr_screen.mode == GR_OPENGL); - Neb_ship_fog_vals_d3d[index][0] = fnear; - Neb_ship_fog_vals_d3d[index][1] = ffar; - } + Neb_ship_fog_vals[index][0] = fnear; + Neb_ship_fog_vals[index][1] = ffar; } } } @@ -1631,33 +1562,19 @@ DCF(neb2_background, "") DCF(neb2_fog_vals, "") { dc_printf("neb2_fog : \n"); - if(gr_screen.mode == GR_GLIDE){ - dc_printf("(1)cargo containers : %f, %f\n", Neb_ship_fog_vals_glide[1][0], Neb_ship_fog_vals_glide[1][1]); - dc_printf("(2)fighters/bombers : %f, %f\n", Neb_ship_fog_vals_glide[2][0], Neb_ship_fog_vals_glide[2][1]); - dc_printf("(3)cruisers : %f, %f\n", Neb_ship_fog_vals_glide[3][0], Neb_ship_fog_vals_glide[3][1]); - dc_printf("(4)freighters : %f, %f\n", Neb_ship_fog_vals_glide[4][0], Neb_ship_fog_vals_glide[4][1]); - dc_printf("(5)cap ships : %f, %f\n", Neb_ship_fog_vals_glide[5][0], Neb_ship_fog_vals_glide[5][1]); - dc_printf("(6)transports : %f, %f\n", Neb_ship_fog_vals_glide[6][0], Neb_ship_fog_vals_glide[6][1]); - dc_printf("(7)support ships : %f, %f\n", Neb_ship_fog_vals_glide[7][0], Neb_ship_fog_vals_glide[7][1]); - dc_printf("(8)navbuoys : %f, %f\n", Neb_ship_fog_vals_glide[8][0], Neb_ship_fog_vals_glide[8][1]); - dc_printf("(9)sentry guns : %f, %f\n", Neb_ship_fog_vals_glide[9][0], Neb_ship_fog_vals_glide[9][1]); - dc_printf("(10)escape pods : %f, %f\n", Neb_ship_fog_vals_glide[10][0], Neb_ship_fog_vals_glide[10][1]); - dc_printf("(11)background polys : %f, %f\n\n", Neb_backg_fog_near, Neb_backg_fog_far); - } else { - SDL_assert(gr_screen.mode == GR_DIRECT3D || gr_screen.mode == GR_OPENGL); - dc_printf("(1)cargo containers : %f, %f\n", Neb_ship_fog_vals_d3d[1][0], Neb_ship_fog_vals_d3d[1][1]); - dc_printf("(2)fighters/bombers : %f, %f\n", Neb_ship_fog_vals_d3d[2][0], Neb_ship_fog_vals_d3d[2][1]); - dc_printf("(3)cruisers : %f, %f\n", Neb_ship_fog_vals_d3d[3][0], Neb_ship_fog_vals_d3d[3][1]); - dc_printf("(4)freighters : %f, %f\n", Neb_ship_fog_vals_d3d[4][0], Neb_ship_fog_vals_d3d[4][1]); - dc_printf("(5)cap ships : %f, %f\n", Neb_ship_fog_vals_d3d[5][0], Neb_ship_fog_vals_d3d[5][1]); - dc_printf("(6)transports : %f, %f\n", Neb_ship_fog_vals_d3d[6][0], Neb_ship_fog_vals_d3d[6][1]); - dc_printf("(7)support ships : %f, %f\n", Neb_ship_fog_vals_d3d[7][0], Neb_ship_fog_vals_d3d[7][1]); - dc_printf("(8)navbuoys : %f, %f\n", Neb_ship_fog_vals_d3d[8][0], Neb_ship_fog_vals_d3d[8][1]); - dc_printf("(9)sentry guns : %f, %f\n", Neb_ship_fog_vals_d3d[9][0], Neb_ship_fog_vals_d3d[9][1]); - dc_printf("(10)escape pods : %f, %f\n", Neb_ship_fog_vals_d3d[10][0], Neb_ship_fog_vals_d3d[10][1]); - dc_printf("(11)background polys : %f, %f\n\n", Neb_backg_fog_near, Neb_backg_fog_far); - } + dc_printf("(1)cargo containers : %f, %f\n", Neb_ship_fog_vals[1][0], Neb_ship_fog_vals[1][1]); + dc_printf("(2)fighters/bombers : %f, %f\n", Neb_ship_fog_vals[2][0], Neb_ship_fog_vals[2][1]); + dc_printf("(3)cruisers : %f, %f\n", Neb_ship_fog_vals[3][0], Neb_ship_fog_vals[3][1]); + dc_printf("(4)freighters : %f, %f\n", Neb_ship_fog_vals[4][0], Neb_ship_fog_vals[4][1]); + dc_printf("(5)cap ships : %f, %f\n", Neb_ship_fog_vals[5][0], Neb_ship_fog_vals[5][1]); + dc_printf("(6)transports : %f, %f\n", Neb_ship_fog_vals[6][0], Neb_ship_fog_vals[6][1]); + dc_printf("(7)support ships : %f, %f\n", Neb_ship_fog_vals[7][0], Neb_ship_fog_vals[7][1]); + dc_printf("(8)navbuoys : %f, %f\n", Neb_ship_fog_vals[8][0], Neb_ship_fog_vals[8][1]); + dc_printf("(9)sentry guns : %f, %f\n", Neb_ship_fog_vals[9][0], Neb_ship_fog_vals[9][1]); + dc_printf("(10)escape pods : %f, %f\n", Neb_ship_fog_vals[10][0], Neb_ship_fog_vals[10][1]); + dc_printf("(11)background polys : %f, %f\n\n", Neb_backg_fog_near, Neb_backg_fog_far); + dc_printf("neb2_max_alpha : %f\n", Nd->max_alpha_glide); dc_printf("neb2_break_alpha : %f\n", Nd->break_alpha); dc_printf("neb2_break_off : %d\n", (int)Nd->break_y); diff --git a/src/render/3ddraw.cpp b/src/render/3ddraw.cpp index c168926..046a53a 100644 --- a/src/render/3ddraw.cpp +++ b/src/render/3ddraw.cpp @@ -1771,7 +1771,7 @@ int g3_draw_2d_poly_bitmap(int x, int y, int w, int h, uint additional_tmap_flag saved_zbuffer_mode = gr_zbuffer_get(); gr_zbuffer_set(GR_ZBUFF_NONE); - bm_get_section_size(gr_screen.current_bitmap, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, &bw, &bh); +// bm_get_section_size(gr_screen.current_bitmap, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, &bw, &bh); // stuff coords v[0].sx = (float)x; diff --git a/src/render/3dlaser.cpp b/src/render/3dlaser.cpp index 3aa303c..8f02c5f 100644 --- a/src/render/3dlaser.cpp +++ b/src/render/3dlaser.cpp @@ -296,11 +296,7 @@ float g3_draw_laser(vector *headp, float head_width, vector *tailp, float tail_w v[3].v = 1.0f; v[3].b = 191; - if(gr_screen.mode == GR_GLIDE){ - gr_tmapper(4, vertlist, tmap_flags); - } else { - gr_tmapper(4, vertlist, tmap_flags | TMAP_FLAG_CORRECT); - } + gr_tmapper(4, vertlist, tmap_flags | TMAP_FLAG_CORRECT); return depth; } @@ -468,11 +464,7 @@ float g3_draw_laser_rgb(vector *headp, float head_width, vector *tailp, float ta v[3].b = (ubyte)b; v[3].a = 255; - if(gr_screen.mode == GR_GLIDE){ - gr_tmapper(4, vertlist, tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD); - } else { - gr_tmapper(4, vertlist, tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT); - } + gr_tmapper(4, vertlist, tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT); return depth; } diff --git a/src/render/3dmath.cpp b/src/render/3dmath.cpp index 3fe53e1..8ecae54 100644 --- a/src/render/3dmath.cpp +++ b/src/render/3dmath.cpp @@ -282,11 +282,8 @@ int g3_project_vertex(vertex *p) p->sx = (Canvas_width + (p->x*Canvas_width*w))*0.5f; p->sy = (Canvas_height - (p->y*Canvas_height*w))*0.5f; - if(gr_screen.mode == GR_GLIDE){ - if ( w > 61439.0f ) w = 61439.0f; - } else { - if ( w > 1.0f ) w = 1.0f; - } + if ( w > 1.0f ) w = 1.0f; + p->sw = w; p->flags |= PF_PROJECTED; } diff --git a/src/ship/ship.cpp b/src/ship/ship.cpp index fbd3f10..e4412b0 100644 --- a/src/ship/ship.cpp +++ b/src/ship/ship.cpp @@ -8987,12 +8987,7 @@ void ship_page_in() int bitmap_num = pm->original_textures[j]; if ( bitmap_num > -1 ) { - // if we're in Glide (and maybe later with D3D), use nondarkening textures - if(gr_screen.mode == GR_GLIDE){ - bm_page_in_nondarkening_texture( bitmap_num ); - } else { - bm_page_in_texture( bitmap_num ); - } + bm_page_in_texture( bitmap_num ); } } diff --git a/src/weapon/weapons.cpp b/src/weapon/weapons.cpp index a3d8490..a28b3d4 100644 --- a/src/weapon/weapons.cpp +++ b/src/weapon/weapons.cpp @@ -1583,11 +1583,11 @@ void weapon_level_init() MONITOR( NumWeaponsRend ); -float weapon_glow_scale_f = 2.3f; -float weapon_glow_scale_r = 2.3f; -float weapon_glow_scale_l = 1.5f; -float weapon_glow_alpha_d3d = 0.85f; -float weapon_glow_alpha_glide = 0.99f; +static const float weapon_glow_scale_f = 2.3f; +static const float weapon_glow_scale_r = 2.3f; +static const float weapon_glow_scale_l = 1.5f; +static const float weapon_glow_alpha = 0.85f; + void weapon_render(object *obj) { int num; @@ -1627,7 +1627,7 @@ void weapon_render(object *obj) vector headp2; vm_vec_scale_add(&headp2, &obj->pos, &obj->orient.v.fvec, wip->laser_length * weapon_glow_scale_l); - gr_set_bitmap(wip->laser_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, (gr_screen.mode == GR_DIRECT3D || gr_screen.mode == GR_OPENGL) ? weapon_glow_alpha_d3d : weapon_glow_alpha_glide, -1, -1); + gr_set_bitmap(wip->laser_glow_bitmap, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, weapon_glow_alpha, -1, -1); g3_draw_laser_rgb(&headp2, wip->laser_head_radius * weapon_glow_scale_f, &obj->pos, wip->laser_tail_radius * weapon_glow_scale_r, c.red, c.green, c.blue); } break; @@ -3380,12 +3380,7 @@ void weapons_page_in() int bitmap_num = pm->original_textures[j]; if ( bitmap_num > -1 ) { - // if we're in Glide (and maybe later with D3D), use nondarkening textures - if(gr_screen.mode == GR_GLIDE){ - bm_page_in_nondarkening_texture( bitmap_num ); - } else { - bm_page_in_texture( bitmap_num ); - } + bm_page_in_texture( bitmap_num ); } } } -- 2.39.2