Get entity alpha (mostly) working.

I'm not sure if bsp model rendering is correct (backside issues), but
enities now sport transparency. Good test map:
http://www.celephais.net/board/view_thread.php?id=60157&
This commit is contained in:
Bill Currie 2010-12-16 09:34:29 +09:00
parent 765807def0
commit 12da412871
6 changed files with 31 additions and 36 deletions

View file

@ -116,7 +116,7 @@
#define ENTALPHA_DEFAULT 0 //entity's alpha is "default" (i.e. water obeys r_wateralpha) -- must be zero so zeroed out memory works
#define ENTALPHA_ZERO 1 //entity is invisible (lowest possible alpha)
#define ENTALPHA_ONE 255 //entity is fully opaque (highest possible alpha)
#define ENTALPHA_ENCODE(a) (((a)==0)?ENTALPHA_DEFAULT:RINT(CLAMP(1,(a)*254.0f+1,255))) //server convert to byte to send to client
#define ENTALPHA_ENCODE(a) (((a)==0)?ENTALPHA_DEFAULT:RINT(bound(1,(a)*254.0f+1,255))) //server convert to byte to send to client
#define ENTALPHA_DECODE(a) (((a)==ENTALPHA_DEFAULT)?1.0f:((float)(a)-1)/(254)) //client convert to float for rendering
#define ENTALPHA_TOSAVE(a) (((a)==ENTALPHA_DEFAULT)?0.0f:(((a)==ENTALPHA_ZERO)?-1.0f:((float)(a)-1)/(254))) //server convert to float for savegame

View file

@ -187,6 +187,8 @@ typedef struct
pr_int_t speed; //float
pr_int_t rotated_bbox; //int
pr_int_t alpha; //float
pr_int_t lastruntime; //float
} sv_fields_t;
@ -220,6 +222,8 @@ typedef struct sv_data_s {
link_t area; ///< linked to a division node or leaf
edict_leaf_t *leafs;
entity_state_t state;
byte alpha;
qboolean sendinterval;
} sv_data_t;
#define SVdata(e) ((sv_data_t *) ((e)->edata))

View file

@ -541,6 +541,8 @@ CL_RelinkEntities (void)
continue;
}
ent->colormod[3] = ENTALPHA_DECODE (state->alpha);
VectorCopy (ent->origin, ent->old_origin);
if (state->forcelink) {

View file

@ -514,31 +514,22 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
if (baseline->modelindex != SVfloat (ent, modelindex))
bits |= U_MODEL;
#if 0
//FIXME finish porting to QF
if (pr_alpha_supported) {
// TODO: find a cleaner place to put this code
eval_t *val;
val = GetEdictFieldValue(ent, "alpha");
if (val)
ent->alpha = ENTALPHA_ENCODE(val->_float);
}
if (sv_fields.alpha != -1)
SVdata (ent)->alpha = ENTALPHA_ENCODE(SVfloat (ent, alpha));
//don't send invisible entities unless they have effects
if (ent->alpha == ENTALPHA_ZERO && !ent->v.effects)
if (SVdata (ent)->alpha == ENTALPHA_ZERO && !SVfloat (ent, effects))
continue;
#endif
if (sv.protocol != PROTOCOL_NETQUAKE) {
//FIXME
//if (ent->baseline.alpha != ent->alpha)
// bits |= U_ALPHA;
if (SVdata (ent)->state.alpha != SVdata (ent)->alpha)
bits |= U_ALPHA;
if (bits & U_FRAME && (int) SVfloat (ent, frame) & 0xFF00)
bits |= U_FRAME2;
if (bits & U_MODEL && (int) SVfloat (ent, modelindex) & 0xFF00)
bits |= U_MODEL2;
//if (ent->sendinterval) FIXME
// bits |= U_LERPFINISH;
if (SVdata (ent)->sendinterval)
bits |= U_LERPFINISH;
if (bits >= 65536)
bits |= U_EXTEND1;
if (bits >= 16777216)
@ -590,9 +581,8 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
if (bits & U_ANGLE3)
MSG_WriteAngle (msg, SVvector (ent, angles)[2]);
//FIXME
//if (bits & U_ALPHA)
// MSG_WriteByte(msg, ent->alpha);
if (bits & U_ALPHA)
MSG_WriteByte(msg, SVdata (ent)->alpha);
if (bits & U_FRAME2)
MSG_WriteByte(msg, (int) SVfloat (ent, frame) >> 8);
if (bits & U_MODEL2)
@ -705,9 +695,8 @@ SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
bits |= SU_CELLS2;
if (bits & SU_WEAPONFRAME && (int) SVfloat (ent, weaponframe) & 0xFF00)
bits |= SU_WEAPONFRAME2;
//FIXME
//if (bits & SU_WEAPON && ent->alpha != ENTALPHA_DEFAULT)
// bits |= SU_WEAPONALPHA; //for now, weaponalpha = client entity alpha
if (bits & SU_WEAPON && SVdata (ent)->alpha != ENTALPHA_DEFAULT)
bits |= SU_WEAPONALPHA; //for now, weaponalpha = client entity alpha
if (bits >= 65536)
bits |= SU_EXTEND1;
if (bits >= 16777216)
@ -781,9 +770,8 @@ SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
MSG_WriteByte (msg, (int) SVfloat (ent, ammo_cells) >> 8);
if (bits & SU_WEAPONFRAME2)
MSG_WriteByte (msg, (int) SVfloat (ent, weaponframe) >> 8);
// FIXME
//if (bits & SU_WEAPONALPHA)
// MSG_WriteByte (msg, ent->alpha); //for now, weaponalpha = client entity alpha
if (bits & SU_WEAPONALPHA)
MSG_WriteByte (msg, SVdata (ent)->alpha); //for now, weaponalpha = client entity alpha
}
static qboolean

View file

@ -1160,10 +1160,10 @@ PF_makestatic (progs_t *pr)
int bits = 0;
ent = P_EDICT (pr, 0);
//if (ent->alpha == ENTALPHA_ZERO) { //FIXME
// //johnfitz -- don't send invisible static entities
// goto nosend;
//}
if (SVdata (ent)->alpha == ENTALPHA_ZERO) {
//johnfitz -- don't send invisible static entities
goto nosend;
}
model = PR_GetString (pr, SVstring (ent, model));
if (sv.protocol == PROTOCOL_NETQUAKE) {
@ -1175,9 +1175,8 @@ PF_makestatic (progs_t *pr)
bits |= B_LARGEMODEL;
if ((int) SVfloat (ent, frame) & 0xff00)
bits |= B_LARGEFRAME;
//FIXME
//if (ent->alpha != ENTALPHA_DEFAULT)
// bits |= B_ALPHA;
if (SVdata (ent)->alpha != ENTALPHA_DEFAULT)
bits |= B_ALPHA;
}
if (bits) {
@ -1203,9 +1202,8 @@ PF_makestatic (progs_t *pr)
MSG_WriteCoordAngleV (&sv.signon, SVvector (ent, origin),
SVvector (ent, angles));
//FIXME
//if (bits & B_ALPHA)
// MSG_WriteByte (&sv.signon, ent->alpha);
if (bits & B_ALPHA)
MSG_WriteByte (&sv.signon, SVdata (ent)->alpha);
// throw the entity away now
nosend:
ED_Free (pr, ent);

View file

@ -169,6 +169,8 @@ parse_field (progs_t *pr, const char *key, const char *value)
|| strequal (key, "qlsky")
|| strequal (key, "fog"))
return 1;
if (strequal (key, "mapversion")) // ignore HL(?) version field
return 1;
if (*key == '_') // ignore _fields
return 1;
return 0;
@ -327,6 +329,7 @@ static sv_def_t nq_opt_funcs[] = {
static sv_def_t nq_opt_fields[] = {
{ev_integer, 0, "rotated_bbox", &sv_fields.rotated_bbox},
{ev_float, 0, "alpha", &sv_fields.alpha},
{ev_float, 0, "gravity", &sv_fields.gravity},
// Quake 2 fields?
{ev_float, 0, "dmg", &sv_fields.dmg},