Use OpenGL multitexturing extensions to implement multitexturing...

This is a slighty revised version of id Software original code. Icculus
code may have some advantages on broken drivers or underpowered GPUs.
Today it's just a performance hook. This is a first step in fixing #147.
This commit is contained in:
Yamagi Burmeister 2016-08-05 18:27:05 +02:00
parent 2baf97bdf6
commit e4751e8c44
6 changed files with 46 additions and 99 deletions

View file

@ -117,6 +117,7 @@ extern void ( APIENTRY *qglColorTableEXT ) ( GLenum, GLenum, GLsizei, GLenum,
extern void ( APIENTRY *qglLockArraysEXT ) ( int, int );
extern void ( APIENTRY *qglUnlockArraysEXT ) ( void );
extern void ( APIENTRY *qglMultiTexCoord2fARB) ( GLenum, GLfloat, GLfloat );
extern void ( APIENTRY *qglMultiTexCoord2fvARB) ( GLenum, GLfloat* );
extern void ( APIENTRY *qglActiveTextureARB ) ( GLenum );
extern void ( APIENTRY *qglClientActiveTextureARB ) ( GLenum );

View file

@ -47,6 +47,7 @@ void (APIENTRY *qglColorTableEXT)(GLenum, GLenum, GLsizei, GLenum, GLenum,
void ( APIENTRY *qgl3DfxSetPaletteEXT ) ( GLuint * );
void ( APIENTRY *qglMultiTexCoord2fARB ) ( GLenum, GLfloat, GLfloat );
void ( APIENTRY *qglMultiTexCoord2fvARB) ( GLenum, GLfloat* );
void ( APIENTRY *qglActiveTextureARB ) ( GLenum );
void ( APIENTRY *qglClientActiveTextureARB ) ( GLenum );
@ -61,6 +62,7 @@ void QGL_EXT_Reset ( void )
qglColorTableEXT = NULL;
qgl3DfxSetPaletteEXT = NULL;
qglMultiTexCoord2fARB = NULL;
qglMultiTexCoord2fvARB = NULL;
qglActiveTextureARB = NULL;
qglClientActiveTextureARB = NULL;
}

View file

@ -377,12 +377,12 @@ typedef struct
const char *version_string;
const char *extensions_string;
qboolean allow_cds;
qboolean mtexcombine;
qboolean anisotropic;
qboolean tex_npot;
float max_anisotropy;
qboolean tex_npot;
} glconfig_t;
typedef struct
@ -398,6 +398,7 @@ typedef struct
int currenttextures[2];
int currenttmu;
GLenum currenttarget;
float camera_separation;
enum stereo_modes stereo_mode;

View file

@ -195,12 +195,10 @@ R_SelectTexture(GLenum texture)
}
gl_state.currenttmu = tmu;
gl_state.currenttarget = texture;
if (qglActiveTextureARB)
{
qglActiveTextureARB(texture);
qglClientActiveTextureARB(texture);
}
qglActiveTextureARB(texture);
qglClientActiveTextureARB(texture);
}
void
@ -237,7 +235,10 @@ R_Bind(int texnum)
void
R_MBind(GLenum target, int texnum)
{
R_SelectTexture(target);
if (target != gl_state.currenttarget)
{
R_SelectTexture(target);
}
if (target == GL_TEXTURE0_ARB)
{

View file

@ -1421,9 +1421,6 @@ R_Init(void *hinstance, void *hWnd)
Q_strlcpy(vendor_buffer, gl_config.vendor_string, sizeof(vendor_buffer));
Q_strlwr(vendor_buffer);
Cvar_Set("scr_drawall", "0");
gl_config.allow_cds = true;
VID_Printf(PRINT_ALL, "\n\nProbing for OpenGL extensions:\n");
/* grab extensions */
@ -1485,6 +1482,7 @@ R_Init(void *hinstance, void *hWnd)
{
VID_Printf(PRINT_ALL, "...using GL_ARB_multitexture\n");
qglMultiTexCoord2fARB = ( void * ) GLimp_GetProcAddress ( "glMultiTexCoord2fARB" );
qglMultiTexCoord2fvARB = (void * ) GLimp_GetProcAddress( "glMultiTexCoord2fvARB" );
qglActiveTextureARB = ( void * ) GLimp_GetProcAddress ( "glActiveTextureARB" );
qglClientActiveTextureARB = ( void * ) GLimp_GetProcAddress ( "glClientActiveTextureARB" );
}

View file

@ -737,8 +737,7 @@ R_RenderLightmappedPoly(msurface_t *surf)
{
float scroll;
scroll = -64 *
((r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0));
scroll = -64 * ((r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0));
if (scroll == 0.0)
{
@ -748,60 +747,34 @@ R_RenderLightmappedPoly(msurface_t *surf)
for (p = surf->polys; p; p = p->chain)
{
v = p->verts[0];
glBegin(GL_POLYGON);
GLfloat tex[2*nv];
unsigned int index_tex = 0;
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
for (i = 0; i < nv; i++, v += VERTEXSIZE)
{
tex[index_tex++] = v [ 3 ] + scroll;
tex[index_tex++] = v [ 4 ];
qglMultiTexCoord2fARB(GL_TEXTURE0, (v[3]+scroll), v[4]);
qglMultiTexCoord2fvARB(GL_TEXTURE1, &v[5]);
glVertex3fv(v);
}
v = p->verts [ 0 ];
R_SelectTexture( GL_TEXTURE0 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glVertexPointer( 3, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v );
glTexCoordPointer( 2, GL_FLOAT, 0, tex );
R_SelectTexture( GL_TEXTURE1 );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v+5 );
glDrawArrays( GL_TRIANGLE_FAN, 0, nv );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
R_SelectTexture( GL_TEXTURE0 );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glEnd();
}
}
else
{
for (p = surf->polys; p; p = p->chain)
{
v = p->verts[0];
glBegin(GL_POLYGON);
R_SelectTexture( GL_TEXTURE0 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
{
qglMultiTexCoord2fvARB(GL_TEXTURE0, &v[3]);
qglMultiTexCoord2fvARB(GL_TEXTURE1, &v[5]);
glVertex3fv(v);
}
glVertexPointer( 3, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v );
glTexCoordPointer( 2, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v+3 );
R_SelectTexture( GL_TEXTURE1 );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v+5 );
glDrawArrays( GL_TRIANGLE_FAN, 0, nv );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
R_SelectTexture( GL_TEXTURE0 );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glEnd();
}
}
}
@ -822,39 +795,18 @@ R_RenderLightmappedPoly(msurface_t *surf)
{
scroll = -64.0;
}
for (p = surf->polys; p; p = p->chain)
{
v = p->verts[0];
glBegin(GL_POLYGON);
GLfloat tex[2*nv];
unsigned int index_tex = 0;
for ( i = 0; i < nv; i++, v += VERTEXSIZE )
for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
{
tex[index_tex++] = v [ 3 ] + scroll;
tex[index_tex++] = v [ 4 ];
qglMultiTexCoord2fARB(GL_TEXTURE0, (v[3]+scroll), v[4]);
qglMultiTexCoord2fARB(GL_TEXTURE1, v[5], v[6]);
}
v = p->verts [ 0 ];
R_SelectTexture( GL_TEXTURE0 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glVertexPointer( 3, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v );
glTexCoordPointer( 2, GL_FLOAT, 0, tex );
R_SelectTexture( GL_TEXTURE1 );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v+5 );
glDrawArrays( GL_TRIANGLE_FAN, 0, nv );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
R_SelectTexture( GL_TEXTURE0 );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glEnd();
}
}
else
@ -862,23 +814,16 @@ R_RenderLightmappedPoly(msurface_t *surf)
for (p = surf->polys; p; p = p->chain)
{
v = p->verts[0];
glBegin (GL_POLYGON);
R_SelectTexture( GL_TEXTURE0 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
{
qglMultiTexCoord2fvARB(GL_TEXTURE0, &v[3]);
qglMultiTexCoord2fvARB(GL_TEXTURE1, &v[5]);
glVertex3fv(v);
}
glVertexPointer( 3, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v );
glTexCoordPointer( 2, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v+3 );
R_SelectTexture( GL_TEXTURE1 );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v+5 );
glDrawArrays( GL_TRIANGLE_FAN, 0, nv );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
R_SelectTexture( GL_TEXTURE0 );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glEnd();
}
}
}
@ -900,8 +845,7 @@ R_DrawInlineBModel(void)
for (k = 0; k < r_newrefdef.num_dlights; k++, lt++)
{
R_MarkLights(lt, 1 << k,
currentmodel->nodes + currentmodel->firstnode);
R_MarkLights(lt, 1 << k, currentmodel->nodes + currentmodel->firstnode);
}
}
@ -1264,7 +1208,7 @@ R_DrawWorld(void)
if (!gl_config.mtexcombine)
{
R_TexEnv(GL_REPLACE);
R_SelectTexture(GL_TEXTURE1);
R_SelectTexture(GL_TEXTURE1_ARB);
if (gl_lightmap->value)
{
@ -1282,7 +1226,7 @@ R_DrawWorld(void)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
R_SelectTexture(GL_TEXTURE1);
R_SelectTexture(GL_TEXTURE1_ARB);
R_TexEnv(GL_COMBINE_EXT);
if (gl_lightmap->value)