MSG_WriteByte (&buf, in_impulse);
in_impulse = 0;
- if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3)
- {
- // LordHavoc: should we ack this on receipt instead? would waste net bandwidth though
- if (cl.entitydatabase)
- {
- i = EntityFrame_MostRecentlyRecievedFrameNum(cl.entitydatabase);
- if (i > 0)
- {
- MSG_WriteByte(&buf, clc_ackentities);
- MSG_WriteLong(&buf, i);
- }
- }
- }
- else if (cl.protocol == PROTOCOL_DARKPLACES4)
- {
- if (cl.entitydatabase4)
- {
- i = cl.latestframenum;
- if (cl_nodelta.integer)
- i = -1;
- if (developer_networkentities.integer >= 1)
- Con_Printf("send clc_ackentities %i\n", i);
- MSG_WriteByte(&buf, clc_ackentities);
- MSG_WriteLong(&buf, i);
- }
- }
- else if (cl.protocol == PROTOCOL_DARKPLACES5)
+ // FIXME: should ack latest 3 frames perhaps?
+ if (cl.latestframenum > 0)
{
i = cl.latestframenum;
if (cl_nodelta.integer)
// skip inactive entities and world
if (!e->state_current.active || e == cl_entities)
return;
+ e->render.alpha = e->state_current.alpha * (1.0f / 255.0f); // FIXME: interpolate?
+ e->render.scale = e->state_current.scale * (1.0f / 16.0f); // FIXME: interpolate?
+ e->render.flags = e->state_current.flags;
+ e->render.effects = e->state_current.effects;
+ if (e->state_current.flags & RENDER_COLORMAPPED)
+ e->render.colormap = e->state_current.colormap;
+ else if (cl.scores != NULL && e->state_current.colormap)
+ e->render.colormap = cl.scores[e->state_current.colormap - 1].colors; // color it
+ else
+ e->render.colormap = -1; // no special coloring
+ e->render.skinnum = e->state_current.skin;
if (e->render.flags & RENDER_VIEWMODEL)
{
if (!r_drawviewmodel.integer || chase_active.integer || envmap)
CL_LinkNetworkEntity(t);
// make relative to the entity
matrix = &t->render.matrix;
+ // some properties of the tag entity carry over
+ e->render.flags |= t->render.flags & RENDER_EXTERIORMODEL;
// if a valid tagindex is used, make it relative to that tag instead
// FIXME: use a model function to get tag info (need to handle skeletal)
if (e->state_current.tagentity && e->state_current.tagindex >= 1 && (model = t->render.model) && e->state_current.tagindex <= t->render.model->alias.aliasnum_tags)
matrix = &tempmatrix;
}
}
- e->render.alpha = e->state_current.alpha * (1.0f / 255.0f); // FIXME: interpolate?
- e->render.scale = e->state_current.scale * (1.0f / 16.0f); // FIXME: interpolate?
- e->render.flags = e->state_current.flags;
- if (e - cl_entities == cl.viewentity)
- e->render.flags |= RENDER_EXTERIORMODEL;
- e->render.effects = e->state_current.effects;
- if (e->state_current.flags & RENDER_COLORMAPPED)
- e->render.colormap = e->state_current.colormap;
- else if (cl.scores != NULL && e->state_current.colormap)
- e->render.colormap = cl.scores[e->state_current.colormap - 1].colors; // color it
- else
- e->render.colormap = -1; // no special coloring
- e->render.skinnum = e->state_current.skin;
// set up the render matrix
if (e->state_previous.active && e->state_current.modelindex == e->state_previous.modelindex)
{
if (cl_itembobheight.value)
origin[2] += (cos(cl.time * cl_itembobspeed.value * (2.0 * M_PI)) + 1.0) * 0.5 * cl_itembobheight.value;
}
+ // transfer certain model flags to effects
+ if (e->render.model->flags2 & EF_FULLBRIGHT)
+ e->render.effects |= EF_FULLBRIGHT;
}
R_LerpAnimation(&e->render);
CL_RocketTrail(e->persistent.trail_origin, origin, trailtype, e->state_current.glowcolor, e);
}
VectorCopy(origin, e->persistent.trail_origin);
- // note: the cl.viewentity and intermission check is to hide player
- // shadow during intermission and during the Nehahra movie and
- // Nehahra cinematics
- if (!(e->render.effects & (EF_NOSHADOW | EF_ADDITIVE))
- && (e->render.alpha == 1)
- && !(e->render.flags & RENDER_VIEWMODEL)
- && ((e - cl_entities) != cl.viewentity || (!cl.intermission && cl.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer)))
- e->render.flags |= RENDER_SHADOW;
- if (!(e->render.effects & EF_FULLBRIGHT))
+ // tenebrae's sprites are all additive mode (weird)
+ if (gamemode == GAME_TENEBRAE && e->render.model && e->render.model->type == mod_sprite)
+ e->render.effects |= EF_ADDITIVE;
+ // player model is only shown with chase_active on
+ if (e - cl_entities == cl.viewentity)
+ e->render.flags |= RENDER_EXTERIORMODEL;
+ // transparent stuff can't be lit during the opaque stage
+ if (e->render.effects & (EF_ADDITIVE) || e->render.alpha < 1)
+ e->render.flags |= RENDER_TRANSPARENT;
+ // either fullbright or lit
+ if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer)
e->render.flags |= RENDER_LIGHT;
+ // hide player shadow during intermission or nehahra movie
+ if (!(e->render.effects & EF_NOSHADOW)
+ && !(e->render.flags & (RENDER_VIEWMODEL | RENDER_TRANSPARENT))
+ && (!(e->render.flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cl.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer)))
+ e->render.flags |= RENDER_SHADOW;
// as soon as player is known we can call V_CalcRefDef
if ((e - cl_entities) == cl.viewentity)
V_CalcRefdef();
if (e->render.model && e->render.model->name[0] == '*' && e->render.model->TraceBox)
cl_brushmodel_entities[cl_num_brushmodel_entities++] = &e->render;
- if (gamemode == GAME_TENEBRAE && e->render.model && e->render.model->type == mod_sprite)
- e->render.effects |= EF_ADDITIVE;
// don't show entities with no modelindex (note: this still shows
// entities which have a modelindex that resolved to a NULL model)
if (e->render.model && !(e->render.effects & EF_NODRAW) && r_refdef.numentities < r_refdef.maxentities)
return;
//VectorCopy (org, ent->render.origin);
ent->render.model = b->model;
- ent->render.effects = EF_FULLBRIGHT;
+ //ent->render.effects = EF_FULLBRIGHT;
//ent->render.angles[0] = pitch;
//ent->render.angles[1] = yaw;
//ent->render.angles[2] = rand()%360;
|| ((layer->flags & ALIASLAYER_NODRAW_IF_COLORMAPPED) && ent->colormap >= 0)
|| ((layer->flags & ALIASLAYER_FOG) && !fogenabled)
|| (layer->flags & ALIASLAYER_SPECULAR)
- || ((layer->flags & ALIASLAYER_DIFFUSE) && (r_shadow_realtime_world.integer && r_shadow_realtime_world_lightmaps.value <= 0 && r_ambient.integer <= 0 && r_fullbright.integer == 0 && !(ent->effects & EF_FULLBRIGHT))))
+ || ((layer->flags & ALIASLAYER_DIFFUSE) && (ent->flags & RENDER_LIGHT) && r_lightmapintensity <= 0 && !(ent->flags & RENDER_TRANSPARENT) && r_ambient.integer <= 0))
continue;
}
if (!firstpass || (ent->effects & EF_ADDITIVE))
}
else
{
- fullbright = !(layer->flags & ALIASLAYER_DIFFUSE) || r_fullbright.integer || (ent->effects & EF_FULLBRIGHT);
+ fullbright = !(layer->flags & ALIASLAYER_DIFFUSE) || !(ent->flags & RENDER_LIGHT);
if (layer->flags & (ALIASLAYER_COLORMAP_PANTS | ALIASLAYER_COLORMAP_SHIRT))
{
// 128-224 are backwards ranges
}
else
tint[0] = tint[1] = tint[2] = 1;
- if (r_shadow_realtime_world.integer && !fullbright)
- VectorScale(tint, r_shadow_realtime_world_lightmaps.value, tint);
+ if (!fullbright && !(ent->flags & RENDER_TRANSPARENT))
+ colorscale *= r_lightmapintensity;
colorscale *= ifog;
if (fullbright)
GL_Color(tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha);
- else
+ else if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha, false))
{
- if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0] * colorscale, tint[1] * colorscale, tint[2] * colorscale, ent->alpha, false))
+ m.pointer_color = varray_color4f;
+ if (normal3f == NULL)
{
- m.pointer_color = varray_color4f;
- if (normal3f == NULL)
- {
- normal3f = varray_normal3f;
- Mod_BuildNormals(mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
- }
- R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
+ normal3f = varray_normal3f;
+ Mod_BuildNormals(mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
}
- else
- GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
+ R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
}
+ else
+ GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
}
R_Mesh_State(&m);
GL_LockArrays(0, mesh->num_vertices);
aliasmesh_t *mesh;
aliasskin_t *skin;
float projectdistance, *vertex3f;
- if (ent->effects & EF_ADDITIVE || ent->alpha < 1)
+ if (!(ent->flags & RENDER_SHADOW))
return;
projectdistance = lightradius + ent->model->radius;// - sqrt(DotProduct(relativelightorigin, relativelightorigin));
if (projectdistance > 0.1)
aliaslayer_t *layer;
aliasskin_t *skin;
- if (ent->effects & (EF_ADDITIVE | EF_FULLBRIGHT) || ent->alpha < 1)
- return;
-
R_Mesh_Matrix(&ent->matrix);
fog = 0;
for (meshnum = 0, mesh = ent->model->alias.aliasdata_meshes;meshnum < ent->model->alias.aliasnum_meshes;meshnum++, mesh++)
{
skin = R_FetchAliasSkin(ent, mesh);
+ // FIXME: transparent skins need to be lit during the transparent render
if (skin->flags & ALIASSKIN_TRANSPARENT)
continue;
if (ent->frameblend[0].frame == 0 && ent->frameblend[0].lerp == 1)
// true during envmap command capture
qboolean envmap;
+// maximum visible distance (recalculated from world box each frame)
float r_farclip;
+// brightness of world lightmaps and related lighting
+// (often reduced when world rtlights are enabled)
+float r_lightmapintensity;
+// whether to draw world lights realtime, dlights realtime, and their shadows
+qboolean r_rtworld;
+qboolean r_rtworldshadows;
+qboolean r_rtdlight;
+qboolean r_rtdlightshadows;
+
// forces all rendering to draw triangle outlines
int r_showtrispass;
return sky;
}
-/*
-=============
-R_DrawViewModel
-=============
-*/
-/*
-void R_DrawViewModel (void)
-{
- entity_render_t *ent;
-
- // FIXME: move these checks to client
- if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model)
- return;
-
- ent = &cl.viewent.render;
- Mod_CheckLoaded(ent->model);
- R_LerpAnimation(ent);
- Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], -ent->angles[0], ent->angles[1], ent->angles[2], ent->scale);
- Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
- R_UpdateEntLights(ent);
- ent->model->Draw(ent);
-}
-*/
-
void R_DrawNoModel(entity_render_t *ent);
void R_DrawModels(void)
{
if (!r_refdef.entities/* || !cl.worldmodel*/)
return; //Host_Error ("R_RenderView: NULL worldmodel");
+ /*
if (r_shadow_realtime_world.integer && !gl_stencil)
{
Con_Print("Realtime world lighting requires 32bit color; turning off r_shadow_realtime_world, please type vid_bitsperpixel 32;vid_restart and try again\n");
Cvar_SetValueQuick(&r_shadow_realtime_world, 0);
}
+ */
// don't allow cheats in multiplayer
if (!cl.islocalgame && cl.worldmodel)
r_view_fov_y = bound(1, r_refdef.fov_y, 170);
r_view_matrix = r_refdef.viewentitymatrix;
GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+ r_rtworld = r_shadow_realtime_world.integer;
+ r_rtworldshadows = r_rtworld && r_shadow_realtime_world_shadows.integer;
+ r_rtdlight = r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer;
+ r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer);
+ r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
// GL is weird because it's bottom to top, r_view_y is top to bottom
qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
R_SetFrustum();
r_farclip = R_FarClip(r_vieworigin, r_viewforward, 768.0f) + 256.0f;
- if (gl_stencil && (r_shadow_realtime_world.integer || (r_shadow_realtime_dlight.integer && r_shadow_realtime_dlight_shadows.integer)))
+ if (gl_stencil && (r_rtworldshadows || r_rtdlightshadows))
GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_view_fov_x, r_view_fov_y, 1.0f);
else
GL_SetupView_Mode_Perspective(r_view_fov_x, r_view_fov_y, 1.0f, r_farclip);
}
turb = (surf->flags & SURF_DRAWTURB) && r_waterscroll.value;
- fullbright = (ent->effects & EF_FULLBRIGHT) || (surf->flags & SURF_DRAWFULLBRIGHT) || !surf->samples;
+ fullbright = !(ent->flags & RENDER_LIGHT) || (surf->flags & SURF_DRAWFULLBRIGHT) || !surf->samples;
base = fullbright ? 2.0f : r_ambient.value * (1.0f / 64.0f);
if (surf->flags & SURF_DRAWTURB)
base *= 0.5f;
m.tex[3] = R_GetTexture(texture->skin.glow);
m.texcombinergb[3] = GL_ADD;
}
- if (r_shadow_realtime_world.integer)
- GL_Color(r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, 1);
- else
- GL_Color(1, 1, 1, 1);
+ GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
while((surf = *surfchain++) != NULL)
{
m.texrgbscale[1] = 2;
m.tex[2] = R_GetTexture(texture->skin.detail);
m.texrgbscale[2] = 2;
- if (r_shadow_realtime_world.integer)
- GL_Color(r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, 1);
- else
- GL_Color(1, 1, 1, 1);
+ GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
while((surf = *surfchain++) != NULL)
{
m.tex[0] = R_GetTexture(texture->skin.base);
m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
m.texrgbscale[1] = 2;
- if (r_shadow_realtime_world.integer)
- GL_Color(r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, 1);
- else
- GL_Color(1, 1, 1, 1);
+ GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
GL_DepthTest(true);
GL_BlendFunc(GL_ONE, GL_ZERO);
m.tex[0] = R_GetTexture(texture->skin.base);
- if (r_shadow_realtime_world.integer)
- GL_Color(r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, 1);
- else
- GL_Color(1, 1, 1, 1);
+ GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
GL_DepthMask(true);
GL_DepthTest(true);
m.tex[0] = R_GetTexture((**surfchain).lightmaptexture);
- if (r_shadow_realtime_world.integer)
- GL_Color(r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, 1);
- else
- GL_Color(1, 1, 1, 1);
+ GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
model_t *model = ent->model;
if (!model)
return;
- if (r_dynamic.integer && !r_shadow_realtime_dlight.integer)
+ if (r_dynamic.integer && !r_rtdlight)
R_MarkLights(ent);
for (i = 0;i < model->brushq1.light_styles;i++)
{
}
else
{
- if (ent->effects & EF_FULLBRIGHT || r_fullbright.integer)
+ if (!(ent->flags & RENDER_LIGHT))
{
RSurfShader_OpaqueWall_Pass_BaseTexture(ent, texture, surfchain);
if (r_detailtextures.integer)
else if (ent != &cl_entities[0].render || surface->visframe == r_framecount)
{
t = surface->texinfo->texture->currentframe;
- if (t->flags & SURF_LIGHTMAP && t->rendertype == SURFRENDER_OPAQUE)
+ if (t->flags & SURF_LIGHTMAP)
R_Shadow_RenderLighting(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_element3i, surface->mesh.data_vertex3f, surface->mesh.data_svector3f, surface->mesh.data_tvector3f, surface->mesh.data_normal3f, surface->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, t->skin.gloss, lightcubemap, LIGHTING_DIFFUSE | LIGHTING_SPECULAR);
}
}
GL_DepthTest(true);
m.tex[0] = R_GetTexture(face->lightmaptexture);
m.pointer_texcoord[0] = face->data_texcoordlightmap2f;
- if (r_shadow_realtime_world.integer)
- GL_Color(r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, r_shadow_realtime_world_lightmaps.value, 1);
- else
- GL_Color(1, 1, 1, 1);
+ GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
m.pointer_vertex = face->data_vertex3f;
R_Mesh_State(&m);
GL_LockArrays(0, face->num_vertices);
GL_DepthTest(true);
m.tex[0] = R_GetTexture(face->texture->skin.base);
m.pointer_texcoord[0] = face->data_texcoordtexture2f;
- mul = 2.0f;
- if (r_shadow_realtime_world.integer && r_shadow_realtime_world_lightmaps.value != 1)
- mul *= r_shadow_realtime_world_lightmaps.value;
+ mul = 2.0f * r_lightmapintensity;
if (mul == 2 && gl_combine.integer)
{
m.texrgbscale[0] = 2;
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(true);
GL_DepthTest(true);
- mul = 2.0f;
- if (r_shadow_realtime_world.integer && r_shadow_realtime_world_lightmaps.value != 1)
- mul *= r_shadow_realtime_world_lightmaps.value;
+ mul = 2.0f * r_lightmapintensity;
if (mul == 1)
m.pointer_color = face->data_color4f;
else
void R_Q3BSP_DrawFace_TransparentCallback(const void *voident, int facenumber)
{
+ int i;
+ float colorscale;
const entity_render_t *ent = voident;
q3msurface_t *face = ent->model->brushq3.data_faces + facenumber;
rmeshstate_t m;
GL_DepthTest(true);
m.tex[0] = R_GetTexture(face->texture->skin.base);
m.pointer_texcoord[0] = face->data_texcoordtexture2f;
- // LordHavoc: quake3 was not able to do this; lit transparent surfaces
+ colorscale = r_lightmapintensity;
if (gl_combine.integer)
- {
m.texrgbscale[0] = 2;
- if (r_textureunits.integer >= 2)
- {
- m.tex[1] = R_GetTexture(face->lightmaptexture);
- m.pointer_texcoord[1] = face->data_texcoordlightmap2f;
- GL_Color(1, 1, 1, ent->alpha);
- }
- else
- {
- if (ent->alpha == 1)
- m.pointer_color = face->data_color4f;
- else
- {
- int i;
- for (i = 0;i < face->num_vertices;i++)
- {
- varray_color4f[i*4+0] = face->data_color4f[i*4+0];
- varray_color4f[i*4+1] = face->data_color4f[i*4+1];
- varray_color4f[i*4+2] = face->data_color4f[i*4+2];
- varray_color4f[i*4+3] = face->data_color4f[i*4+3] * ent->alpha;
- }
- m.pointer_color = varray_color4f;
- }
- }
- }
else
+ colorscale *= 2.0f;
+ for (i = 0;i < face->num_vertices;i++)
{
- int i;
- for (i = 0;i < face->num_vertices;i++)
- {
- varray_color4f[i*4+0] = face->data_color4f[i*4+0] * 2.0f;
- varray_color4f[i*4+1] = face->data_color4f[i*4+1] * 2.0f;
- varray_color4f[i*4+2] = face->data_color4f[i*4+2] * 2.0f;
- varray_color4f[i*4+3] = face->data_color4f[i*4+3] * ent->alpha;
- }
- m.pointer_color = varray_color4f;
+ varray_color4f[i*4+0] = face->data_color4f[i*4+0] * colorscale;
+ varray_color4f[i*4+1] = face->data_color4f[i*4+1] * colorscale;
+ varray_color4f[i*4+2] = face->data_color4f[i*4+2] * colorscale;
+ varray_color4f[i*4+3] = face->data_color4f[i*4+3] * ent->alpha;
}
+ m.pointer_color = varray_color4f;
m.pointer_vertex = face->data_vertex3f;
R_Mesh_State(&m);
qglDisable(GL_CULL_FACE);
return;
}
R_Mesh_Matrix(&ent->matrix);
- if (r_shadow_realtime_world.integer && r_shadow_realtime_world_lightmaps.value <= 0)
+ if (r_lightmapintensity <= 0)
R_Q3BSP_DrawFace_OpaqueWall_Pass_OpaqueGlow(ent, face);
- else if ((ent->effects & EF_FULLBRIGHT) || r_fullbright.integer)
+ else if (!(ent->flags & RENDER_LIGHT))
{
R_Q3BSP_DrawFace_OpaqueWall_Pass_Texture(ent, face);
if (face->texture->skin.glow)
int flags;
// engine calculated flags, ones that can not be set in the file
int flags2;
- // LordHavoc: if true (normally only for sprites) the model/sprite/bmodel is always rendered fullbright
- int fullbright;
// number of QC accessible frame(group)s in the model
int numframes;
// number of QC accessible skin(group)s in the model
Host_Error ("Mod_Sprite_SharedSetup: Invalid # of frames: %d\n", loadmodel->numframes);
loadmodel->type = mod_sprite;
- loadmodel->flags = EF_FULLBRIGHT;
+ loadmodel->flags2 = EF_FULLBRIGHT;
// LordHavoc: hack to allow sprites to be non-fullbright
for (i = 0;i < MAX_QPATH && loadmodel->name[i];i++)
{
if (loadmodel->name[i] == '!')
{
- loadmodel->flags &= ~EF_FULLBRIGHT;
+ loadmodel->flags2 &= ~EF_FULLBRIGHT;
break;
}
}
palette[i][2] = *in++;
palette[i][3] = 255;
}
- loadmodel->flags |= EF_ADDITIVE;
+ loadmodel->flags2 |= EF_ADDITIVE;
break;
case SPRHL_INDEXALPHA:
for (i = 0;i < 256;i++)
// read the frame header info
f->time = cl.mtime[0];
number = MSG_ReadLong();
- f->framenum = MSG_ReadLong();
+ cl.latestframenum = f->framenum = MSG_ReadLong();
f->eye[0] = MSG_ReadFloat();
f->eye[1] = MSG_ReadFloat();
f->eye[2] = MSG_ReadFloat();
d->referenceentity[i] = defaultstate;
}
-int EntityFrame4_AckFrame(entityframe4_database_t *d, int framenum)
+int EntityFrame4_AckFrame(entityframe4_database_t *d, int framenum, int servermode)
{
int i, j, found;
entity_database4_commit_t *commit;
d->referenceframenum = -1;
for (i = 0;i < d->maxreferenceentities;i++)
d->referenceentity[i] = defaultstate;
+ // if this is the server, remove commits
+ for (i = 0, commit = d->commit;i < MAX_ENTITY_HISTORY;i++, commit++)
+ commit->numentities = 0;
found = true;
}
else if (d->referenceframenum == framenum)
// read the number of the frame this refers to
referenceframenum = MSG_ReadLong();
// read the number of this frame
- framenum = MSG_ReadLong();
+ cl.latestframenum = framenum = MSG_ReadLong();
// read the start number
enumber = (unsigned short) MSG_ReadShort();
if (developer_networkentities.integer >= 1)
Con_Printf(" %i", d->commit[i].framenum);
Con_Print("\n");
}
- if (!EntityFrame4_AckFrame(d, referenceframenum))
+ if (!EntityFrame4_AckFrame(d, referenceframenum, false))
{
Con_Print("EntityFrame4_CL_ReadFrame: reference frame invalid (VERY BAD ERROR), this update will be skipped\n");
skip = true;
#define RENDER_EXTERIORMODEL 8
#define RENDER_LOWPRECISION 16 // send as low precision coordinates to save bandwidth
#define RENDER_COLORMAPPED 32
-#define RENDER_SHADOW 64 // cast shadow
-#define RENDER_LIGHT 128 // receive light
+#define RENDER_SHADOW 65536 // cast shadow
+#define RENDER_LIGHT 131072 // receive light
+#define RENDER_TRANSPARENT 262144 // can't light during opaque stage
// this is 80 bytes
typedef struct
// reset a database (resets compression but does not reallocate anything)
void EntityFrame4_ResetDatabase(entityframe4_database_t *d);
// updates database to account for a frame-received acknowledgment
-int EntityFrame4_AckFrame(entityframe4_database_t *d, int framenum);
+int EntityFrame4_AckFrame(entityframe4_database_t *d, int framenum, int servermode);
// writes a frame to the network stream
void EntityFrame4_WriteFrame(sizebuf_t *msg, entityframe4_database_t *d, int numstates, const entity_state_t *states);
// reads a frame from the network stream
return;
R_Mesh_Matrix(&r_identitymatrix);
viewdist = DotProduct(r_vieworigin, r_viewforward);
- if (r_shadow_realtime_world.integer)
+ if (r_rtworld)
{
for (lnum = 0, light = r_shadow_worldlightchain;light;light = light->next, lnum++)
{
ambient4f[0] = ambient4f[1] = ambient4f[2] = r_ambient.value * (2.0f / 128.0f);
VectorClear(diffusecolor);
VectorClear(diffusenormal);
- if (r_fullbright.integer || (ent->effects & EF_FULLBRIGHT))
+ if (!(ent->flags & RENDER_LIGHT))
{
// highly rare
VectorSet(ambient4f, 1, 1, 1);
maxnearlights = 0;
}
- else if (r_shadow_realtime_world.integer && r_shadow_realtime_world_lightmaps.value <= 0)
+ else if (r_lightmapintensity <= 0 && !(ent->flags & RENDER_TRANSPARENT))
maxnearlights = 0;
else
{
nl->offset = sl->distbias;
}
}
- if (!r_shadow_realtime_dlight.integer)
+ if (!r_rtdlight || (ent->flags & RENDER_TRANSPARENT))
{
+ // FIXME: this dlighting doesn't look like rtlights
for (i = 0;i < r_numdlights;i++)
{
light = r_dlight + i;
// pretty good lighting
for (j = 0, nl = &nearlight[0];j < nearlights;j++, nl++)
{
- VectorSubtract(vertex3f, nl->origin, v);
+ VectorSubtract(nl->origin, vertex3f, v);
// first eliminate negative lighting (back side)
dot = DotProduct(normal3f, v);
if (dot > 0)
int i;
const mlight_t *sl;
vec3_t v;
- if (r_shadow_realtime_world.integer && r_shadow_realtime_world_lightmaps.value <= 0)
+ if (r_lightmapintensity <= 0 && !(ent->flags & RENDER_TRANSPARENT))
return;
VectorSubtract(ent->origin, ent->entlightsorigin, v);
if (ent->entlightsframe != (r_framecount - 1) || (realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
int i, shadow;
entity_render_t *ent;
float f;
- vec3_t relativelightorigin, relativeeyeorigin, lightcolor;
+ vec3_t relativelightorigin, relativeeyeorigin, lightcolor, lightcolor2;
rtexture_t *cubemaptexture;
matrix4x4_t matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz;
int numclusters, numsurfaces;
}
*/
-#if 1
- shadow = rtlight->shadow && (rtlight->isstatic ? r_shadow_realtime_world_shadows.integer : (r_shadow_realtime_world.integer ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer));
-#else
- shadow = false;
- if (rtlight->shadow)
- {
- if (rtlight->isstatic)
- shadow = r_shadow_realtime_world_shadows.integer;
- else
- {
- if (r_shadow_realtime_world.integer)
- shadow = r_shadow_realtime_world_dlightshadows.integer;
- else
- shadow = r_shadow_realtime_dlight_shadows.integer;
- }
- }
-#endif
+ shadow = rtlight->shadow && (rtlight->isstatic ? r_rtworldshadows : r_rtdlightshadows);
if (shadow && (gl_stencil || visiblevolumes))
{
for (i = 0;i < r_refdef.numentities;i++)
{
ent = r_refdef.entities[i];
- if (ent->visframe == r_framecount && BoxesOverlap(ent->mins, ent->maxs, cullmins, cullmaxs) && ent->model && ent->model->DrawLight && (ent->flags & RENDER_LIGHT))
+ // can't draw transparent entity lighting here because
+ // transparent meshes are deferred for later
+ if (ent->visframe == r_framecount && BoxesOverlap(ent->mins, ent->maxs, cullmins, cullmaxs) && ent->model && ent->model->DrawLight && (ent->flags & (RENDER_LIGHT | RENDER_TRANSPARENT)) == RENDER_LIGHT)
{
+ VectorScale(lightcolor, ent->alpha, lightcolor2);
Matrix4x4_Transform(&ent->inversematrix, rtlight->shadoworigin, relativelightorigin);
Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin);
Matrix4x4_Concat(&matrix_modeltolight, &rtlight->matrix_worldtolight, &ent->matrix);
Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &rtlight->matrix_worldtoattenuationxyz, &ent->matrix);
Matrix4x4_Concat(&matrix_modeltoattenuationz, &rtlight->matrix_worldtoattenuationz, &ent->matrix);
- ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, ent->model->nummodelsurfaces, ent->model->surfacelist);
+ ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, ent->model->nummodelsurfaces, ent->model->surfacelist);
}
}
}
}
else
R_Shadow_Stage_Begin();
- if (r_shadow_realtime_world.integer)
+ if (r_rtworld)
{
if (r_shadow_debuglight.integer >= 0)
{
for (lnum = 0, light = r_shadow_worldlightchain;light;lnum++, light = light->next)
R_DrawRTLight(&light->rtlight, visiblevolumes);
}
- if (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer)
+ if (r_rtdlight)
for (lnum = 0, light = r_dlight;lnum < r_numdlights;lnum++, light++)
R_DrawRTLight(&light->rtlight, visiblevolumes);
R_Mesh_Matrix(&r_identitymatrix);
- if ((ent->model->flags & EF_FULLBRIGHT) || (ent->effects & EF_FULLBRIGHT))
+ if (!(ent->flags & RENDER_LIGHT))
color[0] = color[1] = color[2] = 1;
else
{
if (ent->frameblend[i].lerp >= 0.01f)
{
frame = ent->model->sprite.sprdata_frames + ent->frameblend[i].frame;
- R_DrawSpriteImage((ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, frame->texture, org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha * ent->frameblend[i].lerp);
+ R_DrawSpriteImage((ent->effects & EF_ADDITIVE), frame, frame->texture, org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha * ent->frameblend[i].lerp);
if (fog * ent->frameblend[i].lerp >= 0.01f)
R_DrawSpriteImage(true, frame, frame->fogtexture, org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha * ent->frameblend[i].lerp);
}
if (frame)
{
- R_DrawSpriteImage((ent->effects & EF_ADDITIVE) || (ent->model->flags & EF_ADDITIVE), frame, frame->texture, org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha);
+ R_DrawSpriteImage((ent->effects & EF_ADDITIVE), frame, frame->texture, org, up, left, color[0] * ifog, color[1] * ifog, color[2] * ifog, ent->alpha);
if (fog * ent->frameblend[i].lerp >= 0.01f)
R_DrawSpriteImage(true, frame, frame->fogtexture, org, up, left, fogcolor[0],fogcolor[1],fogcolor[2], fog * ent->alpha);
}
extern mplane_t frustum[4];
extern int c_alias_polys, c_light_polys, c_faces, c_nodes, c_leafs, c_models, c_bmodels, c_sprites, c_particles, c_dlights;
+// brightness of world lightmaps and related lighting
+// (often reduced when world rtlights are enabled)
+extern float r_lightmapintensity;
+// whether to draw world lights realtime, dlights realtime, and their shadows
+extern qboolean r_rtworld;
+extern qboolean r_rtworldshadows;
+extern qboolean r_rtdlight;
+extern qboolean r_rtdlightshadows;
+
// forces all rendering to draw triangle outlines
extern cvar_t r_showtris;
extern int r_showtrispass;
if (host_client->entitydatabase)
EntityFrame_AckFrame(host_client->entitydatabase, num);
else if (host_client->entitydatabase4)
- EntityFrame4_AckFrame(host_client->entitydatabase4, host_client->entitydatabase4->ackframenum);
+ EntityFrame4_AckFrame(host_client->entitydatabase4, host_client->entitydatabase4->ackframenum, true);
else if (host_client->entitydatabase5)
EntityFrame5_AckFrame(host_client->entitydatabase5, num, host_client - svs.clients + 1);
break;