📄 gl_rsurf.c
字号:
fa->light_s, fa->light_t,
smax, tmax,
GL_LIGHTMAP_FORMAT,
GL_UNSIGNED_BYTE, temp );
fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
}
else
{
fa->lightmapchain = gl_lms.lightmap_surfaces[0];
gl_lms.lightmap_surfaces[0] = fa;
}
}
else
{
fa->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
}
}
/*
================
R_DrawAlphaSurfaces
Draw water surfaces and windows.
The BSP tree is waled front to back, so unwinding the chain
of alpha_surfaces will draw back to front, giving proper ordering.
================
*/
void R_DrawAlphaSurfaces (void)
{
msurface_t *s;
float intens;
//
// go back to the world matrix
//
qglLoadMatrixf (r_world_matrix);
qglEnable (GL_BLEND);
GL_TexEnv( GL_MODULATE );
// the textures are prescaled up for a better lighting range,
// so scale it back down
intens = gl_state.inverse_intensity;
for (s=r_alpha_surfaces ; s ; s=s->texturechain)
{
GL_Bind(s->texinfo->image->texnum);
c_brush_polys++;
if (s->texinfo->flags & SURF_TRANS33)
qglColor4f (intens,intens,intens,0.33);
else if (s->texinfo->flags & SURF_TRANS66)
qglColor4f (intens,intens,intens,0.66);
else
qglColor4f (intens,intens,intens,1);
if (s->flags & SURF_DRAWTURB)
EmitWaterPolys (s);
else if(s->texinfo->flags & SURF_FLOWING) // PGM 9/16/98
DrawGLFlowingPoly (s); // PGM
else
DrawGLPoly (s->polys);
}
GL_TexEnv( GL_REPLACE );
qglColor4f (1,1,1,1);
qglDisable (GL_BLEND);
r_alpha_surfaces = NULL;
}
/*
================
DrawTextureChains
================
*/
void DrawTextureChains (void)
{
int i;
msurface_t *s;
image_t *image;
c_visible_textures = 0;
// GL_TexEnv( GL_REPLACE );
if ( !qglSelectTextureSGIS && !qglActiveTextureARB )
{
for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
{
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);
}
}
GL_EnableMultitexture( false );
for ( i = 0, image=gltextures ; i<numgltextures ; i++,image++)
{
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;
}
// GL_EnableMultitexture( true );
}
GL_TexEnv( GL_REPLACE );
}
static void GL_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;
}
// dynamic this frame or dynamic previously
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 );
GL_MBind( GL_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 );
GL_MBind( GL_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++;
GL_MBind( GL_TEXTURE0, image->texnum );
GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
//==========
//PGM
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( GL_TEXTURE0, (v[3]+scroll), v[4]);
qglMTexCoord2fSGIS( GL_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( GL_TEXTURE0, v[3], v[4]);
qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
qglVertex3fv (v);
}
qglEnd ();
}
}
//PGM
//==========
}
else
{
c_brush_polys++;
GL_MBind( GL_TEXTURE0, image->texnum );
GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
//==========
//PGM
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( GL_TEXTURE0, (v[3]+scroll), v[4]);
qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
qglVertex3fv (v);
}
qglEnd ();
}
}
else
{
//PGM
//==========
for ( p = surf->polys; p; p = p->chain )
{
v = p->verts[0];
qglBegin (GL_POLYGON);
for (i=0 ; i< nv; i++, v+= VERTEXSIZE)
{
qglMTexCoord2fSGIS( GL_TEXTURE0, v[3], v[4]);
qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
qglVertex3fv (v);
}
qglEnd ();
}
//==========
//PGM
}
//PGM
//==========
}
}
/*
=================
R_DrawInlineBModel
=================
*/
void R_DrawInlineBModel (void)
{
int i, k;
cplane_t *pplane;
float dot;
msurface_t *psurf;
dlight_t *lt;
// calculate dynamic lighting for bmodel
if ( !gl_flashblend->value )
{
lt = r_newrefdef.dlights;
for (k=0 ; k<r_newrefdef.num_dlights ; k++, lt++)
{
R_MarkLights (lt, 1<<k, currentmodel->nodes + currentmodel->firstnode);
}
}
psurf = ¤tmodel->surfaces[currentmodel->firstmodelsurface];
if ( currententity->flags & RF_TRANSLUCENT )
{
qglEnable (GL_BLEND);
qglColor4f (1,1,1,0.25);
GL_TexEnv( GL_MODULATE );
}
//
// draw texture
//
for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++)
{
// find which side of the node we are on
pplane = psurf->plane;
dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
// draw the polygon
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(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 ) )
{
GL_RenderLightmappedPoly( psurf );
}
else
{
GL_EnableMultitexture( false );
R_RenderBrushPoly( psurf );
GL_EnableMultitexture( true );
}
}
}
if ( !(currententity->flags & RF_TRANSLUCENT) )
{
if ( !qglMTexCoord2fSGIS )
R_BlendLightmaps ();
}
else
{
qglDisable (GL_BLEND);
qglColor4f (1,1,1,1);
GL_TexEnv( GL_REPLACE );
}
}
/*
=================
R_DrawBrushModel
=================
*/
void R_DrawBrushModel (entity_t *e)
{
vec3_t mins, maxs;
int i;
qboolean rotated;
if (currentmodel->nummodelsurfaces == 0)
return;
currententity = e;
gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
if (e->angles[0] || e->angles[1] || e->angles[2])
{
rotated = true;
for (i=0 ; i<3 ; i++)
{
mins[i] = e->origin[i] - currentmodel->radius;
maxs[i] = e->origin[i] + currentmodel->radius;
}
}
else
{
rotated = false;
VectorAdd (e->origin, currentmodel->mins, mins);
VectorAdd (e->origin, currentmodel->maxs, maxs);
}
if (R_CullBox (mins, maxs))
return;
qglColor3f (1,1,1);
memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
VectorSubtract (r_newrefdef.vieworg, e->origin, modelorg);
if (rotated)
{
vec3_t temp;
vec3_t forward, right, up;
VectorCopy (modelorg, temp);
AngleVectors (e->angles, forward, right, up);
modelorg[0] = DotProduct (temp, forward);
modelorg[1] = -DotProduct (temp, right);
modelorg[2] = DotProduct (temp, up);
}
qglPushMatrix ();
e->angles[0] = -e->angles[0]; // stupid quake bug
e->angles[2] = -e->angles[2]; // stupid quake bug
R_RotateForEntity (e);
e->angles[0] = -e->angles[0]; // stupid quake bug
e->angles[2] = -e->angles[2]; // stupid quake bug
GL_EnableMultitexture( true );
GL_SelectTexture( GL_TEXTURE0);
GL_TexEnv( GL_REPLACE );
GL_SelectTexture( GL_TEXTURE1);
GL_TexEnv( GL_MODULATE );
R_DrawInlineBModel ();
GL_EnableMultitexture( false );
qglPopMatrix ();
}
/*
=============================================================
WORLD MODEL
=============================================================
*/
/*
================
R_RecursiveWorldNode
================
*/
void R_RecursiveWorldNode (mnode_t *node)
{
int c, side, sidebit;
cplane_t *plane;
msurface_t *surf, **mark;
mleaf_t *pleaf;
float dot;
image_t *image;
if (node->contents == CONTENTS_SOLID)
return; // solid
if (node->visframe != r_visframecount)
return;
if (R_CullBox (node->minmaxs, node->minmaxs+3))
return;
// if a leaf node, draw stuff
if (node->contents != -1)
{
pleaf = (mleaf_t *)node;
// check for door connected areas
if (r_newrefdef.areabits)
{
if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
return; // not visible
}
mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces;
if (c)
{
do
{
(*mark)->visframe = r_framecount;
mark++;
} while (--c);
}
return;
}
// 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)
{
case PLANE_X:
dot = modelorg[0] - plane->dist;
break;
case PLANE_Y:
dot = modelorg[1] - plane->dist;
break;
case PLANE_Z:
dot = modelorg[2] - plane->dist;
break;
default:
dot = DotProduct (modelorg, plane->normal) - plane->dist;
break;
}
if (dot >= 0)
{
side = 0;
sidebit = 0;
}
else
{
side = 1;
sidebit = SURF_PLANEBACK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -