ref_soft: Add r_poly, transparent brushes support

This commit is contained in:
mittorn 2019-03-29 02:02:38 +07:00
parent 72d5dfed34
commit 77e296ffef
7 changed files with 1489 additions and 15 deletions

99
r_bsp.c
View File

@ -920,3 +920,102 @@ void R_RenderWorld (void)
}
/*
================
R_DrawBrushModel
not covered by edge drawing
================
*/
void R_DrawBrushModel(cl_entity_t *pent)
{
int i;
vec_t dot;
msurface_t *psurf;
int numsurfaces;
mplane_t *pplane;
vec3_t mins, maxs;
float minmaxs[6];
int clipflags, k;
model_t *pmodel;
vec3_t oldorigin;
VectorCopy (modelorg, oldorigin);
insubmodel = true;
if( !pent || !pent->model )
return;
pmodel = pent->model;
if (pmodel->type != mod_brush)
return;
if (pmodel->nummodelsurfaces == 0)
return; // clip brush only
#if 0
// FIXME: use bounding-box-based frustum clipping info?
RotatedBBox (pmodel->mins, pmodel->maxs,
RI.currententity->angles, mins, maxs);
VectorAdd (mins, RI.currententity->origin, minmaxs);
VectorAdd (maxs, RI.currententity->origin, (minmaxs+3));
clipflags = R_BmodelCheckBBox (minmaxs);
if (clipflags == BMODEL_FULLY_CLIPPED)
return; // off the edge of the screen
R_RotateBmodel ();
VectorCopy (RI.currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
//VectorSubtract (r_origin, RI.currententity->origin, modelorg);
r_pcurrentvertbase = pmodel->vertexes;
// calculate dynamic lighting for bmodel
for( k = 0; k < MAX_DLIGHTS; k++ )
{
dlight_t *l = gEngfuncs.GetDynamicLight( k );
if( l->die < gpGlobals->time || !l->radius )
continue;
/*VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1<<k, clmodel->nodes + clmodel->hulls[0].firstclipnode );
VectorCopy( oldorigin, l->origin ); // restore lightorigin*/
R_MarkLights( l, 1<<k, pmodel->nodes + pmodel->hulls[0].firstclipnode );
}
#endif
psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
numsurfaces = pmodel->nummodelsurfaces;
for (i=0 ; i<numsurfaces ; 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)))
{
// FIXME: use bounding-box-based frustum clipping info?
R_BuildPolygonFromSurface( psurf );
R_ClipAndDrawPoly( pent->curstate.renderamt / 255, !!(psurf->flags & SURF_DRAWTURB), true );
}
}
// put back world rotation and frustum clipping
// FIXME: R_RotateBmodel should just work off base_vxx
VectorCopy (base_vpn, vpn);
VectorCopy (base_vup, vup);
VectorCopy (base_vright, vright);
VectorCopy (oldorigin, modelorg);
R_TransformFrustum ();
}

View File

@ -535,7 +535,6 @@ static qboolean GL_UploadTexture( image_t *tex, rgbdata_t *pic )
if( j == 0 && tex->flags & TF_HAS_ALPHA )
tex->alpha_pixels = Mem_Calloc( r_temppool, width * height * sizeof(pixel_t) + 64 );
for(i = 0; i < height * width; i++ )
{
unsigned int r, g, b, major, minor;
@ -560,6 +559,8 @@ static qboolean GL_UploadTexture( image_t *tex, rgbdata_t *pic )
{
unsigned int alpha = (pic->buffer[i * 4 + 3] * 8 / 256) << (16 - 3);
tex->alpha_pixels[i] = (tex->pixels[j][i] >> 3) | alpha;
if( pic->buffer[i * 4 + 3] < 128 && FBitSet( pic->flags, IMAGE_ONEBIT_ALPHA ) )
tex->pixels[j][i] = TRANSPARENT_COLOR; //0000 0011 0100 1001;
}
}

View File

@ -244,9 +244,11 @@ typedef struct
typedef struct
{
cl_entity_t *edge_entities[MAX_VISIBLE_PACKET]; // brush edge drawing
cl_entity_t *solid_entities[MAX_VISIBLE_PACKET]; // opaque moving or alpha brushes
cl_entity_t *trans_entities[MAX_VISIBLE_PACKET]; // translucent brushes
cl_entity_t *beam_entities[MAX_VISIBLE_PACKET];
uint num_edge_entities;
uint num_solid_entities;
uint num_trans_entities;
uint num_beam_entities;
@ -799,7 +801,7 @@ extern cvar_t *r_showhull;
#define PARTICLE_Z_CLIP 8.0
// !!! must be kept the same as in quakeasm.h !!!
#define TRANSPARENT_COLOR 0xFF
#define TRANSPARENT_COLOR 0x0349 //0xFF
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
@ -1027,7 +1029,7 @@ typedef struct
{
int nump;
emitpoint_t *pverts;
byte *pixels; // image
pixel_t *pixels; // image
int pixel_width; // image width
int pixel_height; // image height
vec3_t vup, vright, vpn; // in worldspace, for plane eq
@ -1282,6 +1284,7 @@ void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t
void R_RotateBmodel (void);
void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode);
void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode);
void R_DrawBrushModel(cl_entity_t *pent);
//
// r_blitscreen.c
@ -1335,6 +1338,17 @@ void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
void R_RenderTriangle( finalvert_t *fv1 , finalvert_t *fv2, finalvert_t *fv3 );
void R_SetupFinalVert( finalvert_t *fv, float x, float y, float z, int light, int s, int t );
void RotatedBBox (vec3_t mins, vec3_t maxs, vec3_t angles, vec3_t tmins, vec3_t tmaxs);
int R_BmodelCheckBBox (float *minmaxs);
//
// r_poly.c
//
void R_BuildPolygonFromSurface(msurface_t *fa);
void R_ClipAndDrawPoly( float alpha, qboolean isturbulent, qboolean textured );
void R_SetUpWorldTransform (void);
//
// engine callbacks

View File

@ -407,6 +407,7 @@ void R_ClearScene( void )
tr.draw_list->num_solid_entities = 0;
tr.draw_list->num_trans_entities = 0;
tr.draw_list->num_beam_entities = 0;
tr.draw_list->num_edge_entities = 0;
// clear the scene befor start new frame
if( gEngfuncs.drawFuncs->R_ClearScene != NULL )
@ -436,9 +437,17 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
if( type == ET_FRAGMENTED )
r_stats.c_client_ents++;
// debug: mark all solid
if( true ) // R_OpaqueEntity( clent ))
if( R_OpaqueEntity( clent ))
{
if( clent->model->type == mod_brush )
{
if( tr.draw_list->num_edge_entities >= MAX_VISIBLE_PACKET )
return false;
tr.draw_list->edge_entities[tr.draw_list->num_edge_entities] = clent;
tr.draw_list->num_edge_entities++;
return true;
}
// opaque
if( tr.draw_list->num_solid_entities >= MAX_VISIBLE_PACKET )
return false;
@ -1011,10 +1020,7 @@ void R_DrawEntitiesOnList( void )
d_aflatcolor = 0;
tr.blend = 1.0f;
// GL_CheckForErrors();
// HACK: setup world transform
void R_AliasSetUpTransform (void);
RI.currententity = gEngfuncs.GetEntityByIndex(0);
R_AliasSetUpTransform();
//RI.currententity = gEngfuncs.GetEntityByIndex(0);
extern void (*d_pdrawspans)(void *);
extern void R_PolysetFillSpans8 ( void * );
d_pdrawspans = R_PolysetFillSpans8;
@ -1031,12 +1037,13 @@ void R_DrawEntitiesOnList( void )
switch( RI.currentmodel->type )
{
case mod_brush:
//R_DrawBrushModel( RI.currententity );
R_DrawBrushModel( RI.currententity );
break;
case mod_alias:
//R_DrawAliasModel( RI.currententity );
break;
case mod_studio:
R_SetUpWorldTransform();
R_DrawStudioModel( RI.currententity );
#if 0
// gradient debug (for colormap testing)
@ -1114,7 +1121,7 @@ void R_DrawEntitiesOnList( void )
tr.blend = gEngfuncs.CL_FxBlend( RI.currententity ) / 255.0f;
else tr.blend = 1.0f; // draw as solid but sorted by distance
if( tr.blend <= 0.0f ) continue;
//if( tr.blend <= 0.0f ) continue;
Assert( RI.currententity != NULL );
Assert( RI.currentmodel != NULL );
@ -1122,13 +1129,14 @@ void R_DrawEntitiesOnList( void )
switch( RI.currentmodel->type )
{
case mod_brush:
// R_DrawBrushModel( RI.currententity );
R_DrawBrushModel( RI.currententity );
break;
case mod_alias:
//R_DrawAliasModel( RI.currententity );
break;
case mod_studio:
// R_DrawStudioModel( RI.currententity );
R_SetUpWorldTransform();
R_DrawStudioModel( RI.currententity );
break;
case mod_sprite:
// R_DrawSpriteModel( RI.currententity );
@ -1159,6 +1167,7 @@ void R_DrawEntitiesOnList( void )
// pglDisable( GL_BLEND ); // Trinity Render issues
R_SetUpWorldTransform();
if( !RI.onlyClientDraw )
R_DrawViewModel();
gEngfuncs.CL_ExtraUpdate();
@ -1334,10 +1343,10 @@ void R_DrawBEntitiesOnList (void)
insubmodel = true;
//r_dlightframecount = r_framecount;
for( i = 0; i < tr.draw_list->num_solid_entities && !RI.onlyClientDraw; i++ )
for( i = 0; i < tr.draw_list->num_edge_entities && !RI.onlyClientDraw; i++ )
{
int k;
RI.currententity = tr.draw_list->solid_entities[i];
RI.currententity = tr.draw_list->edge_entities[i];
RI.currentmodel = RI.currententity->model;
if (!RI.currentmodel)
continue;

1275
r_poly.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -582,6 +582,8 @@ void R_DrawSurfaceBlock8_mip0 (void)
{
pix = psource[b];
prowdest[b] = BLEND_LM(pix, light);
if( pix == TRANSPARENT_COLOR )
prowdest[b] = TRANSPARENT_COLOR;
// pix;
//((unsigned char *)vid.colormap)
@ -1069,6 +1071,8 @@ void R_DrawSurfaceDecals()
if( alpha < 7) // && (vid.rendermode == kRenderTransAlpha || vid.rendermode == kRenderTransTexture ) )
{
pixel_t screen = dest[u]; // | 0xff & screen & src ;
if( screen == TRANSPARENT_COLOR )
continue;
dest[u] = vid.alphamap[( alpha << 16)|(src & 0xff00)|(screen>>8)] << 8 | (screen & 0x7f) >> 3 | ((src & 0xff));
}

View File

@ -78,6 +78,78 @@ void VectorInverse (vec3_t v)
v[2] = -v[2];
}
/*
================
R_SetUpWorldTransform
================
*/
void R_SetUpWorldTransform (void)
{
int i;
static float viewmatrix[3][4];
vec3_t angles;
// TODO: should really be stored with the entity instead of being reconstructed
// TODO: should use a look-up table
// TODO: could cache lazily, stored in the entity
//
s_ziscale = (float)0x8000 * (float)0x10000;
angles[ROLL] = 0;
angles[PITCH] = 0;
angles[YAW] = 0;
AngleVectors( angles, s_alias_forward, s_alias_right, s_alias_up );
// TODO: can do this with simple matrix rearrangement
memset( aliasworldtransform, 0, sizeof( aliasworldtransform ) );
memset( aliasoldworldtransform, 0, sizeof( aliasworldtransform ) );
for (i=0 ; i<3 ; i++)
{
aliasoldworldtransform[i][0] = aliasworldtransform[i][0] = s_alias_forward[i];
aliasoldworldtransform[i][0] = aliasworldtransform[i][1] = -s_alias_right[i];
aliasoldworldtransform[i][0] = aliasworldtransform[i][2] = s_alias_up[i];
}
aliasworldtransform[0][3] = -r_origin[0];
aliasworldtransform[1][3] = -r_origin[1];
aliasworldtransform[2][3] = -r_origin[2];
//aliasoldworldtransform[0][3] = RI.currententity->oldorigin[0]-r_origin[0];
//aliasoldworldtransform[1][3] = RI.currententity->oldorigin[1]-r_origin[1];
//aliasoldworldtransform[2][3] = RI.currententity->oldorigin[2]-r_origin[2];
// FIXME: can do more efficiently than full concatenation
// memcpy( rotationmatrix, t2matrix, sizeof( rotationmatrix ) );
// R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix);
// TODO: should be global, set when vright, etc., set
VectorCopy (vright, viewmatrix[0]);
VectorCopy (vup, viewmatrix[1]);
VectorInverse (viewmatrix[1]);
//VectorScale(viewmatrix[1], -1, viewmatrix[1]);
VectorCopy (vpn, viewmatrix[2]);
viewmatrix[0][3] = 0;
viewmatrix[1][3] = 0;
viewmatrix[2][3] = 0;
// memcpy( aliasworldtransform, rotationmatrix, sizeof( aliastransform ) );
R_ConcatTransforms (viewmatrix, aliasworldtransform, aliastransform);
aliasworldtransform[0][3] = 0;
aliasworldtransform[1][3] = 0;
aliasworldtransform[2][3] = 0;
//aliasoldworldtransform[0][3] = RI.currententity->oldorigin[0];
//aliasoldworldtransform[1][3] = RI.currententity->oldorigin[1];
//aliasoldworldtransform[2][3] = RI.currententity->oldorigin[2];
}
/*
================
R_AliasSetUpTransform