07 Sep 2016

This commit is contained in:
g-cont 2016-09-07 00:00:00 +03:00 committed by Alibek Omarov
parent 7a9aadec2b
commit c14f696948
9 changed files with 245 additions and 146 deletions

View File

@ -48,7 +48,7 @@ GNU General Public License for more details.
#define PARM_TEX_CACHEFRAME 12 // compare with worldmodel->needload
#define PARM_TEX_GLFORMAT 13 // get a texture GL-format
#define PARM_TEX_ENCODE 14 // custom encoding for DXT image
// reserved
#define PARM_TEX_MIPCOUNT 15 // count of mipmaps (0 - autogenerated, 1 - disabled of mipmapping)
#define PARM_WORLD_VERSION 16 // return the version of bsp
#define PARM_SKY_SPHERE 17 // sky is quake sphere ?
#define PARM_MAP_HAS_MIRRORS 18 // current map has mirorrs

View File

@ -351,6 +351,9 @@ void CL_SetSolidPlayers( int playernum )
if( !state->solid )
continue; // not solid
if( !state->movetype )
continue; // dead
pe = &clgame.pmove->physents[clgame.pmove->numphysent];
if( CL_CopyEntityToPhysEnt( pe, ent ))
clgame.pmove->numphysent++;

View File

@ -977,7 +977,13 @@ void GL_GenerateMipmaps( byte *buffer, rgbdata_t *pic, gltexture_t *tex, GLenum
{
int mipLevel;
int dataType = GL_UNSIGNED_BYTE;
int w, h;
int w, h, maxdim;
mipLevel = 0;
w = tex->width;
h = tex->height;
maxdim = max( w, h );
tex->numMips = 1; // always have mip #0
// not needs
if( tex->flags & TF_NOMIPMAP )
@ -988,16 +994,13 @@ void GL_GenerateMipmaps( byte *buffer, rgbdata_t *pic, gltexture_t *tex, GLenum
pglHint( GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST );
pglTexParameteri( glTarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
pglGetError(); // clear error queue on mips generate
while( maxdim >>= 1 ) tex->numMips++;
return;
}
// screen texture?
if( !buffer ) return;
mipLevel = 0;
w = tex->width;
h = tex->height;
// software mipmap generator
while( w > 1 || h > 1 )
{
@ -1007,6 +1010,7 @@ void GL_GenerateMipmaps( byte *buffer, rgbdata_t *pic, gltexture_t *tex, GLenum
w = (w+1)>>1;
h = (h+1)>>1;
tex->numMips++;
mipLevel++;
if( subImage ) pglTexSubImage2D( tex->target + side, mipLevel, 0, 0, w, h, inFormat, dataType, buffer );
@ -1109,8 +1113,7 @@ static void GL_UploadTextureDXT( rgbdata_t *pic, gltexture_t *tex, qboolean subI
GLenum inFormat, glTarget;
uint width, height, depth;
int texsize = 0, samples;
uint i, j, s, numSides;
int numMips, err;
uint i, j, s, err, numSides;
ASSERT( pic != NULL && tex != NULL );
@ -1158,7 +1161,7 @@ static void GL_UploadTextureDXT( rgbdata_t *pic, gltexture_t *tex, qboolean subI
// determine target
tex->target = glTarget = GL_TEXTURE_2D;
numMips = (pic->numMips > 0) ? pic->numMips : 1;
tex->numMips = (pic->numMips > 0) ? pic->numMips : 1;
numSides = 1;
if( pic->flags & IMAGE_CUBEMAP )
@ -1215,7 +1218,7 @@ static void GL_UploadTextureDXT( rgbdata_t *pic, gltexture_t *tex, qboolean subI
height = pic->height;
depth = pic->depth;
for( j = 0; j < numMips; j++ )
for( j = 0; j < tex->numMips; j++ )
{
width = max( 1, ( pic->width >> j ));
height = max( 1, ( pic->height >> j ));
@ -1268,6 +1271,8 @@ static void GL_UploadTexture( rgbdata_t *pic, gltexture_t *tex, qboolean subImag
tex->fogParams[2] = pic->fogParams[2];
tex->fogParams[3] = pic->fogParams[3];
tex->numMips = pic->numMips;
// NOTE: normalmaps must be power of two or software mip generator will stop working
GL_RoundImageDimensions( &tex->width, &tex->height, tex->flags, ( tex->flags & TF_NORMALMAP ));

View File

@ -64,6 +64,7 @@ typedef struct gltexture_s
word srcHeight;
word width; // upload width\height
word height;
byte numMips; // mipmap count
uint cacheframe; // worldmodel->load_sequence
@ -422,10 +423,8 @@ void R_InitSky( struct mip_s *mt, struct texture_s *tx );
void R_AddSkyBoxSurface( msurface_t *fa );
void R_ClearSkyBox( void );
void R_DrawSkyBox( void );
void EmitSkyLayers( msurface_t *fa );
void EmitSkyPolys( msurface_t *fa );
void R_DrawClouds( void );
void EmitWaterPolys( glpoly_t *polys, qboolean noCull );
void R_DrawSkyChain( msurface_t *s );
//
// gl_vidnt.c

View File

@ -1409,6 +1409,9 @@ static int GL_RenderGetParm( int parm, int arg )
case PARM_TEX_ENCODE:
glt = R_GetTexture( arg );
return glt->encode;
case PARM_TEX_MIPCOUNT:
glt = R_GetTexture( arg );
return glt->numMips;
case PARM_TEX_SKYBOX:
ASSERT( arg >= 0 && arg < 6 );
return tr.skyboxTextures[arg];

View File

@ -1088,15 +1088,8 @@ void R_RenderBrushPoly( msurface_t *fa )
else r_stats.c_brush_polys++;
if( fa->flags & SURF_DRAWSKY )
{
if( world.sky_sphere )
{
// warp texture, no lightmaps
EmitSkyLayers( fa );
}
return;
}
return; // already handled
t = R_TextureAnimation( fa->texinfo->texture, fa - RI.currententity->model->surfaces );
if( RP_NORMALPASS() && fa->flags & SURF_REFLECT )
@ -1130,7 +1123,7 @@ void R_RenderBrushPoly( msurface_t *fa )
return;
}
if( t->fb_texturenum )
if( t->fb_texturenum && fa->polys )
{
// HACKHACK: store fullbrights in poly->next (only for non-water surfaces)
fa->polys->next = fullbright_polys[t->fb_texturenum];
@ -1251,31 +1244,40 @@ void R_DrawTextureChains( void )
RI.currententity = clgame.entities;
RI.currentmodel = RI.currententity->model;
if( world.sky_sphere )
{
pglDisable( GL_TEXTURE_2D );
pglColor3f( 1.0f, 1.0f, 1.0f );
}
// clip skybox surfaces
for( s = skychain; s != NULL; s = s->texturechain )
R_AddSkyBoxSurface( s );
if( world.sky_sphere )
{
pglEnable( GL_TEXTURE_2D );
if( skychain )
R_DrawClouds();
skychain = NULL;
}
for( i = 0; i < cl.worldmodel->numtextures; i++ )
{
t = cl.worldmodel->textures[i];
if( !t ) continue;
s = t->texturechain;
if( !s ) continue;
if( i == tr.skytexturenum )
{
if( world.sky_sphere )
R_DrawSkyChain( s );
}
else
{
if(( s->flags & SURF_DRAWTURB ) && cl.refdef.movevars->wateralpha < 1.0f )
continue; // draw translucent water later
if( !s || ( i == tr.skytexturenum ))
continue;
for( ; s != NULL; s = s->texturechain )
R_RenderBrushPoly( s );
}
if(( s->flags & SURF_DRAWTURB ) && cl.refdef.movevars->wateralpha < 1.0f )
continue; // draw translucent water later
for( ; s != NULL; s = s->texturechain )
R_RenderBrushPoly( s );
t->texturechain = NULL;
}
@ -1553,7 +1555,7 @@ void R_DrawStaticModel( cl_entity_t *e )
if( R_CullSurface( psurf, RI.clipFlags ))
continue;
if( psurf->flags & SURF_DRAWSKY && !world.sky_sphere )
if( psurf->flags & SURF_DRAWSKY )
{
// make sky chain to right clip the skybox
psurf->texturechain = skychain;
@ -1679,7 +1681,7 @@ void R_RecursiveWorldNode( mnode_t *node, uint clipflags )
if( R_CullSurface( surf, clipflags ))
continue;
if( surf->flags & SURF_DRAWSKY && !world.sky_sphere )
if( surf->flags & SURF_DRAWSKY )
{
// make sky chain to right clip the skybox
surf->texturechain = skychain;
@ -2168,9 +2170,6 @@ void GL_BuildLightmaps( void )
if( m->surfaces[j].flags & SURF_DRAWTURB )
continue;
if( m->surfaces[j].flags & SURF_DRAWSKY && world.sky_sphere )
continue;
GL_BuildPolygonFromSurface( m, m->surfaces + j );
}

View File

@ -19,9 +19,9 @@ GNU General Public License for more details.
#include "com_model.h"
#include "wadfile.h"
#define SKYCLOUDS_QUALITY 12
#define MAX_CLIP_VERTS 64 // skybox clip vertices
#define TURBSCALE ( 256.0f / ( M_PI2 ))
static float speedscale;
static const char* r_skyBoxSuffix[6] = { "rt", "bk", "lf", "ft", "up", "dn" };
static const int r_skyTexOrder[6] = { 0, 2, 1, 3, 4, 5 };
@ -304,6 +304,7 @@ void R_AddSkyBoxSurface( msurface_t *fa )
{
vec3_t verts[MAX_CLIP_VERTS];
glpoly_t *p;
float *v;
int i;
if( r_fastsky->integer )
@ -319,6 +320,20 @@ void R_AddSkyBoxSurface( msurface_t *fa )
}
}
if( world.sky_sphere && fa->polys )
{
glpoly_t *p = fa->polys;
// draw the sky poly
pglBegin( GL_POLYGON );
for( i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE )
{
pglTexCoord2f( v[3], v[4] );
pglVertex3fv( v );
}
pglEnd ();
}
// calculate vertex values for sky box
for( p = fa->polys; p; p = p->next )
{
@ -470,6 +485,179 @@ void R_SetupSky( const char *skyboxname )
R_UnloadSkybox();
}
//==============================================================================
//
// RENDER CLOUDS
//
//==============================================================================
/*
==============
R_CloudVertex
==============
*/
void R_CloudVertex( float s, float t, int axis, vec3_t v )
{
int j, k, farclip;
vec3_t b;
farclip = RI.farClip;
b[0] = s * (farclip >> 1);
b[1] = t * (farclip >> 1);
b[2] = (farclip >> 1);
for( j = 0; j < 3; j++ )
{
k = st_to_vec[axis][j];
v[j] = (k < 0) ? -b[-k-1] : b[k-1];
v[j] += RI.cullorigin[j];
}
}
/*
=============
R_CloudTexCoord
=============
*/
void R_CloudTexCoord( vec3_t v, float speed, float *s, float *t )
{
float length, speedscale;
vec3_t dir;
speedscale = cl.time * speed;
speedscale -= (int)speedscale & ~127;
VectorSubtract( v, RI.vieworg, dir );
dir[2] *= 3.0f; // flatten the sphere
length = VectorLength( dir );
length = 6.0f * 63.0f / length;
*s = ( speedscale + dir[0] * length ) * (1.0f / 128.0f);
*t = ( speedscale + dir[1] * length ) * (1.0f / 128.0f);
}
/*
===============
Sky_DrawFaceQuad
===============
*/
void R_CloudDrawPoly( glpoly_t *p )
{
float s, t;
float *v;
int i;
GL_SetRenderMode( kRenderNormal );
GL_Bind( GL_TEXTURE0, tr.solidskyTexture );
pglBegin( GL_QUADS );
for( i = 0, v = p->verts[0]; i < 4; i++, v += VERTEXSIZE )
{
R_CloudTexCoord( v, 8.0f, &s, &t );
pglTexCoord2f( s, t );
pglVertex3fv( v );
}
pglEnd();
GL_SetRenderMode( kRenderTransTexture );
GL_Bind( GL_TEXTURE0, tr.alphaskyTexture );
pglBegin( GL_QUADS );
for( i = 0, v = p->verts[0]; i < 4; i++, v += VERTEXSIZE )
{
R_CloudTexCoord( v, 16.0f, &s, &t );
pglTexCoord2f( s, t );
pglVertex3fv( v );
}
pglEnd();
pglDisable( GL_BLEND );
}
/*
==============
R_CloudRenderSide
==============
*/
void R_CloudRenderSide( int axis )
{
vec3_t verts[4];
float di, qi, dj, qj;
vec3_t vup, vright;
vec3_t temp, temp2;
glpoly_t p[1];
int i, j;
R_CloudVertex( -1.0f, -1.0f, axis, verts[0] );
R_CloudVertex( -1.0f, 1.0f, axis, verts[1] );
R_CloudVertex( 1.0f, 1.0f, axis, verts[2] );
R_CloudVertex( 1.0f, -1.0f, axis, verts[3] );
VectorSubtract( verts[2], verts[3], vup );
VectorSubtract( verts[2], verts[1], vright );
p->numverts = 4;
di = SKYCLOUDS_QUALITY;
qi = 1.0 / di;
dj = (axis < 4) ? di * 2 : di; //subdivide vertically more than horizontally on skybox sides
qj = 1.0 / dj;
for( i = 0; i < di; i++ )
{
for( j = 0; j < dj; j++ )
{
if( i * qi < RI.skyMins[0][axis] / 2 + 0.5f - qi
|| i * qi > RI.skyMaxs[0][axis] / 2 + 0.5f
|| j * qj < RI.skyMins[1][axis] / 2 + 0.5f - qj
|| j * qj > RI.skyMaxs[1][axis] / 2 + 0.5f )
continue;
VectorScale( vright, qi * i, temp );
VectorScale( vup, qj * j, temp2 );
VectorAdd( temp, temp2, temp );
VectorAdd( verts[0], temp, p->verts[0] );
VectorScale( vup, qj, temp );
VectorAdd( p->verts[0], temp, p->verts[1] );
VectorScale( vright, qi, temp );
VectorAdd( p->verts[1], temp, p->verts[2] );
VectorAdd( p->verts[0], temp, p->verts[3] );
R_CloudDrawPoly( p );
}
}
}
/*
==============
R_DrawClouds
Quake-style clouds
==============
*/
void R_DrawClouds( void )
{
int i;
RI.isSkyVisible = true;
pglDepthFunc( GL_GEQUAL );
pglDepthMask( 0 );
for( i = 0; i < 6; i++ )
{
if( RI.skyMins[0][i] >= RI.skyMaxs[0][i] || RI.skyMins[1][i] >= RI.skyMaxs[1][i] )
continue;
R_CloudRenderSide( i );
}
pglDepthMask( GL_TRUE );
pglDepthFunc( GL_LEQUAL );
}
/*
=============
R_InitSky
@ -634,103 +822,4 @@ void EmitWaterPolys( glpoly_t *polys, qboolean noCull )
if( noCull ) pglEnable( GL_CULL_FACE );
GL_SetupFogColorForSurfaces();
}
/*
=============
EmitSkyPolys
=============
*/
void EmitSkyPolys( msurface_t *fa )
{
glpoly_t *p;
float *v;
int i;
float s, t;
vec3_t dir;
float length;
for( p = fa->polys; p; p = p->next )
{
pglBegin( GL_POLYGON );
for( i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE )
{
VectorSubtract( v, RI.vieworg, dir );
dir[2] *= 3.0f; // flatten the sphere
length = VectorLength( dir );
length = 6.0f * 63.0f / length;
dir[0] *= length;
dir[1] *= length;
s = ( speedscale + dir[0] ) * (1.0f / 128.0f);
t = ( speedscale + dir[1] ) * (1.0f / 128.0f);
pglTexCoord2f( s, t );
pglVertex3fv( v );
}
pglEnd ();
}
}
/*
=================
R_DrawSkyChain
=================
*/
void R_DrawSkyChain( msurface_t *s )
{
msurface_t *fa;
GL_SetRenderMode( kRenderNormal );
GL_Bind( GL_TEXTURE0, tr.solidskyTexture );
speedscale = cl.time * 8.0f;
speedscale -= (int)speedscale & ~127;
for( fa = s; fa; fa = fa->texturechain )
EmitSkyPolys( fa );
GL_SetRenderMode( kRenderTransTexture );
GL_Bind( GL_TEXTURE0, tr.alphaskyTexture );
speedscale = cl.time * 16.0f;
speedscale -= (int)speedscale & ~127;
for( fa = s; fa; fa = fa->texturechain )
EmitSkyPolys( fa );
pglDisable( GL_BLEND );
}
/*
===============
EmitBothSkyLayers
Does a sky warp on the pre-fragmented glpoly_t chain
This will be called for brushmodels, the world
will have them chained together.
===============
*/
void EmitSkyLayers( msurface_t *fa )
{
GL_SetRenderMode( kRenderNormal );
GL_Bind( GL_TEXTURE0, tr.solidskyTexture );
speedscale = cl.time * 8.0f;
speedscale -= (int)speedscale & ~127;
EmitSkyPolys( fa );
GL_SetRenderMode( kRenderTransTexture );
GL_Bind( GL_TEXTURE0, tr.alphaskyTexture );
speedscale = cl.time * 16.0f;
speedscale -= (int)speedscale & ~127;
EmitSkyPolys( fa );
pglDisable( GL_BLEND );
}

View File

@ -1726,7 +1726,7 @@ void Mod_BuildSurfacePolygons( msurface_t *surf, mextrasurf_t *info )
}
// subdivide water or sky sphere for Quake1 maps
if(( surf->flags & SURF_DRAWTURB && !( surf->flags & SURF_REFLECT )) || ( surf->flags & SURF_DRAWSKY && world.loading && world.sky_sphere ))
if( surf->flags & SURF_DRAWTURB && !( surf->flags & SURF_REFLECT ))
{
Mod_SubdividePolygon( info, surf, surf->numedges, verts[0], 64.0f );
Mod_ConvertSurface( info, surf );
@ -1905,9 +1905,6 @@ static void Mod_LoadSurfaces( const dlump_t *l )
if( host.features & ENGINE_BUILD_SURFMESHES && (( out->flags & SURF_DRAWTILED ) || !out->samples ))
Mod_BuildSurfacePolygons( out, info );
if( out->flags & SURF_DRAWSKY && world.loading && world.sky_sphere )
GL_SubdivideSurface( out ); // cut up polygon for warps
if( out->flags & SURF_DRAWTURB )
GL_SubdivideSurface( out ); // cut up polygon for warps
}

View File

@ -804,7 +804,11 @@ void Delta_Init( void )
Delta_AddField( "movevars_t", "bounce", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "stepsize", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( "movevars_t", "maxvelocity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f ); // no fractional part
if( host.features & ENGINE_WRITE_LARGE_COORD )
Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f );
else Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 8.0f );
Delta_AddField( "movevars_t", "skyName", DT_STRING, 1, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "footsteps", DT_INTEGER, 1, 1.0f, 1.0f );