2014-06-01 17:55:23 +00:00
/*
* This file is part of the DXX - Rebirth project < http : //www.dxx-rebirth.com/>.
* It is copyright by its individual contributors , as recorded in the
* project ' s Git history . See COPYING . txt at the top level for license
* terms and a link to the Git history .
*/
2007-06-10 16:21:53 +00:00
/*
*
* Graphics support functions for OpenGL .
*
*/
2006-03-20 16:43:15 +00:00
//#include <stdio.h>
2008-04-06 20:23:28 +00:00
# ifdef _WIN32
2006-03-20 16:43:15 +00:00
# include <windows.h>
# include <stddef.h>
# endif
2007-06-10 16:21:53 +00:00
# if defined(__APPLE__) && defined(__MACH__)
# include <OpenGL/gl.h>
# include <OpenGL/glu.h>
# else
2011-01-06 11:43:55 +00:00
# ifdef OGLES
# include <GLES/gl.h>
# else
2006-03-20 16:43:15 +00:00
# include <GL/gl.h>
# include <GL/glu.h>
2007-06-10 16:21:53 +00:00
# endif
2011-01-06 11:43:55 +00:00
# endif
2006-03-20 16:43:15 +00:00
# include <string.h>
# include <math.h>
2007-06-10 16:21:53 +00:00
# include <stdio.h>
2006-03-20 16:43:15 +00:00
# include "3d.h"
# include "piggy.h"
2013-03-03 01:03:33 +00:00
# include "common/3d/globvars.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-03-20 16:43:15 +00:00
# include "texmap.h"
# include "palette.h"
# include "rle.h"
2008-04-06 20:23:28 +00:00
# include "console.h"
2013-12-26 04:18:28 +00:00
# include "config.h"
2007-01-09 01:23:49 +00:00
# include "u_mem.h"
2007-06-10 16:21:53 +00:00
# ifdef HAVE_LIBPNG
# include "pngfile.h"
# endif
2006-03-20 16:43:15 +00:00
# include "segment.h"
# include "textures.h"
# include "texmerge.h"
# include "effects.h"
# include "weapon.h"
# include "powerup.h"
2007-06-10 16:21:53 +00:00
# include "laser.h"
# include "player.h"
2006-03-20 16:43:15 +00:00
# include "polyobj.h"
# include "gamefont.h"
2014-07-03 01:47:29 +00:00
# include "byteutil.h"
2008-01-29 14:49:54 +00:00
# include "internal.h"
2007-10-05 23:47:16 +00:00
# include "gauges.h"
2008-04-13 00:28:36 +00:00
# include "playsave.h"
2013-03-03 19:41:09 +00:00
# include "args.h"
2006-03-20 16:43:15 +00:00
2014-01-18 18:02:02 +00:00
# include "compiler-range_for.h"
# include "partial_range.h"
2012-11-11 22:12:51 +00:00
# include <algorithm>
using std : : max ;
2006-03-20 16:43:15 +00:00
//change to 1 for lots of spew.
#if 0
2008-04-06 20:23:28 +00:00
# define glmprintf(0,a) con_printf(CON_DEBUG, a)
2006-03-20 16:43:15 +00:00
# else
# define glmprintf(a)
# endif
# ifndef M_PI
# define M_PI 3.14159
# endif
2008-04-06 20:23:28 +00:00
# if defined(_WIN32) || (defined(__APPLE__) && defined(__MACH__)) || defined(__sun__) || defined(macintosh)
2006-03-20 16:43:15 +00:00
# define cosf(a) cos(a)
# define sinf(a) sin(a)
# endif
2013-08-14 21:12:51 +00:00
static GLubyte * pixels = NULL ;
static GLubyte * texbuf = NULL ;
2013-01-06 21:03:57 +00:00
static palette_array_t * ogl_pal = & gr_palette ;
2006-03-20 16:43:15 +00:00
2013-08-04 22:24:33 +00:00
unsigned last_width = ~ 0u , last_height = ~ 0u ;
2006-03-20 16:43:15 +00:00
int GL_TEXTURE_2D_enabled = - 1 ;
2011-01-16 00:50:28 +00:00
GLfloat ogl_maxanisotropy = 0 ;
2006-03-20 16:43:15 +00:00
2013-08-14 21:12:51 +00:00
static int r_texcount = 0 , r_cachedtexcount = 0 ;
2011-01-06 11:43:55 +00:00
# ifdef OGLES
2013-08-14 21:12:51 +00:00
static int ogl_rgba_internalformat = GL_RGBA ;
static int ogl_rgb_internalformat = GL_RGB ;
2011-01-06 11:43:55 +00:00
# else
2013-08-14 21:12:51 +00:00
static int ogl_rgba_internalformat = GL_RGBA8 ;
static int ogl_rgb_internalformat = GL_RGB8 ;
2011-01-06 11:43:55 +00:00
# endif
2013-08-14 21:12:51 +00:00
static GLfloat * sphere_va = NULL , * circle_va = NULL , * disk_va = NULL ;
static GLfloat * secondary_lva [ 3 ] = { NULL , NULL , NULL } ;
static int r_polyc , r_tpolyc , r_bitmapc , r_ubitbltc ;
int r_upixelc ;
2008-10-28 17:04:35 +00:00
# define f2glf(x) (f2fl(x))
2007-01-09 01:23:49 +00:00
2007-02-19 15:30:13 +00:00
# define OGL_BINDTEXTURE(a) glBindTexture(GL_TEXTURE_2D, a);
2006-03-20 16:43:15 +00:00
2013-08-14 21:12:51 +00:00
static ogl_texture ogl_texture_list [ OGL_TEXTURE_LIST_SIZE ] ;
static int ogl_texture_list_cur ;
2006-03-20 16:43:15 +00:00
2007-06-10 16:21:53 +00:00
/* some function prototypes */
# define GL_TEXTURE0_ARB 0x84C0
2013-08-14 21:12:51 +00:00
static int ogl_loadtexture ( unsigned char * data , int dxo , int dyo , ogl_texture * tex , int bm_flags , int data_format , int texfilt ) ;
static void ogl_freetexture ( ogl_texture * gltexture ) ;
static void ogl_loadbmtexture ( grs_bitmap * bm )
{
ogl_loadbmtexture_f ( bm , GameCfg . TexFilt ) ;
}
2007-06-10 16:21:53 +00:00
2011-01-06 11:43:55 +00:00
# ifdef OGLES
// Replacement for gluPerspective
2013-08-14 21:12:51 +00:00
static void perspective ( double fovy , double aspect , double zNear , double zFar )
2011-01-06 11:43:55 +00:00
{
double xmin , xmax , ymin , ymax ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
ymax = zNear * tan ( fovy * M_PI / 360.0 ) ;
ymin = - ymax ;
xmin = ymin * aspect ;
xmax = ymax * aspect ;
glFrustumf ( xmin , xmax , ymin , ymax , zNear , zFar ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glHint ( GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST ) ;
glDepthMask ( GL_TRUE ) ;
}
# endif
2013-08-14 21:12:51 +00:00
static void ogl_init_texture_stats ( ogl_texture * t ) {
2006-03-20 16:43:15 +00:00
t - > prio = 0.3 ; //default prio
t - > numrend = 0 ;
}
2009-11-30 19:11:46 +00:00
2007-06-10 16:21:53 +00:00
void ogl_init_texture ( ogl_texture * t , int w , int h , int flags )
{
t - > handle = 0 ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2007-06-10 16:21:53 +00:00
if ( flags & OGL_FLAG_NOCOLOR )
{
// use GL_INTENSITY instead of GL_RGB
if ( flags & OGL_FLAG_ALPHA )
{
2007-07-23 18:13:49 +00:00
if ( GameArg . DbgGlIntensity4Ok )
2007-06-10 16:21:53 +00:00
{
t - > internalformat = GL_INTENSITY4 ;
t - > format = GL_LUMINANCE ;
}
2007-07-23 18:13:49 +00:00
else if ( GameArg . DbgGlLuminance4Alpha4Ok )
2007-06-10 16:21:53 +00:00
{
t - > internalformat = GL_LUMINANCE4_ALPHA4 ;
t - > format = GL_LUMINANCE_ALPHA ;
}
2007-07-23 18:13:49 +00:00
else if ( GameArg . DbgGlRGBA2Ok )
2007-06-10 16:21:53 +00:00
{
t - > internalformat = GL_RGBA2 ;
t - > format = GL_RGBA ;
}
else
{
t - > internalformat = ogl_rgba_internalformat ;
t - > format = GL_RGBA ;
}
}
else
{
// there are certainly smaller formats we could use here, but nothing needs it ATM.
t - > internalformat = ogl_rgb_internalformat ;
t - > format = GL_RGB ;
}
}
else
{
2011-01-06 11:43:55 +00:00
# endif
2007-06-10 16:21:53 +00:00
if ( flags & OGL_FLAG_ALPHA )
{
t - > internalformat = ogl_rgba_internalformat ;
t - > format = GL_RGBA ;
}
else
{
t - > internalformat = ogl_rgb_internalformat ;
t - > format = GL_RGB ;
}
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2007-06-10 16:21:53 +00:00
}
2011-01-06 11:43:55 +00:00
# endif
2007-06-10 16:21:53 +00:00
t - > wrapstate = - 1 ;
t - > lw = t - > w = w ;
t - > h = h ;
2006-03-20 16:43:15 +00:00
ogl_init_texture_stats ( t ) ;
}
2007-06-10 16:21:53 +00:00
2013-08-14 21:12:51 +00:00
static void ogl_reset_texture ( ogl_texture * t )
2007-06-10 16:21:53 +00:00
{
ogl_init_texture ( t , 0 , 0 , 0 ) ;
}
2013-08-14 21:12:51 +00:00
static void ogl_reset_texture_stats_internal ( void ) {
2006-03-20 16:43:15 +00:00
int i ;
for ( i = 0 ; i < OGL_TEXTURE_LIST_SIZE ; i + + )
if ( ogl_texture_list [ i ] . handle > 0 ) {
ogl_init_texture_stats ( & ogl_texture_list [ i ] ) ;
}
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
void ogl_init_texture_list_internal ( void ) {
int i ;
ogl_texture_list_cur = 0 ;
for ( i = 0 ; i < OGL_TEXTURE_LIST_SIZE ; i + + )
2007-06-10 16:21:53 +00:00
ogl_reset_texture ( & ogl_texture_list [ i ] ) ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
void ogl_smash_texture_list_internal ( void ) {
int i ;
2011-01-06 11:43:55 +00:00
if ( sphere_va ! = NULL )
{
d_free ( sphere_va ) ;
sphere_va = NULL ;
}
2011-02-09 16:18:26 +00:00
if ( circle_va ! = NULL )
{
d_free ( circle_va ) ;
circle_va = NULL ;
}
if ( disk_va ! = NULL )
{
d_free ( disk_va ) ;
disk_va = NULL ;
}
2011-01-06 11:43:55 +00:00
for ( i = 0 ; i < 3 ; i + + ) {
if ( secondary_lva [ i ] ! = NULL )
{
d_free ( secondary_lva [ i ] ) ;
secondary_lva [ i ] = NULL ;
}
}
2006-03-20 16:43:15 +00:00
for ( i = 0 ; i < OGL_TEXTURE_LIST_SIZE ; i + + ) {
if ( ogl_texture_list [ i ] . handle > 0 ) {
glDeleteTextures ( 1 , & ogl_texture_list [ i ] . handle ) ;
ogl_texture_list [ i ] . handle = 0 ;
}
2007-06-10 16:21:53 +00:00
ogl_texture_list [ i ] . wrapstate = - 1 ;
2006-03-20 16:43:15 +00:00
}
}
ogl_texture * ogl_get_free_texture ( void ) {
int i ;
for ( i = 0 ; i < OGL_TEXTURE_LIST_SIZE ; i + + ) {
if ( ogl_texture_list [ ogl_texture_list_cur ] . handle < = 0 & & ogl_texture_list [ ogl_texture_list_cur ] . w = = 0 )
return & ogl_texture_list [ ogl_texture_list_cur ] ;
if ( + + ogl_texture_list_cur > = OGL_TEXTURE_LIST_SIZE )
ogl_texture_list_cur = 0 ;
}
Error ( " OGL: texture list full! \n " ) ;
}
2007-06-10 16:21:53 +00:00
2013-10-27 22:00:14 +00:00
static void ogl_texture_stats ( void )
2008-10-28 17:04:35 +00:00
{
2007-06-10 16:21:53 +00:00
int used = 0 , usedother = 0 , usedidx = 0 , usedrgb = 0 , usedrgba = 0 ;
int databytes = 0 , truebytes = 0 , datatexel = 0 , truetexel = 0 , i ;
2006-03-20 16:43:15 +00:00
int prio0 = 0 , prio1 = 0 , prio2 = 0 , prio3 = 0 , prioh = 0 ;
2008-10-28 17:04:35 +00:00
GLint idx , r , g , b , a , dbl , depth ;
int res , colorsize , depthsize ;
2006-03-20 16:43:15 +00:00
ogl_texture * t ;
2008-10-28 17:04:35 +00:00
2006-03-20 16:43:15 +00:00
for ( i = 0 ; i < OGL_TEXTURE_LIST_SIZE ; i + + ) {
t = & ogl_texture_list [ i ] ;
if ( t - > handle > 0 ) {
used + + ;
datatexel + = t - > w * t - > h ;
truetexel + = t - > tw * t - > th ;
databytes + = t - > bytesu ;
truebytes + = t - > bytes ;
if ( t - > prio < 0.299 ) prio0 + + ;
else if ( t - > prio < 0.399 ) prio1 + + ;
else if ( t - > prio < 0.499 ) prio2 + + ;
else if ( t - > prio < 0.599 ) prio3 + + ;
else prioh + + ;
2007-06-10 16:21:53 +00:00
if ( t - > format = = GL_RGBA )
usedrgba + + ;
else if ( t - > format = = GL_RGB )
usedrgb + + ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2007-06-10 16:21:53 +00:00
else if ( t - > format = = GL_COLOR_INDEX )
usedidx + + ;
2011-01-06 11:43:55 +00:00
# endif
2007-06-10 16:21:53 +00:00
else
usedother + + ;
2006-03-20 16:43:15 +00:00
}
}
2007-06-10 16:21:53 +00:00
2008-10-28 17:04:35 +00:00
res = SWIDTH * SHEIGHT ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2008-10-28 17:04:35 +00:00
glGetIntegerv ( GL_INDEX_BITS , & idx ) ;
2011-01-06 11:43:55 +00:00
# endif
2008-10-28 17:04:35 +00:00
glGetIntegerv ( GL_RED_BITS , & r ) ;
glGetIntegerv ( GL_GREEN_BITS , & g ) ;
glGetIntegerv ( GL_BLUE_BITS , & b ) ;
glGetIntegerv ( GL_ALPHA_BITS , & a ) ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2008-10-28 17:04:35 +00:00
glGetIntegerv ( GL_DOUBLEBUFFER , & dbl ) ;
2011-01-06 11:43:55 +00:00
# endif
2008-10-28 17:04:35 +00:00
dbl + = 1 ;
glGetIntegerv ( GL_DEPTH_BITS , & depth ) ;
gr_set_current_canvas ( NULL ) ;
gr_set_curfont ( GAME_FONT ) ;
gr_set_fontcolor ( BM_XRGB ( 255 , 255 , 255 ) , - 1 ) ;
colorsize = ( idx * res * dbl ) / 8 ;
depthsize = res * depth / 8 ;
2013-06-23 21:31:26 +00:00
gr_printf ( FSPACX ( 2 ) , FSPACY ( 1 ) , " %i flat %i tex %i bitmaps " , r_polyc , r_tpolyc , r_bitmapc ) ;
2008-10-28 17:04:35 +00:00
gr_printf ( FSPACX ( 2 ) , FSPACY ( 1 ) + LINE_SPACING , " %i(%i,%i,%i,%i) %iK(%iK wasted) (%i postcachedtex) " , used , usedrgba , usedrgb , usedidx , usedother , truebytes / 1024 , ( truebytes - databytes ) / 1024 , r_texcount - r_cachedtexcount ) ;
gr_printf ( FSPACX ( 2 ) , FSPACY ( 1 ) + ( LINE_SPACING * 2 ) , " %ibpp(r%i,g%i,b%i,a%i)x%i=%iK depth%i=%iK " , idx , r , g , b , a , dbl , colorsize / 1024 , depth , depthsize / 1024 ) ;
gr_printf ( FSPACX ( 2 ) , FSPACY ( 1 ) + ( LINE_SPACING * 3 ) , " total=%iK " , ( colorsize + depthsize + truebytes ) / 1024 ) ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2013-08-14 21:12:51 +00:00
static void ogl_bindbmtex ( grs_bitmap * bm ) {
2006-03-20 16:43:15 +00:00
if ( bm - > gltexture = = NULL | | bm - > gltexture - > handle < = 0 )
ogl_loadbmtexture ( bm ) ;
OGL_BINDTEXTURE ( bm - > gltexture - > handle ) ;
bm - > gltexture - > numrend + + ;
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
//gltexture MUST be bound first
2013-08-14 21:12:51 +00:00
static void ogl_texwrap ( ogl_texture * gltexture , int state )
2007-06-10 16:21:53 +00:00
{
if ( gltexture - > wrapstate ! = state | | gltexture - > numrend < 1 )
{
2006-03-20 16:43:15 +00:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , state ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , state ) ;
2007-06-10 16:21:53 +00:00
gltexture - > wrapstate = state ;
2006-03-20 16:43:15 +00:00
}
}
//crude texture precaching
//handles: powerups, walls, weapons, polymodels, etc.
//it is done with the horrid do_special_effects kludge so that sides that have to be texmerged and have animated textures will be correctly cached.
//similarly, with the objects(esp weapons), we could just go through and cache em all instead, but that would get ones that might not even be on the level
//TODO: doors
2007-06-10 16:21:53 +00:00
void ogl_cache_polymodel_textures ( int model_num )
{
polymodel * po ;
2006-03-20 16:43:15 +00:00
int i ;
2007-06-10 16:21:53 +00:00
if ( model_num < 0 )
return ;
po = & Polygon_models [ model_num ] ;
2006-03-20 16:43:15 +00:00
for ( i = 0 ; i < po - > n_textures ; i + + ) {
ogl_loadbmtexture ( & GameBitmaps [ ObjBitmaps [ ObjBitmapPtrs [ po - > first_texture + i ] ] . index ] ) ;
}
}
2009-11-30 19:11:46 +00:00
2013-10-27 22:00:14 +00:00
static void ogl_cache_vclip_textures ( vclip * vc ) {
2006-03-20 16:43:15 +00:00
int i ;
for ( i = 0 ; i < vc - > num_frames ; i + + ) {
PIGGY_PAGE_IN ( vc - > frames [ i ] ) ;
ogl_loadbmtexture ( & GameBitmaps [ vc - > frames [ i ] . index ] ) ;
}
}
2007-06-10 16:21:53 +00:00
2013-10-27 22:00:14 +00:00
static void ogl_cache_vclipn_textures ( int i )
2007-06-10 16:21:53 +00:00
{
if ( i > = 0 & & i < VCLIP_MAXNUM )
ogl_cache_vclip_textures ( & Vclip [ i ] ) ;
}
2013-10-27 22:00:14 +00:00
static void ogl_cache_weapon_textures ( int weapon_type )
2007-06-10 16:21:53 +00:00
{
weapon_info * w ;
if ( weapon_type < 0 )
return ;
w = & Weapon_info [ weapon_type ] ;
2006-03-20 16:43:15 +00:00
ogl_cache_vclipn_textures ( w - > flash_vclip ) ;
ogl_cache_vclipn_textures ( w - > robot_hit_vclip ) ;
ogl_cache_vclipn_textures ( w - > wall_hit_vclip ) ;
if ( w - > render_type = = WEAPON_RENDER_VCLIP )
ogl_cache_vclipn_textures ( w - > weapon_vclip ) ;
2007-06-10 16:21:53 +00:00
else if ( w - > render_type = = WEAPON_RENDER_POLYMODEL )
{
2006-03-20 16:43:15 +00:00
ogl_cache_polymodel_textures ( w - > model_num ) ;
2007-06-10 16:21:53 +00:00
ogl_cache_polymodel_textures ( w - > model_num_inner ) ;
}
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
void ogl_cache_level_textures ( void )
{
2014-01-18 18:02:02 +00:00
int seg , side ;
2006-03-20 16:43:15 +00:00
short tmap1 , tmap2 ;
grs_bitmap * bm , * bm2 ;
struct side * sidep ;
int max_efx = 0 , ef ;
ogl_reset_texture_stats_internal ( ) ; //loading a new lev should reset textures
2014-01-18 18:02:02 +00:00
range_for ( eclip & ec , partial_range ( Effects , Num_effects ) )
{
2014-01-19 22:58:24 +00:00
ogl_cache_vclipn_textures ( ec . dest_vclip ) ;
if ( ( ec . changing_wall_texture = = - 1 ) & & ( ec . changing_object_texture = = - 1 ) )
2006-03-20 16:43:15 +00:00
continue ;
2014-01-19 22:58:24 +00:00
if ( ec . vc . num_frames > max_efx )
max_efx = ec . vc . num_frames ;
2006-03-20 16:43:15 +00:00
}
glmprintf ( ( 0 , " max_efx:%i \n " , max_efx ) ) ;
for ( ef = 0 ; ef < max_efx ; ef + + ) {
2014-01-18 18:02:02 +00:00
range_for ( eclip & ec , partial_range ( Effects , Num_effects ) )
{
2014-01-19 22:58:24 +00:00
if ( ( ec . changing_wall_texture = = - 1 ) & & ( ec . changing_object_texture = = - 1 ) )
2006-03-20 16:43:15 +00:00
continue ;
2014-01-19 22:58:24 +00:00
ec . time_left = - 1 ;
2006-03-20 16:43:15 +00:00
}
do_special_effects ( ) ;
for ( seg = 0 ; seg < Num_segments ; seg + + ) {
for ( side = 0 ; side < MAX_SIDES_PER_SEGMENT ; side + + ) {
sidep = & Segments [ seg ] . sides [ side ] ;
tmap1 = sidep - > tmap_num ;
tmap2 = sidep - > tmap_num2 ;
if ( tmap1 < 0 | | tmap1 > = NumTextures ) {
glmprintf ( ( 0 , " ogl_cache_level_textures %i %i %i %i \n " , seg , side , tmap1 , NumTextures ) ) ;
// tmap1=0;
continue ;
}
PIGGY_PAGE_IN ( Textures [ tmap1 ] ) ;
bm = & GameBitmaps [ Textures [ tmap1 ] . index ] ;
if ( tmap2 ! = 0 ) {
PIGGY_PAGE_IN ( Textures [ tmap2 & 0x3FFF ] ) ;
bm2 = & GameBitmaps [ Textures [ tmap2 & 0x3FFF ] . index ] ;
2013-11-10 17:16:55 +00:00
if ( GameArg . DbgUseOldTextureMerge | | ( bm2 - > bm_flags & BM_FLAG_SUPER_TRANSPARENT ) )
2006-03-20 16:43:15 +00:00
bm = texmerge_get_cached_bitmap ( tmap1 , tmap2 ) ;
else {
ogl_loadbmtexture ( bm2 ) ;
}
}
ogl_loadbmtexture ( bm ) ;
}
}
glmprintf ( ( 0 , " finished ef:%i \n " , ef ) ) ;
}
reset_special_effects ( ) ;
init_special_effects ( ) ;
{
2007-06-10 16:21:53 +00:00
// always have lasers, concs, flares. Always shows player appearance, and at least concs are always available to disappear.
ogl_cache_weapon_textures ( Primary_weapon_to_weapon_info [ LASER_INDEX ] ) ;
ogl_cache_weapon_textures ( Secondary_weapon_to_weapon_info [ CONCUSSION_INDEX ] ) ;
ogl_cache_weapon_textures ( FLARE_ID ) ;
ogl_cache_vclipn_textures ( VCLIP_PLAYER_APPEARANCE ) ;
ogl_cache_vclipn_textures ( VCLIP_POWERUP_DISAPPEARANCE ) ;
ogl_cache_polymodel_textures ( Player_ship - > model_num ) ;
ogl_cache_vclipn_textures ( Player_ship - > expl_vclip_num ) ;
2014-01-18 18:02:02 +00:00
for ( unsigned i = 0 ; i < = Highest_object_index ; i + + ) {
2006-03-20 16:43:15 +00:00
if ( Objects [ i ] . render_type = = RT_POWERUP ) {
ogl_cache_vclipn_textures ( Objects [ i ] . rtype . vclip_info . vclip_num ) ;
2013-10-07 23:52:33 +00:00
switch ( get_powerup_id ( & Objects [ i ] ) ) {
2006-03-20 16:43:15 +00:00
case POW_VULCAN_WEAPON :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Primary_weapon_to_weapon_info [ VULCAN_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
case POW_SPREADFIRE_WEAPON :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Primary_weapon_to_weapon_info [ SPREADFIRE_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
case POW_PLASMA_WEAPON :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Primary_weapon_to_weapon_info [ PLASMA_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
case POW_FUSION_WEAPON :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Primary_weapon_to_weapon_info [ FUSION_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
case POW_PROXIMITY_WEAPON :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Secondary_weapon_to_weapon_info [ PROXIMITY_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
case POW_HOMING_AMMO_1 :
case POW_HOMING_AMMO_4 :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Primary_weapon_to_weapon_info [ HOMING_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
case POW_SMARTBOMB_WEAPON :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Secondary_weapon_to_weapon_info [ SMART_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
case POW_MEGA_WEAPON :
2007-06-10 16:21:53 +00:00
ogl_cache_weapon_textures ( Secondary_weapon_to_weapon_info [ MEGA_INDEX ] ) ;
2006-03-20 16:43:15 +00:00
break ;
}
}
else if ( Objects [ i ] . render_type = = RT_POLYOBJ ) {
2007-06-10 16:21:53 +00:00
if ( Objects [ i ] . type = = OBJ_ROBOT )
{
2013-10-07 23:52:33 +00:00
ogl_cache_vclipn_textures ( Robot_info [ get_robot_id ( & Objects [ i ] ) ] . exp1_vclip_num ) ;
ogl_cache_vclipn_textures ( Robot_info [ get_robot_id ( & Objects [ i ] ) ] . exp2_vclip_num ) ;
ogl_cache_weapon_textures ( Robot_info [ get_robot_id ( & Objects [ i ] ) ] . weapon_type ) ;
2007-06-10 16:21:53 +00:00
}
if ( Objects [ i ] . rtype . pobj_info . tmap_override ! = - 1 )
ogl_loadbmtexture ( & GameBitmaps [ Textures [ Objects [ i ] . rtype . pobj_info . tmap_override ] . index ] ) ;
else
ogl_cache_polymodel_textures ( Objects [ i ] . rtype . pobj_info . model_num ) ;
2006-03-20 16:43:15 +00:00
}
}
}
glmprintf ( ( 0 , " finished caching \n " ) ) ;
2007-06-10 16:21:53 +00:00
r_cachedtexcount = r_texcount ;
2006-03-20 16:43:15 +00:00
}
2013-07-27 21:27:51 +00:00
bool g3_draw_line ( g3s_point * p0 , g3s_point * p1 )
2006-03-20 16:43:15 +00:00
{
int c ;
2011-01-06 11:43:55 +00:00
GLfloat color_r , color_g , color_b ;
GLfloat color_array [ ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 } ;
2013-10-09 01:54:12 +00:00
GLfloat vertex_array [ ] = {
static_cast < GLfloat > ( f2glf ( p0 - > p3_vec . x ) ) , static_cast < GLfloat > ( f2glf ( p0 - > p3_vec . y ) ) , static_cast < GLfloat > ( - f2glf ( p0 - > p3_vec . z ) ) ,
static_cast < GLfloat > ( f2glf ( p1 - > p3_vec . x ) ) , static_cast < GLfloat > ( f2glf ( p1 - > p3_vec . y ) ) , static_cast < GLfloat > ( - f2glf ( p1 - > p3_vec . z ) )
} ;
2011-01-06 11:43:55 +00:00
2006-03-20 16:43:15 +00:00
c = grd_curcanv - > cv_color ;
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
2006-03-20 16:43:15 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
2011-01-06 11:43:55 +00:00
color_r = PAL2Tr ( c ) ;
color_g = PAL2Tg ( c ) ;
color_b = PAL2Tb ( c ) ;
color_array [ 0 ] = color_array [ 4 ] = color_r ;
color_array [ 1 ] = color_array [ 5 ] = color_g ;
color_array [ 2 ] = color_array [ 6 ] = color_b ;
color_array [ 3 ] = color_array [ 7 ] = 1.0 ;
glVertexPointer ( 3 , GL_FLOAT , 0 , vertex_array ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
glDrawArrays ( GL_LINES , 0 , 2 ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
2006-03-20 16:43:15 +00:00
return 1 ;
}
2007-06-10 16:21:53 +00:00
2013-10-27 22:00:14 +00:00
static void ogl_drawcircle ( int nsides , int type , GLfloat * vertex_array )
2011-01-06 11:43:55 +00:00
{
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glVertexPointer ( 2 , GL_FLOAT , 0 , vertex_array ) ;
glDrawArrays ( type , 0 , nsides ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2013-08-14 21:12:51 +00:00
static GLfloat * circle_array_init ( int nsides )
2011-01-06 11:43:55 +00:00
{
2006-03-20 16:43:15 +00:00
int i ;
float ang ;
2013-10-24 03:08:58 +00:00
GLfloat * vertex_array ;
MALLOC ( vertex_array , GLfloat , nsides * 2 ) ;
2011-01-06 11:43:55 +00:00
for ( i = 0 ; i < nsides ; i + + ) {
ang = 2.0 * M_PI * i / nsides ;
vertex_array [ i * 2 ] = cosf ( ang ) ;
vertex_array [ i * 2 + 1 ] = sinf ( ang ) ;
2006-03-20 16:43:15 +00:00
}
2011-01-06 11:43:55 +00:00
return vertex_array ;
2006-03-20 16:43:15 +00:00
}
2013-08-14 21:12:51 +00:00
static GLfloat * circle_array_init_2 ( int nsides , float xsc , float xo , float ysc , float yo )
2011-01-06 11:43:55 +00:00
{
int i ;
float ang ;
2013-10-24 03:08:58 +00:00
GLfloat * vertex_array ;
MALLOC ( vertex_array , GLfloat , nsides * 2 ) ;
2011-01-06 11:43:55 +00:00
for ( i = 0 ; i < nsides ; i + + ) {
ang = 2.0 * M_PI * i / nsides ;
vertex_array [ i * 2 ] = cosf ( ang ) * xsc + xo ;
vertex_array [ i * 2 + 1 ] = sinf ( ang ) * ysc + yo ;
}
return vertex_array ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2011-01-10 15:12:00 +00:00
void ogl_draw_vertex_reticle ( int cross , int primary , int secondary , int color , int alpha , int size_offs )
2008-04-19 19:11:32 +00:00
{
2011-01-10 15:12:00 +00:00
int size = 270 + ( size_offs * 20 ) , i ;
float scale = ( ( float ) SWIDTH / SHEIGHT ) , ret_rgba [ 4 ] , ret_dark_rgba [ 4 ] ;
GLfloat cross_lva [ 8 * 2 ] = {
- 4.0 , 2.0 , - 2.0 , 0 , - 3.0 , - 4.0 , - 2.0 , - 3.0 , 4.0 , 2.0 , 2.0 , 0 , 3.0 , - 4.0 , 2.0 , - 3.0 ,
} ;
GLfloat primary_lva [ 4 ] [ 4 * 2 ] = {
{ - 5.5 , - 5.0 , - 6.5 , - 7.5 , - 10.0 , - 7.0 , - 10.0 , - 8.7 } ,
{ - 10.0 , - 7.0 , - 10.0 , - 8.7 , - 15.0 , - 8.5 , - 15.0 , - 9.5 } ,
{ 5.5 , - 5.0 , 6.5 , - 7.5 , 10.0 , - 7.0 , 10.0 , - 8.7 } ,
{ 10.0 , - 7.0 , 10.0 , - 8.7 , 15.0 , - 8.5 , 15.0 , - 9.5 }
} ;
GLfloat dark_lca [ 16 * 4 ] = {
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 ,
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 ,
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 ,
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6
} ;
GLfloat bright_lca [ 16 * 4 ] = {
0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 ,
0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 ,
0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 ,
0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0
} ;
GLfloat cross_lca [ 8 * 4 ] = {
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 1.0 , 0.125 , 1.0 ,
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 1.0 , 0.125 , 1.0 ,
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 1.0 , 0.125 , 1.0 ,
0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 1.0 , 0.125 , 1.0
} ;
GLfloat primary_lca [ 2 ] [ 4 * 4 ] = {
{ 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 } ,
{ 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 0.54 , 0.125 , 0.6 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 , 0.125 , 1.0 }
} ;
ret_rgba [ 0 ] = PAL2Tr ( color ) ;
ret_dark_rgba [ 0 ] = ret_rgba [ 0 ] / 2 ;
ret_rgba [ 1 ] = PAL2Tg ( color ) ;
ret_dark_rgba [ 1 ] = ret_rgba [ 1 ] / 2 ;
ret_rgba [ 2 ] = PAL2Tb ( color ) ;
ret_dark_rgba [ 2 ] = ret_rgba [ 2 ] / 2 ;
ret_rgba [ 3 ] = 1.0 - ( ( float ) alpha / ( ( float ) GR_FADE_LEVELS ) ) ;
ret_dark_rgba [ 3 ] = ret_rgba [ 3 ] / 2 ;
for ( i = 0 ; i < 16 * 4 ; i + = 4 )
{
bright_lca [ i ] = ret_rgba [ 0 ] ;
dark_lca [ i ] = ret_dark_rgba [ 0 ] ;
bright_lca [ i + 1 ] = ret_rgba [ 1 ] ;
dark_lca [ i + 1 ] = ret_dark_rgba [ 1 ] ;
bright_lca [ i + 2 ] = ret_rgba [ 2 ] ;
dark_lca [ i + 2 ] = ret_dark_rgba [ 2 ] ;
bright_lca [ i + 3 ] = ret_rgba [ 3 ] ;
dark_lca [ i + 3 ] = ret_dark_rgba [ 3 ] ;
}
for ( i = 0 ; i < 8 * 4 ; i + = 8 )
{
cross_lca [ i ] = ret_dark_rgba [ 0 ] ;
cross_lca [ i + 1 ] = ret_dark_rgba [ 1 ] ;
cross_lca [ i + 2 ] = ret_dark_rgba [ 2 ] ;
cross_lca [ i + 3 ] = ret_dark_rgba [ 3 ] ;
cross_lca [ i + 4 ] = ret_rgba [ 0 ] ;
cross_lca [ i + 5 ] = ret_rgba [ 1 ] ;
cross_lca [ i + 6 ] = ret_rgba [ 2 ] ;
cross_lca [ i + 7 ] = ret_rgba [ 3 ] ;
}
primary_lca [ 0 ] [ 0 ] = primary_lca [ 0 ] [ 4 ] = primary_lca [ 1 ] [ 8 ] = primary_lca [ 1 ] [ 12 ] = ret_rgba [ 0 ] ;
primary_lca [ 0 ] [ 1 ] = primary_lca [ 0 ] [ 5 ] = primary_lca [ 1 ] [ 9 ] = primary_lca [ 1 ] [ 13 ] = ret_rgba [ 1 ] ;
primary_lca [ 0 ] [ 2 ] = primary_lca [ 0 ] [ 6 ] = primary_lca [ 1 ] [ 10 ] = primary_lca [ 1 ] [ 14 ] = ret_rgba [ 2 ] ;
primary_lca [ 0 ] [ 3 ] = primary_lca [ 0 ] [ 7 ] = primary_lca [ 1 ] [ 11 ] = primary_lca [ 1 ] [ 15 ] = ret_rgba [ 3 ] ;
primary_lca [ 1 ] [ 0 ] = primary_lca [ 1 ] [ 4 ] = primary_lca [ 0 ] [ 8 ] = primary_lca [ 0 ] [ 12 ] = ret_dark_rgba [ 0 ] ;
primary_lca [ 1 ] [ 1 ] = primary_lca [ 1 ] [ 5 ] = primary_lca [ 0 ] [ 9 ] = primary_lca [ 0 ] [ 13 ] = ret_dark_rgba [ 1 ] ;
primary_lca [ 1 ] [ 2 ] = primary_lca [ 1 ] [ 6 ] = primary_lca [ 0 ] [ 10 ] = primary_lca [ 0 ] [ 14 ] = ret_dark_rgba [ 2 ] ;
primary_lca [ 1 ] [ 3 ] = primary_lca [ 1 ] [ 7 ] = primary_lca [ 0 ] [ 11 ] = primary_lca [ 0 ] [ 15 ] = ret_dark_rgba [ 3 ] ;
2008-02-27 22:05:58 +00:00
2006-03-20 16:43:15 +00:00
glPushMatrix ( ) ;
glTranslatef ( ( grd_curcanv - > cv_bitmap . bm_w / 2 + grd_curcanv - > cv_bitmap . bm_x ) / ( float ) last_width , 1.0 - ( grd_curcanv - > cv_bitmap . bm_h / 2 + grd_curcanv - > cv_bitmap . bm_y ) / ( float ) last_height , 0 ) ;
2008-11-09 14:31:30 +00:00
if ( scale > = 1 )
{
size / = scale ;
glScalef ( f2glf ( size ) , f2glf ( size * scale ) , f2glf ( size ) ) ;
}
else
{
size * = scale ;
glScalef ( f2glf ( size / scale ) , f2glf ( size ) , f2glf ( size ) ) ;
}
glLineWidth ( linedotscale * 2 ) ;
2006-03-20 16:43:15 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
2006-07-11 16:13:47 +00:00
glDisable ( GL_CULL_FACE ) ;
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
//cross
if ( cross )
glColorPointer ( 4 , GL_FLOAT , 0 , cross_lca ) ;
2008-04-19 19:11:32 +00:00
else
2011-01-06 11:43:55 +00:00
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
glVertexPointer ( 2 , GL_FLOAT , 0 , cross_lva ) ;
glDrawArrays ( GL_LINES , 0 , 8 ) ;
//left primary bar
if ( primary = = 0 )
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
else
glColorPointer ( 4 , GL_FLOAT , 0 , primary_lca [ 0 ] ) ;
glVertexPointer ( 2 , GL_FLOAT , 0 , primary_lva [ 0 ] ) ;
glDrawArrays ( GL_TRIANGLE_STRIP , 0 , 4 ) ;
if ( primary ! = 2 )
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
else
glColorPointer ( 4 , GL_FLOAT , 0 , primary_lca [ 1 ] ) ;
glVertexPointer ( 2 , GL_FLOAT , 0 , primary_lva [ 1 ] ) ;
glDrawArrays ( GL_TRIANGLE_STRIP , 0 , 4 ) ;
//right primary bar
if ( primary = = 0 )
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
else
glColorPointer ( 4 , GL_FLOAT , 0 , primary_lca [ 0 ] ) ;
glVertexPointer ( 2 , GL_FLOAT , 0 , primary_lva [ 2 ] ) ;
glDrawArrays ( GL_TRIANGLE_STRIP , 0 , 4 ) ;
if ( primary ! = 2 )
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
else
glColorPointer ( 4 , GL_FLOAT , 0 , primary_lca [ 1 ] ) ;
glVertexPointer ( 2 , GL_FLOAT , 0 , primary_lva [ 3 ] ) ;
glDrawArrays ( GL_TRIANGLE_STRIP , 0 , 4 ) ;
if ( secondary < = 2 ) {
//left secondary
if ( secondary ! = 1 )
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
2008-02-27 22:05:58 +00:00
else
2011-01-06 11:43:55 +00:00
glColorPointer ( 4 , GL_FLOAT , 0 , bright_lca ) ;
if ( ! secondary_lva [ 0 ] )
secondary_lva [ 0 ] = circle_array_init_2 ( 16 , 2.0 , - 10.0 , 2.0 , - 2.0 ) ;
ogl_drawcircle ( 16 , GL_LINE_LOOP , secondary_lva [ 0 ] ) ;
//right secondary
if ( secondary ! = 2 )
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
2008-04-19 19:11:32 +00:00
else
2011-01-06 11:43:55 +00:00
glColorPointer ( 4 , GL_FLOAT , 0 , bright_lca ) ;
if ( ! secondary_lva [ 1 ] )
secondary_lva [ 1 ] = circle_array_init_2 ( 16 , 2.0 , 10.0 , 2.0 , - 2.0 ) ;
ogl_drawcircle ( 16 , GL_LINE_LOOP , secondary_lva [ 1 ] ) ;
2008-04-19 19:11:32 +00:00
}
2011-01-06 11:43:55 +00:00
else {
//bottom/middle secondary
if ( secondary ! = 4 )
glColorPointer ( 4 , GL_FLOAT , 0 , dark_lca ) ;
2008-04-19 19:11:32 +00:00
else
2011-01-06 11:43:55 +00:00
glColorPointer ( 4 , GL_FLOAT , 0 , bright_lca ) ;
if ( ! secondary_lva [ 2 ] )
secondary_lva [ 2 ] = circle_array_init_2 ( 16 , 2.0 , 0.0 , 2.0 , - 8.0 ) ;
ogl_drawcircle ( 16 , GL_LINE_LOOP , secondary_lva [ 2 ] ) ;
2008-04-19 19:11:32 +00:00
}
2011-01-06 11:43:55 +00:00
//glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState ( GL_COLOR_ARRAY ) ;
2006-03-20 16:43:15 +00:00
glPopMatrix ( ) ;
2011-02-02 01:12:09 +00:00
glLineWidth ( linedotscale ) ;
2006-03-20 16:43:15 +00:00
}
2008-02-27 22:05:58 +00:00
2011-01-06 11:43:55 +00:00
/*
* Stars on heaven in exit sequence , automap objects
*/
2006-03-20 16:43:15 +00:00
int g3_draw_sphere ( g3s_point * pnt , fix rad ) {
2011-01-06 11:43:55 +00:00
int c = grd_curcanv - > cv_color , i ;
2008-11-09 14:31:30 +00:00
float scale = ( ( float ) grd_curcanv - > cv_bitmap . bm_w / grd_curcanv - > cv_bitmap . bm_h ) ;
2011-01-06 11:43:55 +00:00
GLfloat color_array [ 20 * 4 ] ;
for ( i = 0 ; i < 20 * 4 ; i + = 4 )
{
color_array [ i ] = CPAL2Tr ( c ) ;
color_array [ i + 1 ] = CPAL2Tg ( c ) ;
color_array [ i + 2 ] = CPAL2Tb ( c ) ;
color_array [ i + 3 ] = 1.0 ;
}
2006-03-20 16:43:15 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
2007-06-10 16:21:53 +00:00
glDisable ( GL_CULL_FACE ) ;
2006-03-20 16:43:15 +00:00
glPushMatrix ( ) ;
glTranslatef ( f2glf ( pnt - > p3_vec . x ) , f2glf ( pnt - > p3_vec . y ) , - f2glf ( pnt - > p3_vec . z ) ) ;
2008-11-09 14:31:30 +00:00
if ( scale > = 1 )
{
rad / = scale ;
glScalef ( f2glf ( rad ) , f2glf ( rad * scale ) , f2glf ( rad ) ) ;
}
else
{
rad * = scale ;
glScalef ( f2glf ( rad / scale ) , f2glf ( rad ) , f2glf ( rad ) ) ;
}
2011-01-06 11:43:55 +00:00
if ( ! sphere_va )
sphere_va = circle_array_init ( 20 ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
ogl_drawcircle ( 20 , GL_TRIANGLE_FAN , sphere_va ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
2006-03-20 16:43:15 +00:00
glPopMatrix ( ) ;
return 0 ;
}
2007-06-10 16:21:53 +00:00
int gr_ucircle ( fix xc1 , fix yc1 , fix r1 )
{
2011-01-06 11:43:55 +00:00
int c , nsides ;
2006-03-20 16:43:15 +00:00
c = grd_curcanv - > cv_color ;
OGL_DISABLE ( TEXTURE_2D ) ;
2011-02-23 16:46:36 +00:00
glColor4f ( CPAL2Tr ( c ) , CPAL2Tg ( c ) , CPAL2Tb ( c ) , ( grd_curcanv - > cv_fade_level > = GR_FADE_OFF ) ? 1.0 : 1.0 - ( float ) grd_curcanv - > cv_fade_level / ( ( float ) GR_FADE_LEVELS - 1.0 ) ) ;
2006-03-20 16:43:15 +00:00
glPushMatrix ( ) ;
glTranslatef (
2007-02-20 00:00:28 +00:00
( f2fl ( xc1 ) + grd_curcanv - > cv_bitmap . bm_x + 0.5 ) / ( float ) last_width ,
1.0 - ( f2fl ( yc1 ) + grd_curcanv - > cv_bitmap . bm_y + 0.5 ) / ( float ) last_height , 0 ) ;
glScalef ( f2fl ( r1 ) / last_width , f2fl ( r1 ) / last_height , 1.0 ) ;
2011-01-06 11:43:55 +00:00
nsides = 10 + 2 * ( int ) ( M_PI * f2fl ( r1 ) / 19 ) ;
2011-02-09 16:18:26 +00:00
if ( ! circle_va )
circle_va = circle_array_init ( nsides ) ;
ogl_drawcircle ( nsides , GL_LINE_LOOP , circle_va ) ;
2006-03-20 16:43:15 +00:00
glPopMatrix ( ) ;
return 0 ;
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
int gr_circle ( fix xc1 , fix yc1 , fix r1 ) {
return gr_ucircle ( xc1 , yc1 , r1 ) ;
}
2011-01-10 15:12:00 +00:00
int gr_disk ( fix x , fix y , fix r )
{
int c , nsides ;
c = grd_curcanv - > cv_color ;
OGL_DISABLE ( TEXTURE_2D ) ;
2011-02-23 16:46:36 +00:00
glColor4f ( CPAL2Tr ( c ) , CPAL2Tg ( c ) , CPAL2Tb ( c ) , ( grd_curcanv - > cv_fade_level > = GR_FADE_OFF ) ? 1.0 : 1.0 - ( float ) grd_curcanv - > cv_fade_level / ( ( float ) GR_FADE_LEVELS - 1.0 ) ) ;
2011-01-10 15:12:00 +00:00
glPushMatrix ( ) ;
glTranslatef (
( f2fl ( x ) + grd_curcanv - > cv_bitmap . bm_x + 0.5 ) / ( float ) last_width ,
1.0 - ( f2fl ( y ) + grd_curcanv - > cv_bitmap . bm_y + 0.5 ) / ( float ) last_height , 0 ) ;
glScalef ( f2fl ( r ) / last_width , f2fl ( r ) / last_height , 1.0 ) ;
nsides = 10 + 2 * ( int ) ( M_PI * f2fl ( r ) / 19 ) ;
2011-02-09 16:18:26 +00:00
if ( ! disk_va )
disk_va = circle_array_init ( nsides ) ;
2011-02-10 19:53:19 +00:00
ogl_drawcircle ( nsides , GL_TRIANGLE_FAN , disk_va ) ;
2011-01-10 15:12:00 +00:00
glPopMatrix ( ) ;
return 0 ;
}
2011-01-06 11:43:55 +00:00
/*
* Draw flat - shaded Polygon ( Lasers , Drone - arms , Driller - ears )
*/
2013-07-27 21:27:51 +00:00
bool g3_draw_poly ( int nv , g3s_point * * pointlist )
2006-03-20 16:43:15 +00:00
{
2011-01-06 11:43:55 +00:00
int c , index3 , index4 ;
float color_r , color_g , color_b , color_a ;
2013-12-08 18:22:17 +00:00
RAIIdmem < GLfloat > vertex_array , color_array ;
2011-09-26 21:00:23 +00:00
MALLOC ( vertex_array , GLfloat , nv * 3 ) ;
MALLOC ( color_array , GLfloat , nv * 4 ) ;
2011-01-06 11:43:55 +00:00
2011-09-26 21:00:23 +00:00
r_polyc + + ;
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
c = grd_curcanv - > cv_color ;
2006-03-20 16:43:15 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
2011-01-06 11:43:55 +00:00
color_r = PAL2Tr ( c ) ;
color_g = PAL2Tg ( c ) ;
color_b = PAL2Tb ( c ) ;
2011-02-23 16:46:36 +00:00
if ( grd_curcanv - > cv_fade_level > = GR_FADE_OFF )
2011-01-06 11:43:55 +00:00
color_a = 1.0 ;
2011-02-17 23:17:49 +00:00
else
2011-02-23 16:46:36 +00:00
color_a = 1.0 - ( float ) grd_curcanv - > cv_fade_level / ( ( float ) GR_FADE_LEVELS - 1.0 ) ;
2011-01-06 11:43:55 +00:00
for ( c = 0 ; c < nv ; c + + ) {
index3 = c * 3 ;
index4 = c * 4 ;
color_array [ index4 ] = color_r ;
color_array [ index4 + 1 ] = color_g ;
color_array [ index4 + 2 ] = color_b ;
color_array [ index4 + 3 ] = color_a ;
vertex_array [ index3 ] = f2glf ( pointlist [ c ] - > p3_vec . x ) ;
vertex_array [ index3 + 1 ] = f2glf ( pointlist [ c ] - > p3_vec . y ) ;
vertex_array [ index3 + 2 ] = - f2glf ( pointlist [ c ] - > p3_vec . z ) ;
2006-03-20 16:43:15 +00:00
}
2011-01-06 11:43:55 +00:00
glVertexPointer ( 3 , GL_FLOAT , 0 , vertex_array ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
glDrawArrays ( GL_TRIANGLE_FAN , 0 , nv ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
2006-03-20 16:43:15 +00:00
return 0 ;
}
2012-11-11 22:12:51 +00:00
void gr_upoly_tmap ( int , const int * ) {
2008-04-06 20:23:28 +00:00
glmprintf ( ( 0 , " gr_upoly_tmap: unhandled \n " ) ) ; //should never get called
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2012-11-11 22:12:51 +00:00
void draw_tmap_flat ( grs_bitmap * , int , g3s_point * * ) {
2008-04-06 20:23:28 +00:00
glmprintf ( ( 0 , " draw_tmap_flat: unhandled \n " ) ) ; //should never get called
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2011-01-06 11:43:55 +00:00
/*
* Everything texturemapped ( walls , robots , ship )
*/
2014-07-01 03:10:56 +00:00
bool g3_draw_tmap ( int nv , g3s_point * * pointlist , const g3s_uvl * uvl_list , g3s_lrgb * light_rgb , grs_bitmap * bm )
2006-03-20 16:43:15 +00:00
{
2011-01-06 11:43:55 +00:00
int c , index2 , index3 , index4 ;
2013-12-08 18:22:17 +00:00
GLfloat color_alpha = 1.0 ;
2011-09-26 21:00:23 +00:00
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
if ( tmap_drawer_ptr = = draw_tmap ) {
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2006-03-20 16:43:15 +00:00
OGL_ENABLE ( TEXTURE_2D ) ;
ogl_bindbmtex ( bm ) ;
2011-01-06 11:43:55 +00:00
ogl_texwrap ( bm - > gltexture , GL_REPEAT ) ;
r_tpolyc + + ;
2011-02-23 16:46:36 +00:00
color_alpha = ( grd_curcanv - > cv_fade_level > = GR_FADE_OFF ) ? 1.0 : ( 1.0 - ( float ) grd_curcanv - > cv_fade_level / ( ( float ) GR_FADE_LEVELS - 1.0 ) ) ;
2011-01-06 11:43:55 +00:00
} else if ( tmap_drawer_ptr = = draw_tmap_flat ) {
OGL_DISABLE ( TEXTURE_2D ) ;
/* for cloaked state faces */
2011-02-23 16:46:36 +00:00
color_alpha = 1.0 - ( grd_curcanv - > cv_fade_level / ( GLfloat ) NUM_LIGHTING_LEVELS ) ;
2011-01-06 11:43:55 +00:00
} else {
2008-04-06 20:23:28 +00:00
glmprintf ( ( 0 , " g3_draw_tmap: unhandled tmap_drawer %p \n " , tmap_drawer_ptr ) ) ;
2011-01-06 11:43:55 +00:00
return 0 ;
2006-03-20 16:43:15 +00:00
}
2011-09-26 21:00:23 +00:00
2013-12-08 18:22:17 +00:00
RAIIdmem < GLfloat > vertex_array , color_array , texcoord_array ;
2011-09-26 21:00:23 +00:00
MALLOC ( vertex_array , GLfloat , nv * 3 ) ;
MALLOC ( color_array , GLfloat , nv * 4 ) ;
MALLOC ( texcoord_array , GLfloat , nv * 2 ) ;
2011-01-06 11:43:55 +00:00
for ( c = 0 ; c < nv ; c + + ) {
index2 = c * 2 ;
index3 = c * 3 ;
index4 = c * 4 ;
vertex_array [ index3 ] = f2glf ( pointlist [ c ] - > p3_vec . x ) ;
vertex_array [ index3 + 1 ] = f2glf ( pointlist [ c ] - > p3_vec . y ) ;
vertex_array [ index3 + 2 ] = - f2glf ( pointlist [ c ] - > p3_vec . z ) ;
if ( tmap_drawer_ptr = = draw_tmap_flat ) {
color_array [ index4 ] = 0 ;
2011-04-07 20:32:47 +00:00
color_array [ index4 + 1 ] = color_array [ index4 ] ;
color_array [ index4 + 2 ] = color_array [ index4 ] ;
color_array [ index4 + 3 ] = color_alpha ;
2011-01-06 11:43:55 +00:00
} else {
2011-04-07 20:32:47 +00:00
color_array [ index4 ] = bm - > bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf ( light_rgb [ c ] . r ) ;
color_array [ index4 + 1 ] = bm - > bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf ( light_rgb [ c ] . g ) ;
color_array [ index4 + 2 ] = bm - > bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf ( light_rgb [ c ] . b ) ;
color_array [ index4 + 3 ] = color_alpha ;
2011-01-06 11:43:55 +00:00
}
texcoord_array [ index2 ] = f2glf ( uvl_list [ c ] . u ) ;
texcoord_array [ index2 + 1 ] = f2glf ( uvl_list [ c ] . v ) ;
}
glVertexPointer ( 3 , GL_FLOAT , 0 , vertex_array ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
if ( tmap_drawer_ptr = = draw_tmap ) {
glTexCoordPointer ( 2 , GL_FLOAT , 0 , texcoord_array ) ;
}
glDrawArrays ( GL_TRIANGLE_FAN , 0 , nv ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2006-03-20 16:43:15 +00:00
return 0 ;
}
2011-01-06 11:43:55 +00:00
/*
* Everything texturemapped with secondary texture ( walls with secondary texture )
*/
2013-07-27 21:27:51 +00:00
bool g3_draw_tmap_2 ( int nv , g3s_point * * pointlist , g3s_uvl * uvl_list , g3s_lrgb * light_rgb , grs_bitmap * bmbot , grs_bitmap * bm , int orient )
2007-06-10 16:21:53 +00:00
{
2011-09-26 21:00:23 +00:00
int c , index2 , index3 , index4 ;
2013-12-08 18:22:17 +00:00
RAIIdmem < GLfloat > vertex_array , color_array , texcoord_array ;
2011-09-26 21:00:23 +00:00
MALLOC ( vertex_array , GLfloat , nv * 3 ) ;
MALLOC ( color_array , GLfloat , nv * 4 ) ;
MALLOC ( texcoord_array , GLfloat , nv * 2 ) ;
2011-04-07 20:32:47 +00:00
g3_draw_tmap ( nv , pointlist , uvl_list , light_rgb , bmbot ) ; //draw the bottom texture first.. could be optimized with multitexturing..
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2007-06-10 16:21:53 +00:00
r_tpolyc + + ;
OGL_ENABLE ( TEXTURE_2D ) ;
ogl_bindbmtex ( bm ) ;
ogl_texwrap ( bm - > gltexture , GL_REPEAT ) ;
2011-01-06 11:43:55 +00:00
for ( c = 0 ; c < nv ; c + + ) {
index2 = c * 2 ;
index3 = c * 3 ;
index4 = c * 4 ;
2007-06-10 16:21:53 +00:00
switch ( orient ) {
case 1 :
2011-01-06 11:43:55 +00:00
texcoord_array [ index2 ] = 1.0 - f2glf ( uvl_list [ c ] . v ) ;
texcoord_array [ index2 + 1 ] = f2glf ( uvl_list [ c ] . u ) ;
2007-06-10 16:21:53 +00:00
break ;
case 2 :
2011-01-06 11:43:55 +00:00
texcoord_array [ index2 ] = 1.0 - f2glf ( uvl_list [ c ] . u ) ;
texcoord_array [ index2 + 1 ] = 1.0 - f2glf ( uvl_list [ c ] . v ) ;
2007-06-10 16:21:53 +00:00
break ;
case 3 :
2011-01-06 11:43:55 +00:00
texcoord_array [ index2 ] = f2glf ( uvl_list [ c ] . v ) ;
texcoord_array [ index2 + 1 ] = 1.0 - f2glf ( uvl_list [ c ] . u ) ;
2007-06-10 16:21:53 +00:00
break ;
default :
2011-01-06 11:43:55 +00:00
texcoord_array [ index2 ] = f2glf ( uvl_list [ c ] . u ) ;
texcoord_array [ index2 + 1 ] = f2glf ( uvl_list [ c ] . v ) ;
2007-06-10 16:21:53 +00:00
break ;
2006-03-20 16:43:15 +00:00
}
2011-01-06 11:43:55 +00:00
2011-04-07 20:32:47 +00:00
color_array [ index4 ] = bm - > bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf ( light_rgb [ c ] . r ) ;
color_array [ index4 + 1 ] = bm - > bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf ( light_rgb [ c ] . g ) ;
color_array [ index4 + 2 ] = bm - > bm_flags & BM_FLAG_NO_LIGHTING ? 1.0 : f2glf ( light_rgb [ c ] . b ) ;
2011-02-23 16:46:36 +00:00
color_array [ index4 + 3 ] = ( grd_curcanv - > cv_fade_level > = GR_FADE_OFF ) ? 1.0 : ( 1.0 - ( float ) grd_curcanv - > cv_fade_level / ( ( float ) GR_FADE_LEVELS - 1.0 ) ) ;
2011-01-06 11:43:55 +00:00
vertex_array [ index3 ] = f2glf ( pointlist [ c ] - > p3_vec . x ) ;
vertex_array [ index3 + 1 ] = f2glf ( pointlist [ c ] - > p3_vec . y ) ;
vertex_array [ index3 + 2 ] = - f2glf ( pointlist [ c ] - > p3_vec . z ) ;
2006-03-20 16:43:15 +00:00
}
2011-01-06 11:43:55 +00:00
glVertexPointer ( 3 , GL_FLOAT , 0 , vertex_array ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
glTexCoordPointer ( 2 , GL_FLOAT , 0 , texcoord_array ) ;
glDrawArrays ( GL_TRIANGLE_FAN , 0 , nv ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2011-09-26 21:00:23 +00:00
2006-03-20 16:43:15 +00:00
return 0 ;
}
2011-01-06 11:43:55 +00:00
/*
* 2 d Sprites ( Fireaballs , powerups , explosions ) . NOT hostages
*/
2011-02-23 16:46:36 +00:00
bool g3_draw_bitmap ( vms_vector * pos , fix width , fix height , grs_bitmap * bm )
2006-03-20 16:43:15 +00:00
{
2006-05-05 13:23:53 +00:00
vms_vector pv , v1 ;
2006-03-20 16:43:15 +00:00
int i ;
2011-01-06 11:43:55 +00:00
GLfloat vertex_array [ 12 ] , color_array [ 16 ] , texcoord_array [ 8 ] ;
2006-03-20 16:43:15 +00:00
r_bitmapc + + ;
v1 . z = 0 ;
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2009-11-30 19:11:46 +00:00
2006-03-20 16:43:15 +00:00
OGL_ENABLE ( TEXTURE_2D ) ;
ogl_bindbmtex ( bm ) ;
2008-02-24 14:41:27 +00:00
ogl_texwrap ( bm - > gltexture , GL_CLAMP_TO_EDGE ) ;
2009-11-30 19:11:46 +00:00
2007-02-26 13:32:00 +00:00
width = fixmul ( width , Matrix_scale . x ) ;
height = fixmul ( height , Matrix_scale . y ) ;
2006-03-20 16:43:15 +00:00
for ( i = 0 ; i < 4 ; i + + ) {
vm_vec_sub ( & v1 , pos , & View_position ) ;
vm_vec_rotate ( & pv , & v1 , & View_matrix ) ;
switch ( i ) {
case 0 :
2011-01-06 11:43:55 +00:00
texcoord_array [ i * 2 ] = 0.0 ;
texcoord_array [ i * 2 + 1 ] = 0.0 ;
2006-03-20 16:43:15 +00:00
pv . x + = - width ;
pv . y + = height ;
break ;
case 1 :
2011-01-06 11:43:55 +00:00
texcoord_array [ i * 2 ] = bm - > gltexture - > u ;
texcoord_array [ i * 2 + 1 ] = 0.0 ;
2006-03-20 16:43:15 +00:00
pv . x + = width ;
pv . y + = height ;
break ;
case 2 :
2011-01-06 11:43:55 +00:00
texcoord_array [ i * 2 ] = bm - > gltexture - > u ;
texcoord_array [ i * 2 + 1 ] = bm - > gltexture - > v ;
2006-03-20 16:43:15 +00:00
pv . x + = width ;
pv . y + = - height ;
break ;
case 3 :
2011-01-06 11:43:55 +00:00
texcoord_array [ i * 2 ] = 0.0 ;
texcoord_array [ i * 2 + 1 ] = bm - > gltexture - > v ;
2006-03-20 16:43:15 +00:00
pv . x + = - width ;
pv . y + = - height ;
break ;
}
2009-11-30 19:11:46 +00:00
2011-01-06 11:43:55 +00:00
color_array [ i * 4 ] = 1.0 ;
color_array [ i * 4 + 1 ] = 1.0 ;
color_array [ i * 4 + 2 ] = 1.0 ;
2011-02-23 16:46:36 +00:00
color_array [ i * 4 + 3 ] = ( grd_curcanv - > cv_fade_level > = GR_FADE_OFF ) ? 1.0 : ( 1.0 - ( float ) grd_curcanv - > cv_fade_level / ( ( float ) GR_FADE_LEVELS - 1.0 ) ) ;
2011-01-06 11:43:55 +00:00
vertex_array [ i * 3 ] = f2glf ( pv . x ) ;
vertex_array [ i * 3 + 1 ] = f2glf ( pv . y ) ;
vertex_array [ i * 3 + 2 ] = - f2glf ( pv . z ) ;
2006-03-20 16:43:15 +00:00
}
2011-01-06 11:43:55 +00:00
glVertexPointer ( 3 , GL_FLOAT , 0 , vertex_array ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
glTexCoordPointer ( 2 , GL_FLOAT , 0 , texcoord_array ) ;
glDrawArrays ( GL_TRIANGLE_FAN , 0 , 4 ) ; // Replaced GL_QUADS
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2009-11-30 19:11:46 +00:00
2006-03-20 16:43:15 +00:00
return 0 ;
}
2007-06-10 16:21:53 +00:00
2011-01-06 11:43:55 +00:00
/*
* Movies
2011-01-16 00:50:28 +00:00
* Since this function will create a new texture each call , mipmapping can be very GPU intensive - so it has an optional setting for texture filtering .
2011-01-06 11:43:55 +00:00
*/
2011-01-16 00:50:28 +00:00
bool ogl_ubitblt_i ( int dw , int dh , int dx , int dy , int sw , int sh , int sx , int sy , grs_bitmap * src , grs_bitmap * dest , int texfilt )
2006-03-20 16:43:15 +00:00
{
2011-01-06 11:43:55 +00:00
GLfloat xo , yo , xs , ys , u1 , v1 ;
GLfloat color_array [ ] = { 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 } ;
GLfloat texcoord_array [ ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 } ;
GLfloat vertex_array [ ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 } ;
2006-03-20 16:43:15 +00:00
ogl_texture tex ;
r_ubitbltc + + ;
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2011-01-16 00:50:28 +00:00
ogl_init_texture ( & tex , sw , sh , OGL_FLAG_ALPHA ) ;
2007-06-10 16:21:53 +00:00
tex . prio = 0.0 ;
2006-03-20 16:43:15 +00:00
tex . lw = src - > bm_rowsize ;
u1 = v1 = 0 ;
dx + = dest - > bm_x ;
dy + = dest - > bm_y ;
xo = dx / ( float ) last_width ;
xs = dw / ( float ) last_width ;
yo = 1.0 - dy / ( float ) last_height ;
ys = dh / ( float ) last_height ;
OGL_ENABLE ( TEXTURE_2D ) ;
2012-11-10 17:00:29 +00:00
ogl_pal = & gr_current_pal ;
2011-01-16 00:50:28 +00:00
ogl_loadtexture ( src - > bm_data , sx , sy , & tex , src - > bm_flags , 0 , texfilt ) ;
2012-11-10 17:00:29 +00:00
ogl_pal = & gr_palette ;
2006-03-20 16:43:15 +00:00
OGL_BINDTEXTURE ( tex . handle ) ;
2008-02-24 14:41:27 +00:00
ogl_texwrap ( & tex , GL_CLAMP_TO_EDGE ) ;
2006-03-20 16:43:15 +00:00
2011-01-06 11:43:55 +00:00
vertex_array [ 0 ] = xo ;
vertex_array [ 1 ] = yo ;
vertex_array [ 2 ] = xo + xs ;
vertex_array [ 3 ] = yo ;
vertex_array [ 4 ] = xo + xs ;
2011-01-06 19:12:45 +00:00
vertex_array [ 5 ] = yo - ys ;
2011-01-06 11:43:55 +00:00
vertex_array [ 6 ] = xo ;
vertex_array [ 7 ] = yo - ys ;
texcoord_array [ 0 ] = u1 ;
texcoord_array [ 1 ] = v1 ;
texcoord_array [ 2 ] = tex . u ;
texcoord_array [ 3 ] = v1 ;
texcoord_array [ 4 ] = tex . u ;
texcoord_array [ 5 ] = tex . v ;
texcoord_array [ 6 ] = u1 ;
texcoord_array [ 7 ] = tex . v ;
glVertexPointer ( 2 , GL_FLOAT , 0 , vertex_array ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
glTexCoordPointer ( 2 , GL_FLOAT , 0 , texcoord_array ) ;
glDrawArrays ( GL_TRIANGLE_FAN , 0 , 4 ) ; //replaced GL_QUADS
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2006-03-20 16:43:15 +00:00
ogl_freetexture ( & tex ) ;
return 0 ;
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
bool ogl_ubitblt ( int w , int h , int dx , int dy , int sx , int sy , grs_bitmap * src , grs_bitmap * dest ) {
2007-02-02 10:26:13 +00:00
return ogl_ubitblt_i ( w , h , dx , dy , w , h , sx , sy , src , dest , 0 ) ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2011-02-23 16:46:36 +00:00
/*
* set depth testing on or off
*/
2011-02-17 23:17:49 +00:00
void ogl_toggle_depth_test ( int enable )
{
if ( enable )
glEnable ( GL_DEPTH_TEST ) ;
else
glDisable ( GL_DEPTH_TEST ) ;
}
2011-02-23 16:46:36 +00:00
/*
* set blending function
*/
void ogl_set_blending ( )
{
switch ( grd_curcanv - > cv_blend_func )
{
case GR_BLEND_ADDITIVE_A :
glBlendFunc ( GL_SRC_ALPHA , GL_ONE ) ;
break ;
case GR_BLEND_ADDITIVE_C :
2013-01-08 18:12:33 +00:00
glBlendFunc ( GL_ONE , GL_ONE ) ;
2011-02-23 16:46:36 +00:00
break ;
case GR_BLEND_NORMAL :
default :
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
break ;
}
}
2006-03-20 16:43:15 +00:00
void ogl_start_frame ( void ) {
2008-10-28 17:04:35 +00:00
r_polyc = 0 ; r_tpolyc = 0 ; r_bitmapc = 0 ; r_ubitbltc = 0 ; r_upixelc = 0 ;
2006-03-20 16:43:15 +00:00
OGL_VIEWPORT ( grd_curcanv - > cv_bitmap . bm_x , grd_curcanv - > cv_bitmap . bm_y , Canvas_width , Canvas_height ) ;
glClearColor ( 0.0 , 0.0 , 0.0 , 0.0 ) ;
2006-05-05 13:23:53 +00:00
2008-11-09 14:31:30 +00:00
glLineWidth ( linedotscale ) ;
2006-05-05 13:23:53 +00:00
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glEnable ( GL_ALPHA_TEST ) ;
2006-07-11 16:13:47 +00:00
glAlphaFunc ( GL_GEQUAL , 0.02 ) ;
2006-05-05 13:23:53 +00:00
glEnable ( GL_DEPTH_TEST ) ;
glDepthFunc ( GL_LEQUAL ) ;
2006-07-11 16:13:47 +00:00
2006-05-05 13:23:53 +00:00
glClear ( GL_DEPTH_BUFFER_BIT ) ;
2006-07-11 16:13:47 +00:00
glEnable ( GL_CULL_FACE ) ;
glCullFace ( GL_FRONT ) ;
2006-05-05 13:23:53 +00:00
2006-03-20 16:43:15 +00:00
glShadeModel ( GL_SMOOTH ) ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ; //clear matrix
2011-01-06 11:43:55 +00:00
# ifdef OGLES
2011-02-17 23:43:03 +00:00
perspective ( 90.0 , 1.0 , 0.1 , 5000.0 ) ;
2011-01-06 11:43:55 +00:00
# else
2011-02-17 23:43:03 +00:00
gluPerspective ( 90.0 , 1.0 , 0.1 , 5000.0 ) ;
2011-01-06 11:43:55 +00:00
# endif
2006-03-20 16:43:15 +00:00
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ; //clear matrix
}
2006-05-05 13:23:53 +00:00
2006-03-20 16:43:15 +00:00
void ogl_end_frame ( void ) {
OGL_VIEWPORT ( 0 , 0 , grd_curscreen - > sc_w , grd_curscreen - > sc_h ) ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ; //clear matrix
2011-01-06 11:43:55 +00:00
# ifdef OGLES
glOrthof ( 0.0 , 1.0 , 0.0 , 1.0 , - 1.0 , 1.0 ) ;
# else
2006-03-20 16:43:15 +00:00
glOrtho ( 0.0 , 1.0 , 0.0 , 1.0 , - 1.0 , 1.0 ) ;
2011-01-06 11:43:55 +00:00
# endif
2006-03-20 16:43:15 +00:00
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ; //clear matrix
2006-07-16 15:54:30 +00:00
glDisable ( GL_CULL_FACE ) ;
2006-05-05 13:23:53 +00:00
glDisable ( GL_DEPTH_TEST ) ;
2006-03-20 16:43:15 +00:00
}
2007-03-22 14:15:46 +00:00
2007-06-10 16:21:53 +00:00
void gr_flip ( void )
{
2007-07-18 20:13:17 +00:00
if ( GameArg . DbgRenderStats )
2008-10-28 17:04:35 +00:00
ogl_texture_stats ( ) ;
2007-07-18 20:13:17 +00:00
2006-03-20 16:43:15 +00:00
ogl_do_palfx ( ) ;
ogl_swap_buffers_internal ( ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
}
2006-10-17 18:14:56 +00:00
//little hack to find the nearest bigger power of 2 for a given number
2013-08-16 02:00:35 +00:00
unsigned pow2ize ( unsigned f0 ) {
unsigned f1 = ( f0 - 1 ) | 1 ;
for ( unsigned i = 4 ; i - - > 0 ; )
f1 | = f1 > > ( 1 < < i ) ;
unsigned f2 = f1 + 1 ;
assert ( f2 > = f0 ) ;
assert ( ! ( f2 & f1 ) ) ;
assert ( ( f2 > > 1 ) < f0 ) ;
return f2 ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2007-01-09 01:23:49 +00:00
// Allocate the pixel buffers 'pixels' and 'texbuf' based on current screen resolution
2013-08-13 23:11:49 +00:00
void ogl_init_pixel_buffers ( unsigned w , unsigned h )
2007-01-09 01:23:49 +00:00
{
2007-06-10 16:21:53 +00:00
w = pow2ize ( w ) ; // convert to OpenGL texture size
2007-01-09 01:23:49 +00:00
h = pow2ize ( h ) ;
if ( pixels )
2008-01-23 17:25:09 +00:00
d_free ( pixels ) ;
2013-08-20 02:58:15 +00:00
MALLOC ( pixels , GLubyte , w * h * 4 ) ;
2007-01-09 01:23:49 +00:00
if ( texbuf )
2008-01-23 17:25:09 +00:00
d_free ( texbuf ) ;
2013-08-20 02:58:15 +00:00
MALLOC ( texbuf , GLubyte , max ( w , 1024u ) * max ( h , 256u ) * 4 ) ; // must also fit big font texture
2007-01-09 01:23:49 +00:00
if ( ( pixels = = NULL ) | | ( texbuf = = NULL ) )
Error ( " Not enough memory for current resolution " ) ;
}
void ogl_close_pixel_buffers ( void )
{
2008-01-23 17:25:09 +00:00
d_free ( pixels ) ;
d_free ( texbuf ) ;
2007-01-09 01:23:49 +00:00
}
2013-08-14 21:12:51 +00:00
static void ogl_filltexbuf ( unsigned char * data , GLubyte * texp , unsigned truewidth , unsigned width , unsigned height , int dxo , int dyo , unsigned twidth , unsigned theight , int type , int bm_flags , int data_format )
2006-03-20 16:43:15 +00:00
{
2012-11-11 22:12:51 +00:00
if ( ( width > max ( static_cast < unsigned > ( grd_curscreen - > sc_w ) , 1024u ) ) | | ( height > max ( static_cast < unsigned > ( grd_curscreen - > sc_h ) , 256u ) ) )
2007-06-10 16:21:53 +00:00
Error ( " Texture is too big: %ix%i " , width , height ) ;
2006-03-20 16:43:15 +00:00
2013-08-13 23:11:49 +00:00
for ( unsigned y = 0 ; y < theight ; y + + )
2008-04-19 19:11:32 +00:00
{
2013-08-13 23:11:49 +00:00
int i = dxo + truewidth * ( y + dyo ) ;
for ( unsigned x = 0 ; x < twidth ; x + + )
2008-04-19 19:11:32 +00:00
{
2013-08-13 23:11:49 +00:00
int c ;
2006-03-20 16:43:15 +00:00
if ( x < width & & y < height )
2008-02-24 14:41:27 +00:00
{
2007-06-10 16:21:53 +00:00
if ( data_format )
{
int j ;
for ( j = 0 ; j < data_format ; + + j )
( * ( texp + + ) ) = data [ i * data_format + j ] ;
i + + ;
continue ;
}
else
2008-02-24 14:41:27 +00:00
{
2007-06-10 16:21:53 +00:00
c = data [ i + + ] ;
2008-02-24 14:41:27 +00:00
}
}
2011-01-17 14:00:13 +00:00
else if ( x = = width & & y < height ) // end of bitmap reached - fill this pixel with last color to make a clean border when filtering this texture
2011-01-16 18:33:30 +00:00
{
c = data [ ( width * ( y + 1 ) ) - 1 ] ;
}
2011-01-17 14:00:13 +00:00
else if ( y = = height & & x < width ) // end of bitmap reached - fill this row with color or last row to make a clean border when filtering this texture
2011-01-16 18:33:30 +00:00
{
c = data [ ( width * ( height - 1 ) ) + x ] ;
}
2006-03-20 16:43:15 +00:00
else
2008-02-24 14:41:27 +00:00
{
2007-06-10 16:21:53 +00:00
c = 256 ; // fill the pad space with transparency (or blackness)
2008-02-24 14:41:27 +00:00
}
2007-06-10 16:21:53 +00:00
if ( c = = 254 & & ( bm_flags & BM_FLAG_SUPER_TRANSPARENT ) )
{
switch ( type )
{
2008-04-19 19:11:32 +00:00
case GL_LUMINANCE_ALPHA :
( * ( texp + + ) ) = 255 ;
( * ( texp + + ) ) = 0 ;
break ;
case GL_RGBA :
( * ( texp + + ) ) = 255 ;
( * ( texp + + ) ) = 255 ;
( * ( texp + + ) ) = 255 ;
( * ( texp + + ) ) = 0 ; // transparent pixel
break ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2008-04-19 19:11:32 +00:00
case GL_COLOR_INDEX :
( * ( texp + + ) ) = c ;
break ;
2011-01-06 11:43:55 +00:00
# endif
2008-04-19 19:11:32 +00:00
default :
Error ( " ogl_filltexbuf unhandled super-transparent texformat \n " ) ;
break ;
2007-06-10 16:21:53 +00:00
}
}
2008-10-28 13:28:10 +00:00
else if ( ( c = = 255 & & ( bm_flags & BM_FLAG_TRANSPARENT ) ) | | c = = 256 )
2007-06-10 16:21:53 +00:00
{
2008-04-19 19:11:32 +00:00
switch ( type )
{
2006-03-20 16:43:15 +00:00
case GL_LUMINANCE :
( * ( texp + + ) ) = 0 ;
break ;
case GL_LUMINANCE_ALPHA :
( * ( texp + + ) ) = 0 ;
( * ( texp + + ) ) = 0 ;
break ;
2007-06-10 16:21:53 +00:00
case GL_RGB :
( * ( texp + + ) ) = 0 ;
( * ( texp + + ) ) = 0 ;
( * ( texp + + ) ) = 0 ;
break ;
2006-03-20 16:43:15 +00:00
case GL_RGBA :
( * ( texp + + ) ) = 0 ;
( * ( texp + + ) ) = 0 ;
( * ( texp + + ) ) = 0 ;
( * ( texp + + ) ) = 0 ; //transparent pixel
break ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2007-06-10 16:21:53 +00:00
case GL_COLOR_INDEX :
( * ( texp + + ) ) = c ;
break ;
2011-01-06 11:43:55 +00:00
# endif
2007-06-10 16:21:53 +00:00
default :
Error ( " ogl_filltexbuf unknown texformat \n " ) ;
break ;
2006-03-20 16:43:15 +00:00
}
2008-04-19 19:11:32 +00:00
}
else
{
switch ( type )
{
2006-03-20 16:43:15 +00:00
case GL_LUMINANCE : //these could prolly be done to make the intensity based upon the intensity of the resulting color, but its not needed for anything (yet?) so no point. :)
( * ( texp + + ) ) = 255 ;
break ;
case GL_LUMINANCE_ALPHA :
( * ( texp + + ) ) = 255 ;
( * ( texp + + ) ) = 255 ;
break ;
2007-06-10 16:21:53 +00:00
case GL_RGB :
2013-01-06 21:11:53 +00:00
( * ( texp + + ) ) = ( * ogl_pal ) [ c ] . r * 4 ;
( * ( texp + + ) ) = ( * ogl_pal ) [ c ] . g * 4 ;
( * ( texp + + ) ) = ( * ogl_pal ) [ c ] . b * 4 ;
2007-06-10 16:21:53 +00:00
break ;
2006-03-20 16:43:15 +00:00
case GL_RGBA :
2013-01-06 21:11:53 +00:00
( * ( texp + + ) ) = ( * ogl_pal ) [ c ] . r * 4 ;
( * ( texp + + ) ) = ( * ogl_pal ) [ c ] . g * 4 ;
( * ( texp + + ) ) = ( * ogl_pal ) [ c ] . b * 4 ;
2006-03-20 16:43:15 +00:00
( * ( texp + + ) ) = 255 ; //not transparent
2007-06-10 16:21:53 +00:00
break ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2007-06-10 16:21:53 +00:00
case GL_COLOR_INDEX :
( * ( texp + + ) ) = c ;
break ;
2011-01-06 11:43:55 +00:00
# endif
2007-06-10 16:21:53 +00:00
default :
Error ( " ogl_filltexbuf unknown texformat \n " ) ;
2006-03-20 16:43:15 +00:00
break ;
}
}
}
}
}
2007-06-10 16:21:53 +00:00
2013-08-14 21:12:51 +00:00
static void tex_set_size1 ( ogl_texture * tex , int dbits , int bits , int w , int h ) {
2006-03-20 16:43:15 +00:00
int u ;
if ( tex - > tw ! = w | | tex - > th ! = h ) {
u = ( tex - > w / ( float ) tex - > tw * w ) * ( tex - > h / ( float ) tex - > th * h ) ;
glmprintf ( ( 0 , " shrunken texture? \n " ) ) ;
} else
u = tex - > w * tex - > h ;
if ( bits < = 0 ) { //the beta nvidia GLX server. doesn't ever return any bit sizes, so just use some assumptions.
tex - > bytes = ( ( float ) w * h * dbits ) / 8.0 ;
tex - > bytesu = ( ( float ) u * dbits ) / 8.0 ;
} else {
tex - > bytes = ( ( float ) w * h * bits ) / 8.0 ;
tex - > bytesu = ( ( float ) u * bits ) / 8.0 ;
}
glmprintf ( ( 0 , " tex_set_size1: %ix%i, %ib(%i) %iB \n " , w , h , bits , dbits , tex - > bytes ) ) ;
}
2007-06-10 16:21:53 +00:00
2013-08-14 21:12:51 +00:00
static void tex_set_size ( ogl_texture * tex ) {
2007-06-10 16:21:53 +00:00
GLint w , h ;
int bi = 16 , a = 0 ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2007-07-23 18:13:49 +00:00
if ( GameArg . DbgGlGetTexLevelParamOk ) {
2007-06-10 16:21:53 +00:00
GLint t ;
2006-03-20 16:43:15 +00:00
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_WIDTH , & w ) ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_HEIGHT , & h ) ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_LUMINANCE_SIZE , & t ) ; a + = t ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_INTENSITY_SIZE , & t ) ; a + = t ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_RED_SIZE , & t ) ; a + = t ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_GREEN_SIZE , & t ) ; a + = t ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_BLUE_SIZE , & t ) ; a + = t ;
glGetTexLevelParameteriv ( GL_TEXTURE_2D , 0 , GL_TEXTURE_ALPHA_SIZE , & t ) ; a + = t ;
2011-01-06 11:43:55 +00:00
}
else
# endif
{
2006-03-20 16:43:15 +00:00
w = tex - > tw ;
h = tex - > th ;
}
switch ( tex - > format ) {
case GL_LUMINANCE :
bi = 8 ;
break ;
case GL_LUMINANCE_ALPHA :
bi = 8 ;
break ;
2007-06-10 16:21:53 +00:00
case GL_RGB :
2006-03-20 16:43:15 +00:00
case GL_RGBA :
bi = 16 ;
break ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2007-06-10 16:21:53 +00:00
case GL_COLOR_INDEX :
bi = 8 ;
break ;
2011-01-06 11:43:55 +00:00
# endif
2006-03-20 16:43:15 +00:00
default :
Error ( " tex_set_size unknown texformat \n " ) ;
break ;
}
tex_set_size1 ( tex , bi , a , w , h ) ;
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
//loads a palettized bitmap into a ogl RGBA texture.
//Sizes and pads dimensions to multiples of 2 if necessary.
//In theory this could be a problem for repeating textures, but all real
//textures (not sprites, etc) in descent are 64x64, so we are ok.
//stores OpenGL textured id in *texid and u/v values required to get only the real data in *u/*v
2013-08-14 21:12:51 +00:00
static int ogl_loadtexture ( unsigned char * data , int dxo , int dyo , ogl_texture * tex , int bm_flags , int data_format , int texfilt )
2007-06-10 16:21:53 +00:00
{
GLubyte * bufP = texbuf ;
tex - > tw = pow2ize ( tex - > w ) ;
tex - > th = pow2ize ( tex - > h ) ; //calculate smallest texture size that can accomodate us (must be multiples of 2)
2006-03-20 16:43:15 +00:00
2007-06-10 16:21:53 +00:00
//calculate u/v values that would make the resulting texture correctly sized
tex - > u = ( float ) ( ( double ) tex - > w / ( double ) tex - > tw ) ;
tex - > v = ( float ) ( ( double ) tex - > h / ( double ) tex - > th ) ;
if ( data ) {
if ( bm_flags > = 0 )
ogl_filltexbuf ( data , texbuf , tex - > lw , tex - > w , tex - > h , dxo , dyo , tex - > tw , tex - > th ,
tex - > format , bm_flags , data_format ) ;
else {
if ( ! dxo & & ! dyo & & ( tex - > w = = tex - > tw ) & & ( tex - > h = = tex - > th ) )
bufP = data ;
else {
int h , w , tw ;
h = tex - > lw / tex - > w ;
w = ( tex - > w - dxo ) * h ;
data + = tex - > lw * dyo + h * dxo ;
bufP = texbuf ;
tw = tex - > tw * h ;
h = tw - w ;
for ( ; dyo < tex - > h ; dyo + + , data + = tex - > lw ) {
memcpy ( bufP , data , w ) ;
bufP + = w ;
memset ( bufP , 0 , h ) ;
bufP + = h ;
}
memset ( bufP , 0 , tex - > th * tw - ( bufP - texbuf ) ) ;
bufP = texbuf ;
}
2008-02-24 14:41:27 +00:00
}
2007-06-10 16:21:53 +00:00
}
2006-03-20 16:43:15 +00:00
// Generate OpenGL texture IDs.
2007-06-10 16:21:53 +00:00
glGenTextures ( 1 , & tex - > handle ) ;
2011-01-06 11:43:55 +00:00
# ifndef OGLES
2006-03-20 16:43:15 +00:00
//set priority
2007-06-10 16:21:53 +00:00
glPrioritizeTextures ( 1 , & tex - > handle , & tex - > prio ) ;
2011-01-06 11:43:55 +00:00
# endif
2006-03-20 16:43:15 +00:00
// Give our data to OpenGL.
OGL_BINDTEXTURE ( tex - > handle ) ;
2007-06-10 16:21:53 +00:00
glTexEnvi ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2011-01-06 11:43:55 +00:00
2011-01-16 00:50:28 +00:00
if ( texfilt )
2011-01-06 11:43:55 +00:00
{
# ifdef OGLES // in OpenGL ES 1.1 the mipmaps are automatically generated by a parameter
2011-01-16 00:50:28 +00:00
glTexParameteri ( GL_TEXTURE_2D , GL_GENERATE_MIPMAP , texfilt ? GL_TRUE : GL_FALSE ) ;
2011-01-06 11:43:55 +00:00
# endif
2010-09-02 13:55:28 +00:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
2011-01-16 00:50:28 +00:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , ( texfilt > = 2 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST ) ) ;
# ifndef OGLES
if ( texfilt > = 3 & & ogl_maxanisotropy > 1.0 )
glTexParameterf ( GL_TEXTURE_2D , GL_TEXTURE_MAX_ANISOTROPY_EXT , ogl_maxanisotropy ) ;
# endif
2011-01-06 11:43:55 +00:00
}
else
{
2007-06-10 16:21:53 +00:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
2011-01-06 11:43:55 +00:00
}
# ifndef OGLES // see comment above
2011-01-16 00:50:28 +00:00
if ( texfilt )
2011-01-06 11:43:55 +00:00
{
2007-06-10 16:21:53 +00:00
gluBuild2DMipmaps (
GL_TEXTURE_2D , tex - > internalformat ,
tex - > tw , tex - > th , tex - > format ,
GL_UNSIGNED_BYTE ,
bufP ) ;
2011-01-06 11:43:55 +00:00
}
2006-03-20 16:43:15 +00:00
else
2011-01-06 11:43:55 +00:00
# endif
{
2007-06-10 16:21:53 +00:00
glTexImage2D (
GL_TEXTURE_2D , 0 , tex - > internalformat ,
2006-03-20 16:43:15 +00:00
tex - > tw , tex - > th , 0 , tex - > format , // RGBA textures.
GL_UNSIGNED_BYTE , // imageData is a GLubyte pointer.
2007-06-10 16:21:53 +00:00
bufP ) ;
2011-01-06 11:43:55 +00:00
}
2007-06-10 16:21:53 +00:00
tex_set_size ( tex ) ;
2007-06-15 12:32:44 +00:00
r_texcount + + ;
2006-10-20 23:17:48 +00:00
return 0 ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
unsigned char decodebuf [ 1024 * 1024 ] ;
2007-06-10 16:21:53 +00:00
2011-01-16 00:50:28 +00:00
void ogl_loadbmtexture_f ( grs_bitmap * bm , int texfilt )
2007-06-10 16:21:53 +00:00
{
2006-03-20 16:43:15 +00:00
unsigned char * buf ;
2007-06-10 16:21:53 +00:00
# ifdef HAVE_LIBPNG
char * bitmapname ;
# endif
2006-03-20 16:43:15 +00:00
while ( bm - > bm_parent )
bm = bm - > bm_parent ;
2007-06-10 16:21:53 +00:00
if ( bm - > gltexture & & bm - > gltexture - > handle > 0 )
return ;
2006-03-20 16:43:15 +00:00
buf = bm - > bm_data ;
2007-06-10 16:21:53 +00:00
# ifdef HAVE_LIBPNG
if ( ( bitmapname = piggy_game_bitmap_name ( bm ) ) )
{
char filename [ 64 ] ;
png_data pdata ;
sprintf ( filename , " textures/%s.png " , bitmapname ) ;
if ( read_png ( filename , & pdata ) )
{
2013-12-07 00:47:27 +00:00
con_printf ( CON_DEBUG , " %s: %ux%ux%i p=%i(%i) c=%i a=%i chans=%i " , filename , pdata . width , pdata . height , pdata . depth , pdata . paletted , pdata . num_palette , pdata . color , pdata . alpha , pdata . channels ) ;
2007-06-10 16:21:53 +00:00
if ( pdata . depth = = 8 & & pdata . color )
{
if ( bm - > gltexture = = NULL )
ogl_init_texture ( bm - > gltexture = ogl_get_free_texture ( ) , pdata . width , pdata . height , flags | ( ( pdata . alpha | | bm - > bm_flags & BM_FLAG_TRANSPARENT ) ? OGL_FLAG_ALPHA : 0 ) ) ;
2011-01-16 00:50:28 +00:00
ogl_loadtexture ( pdata . data , 0 , 0 , bm - > gltexture , bm - > bm_flags , pdata . paletted ? 0 : pdata . channels , texfilt ) ;
2009-11-30 19:11:46 +00:00
free ( pdata . data ) ;
2007-06-10 16:21:53 +00:00
if ( pdata . palette )
2009-11-30 19:11:46 +00:00
free ( pdata . palette ) ;
2007-06-10 16:21:53 +00:00
return ;
}
else
{
2013-12-07 00:47:27 +00:00
con_printf ( CON_DEBUG , " %s: unsupported texture format: must be rgb, rgba, or paletted, and depth 8 " , filename ) ;
2009-11-30 19:11:46 +00:00
free ( pdata . data ) ;
2007-06-10 16:21:53 +00:00
if ( pdata . palette )
2009-11-30 19:11:46 +00:00
free ( pdata . palette ) ;
2007-06-10 16:21:53 +00:00
}
}
}
# endif
if ( bm - > gltexture = = NULL ) {
2011-01-16 00:50:28 +00:00
ogl_init_texture ( bm - > gltexture = ogl_get_free_texture ( ) , bm - > bm_w , bm - > bm_h , ( ( bm - > bm_flags & ( BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT ) ) ? OGL_FLAG_ALPHA : 0 ) ) ;
2006-03-20 16:43:15 +00:00
}
else {
if ( bm - > gltexture - > handle > 0 )
return ;
if ( bm - > gltexture - > w = = 0 ) {
bm - > gltexture - > lw = bm - > bm_w ;
bm - > gltexture - > w = bm - > bm_w ;
bm - > gltexture - > h = bm - > bm_h ;
}
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
if ( bm - > bm_flags & BM_FLAG_RLE ) {
unsigned char * dbits ;
unsigned char * sbits ;
2008-03-16 08:11:08 +00:00
int i , data_offset ;
2009-11-30 19:11:46 +00:00
2008-03-16 08:11:08 +00:00
data_offset = 1 ;
if ( bm - > bm_flags & BM_FLAG_RLE_BIG )
data_offset = 2 ;
2009-11-30 19:11:46 +00:00
2008-03-16 08:11:08 +00:00
sbits = & bm - > bm_data [ 4 + ( bm - > bm_h * data_offset ) ] ;
2006-03-20 16:43:15 +00:00
dbits = decodebuf ;
2009-11-30 19:11:46 +00:00
2006-03-20 16:43:15 +00:00
for ( i = 0 ; i < bm - > bm_h ; i + + ) {
2014-06-30 23:56:51 +00:00
gr_rle_decode ( { sbits , dbits } , rle_end ( bm , decodebuf ) ) ;
2008-03-16 08:11:08 +00:00
if ( bm - > bm_flags & BM_FLAG_RLE_BIG )
sbits + = ( int ) INTEL_SHORT ( * ( ( short * ) & ( bm - > bm_data [ 4 + ( i * data_offset ) ] ) ) ) ;
else
sbits + = ( int ) bm - > bm_data [ 4 + i ] ;
2006-03-20 16:43:15 +00:00
dbits + = bm - > bm_w ;
}
buf = decodebuf ;
}
2011-01-16 00:50:28 +00:00
ogl_loadtexture ( buf , 0 , 0 , bm - > gltexture , bm - > bm_flags , 0 , texfilt ) ;
2006-03-20 16:43:15 +00:00
}
2007-06-10 16:21:53 +00:00
2013-08-14 21:12:51 +00:00
static void ogl_freetexture ( ogl_texture * gltexture )
2007-06-10 16:21:53 +00:00
{
if ( gltexture - > handle > 0 ) {
2006-03-20 16:43:15 +00:00
r_texcount - - ;
2010-12-22 00:17:49 +00:00
glmprintf ( ( 0 , " ogl_freetexture(%p):%i (%i left) \n " , gltexture , gltexture - > handle , r_texcount ) ) ;
2006-03-20 16:43:15 +00:00
glDeleteTextures ( 1 , & gltexture - > handle ) ;
// gltexture->handle=0;
2007-06-10 16:21:53 +00:00
ogl_reset_texture ( gltexture ) ;
2006-03-20 16:43:15 +00:00
}
}
void ogl_freebmtexture ( grs_bitmap * bm ) {
if ( bm - > gltexture ) {
ogl_freetexture ( bm - > gltexture ) ;
bm - > gltexture = NULL ;
}
}
2011-01-06 11:43:55 +00:00
/*
* Menu / gauges
*/
2006-10-08 15:56:03 +00:00
bool ogl_ubitmapm_cs ( int x , int y , int dw , int dh , grs_bitmap * bm , int c , int scale ) // to scale bitmaps
2006-08-13 15:52:49 +00:00
{
2011-09-26 21:00:23 +00:00
GLfloat xo , yo , xf , yf , u1 , u2 , v1 , v2 , color_r , color_g , color_b , h ;
2011-01-06 11:43:55 +00:00
GLfloat color_array [ ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 } ;
GLfloat texcoord_array [ ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 } ;
GLfloat vertex_array [ ] = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 } ;
2006-08-13 15:52:49 +00:00
x + = grd_curcanv - > cv_bitmap . bm_x ;
y + = grd_curcanv - > cv_bitmap . bm_y ;
xo = x / ( float ) last_width ;
xf = ( bm - > bm_w + x ) / ( float ) last_width ;
yo = 1.0 - y / ( float ) last_height ;
yf = 1.0 - ( bm - > bm_h + y ) / ( float ) last_height ;
2011-01-06 11:43:55 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
glEnableClientState ( GL_COLOR_ARRAY ) ;
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2006-08-13 15:52:49 +00:00
if ( dw < 0 )
dw = grd_curcanv - > cv_bitmap . bm_w ;
else if ( dw = = 0 )
dw = bm - > bm_w ;
if ( dh < 0 )
dh = grd_curcanv - > cv_bitmap . bm_h ;
else if ( dh = = 0 )
dh = bm - > bm_h ;
h = ( double ) scale / ( double ) F1_0 ;
xo = x / ( ( double ) last_width * h ) ;
xf = ( dw + x ) / ( ( double ) last_width * h ) ;
2006-03-20 16:43:15 +00:00
yo = 1.0 - y / ( ( double ) last_height * h ) ;
yf = 1.0 - ( dh + y ) / ( ( double ) last_height * h ) ;
OGL_ENABLE ( TEXTURE_2D ) ;
ogl_bindbmtex ( bm ) ;
2008-02-24 14:41:27 +00:00
ogl_texwrap ( bm - > gltexture , GL_CLAMP_TO_EDGE ) ;
2006-03-20 16:43:15 +00:00
if ( bm - > bm_x = = 0 ) {
u1 = 0 ;
if ( bm - > bm_w = = bm - > gltexture - > w )
u2 = bm - > gltexture - > u ;
else
u2 = ( bm - > bm_w + bm - > bm_x ) / ( float ) bm - > gltexture - > tw ;
} else {
u1 = bm - > bm_x / ( float ) bm - > gltexture - > tw ;
u2 = ( bm - > bm_w + bm - > bm_x ) / ( float ) bm - > gltexture - > tw ;
}
if ( bm - > bm_y = = 0 ) {
v1 = 0 ;
if ( bm - > bm_h = = bm - > gltexture - > h )
v2 = bm - > gltexture - > v ;
else
v2 = ( bm - > bm_h + bm - > bm_y ) / ( float ) bm - > gltexture - > th ;
} else {
v1 = bm - > bm_y / ( float ) bm - > gltexture - > th ;
v2 = ( bm - > bm_h + bm - > bm_y ) / ( float ) bm - > gltexture - > th ;
}
2011-01-06 11:43:55 +00:00
if ( c < 0 ) {
color_r = 1.0 ;
color_g = 1.0 ;
color_b = 1.0 ;
} else {
color_r = CPAL2Tr ( c ) ;
color_g = CPAL2Tg ( c ) ;
color_b = CPAL2Tb ( c ) ;
}
color_array [ 0 ] = color_array [ 4 ] = color_array [ 8 ] = color_array [ 12 ] = color_r ;
color_array [ 1 ] = color_array [ 5 ] = color_array [ 9 ] = color_array [ 13 ] = color_g ;
color_array [ 2 ] = color_array [ 6 ] = color_array [ 10 ] = color_array [ 14 ] = color_b ;
color_array [ 3 ] = color_array [ 7 ] = color_array [ 11 ] = color_array [ 15 ] = 1.0 ;
vertex_array [ 0 ] = xo ;
vertex_array [ 1 ] = yo ;
vertex_array [ 2 ] = xf ;
vertex_array [ 3 ] = yo ;
vertex_array [ 4 ] = xf ;
vertex_array [ 5 ] = yf ;
vertex_array [ 6 ] = xo ;
vertex_array [ 7 ] = yf ;
texcoord_array [ 0 ] = u1 ;
texcoord_array [ 1 ] = v1 ;
texcoord_array [ 2 ] = u2 ;
texcoord_array [ 3 ] = v1 ;
texcoord_array [ 4 ] = u2 ;
texcoord_array [ 5 ] = v2 ;
texcoord_array [ 6 ] = u1 ;
texcoord_array [ 7 ] = v2 ;
glVertexPointer ( 2 , GL_FLOAT , 0 , vertex_array ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , color_array ) ;
glTexCoordPointer ( 2 , GL_FLOAT , 0 , texcoord_array ) ;
glDrawArrays ( GL_TRIANGLE_FAN , 0 , 4 ) ; //replaced GL_QUADS
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2006-03-20 16:43:15 +00:00
return 0 ;
}