mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-14 04:59:58 +01:00
ref_soft: Add r_poly, transparent brushes support
This commit is contained in:
parent
72d5dfed34
commit
77e296ffef
99
r_bsp.c
99
r_bsp.c
@ -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 ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
18
r_local.h
18
r_local.h
@ -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
|
||||
|
33
r_main.c
33
r_main.c
@ -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;
|
||||
|
4
r_surf.c
4
r_surf.c
@ -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));
|
||||
|
||||
}
|
||||
|
72
r_trialias.c
72
r_trialias.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user