From 6847b33cb55d81f0b189e8cbdf5d3af047940e77 Mon Sep 17 00:00:00 2001 From: Yamagi Burmeister Date: Mon, 25 Oct 2010 12:33:55 +0000 Subject: [PATCH] =?UTF-8?q?F=C3=BCge=20Multitexturing=20ein.=20Dies=20funk?= =?UTF-8?q?tioniert=20(nat=C3=BCrlich)=20nicht=20mir=20Mesa3D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/refresh/header/local.h | 23 +-- src/refresh/header/qgl.h | 12 +- src/refresh/r_image.c | 78 ++++++++- src/refresh/r_lightmap.c | 12 +- src/refresh/r_main.c | 80 +++++++-- src/refresh/r_surf.c | 347 +++++++++++++++++++++++++++++++++---- 6 files changed, 477 insertions(+), 75 deletions(-) diff --git a/src/refresh/header/local.h b/src/refresh/header/local.h index c1e9de41..ad7b625c 100644 --- a/src/refresh/header/local.h +++ b/src/refresh/header/local.h @@ -33,20 +33,20 @@ #include #include "../../client/header/ref.h" -#include "qgl.h" +#include "qgl.h" #ifndef GL_COLOR_INDEX8_EXT #define GL_COLOR_INDEX8_EXT GL_COLOR_INDEX #endif - + #define TEXNUM_LIGHTMAPS 1024 #define TEXNUM_SCRAPS 1152 #define TEXNUM_IMAGES 1153 -#define MAX_GLTEXTURES 1024 -#define MAX_SCRAPS 1 -#define BLOCK_WIDTH 128 -#define BLOCK_HEIGHT 128 -#define REF_VERSION "Yamagi Quake II OpenGL Refresher" +#define MAX_GLTEXTURES 1024 +#define MAX_SCRAPS 1 +#define BLOCK_WIDTH 128 +#define BLOCK_HEIGHT 128 +#define REF_VERSION "Yamagi Quake II OpenGL Refresher" #define MAX_LBM_HEIGHT 480 #define BACKFACE_EPSILON 0.01 #define DYNAMIC_LIGHT_WIDTH 128 @@ -54,7 +54,7 @@ #define LIGHTMAP_BYTES 4 #define MAX_LIGHTMAPS 128 #define GL_LIGHTMAP_FORMAT GL_RGBA - + /* up / down */ #define PITCH 0 @@ -75,6 +75,7 @@ typedef struct #endif char *strlwr ( char *s ); + extern viddef_t vid; /* @@ -246,6 +247,8 @@ void R_TranslatePlayerSkin ( int playernum ); void R_Bind ( int texnum ); void R_MBind ( GLenum target, int texnum ); void R_TexEnv ( GLenum value ); +void R_EnableMultitexture ( qboolean enable ); +void R_SelectTexture ( GLenum ); void R_LightPoint ( vec3_t p, vec3_t color ); void R_PushDlights ( void ); @@ -254,7 +257,7 @@ extern model_t *r_worldmodel; extern unsigned d_8to24table [ 256 ]; extern int registration_sequence; -void V_AddBlend ( float r, float g, float b, float a, float *v_blend ); +void V_AddBlend ( float r, float g, float b, float a, float *v_blend ); int R_Init ( void *hinstance, void *hWnd ); void R_Shutdown ( void ); @@ -370,7 +373,7 @@ typedef struct int allocated [ BLOCK_WIDTH ]; /* the lightmap texture data needs to be kept in - main memory so texsubimage can update properly */ + * main memory so texsubimage can update properly */ byte lightmap_buffer [ 4 * BLOCK_WIDTH * BLOCK_HEIGHT ]; } gllightmapstate_t; diff --git a/src/refresh/header/qgl.h b/src/refresh/header/qgl.h index a502806b..bc1b86b4 100644 --- a/src/refresh/header/qgl.h +++ b/src/refresh/header/qgl.h @@ -31,10 +31,13 @@ #ifndef APIENTRY #define APIENTRY -#endif +#endif #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#define GL_TEXTURE0_SGIS 0x835E +#define GL_TEXTURE1_SGIS 0x835F + qboolean QGL_Init ( const char *dllname ); void QGL_Shutdown ( void ); @@ -391,12 +394,19 @@ extern void ( APIENTRY *qglPointParameterfvEXT )( GLenum param, const GLfloat *v extern void ( APIENTRY *qglColorTableEXT )( GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid * ); extern void ( APIENTRY *qglLockArraysEXT )( int, int ); + extern void ( APIENTRY *qglUnlockArraysEXT )( void ); +extern void ( APIENTRY *qglMTexCoord2fSGIS )( GLenum, GLfloat, GLfloat ); +extern void ( APIENTRY *qglSelectTextureSGIS )( GLenum ); + +extern void ( APIENTRY *qglActiveTextureARB )( GLenum ); +extern void ( APIENTRY *qglClientActiveTextureARB )( GLenum ); /* local function in dll */ extern void *qwglGetProcAddress ( char *symbol ); void Fake_glColorTableEXT ( GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table ); + extern int QGL_TEXTURE0, QGL_TEXTURE1; #endif diff --git a/src/refresh/r_image.c b/src/refresh/r_image.c index 28570d94..e88595d2 100644 --- a/src/refresh/r_image.c +++ b/src/refresh/r_image.c @@ -51,7 +51,7 @@ int gl_tex_alpha_format = 4; int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; int gl_filter_max = GL_LINEAR; -image_t * LoadWal ( char *name ); +image_t *LoadWal ( char *name ); void LoadTGA ( char *name, byte **pic, int *width, int *height ); int Draw_GetPalette ( void ); @@ -127,6 +127,68 @@ typedef struct int upload_width, upload_height; qboolean uploaded_paletted; +void +R_EnableMultitexture ( qboolean enable ) +{ + if ( !qglSelectTextureSGIS && !qglActiveTextureARB ) + { + return; + } + + if ( enable ) + { + R_SelectTexture( QGL_TEXTURE1 ); + qglEnable( GL_TEXTURE_2D ); + R_TexEnv( GL_REPLACE ); + } + else + { + R_SelectTexture( QGL_TEXTURE1 ); + qglDisable( GL_TEXTURE_2D ); + R_TexEnv( GL_REPLACE ); + } + + R_SelectTexture( QGL_TEXTURE0 ); + R_TexEnv( GL_REPLACE ); +} + +void +R_SelectTexture ( GLenum texture ) +{ + int tmu; + + if ( !qglSelectTextureSGIS && !qglActiveTextureARB ) + { + return; + } + + if ( texture == QGL_TEXTURE0 ) + { + tmu = 0; + } + else + { + tmu = 1; + } + + if ( tmu == gl_state.currenttmu ) + { + return; + } + + gl_state.currenttmu = tmu; + + if ( qglSelectTextureSGIS ) + { + qglSelectTextureSGIS( texture ); + } + else if ( qglActiveTextureARB ) + { + qglActiveTextureARB( texture ); + qglClientActiveTextureARB( texture ); + } +} + void R_TexEnv ( GLenum mode ) { @@ -161,6 +223,8 @@ R_Bind ( int texnum ) void R_MBind ( GLenum target, int texnum ) { + R_SelectTexture( target ); + if ( target == QGL_TEXTURE0 ) { if ( gl_state.currenttextures [ 0 ] == texnum ) @@ -178,7 +242,7 @@ R_MBind ( GLenum target, int texnum ) R_Bind( texnum ); } - + void R_TextureMode ( char *string ) { @@ -691,11 +755,11 @@ R_Upload8 ( byte *data, int width, int height, qboolean mipmap, qboolean is_sky { p = data [ i ]; trans [ i ] = d_8to24table [ p ]; - + /* transparent, so scan around for another color - to avoid alpha fringes */ + * to avoid alpha fringes */ if ( p == 255 ) - { + { if ( ( i > width ) && ( data [ i - width ] != 255 ) ) { p = data [ i - width ]; @@ -904,7 +968,7 @@ R_FindImage ( char *name, imagetype_t type ) if ( !pic ) { - return ( NULL ); + return ( NULL ); } image = R_LoadPic( name, pic, width, height, type, 32 ); @@ -934,7 +998,7 @@ R_RegisterSkin ( char *name ) } /* - * Any image that was not touched on + * Any image that was not touched on * this registration sequence * will be freed. */ diff --git a/src/refresh/r_lightmap.c b/src/refresh/r_lightmap.c index 7aaddd25..f7f7a0df 100644 --- a/src/refresh/r_lightmap.c +++ b/src/refresh/r_lightmap.c @@ -22,7 +22,7 @@ * Lightmap handling * * ======================================================================= - */ + */ #include "header/local.h" @@ -121,7 +121,7 @@ LM_AllocBlock ( int w, int h, int *x, int *y ) } if ( j == w ) - { + { /* this is a valid spot */ *x = i; *y = best = best2; @@ -255,10 +255,13 @@ LM_BeginBuildingLightmaps ( model_t *m ) memset( gl_lms.allocated, 0, sizeof ( gl_lms.allocated ) ); - r_framecount = 1;/* no dlightcache */ + r_framecount = 1; /* no dlightcache */ + + R_EnableMultitexture( true ); + R_SelectTexture( QGL_TEXTURE1 ); /* setup the base lightstyles so the lightmaps won't have to be regenerated - the first time they're seen */ + * the first time they're seen */ for ( i = 0; i < MAX_LIGHTSTYLES; i++ ) { lightstyles [ i ].rgb [ 0 ] = 1; @@ -295,5 +298,6 @@ void LM_EndBuildingLightmaps ( void ) { LM_UploadBlock( false ); + R_EnableMultitexture( false ); } diff --git a/src/refresh/r_main.c b/src/refresh/r_main.c index 89d19549..e551a5c0 100644 --- a/src/refresh/r_main.c +++ b/src/refresh/r_main.c @@ -22,7 +22,7 @@ * Refresher setup and main part of the frame generation * * ======================================================================= - */ + */ #include "header/local.h" @@ -42,7 +42,7 @@ void Draw_Char ( int x, int y, int c ); void Draw_TileClear ( int x, int y, int w, int h, char *name ); void Draw_Fill ( int x, int y, int w, int h, int c ); void Draw_FadeScreen ( void ); - + viddef_t vid; refimport_t ri; @@ -114,6 +114,7 @@ cvar_t *gl_particle_att_b; cvar_t *gl_particle_att_c; cvar_t *gl_ext_swapinterval; +cvar_t *gl_ext_multitexture; cvar_t *gl_ext_pointparameters; cvar_t *gl_ext_compiled_vertex_array; @@ -198,14 +199,14 @@ R_DrawSpriteModel ( entity_t *e ) dsprite_t *psprite; /* don't even bother culling, because it's just a single - polygon without a surface cache */ + * polygon without a surface cache */ psprite = (dsprite_t *) currentmodel->extradata; e->frame %= psprite->numframes; frame = &psprite->frames [ e->frame ]; - { + { /* normal sprite */ up = vup; right = vright; @@ -369,9 +370,9 @@ R_DrawEntitiesOnList ( void ) } } - /* draw transparent entities - we could sort these if it ever - becomes a problem... */ + /* draw transparent entities + * we could sort these if it ever + * becomes a problem... */ qglDepthMask( 0 ); /* no z writes */ for ( i = 0; i < r_newrefdef.num_entities; i++ ) @@ -891,8 +892,8 @@ R_SetLightLevel ( void ) /* save off light value for server to look at */ R_LightPoint( r_newrefdef.vieworg, shadelight ); - /* pick the greatest component, which should be the same - as the mono value returned by software */ + /* pick the greatest component, which should be the same + * as the mono value returned by software */ if ( shadelight [ 0 ] > shadelight [ 1 ] ) { if ( shadelight [ 0 ] > shadelight [ 2 ] ) @@ -979,6 +980,7 @@ R_Register ( void ) gl_vertex_arrays = ri.Cvar_Get( "gl_vertex_arrays", "0", CVAR_ARCHIVE ); gl_ext_swapinterval = ri.Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE ); + gl_ext_multitexture = ri.Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE ); gl_ext_pointparameters = ri.Cvar_Get( "gl_ext_pointparameters", "1", CVAR_ARCHIVE ); gl_ext_compiled_vertex_array = ri.Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE ); @@ -1012,7 +1014,7 @@ R_SetMode ( void ) gl_mode->modified = false; /* a bit hackish approach to enable custom resolutions: - Glimp_SetMode needs these values set for mode -1 */ + * Glimp_SetMode needs these values set for mode -1 */ vid.width = gl_customwidth->value; vid.height = gl_customheight->value; @@ -1124,7 +1126,7 @@ R_Init ( void *hinstance, void *hWnd ) strncpy( vendor_buffer, gl_config.vendor_string, sizeof ( vendor_buffer ) ); vendor_buffer [ sizeof ( vendor_buffer ) - 1 ] = 0; strlwr( vendor_buffer ); - + ri.Cvar_Set( "scr_drawall", "0" ); gl_config.allow_cds = true; @@ -1146,8 +1148,7 @@ R_Init ( void *hinstance, void *hWnd ) if ( gl_ext_pointparameters->value ) { qglPointParameterfEXT = ( void (APIENTRY *) ( GLenum, GLfloat ) )qwglGetProcAddress( "glPointParameterfEXT" ); - qglPointParameterfvEXT = ( void (APIENTRY *) ( GLenum, const GLfloat * ) )qwglGetProcAddress( - "glPointParameterfvEXT" ); + qglPointParameterfvEXT = ( void (APIENTRY *) ( GLenum, const GLfloat * ) )qwglGetProcAddress( "glPointParameterfvEXT" ); ri.Con_Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" ); } else @@ -1160,6 +1161,51 @@ R_Init ( void *hinstance, void *hWnd ) ri.Con_Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" ); } + if ( strstr( gl_config.extensions_string, "GL_ARB_multitexture" ) ) + { + if ( gl_ext_multitexture->value ) + { + ri.Con_Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" ); + qglMTexCoord2fSGIS = (void *) qwglGetProcAddress( "glMultiTexCoord2fARB" ); + qglActiveTextureARB = (void *) qwglGetProcAddress( "glActiveTextureARB" ); + qglClientActiveTextureARB = (void *) qwglGetProcAddress( "glClientActiveTextureARB" ); + QGL_TEXTURE0 = GL_TEXTURE0_ARB; + QGL_TEXTURE1 = GL_TEXTURE1_ARB; + } + else + { + ri.Con_Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" ); + } + } + else + { + ri.Con_Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" ); + } + + if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) ) + { + if ( qglActiveTextureARB ) + { + ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n" ); + } + else if ( gl_ext_multitexture->value ) + { + ri.Con_Printf( PRINT_ALL, "...using GL_SGIS_multitexture\n" ); + qglMTexCoord2fSGIS = (void *) qwglGetProcAddress( "glMTexCoord2fSGIS" ); + qglSelectTextureSGIS = (void *) qwglGetProcAddress( "glSelectTextureSGIS" ); + QGL_TEXTURE0 = GL_TEXTURE0_SGIS; + QGL_TEXTURE1 = GL_TEXTURE1_SGIS; + } + else + { + ri.Con_Printf( PRINT_ALL, "...ignoring GL_SGIS_multitexture\n" ); + } + } + else + { + ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture not found\n" ); + } + R_SetDefaultState(); R_InitImages(); @@ -1205,7 +1251,7 @@ R_BeginFrame ( float camera_separation ) /* change modes if necessary */ if ( gl_mode->modified || vid_fullscreen->modified ) - { + { cvar_t *ref; ref = ri.Cvar_Get( "vid_ref", "gl", 0 ); @@ -1435,9 +1481,9 @@ R_GetRefAPI ( refimport_t rimp ) return ( re ); } -/* - * this is only here so the functions in - * q_shared.c can link +/* + * this is only here so the functions in + * q_shared.c can link */ void Sys_Error ( char *error, ... ) diff --git a/src/refresh/r_surf.c b/src/refresh/r_surf.c index b9112317..25a05d90 100644 --- a/src/refresh/r_surf.c +++ b/src/refresh/r_surf.c @@ -22,7 +22,7 @@ * Surface generation and drawing * * ======================================================================= - */ + */ #include #include "header/local.h" @@ -205,9 +205,9 @@ R_DrawGLPolyChain ( glpoly_t *p, float soffset, float toffset ) } /* -* This routine takes all the given light mapped surfaces in the world -* and blends them into the framebuffer. -*/ + * This routine takes all the given light mapped surfaces in the world + * and blends them into the framebuffer. + */ void R_BlendLightmaps ( void ) { @@ -228,8 +228,8 @@ R_BlendLightmaps ( void ) /* don't bother writing Z */ qglDepthMask( 0 ); - /* set the appropriate blending mode unless - we're only looking at the lightmaps. */ + /* set the appropriate blending mode unless + * we're only looking at the lightmaps. */ if ( !gl_lightmap->value ) { qglEnable( GL_BLEND ); @@ -478,7 +478,7 @@ R_DrawAlphaSurfaces ( void ) R_TexEnv( GL_MODULATE ); /* the textures are prescaled up for a better lighting range, - so scale it back down */ + * so scale it back down */ intens = gl_state.inverse_intensity; for ( s = r_alpha_surfaces; s; s = s->texturechain ) @@ -529,33 +529,263 @@ R_DrawTextureChains ( void ) c_visible_textures = 0; - for ( i = 0, image = gltextures; i < numgltextures; i++, image++ ) + if ( !qglSelectTextureSGIS && !qglActiveTextureARB ) { - if ( !image->registration_sequence ) + for ( i = 0, image = gltextures; i < numgltextures; i++, image++ ) { - continue; + if ( !image->registration_sequence ) + { + continue; + } + + s = image->texturechain; + + if ( !s ) + { + continue; + } + + c_visible_textures++; + + for ( ; s; s = s->texturechain ) + { + R_RenderBrushPoly( s ); + } + + image->texturechain = NULL; + } + } + else + { + for ( i = 0, image = gltextures; i < numgltextures; i++, image++ ) + { + if ( !image->registration_sequence ) + { + continue; + } + + if ( !image->texturechain ) + { + continue; + } + + c_visible_textures++; + + for ( s = image->texturechain; s; s = s->texturechain ) + { + if ( !( s->flags & SURF_DRAWTURB ) ) + { + R_RenderBrushPoly( s ); + } + } } - s = image->texturechain; + R_EnableMultitexture( false ); - if ( !s ) + for ( i = 0, image = gltextures; i < numgltextures; i++, image++ ) { - continue; + if ( !image->registration_sequence ) + { + continue; + } + + s = image->texturechain; + + if ( !s ) + { + continue; + } + + for ( ; s; s = s->texturechain ) + { + if ( s->flags & SURF_DRAWTURB ) + { + R_RenderBrushPoly( s ); + } + } + + image->texturechain = NULL; } - - c_visible_textures++; - - for ( ; s; s = s->texturechain ) - { - R_RenderBrushPoly( s ); - } - - image->texturechain = NULL; } R_TexEnv( GL_REPLACE ); } +static void +R_RenderLightmappedPoly ( msurface_t *surf ) +{ + int i, nv = surf->polys->numverts; + int map; + float *v; + image_t *image = R_TextureAnimation( surf->texinfo ); + qboolean is_dynamic = false; + unsigned lmtex = surf->lightmaptexturenum; + glpoly_t *p; + + for ( map = 0; map < MAXLIGHTMAPS && surf->styles [ map ] != 255; map++ ) + { + if ( r_newrefdef.lightstyles [ surf->styles [ map ] ].white != surf->cached_light [ map ] ) + { + goto dynamic; + } + } + + if ( ( surf->dlightframe == r_framecount ) ) + { + dynamic: + + if ( gl_dynamic->value ) + { + if ( !( surf->texinfo->flags & ( SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP ) ) ) + { + is_dynamic = true; + } + } + } + + if ( is_dynamic ) + { + unsigned temp [ 128 * 128 ]; + int smax, tmax; + + if ( ( ( surf->styles [ map ] >= 32 ) || ( surf->styles [ map ] == 0 ) ) && ( surf->dlightframe != r_framecount ) ) + { + smax = ( surf->extents [ 0 ] >> 4 ) + 1; + tmax = ( surf->extents [ 1 ] >> 4 ) + 1; + + R_BuildLightMap( surf, (void *) temp, smax * 4 ); + R_SetCacheState( surf ); + + R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + surf->lightmaptexturenum ); + + lmtex = surf->lightmaptexturenum; + + qglTexSubImage2D( GL_TEXTURE_2D, 0, + surf->light_s, surf->light_t, + smax, tmax, + GL_LIGHTMAP_FORMAT, + GL_UNSIGNED_BYTE, temp ); + } + else + { + smax = ( surf->extents [ 0 ] >> 4 ) + 1; + tmax = ( surf->extents [ 1 ] >> 4 ) + 1; + + R_BuildLightMap( surf, (void *) temp, smax * 4 ); + + R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + 0 ); + + lmtex = 0; + + qglTexSubImage2D( GL_TEXTURE_2D, 0, + surf->light_s, surf->light_t, + smax, tmax, + GL_LIGHTMAP_FORMAT, + GL_UNSIGNED_BYTE, temp ); + } + + c_brush_polys++; + + R_MBind( QGL_TEXTURE0, image->texnum ); + R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + lmtex ); + + if ( surf->texinfo->flags & SURF_FLOWING ) + { + float scroll; + + scroll = -64 * ( ( r_newrefdef.time / 40.0 ) - (int) ( r_newrefdef.time / 40.0 ) ); + + if ( scroll == 0.0 ) + { + scroll = -64.0; + } + + for ( p = surf->polys; p; p = p->chain ) + { + v = p->verts [ 0 ]; + qglBegin( GL_POLYGON ); + + for ( i = 0; i < nv; i++, v += VERTEXSIZE ) + { + qglMTexCoord2fSGIS( QGL_TEXTURE0, ( v [ 3 ] + scroll ), v [ 4 ] ); + qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] ); + qglVertex3fv( v ); + } + + qglEnd(); + } + } + else + { + for ( p = surf->polys; p; p = p->chain ) + { + v = p->verts [ 0 ]; + qglBegin( GL_POLYGON ); + + for ( i = 0; i < nv; i++, v += VERTEXSIZE ) + { + qglMTexCoord2fSGIS( QGL_TEXTURE0, v [ 3 ], v [ 4 ] ); + qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] ); + qglVertex3fv( v ); + } + + qglEnd(); + } + } + } + else + { + c_brush_polys++; + + R_MBind( QGL_TEXTURE0, image->texnum ); + R_MBind( QGL_TEXTURE1, gl_state.lightmap_textures + lmtex ); + + if ( surf->texinfo->flags & SURF_FLOWING ) + { + float scroll; + + scroll = -64 * ( ( r_newrefdef.time / 40.0 ) - (int) ( r_newrefdef.time / 40.0 ) ); + + if ( scroll == 0.0 ) + { + scroll = -64.0; + } + + for ( p = surf->polys; p; p = p->chain ) + { + v = p->verts [ 0 ]; + qglBegin( GL_POLYGON ); + + for ( i = 0; i < nv; i++, v += VERTEXSIZE ) + { + qglMTexCoord2fSGIS( QGL_TEXTURE0, ( v [ 3 ] + scroll ), v [ 4 ] ); + qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] ); + qglVertex3fv( v ); + } + + qglEnd(); + } + } + else + { + for ( p = surf->polys; p; p = p->chain ) + { + v = p->verts [ 0 ]; + qglBegin( GL_POLYGON ); + + for ( i = 0; i < nv; i++, v += VERTEXSIZE ) + { + qglMTexCoord2fSGIS( QGL_TEXTURE0, v [ 3 ], v [ 4 ] ); + qglMTexCoord2fSGIS( QGL_TEXTURE1, v [ 5 ], v [ 6 ] ); + qglVertex3fv( v ); + } + + qglEnd(); + } + } + } +} + void R_DrawInlineBModel ( void ) { @@ -598,21 +828,30 @@ R_DrawInlineBModel ( void ) ( !( psurf->flags & SURF_PLANEBACK ) && ( dot > BACKFACE_EPSILON ) ) ) { if ( psurf->texinfo->flags & ( SURF_TRANS33 | SURF_TRANS66 ) ) - { + { /* add to the translucent chain */ psurf->texturechain = r_alpha_surfaces; r_alpha_surfaces = psurf; } + else if ( qglMTexCoord2fSGIS && !( psurf->flags & SURF_DRAWTURB ) ) + { + R_RenderLightmappedPoly( psurf ); + } else { + R_EnableMultitexture( false ); R_RenderBrushPoly( psurf ); + R_EnableMultitexture( true ); } } } if ( !( currententity->flags & RF_TRANSLUCENT ) ) { - R_BlendLightmaps(); + if ( !qglMTexCoord2fSGIS ) + { + R_BlendLightmaps(); + } } else { @@ -678,15 +917,19 @@ R_DrawBrushModel ( entity_t *e ) qglPushMatrix(); e->angles [ 0 ] = -e->angles [ 0 ]; - e->angles [ 2 ] = -e->angles [ 2 ]; + e->angles [ 2 ] = -e->angles [ 2 ]; R_RotateForEntity( e ); - e->angles [ 0 ] = -e->angles [ 0 ]; + e->angles [ 0 ] = -e->angles [ 0 ]; e->angles [ 2 ] = -e->angles [ 2 ]; + R_EnableMultitexture( true ); + R_SelectTexture( QGL_TEXTURE0 ); R_TexEnv( GL_REPLACE ); + R_SelectTexture( QGL_TEXTURE1 ); R_TexEnv( GL_MODULATE ); R_DrawInlineBModel(); + R_EnableMultitexture( false ); qglPopMatrix(); } @@ -746,8 +989,8 @@ R_RecursiveWorldNode ( mnode_t *node ) return; } - /* node is just a decision point, so go down the apropriate sides - find which side of the node we are on */ + /* node is just a decision point, so go down the apropriate sides + * find which side of the node we are on */ plane = node->plane; switch ( plane->type ) @@ -794,22 +1037,29 @@ R_RecursiveWorldNode ( mnode_t *node ) } if ( surf->texinfo->flags & SURF_SKY ) - { + { /* just adds to visible sky bounds */ R_AddSkySurface( surf ); } else if ( surf->texinfo->flags & ( SURF_TRANS33 | SURF_TRANS66 ) ) - { + { /* add to the translucent chain */ surf->texturechain = r_alpha_surfaces; r_alpha_surfaces = surf; } else { - /* the polygon is visible, so add it to the texture */ - image = R_TextureAnimation( surf->texinfo ); - surf->texturechain = image->texturechain; - image->texturechain = surf; + if ( qglMTexCoord2fSGIS && !( surf->flags & SURF_DRAWTURB ) ) + { + R_RenderLightmappedPoly( surf ); + } + else + { + /* the polygon is visible, so add it to the texture sorted chain */ + image = R_TextureAnimation( surf->texinfo ); + surf->texturechain = image->texturechain; + image->texturechain = surf; + } } } @@ -846,7 +1096,32 @@ R_DrawWorld ( void ) qglColor3f( 1, 1, 1 ); memset( gl_lms.lightmap_surfaces, 0, sizeof ( gl_lms.lightmap_surfaces ) ); R_ClearSkyBox(); - R_RecursiveWorldNode( r_worldmodel->nodes ); + + if ( qglMTexCoord2fSGIS ) + { + R_EnableMultitexture( true ); + + R_SelectTexture( QGL_TEXTURE0 ); + R_TexEnv( GL_REPLACE ); + R_SelectTexture( QGL_TEXTURE1 ); + + if ( gl_lightmap->value ) + { + R_TexEnv( GL_REPLACE ); + } + else + { + R_TexEnv( GL_MODULATE ); + } + + R_RecursiveWorldNode( r_worldmodel->nodes ); + + R_EnableMultitexture( false ); + } + else + { + R_RecursiveWorldNode( r_worldmodel->nodes ); + } R_DrawTextureChains(); R_BlendLightmaps(); @@ -877,7 +1152,7 @@ R_MarkLeaves ( void ) } /* development aid to let you run around and see exactly where - the pvs ends */ + * the pvs ends */ if ( gl_lockpvs->value ) { return;