X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=9ccd05c242dffc3f92ae90fbc058db16840bc887;hb=1cf9b7ac5efb61184a2053238ae0c2358394a5c0;hp=24c9baa056c896a373b90581408c14f15e44402c;hpb=105b92bbfd2a623a7bc6f59c4f7110c5b259c9b2;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 24c9baa0..9ccd05c2 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -51,13 +51,14 @@ unsigned short d_lightstylevalue[256]; cvar_t r_drawentities = {0, "r_drawentities","1"}; cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"}; -cvar_t r_shadows = {CVAR_SAVE, "r_shadows", "1"}; -cvar_t r_staticworldlights = {0, "r_staticworldlights", "1"}; +cvar_t r_shadows = {CVAR_SAVE, "r_shadows", "0"}; +cvar_t r_shadow_staticworldlights = {0, "r_shadow_staticworldlights", "1"}; cvar_t r_speeds = {0, "r_speeds","0"}; cvar_t r_fullbright = {0, "r_fullbright","0"}; cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"}; cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"}; cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"}; +cvar_t r_shadow_cull = {0, "r_shadow_cull", "1"}; cvar_t gl_fogenable = {0, "gl_fogenable", "0"}; cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"}; @@ -221,14 +222,15 @@ void GL_Main_Init(void) Cvar_RegisterVariable (&r_drawentities); Cvar_RegisterVariable (&r_drawviewmodel); Cvar_RegisterVariable (&r_shadows); - Cvar_RegisterVariable (&r_staticworldlights); + Cvar_RegisterVariable (&r_shadow_staticworldlights); Cvar_RegisterVariable (&r_speeds); Cvar_RegisterVariable (&r_fullbrights); Cvar_RegisterVariable (&r_wateralpha); Cvar_RegisterVariable (&r_dynamic); Cvar_RegisterVariable (&r_fullbright); Cvar_RegisterVariable (&r_textureunits); - if (gamemode == GAME_NEHAHRA) + Cvar_RegisterVariable (&r_shadow_cull); + if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXIUZ) Cvar_SetValue("r_fullbrights", 0); R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap); } @@ -381,6 +383,8 @@ int PVS_CullBox(const vec3_t mins, const vec3_t maxs) { int stackpos, sides; mnode_t *node, *stack[4096]; + if (cl.worldmodel == NULL) + return false; stackpos = 0; stack[stackpos++] = cl.worldmodel->nodes; while (stackpos) @@ -409,6 +413,8 @@ int VIS_CullBox(const vec3_t mins, const vec3_t maxs) mnode_t *node, *stack[4096]; if (R_CullBox(mins, maxs)) return true; + if (cl.worldmodel == NULL) + return false; stackpos = 0; stack[stackpos++] = cl.worldmodel->nodes; while (stackpos) @@ -444,6 +450,8 @@ int PVS_CullSphere(const vec3_t origin, vec_t radius) int stackpos; mnode_t *node, *stack[4096]; float dist; + if (cl.worldmodel == NULL) + return false; stackpos = 0; stack[stackpos++] = cl.worldmodel->nodes; while (stackpos) @@ -473,6 +481,8 @@ int VIS_CullSphere(const vec3_t origin, vec_t radius) float dist; if (R_CullSphere(origin, radius)) return true; + if (cl.worldmodel == NULL) + return false; stackpos = 0; stack[stackpos++] = cl.worldmodel->nodes; while (stackpos) @@ -577,6 +587,7 @@ int R_DrawBrushModelsSky (void) R_DrawViewModel ============= */ +/* void R_DrawViewModel (void) { entity_render_t *ent; @@ -593,6 +604,7 @@ void R_DrawViewModel (void) R_UpdateEntLights(ent); ent->model->Draw(ent); } +*/ void R_DrawNoModel(entity_render_t *ent); void R_DrawModels () @@ -603,7 +615,6 @@ void R_DrawModels () if (!r_drawentities.integer) return; - R_DrawViewModel(); for (i = 0;i < r_refdef.numentities;i++) { ent = r_refdef.entities[i]; @@ -631,7 +642,7 @@ void R_DrawFakeShadows (void) for (i = 0;i < r_refdef.numentities;i++) { ent = r_refdef.entities[i]; - if (ent->model && ent->model->DrawFakeShadow) + if ((ent->flags & RENDER_SHADOW) && ent->model && ent->model->DrawFakeShadow) ent->model->DrawFakeShadow(ent); } } @@ -644,6 +655,8 @@ int Light_CullBox(const vec3_t mins, const vec3_t maxs) { int stackpos, sides; mnode_t *node, *stack[4096]; + if (cl.worldmodel == NULL) + return false; stackpos = 0; stack[stackpos++] = cl.worldmodel->nodes; while (stackpos) @@ -672,6 +685,8 @@ int LightAndVis_CullBox(const vec3_t mins, const vec3_t maxs) mnode_t *node, *stack[4096]; if (R_CullBox(mins, maxs)) return true; + if (cl.worldmodel == NULL) + return false; stackpos = 0; stack[stackpos++] = cl.worldmodel->nodes; while (stackpos) @@ -694,50 +709,118 @@ int LightAndVis_CullBox(const vec3_t mins, const vec3_t maxs) return true; } +int LightAndVis_CullPointCloud(int numpoints, const float *points) +{ + int i; + const float *p; + int stackpos, sides; + mnode_t *node, *stack[4096]; + //if (R_CullBox(mins, maxs)) + // return true; + if (cl.worldmodel == NULL) + return false; + stackpos = 0; + stack[stackpos++] = cl.worldmodel->nodes; + while (stackpos) + { + node = stack[--stackpos]; + if (node->contents < 0) + { + if (((mleaf_t *)node)->visframe == r_framecount && ((mleaf_t *)node)->worldnodeframe == shadowframecount) + return false; + } + else + { + sides = 0; + for (i = 0, p = points;i < numpoints && sides != 3;i++, p += 3) + { + if (DotProduct(p, node->plane->normal) < node->plane->dist) + sides |= 1; + else + sides |= 2; + } + if (sides & 2 && stackpos < 4096) + stack[stackpos++] = node->children[1]; + if (sides & 1 && stackpos < 4096) + stack[stackpos++] = node->children[0]; + } + } + return true; +} + -void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float cullradius, float lightradius, vec3_t clipmins, vec3_t clipmaxs) +void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float cullradius, float lightradius, vec3_t lightmins, vec3_t lightmaxs, vec3_t clipmins, vec3_t clipmaxs) { + vec3_t relativelightorigin; + #if 0 int i; - vec3_t p, p2, temp, relativelightorigin, mins, maxs; + vec3_t p, p2, temp, relativelightorigin/*, mins, maxs*/; float dist, projectdistance; + float points[16][3]; + #endif // rough checks - if (ent->model && ent->model->DrawShadowVolume) + if (!(ent->flags & RENDER_SHADOW) || ent->model == NULL || ent->model->DrawShadowVolume == NULL) + return; + if (r_shadow_cull.integer) + { + if (ent->maxs[0] < lightmins[0] || ent->mins[0] > lightmaxs[0] + || ent->maxs[1] < lightmins[1] || ent->mins[1] > lightmaxs[1] + || ent->maxs[2] < lightmins[2] || ent->mins[2] > lightmaxs[2] + || Light_CullBox(ent->mins, ent->maxs)) + return; + } + #if 0 + if (r_shadow_cull.integer) { - temp[0] = bound(ent->mins[0], lightorigin[0], ent->maxs[0]) - lightorigin[0]; - temp[1] = bound(ent->mins[1], lightorigin[1], ent->maxs[1]) - lightorigin[1]; - temp[2] = bound(ent->mins[2], lightorigin[2], ent->maxs[2]) - lightorigin[2]; - dist = DotProduct(temp, temp); - if (dist < cullradius * cullradius) + projectdistance = cullradius; + // calculate projected bounding box and decide if it is on-screen + for (i = 0;i < 8;i++) { - if (!Light_CullBox(ent->mins, ent->maxs)) + temp[0] = i & 1 ? ent->model->normalmaxs[0] : ent->model->normalmins[0]; + temp[1] = i & 2 ? ent->model->normalmaxs[1] : ent->model->normalmins[1]; + temp[2] = i & 4 ? ent->model->normalmaxs[2] : ent->model->normalmins[2]; + Matrix4x4_Transform(&ent->matrix, temp, points[i]); + VectorSubtract(points[i], lightorigin, temp); + dist = projectdistance / sqrt(DotProduct(temp, temp)); + VectorMA(points[i], dist, temp, points[i+8]); + } + if (LightAndVis_CullPointCloud(16, points[0])) + return; + /* + for (i = 0;i < 8;i++) + { + p2[0] = i & 1 ? ent->model->normalmaxs[0] : ent->model->normalmins[0]; + p2[1] = i & 2 ? ent->model->normalmaxs[1] : ent->model->normalmins[1]; + p2[2] = i & 4 ? ent->model->normalmaxs[2] : ent->model->normalmins[2]; + Matrix4x4_Transform(&ent->matrix, p2, p); + VectorSubtract(p, lightorigin, temp); + dist = projectdistance / sqrt(DotProduct(temp, temp)); + VectorMA(p, dist, temp, p2); + if (i) { - projectdistance = cullradius - sqrt(dist); - // calculate projected bounding box and decide if it is on-screen - VectorCopy(ent->mins, mins); - VectorCopy(ent->maxs, maxs); - for (i = 0;i < 8;i++) - { - p[0] = i & 1 ? ent->maxs[0] : ent->mins[0]; - p[1] = i & 2 ? ent->maxs[1] : ent->mins[1]; - p[2] = i & 4 ? ent->maxs[2] : ent->mins[2]; - VectorSubtract(p, lightorigin, temp); - dist = projectdistance / sqrt(DotProduct(temp, temp)); - VectorMA(p, dist, temp, p2); - if (mins[0] > p2[0]) mins[0] = p2[0];if (maxs[0] < p2[0]) maxs[0] = p2[0]; - if (mins[1] > p2[1]) mins[1] = p2[1];if (maxs[1] < p2[1]) maxs[1] = p2[1]; - if (mins[2] > p2[2]) mins[2] = p2[2];if (maxs[2] < p2[2]) maxs[2] = p2[2]; - } - if (mins[0] < clipmaxs[0] && maxs[0] > clipmins[0] - && mins[1] < clipmaxs[1] && maxs[1] > clipmins[1] - && mins[2] < clipmaxs[2] && maxs[2] > clipmins[2] - && !LightAndVis_CullBox(mins, maxs)) - { - Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin); - ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius); - } + if (mins[0] > p[0]) mins[0] = p[0];if (maxs[0] < p[0]) maxs[0] = p[0]; + if (mins[1] > p[1]) mins[1] = p[1];if (maxs[1] < p[1]) maxs[1] = p[1]; + if (mins[2] > p[2]) mins[2] = p[2];if (maxs[2] < p[2]) maxs[2] = p[2]; } + else + { + VectorCopy(p, mins); + VectorCopy(p, maxs); + } + if (mins[0] > p2[0]) mins[0] = p2[0];if (maxs[0] < p2[0]) maxs[0] = p2[0]; + if (mins[1] > p2[1]) mins[1] = p2[1];if (maxs[1] < p2[1]) maxs[1] = p2[1]; + if (mins[2] > p2[2]) mins[2] = p2[2];if (maxs[2] < p2[2]) maxs[2] = p2[2]; } + if (mins[0] >= clipmaxs[0] || maxs[0] <= clipmins[0] + || mins[1] >= clipmaxs[1] || maxs[1] <= clipmins[1] + || mins[2] >= clipmaxs[2] || maxs[2] <= clipmins[2] + || LightAndVis_CullBox(mins, maxs)) + return; + */ } + #endif + Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin); + ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius); } void R_Shadow_DrawWorldLightShadowVolume(matrix4x4_t *matrix, worldlight_t *light); @@ -823,7 +906,10 @@ void R_ShadowVolumeLighting (int visiblevolumes) memset(&m, 0, sizeof(m)); m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ONE; + if (r_shadow_realtime.integer >= 3) + m.depthdisable = true; R_Mesh_State(&m); + qglDisable(GL_CULL_FACE); GL_Color(0.0 * r_colorscale, 0.0125 * r_colorscale, 0.1 * r_colorscale, 1); } else @@ -844,41 +930,49 @@ void R_ShadowVolumeLighting (int visiblevolumes) if (r_shadow_debuglight.integer >= 0 && lnum != r_shadow_debuglight.integer) continue; - for (i = 0;i < wl->numleafs;i++) - if (wl->leafs[i]->visframe == r_framecount) - break; - if (i == wl->numleafs) - continue; - leaf = wl->leafs[i]; - VectorCopy(leaf->mins, clipmins); - VectorCopy(leaf->maxs, clipmaxs); - for (i = 0;i < wl->numleafs;i++) + if (cl.worldmodel != NULL) { - leaf = wl->leafs[i]; - if (leaf->visframe == r_framecount) + for (i = 0;i < wl->numleafs;i++) + if (wl->leafs[i]->visframe == r_framecount) + break; + if (i == wl->numleafs) + continue; + leaf = wl->leafs[i++]; + VectorCopy(leaf->mins, clipmins); + VectorCopy(leaf->maxs, clipmaxs); + for (i++;i < wl->numleafs;i++) { - if (clipmins[0] > leaf->mins[0]) clipmins[0] = leaf->mins[0]; - if (clipmaxs[0] < leaf->maxs[0]) clipmaxs[0] = leaf->maxs[0]; - if (clipmins[1] > leaf->mins[1]) clipmins[1] = leaf->mins[1]; - if (clipmaxs[1] < leaf->maxs[1]) clipmaxs[1] = leaf->maxs[1]; - if (clipmins[2] > leaf->mins[2]) clipmins[2] = leaf->mins[2]; - if (clipmaxs[2] < leaf->maxs[2]) clipmaxs[2] = leaf->maxs[2]; + leaf = wl->leafs[i]; + if (leaf->visframe == r_framecount) + { + if (clipmins[0] > leaf->mins[0]) clipmins[0] = leaf->mins[0]; + if (clipmaxs[0] < leaf->maxs[0]) clipmaxs[0] = leaf->maxs[0]; + if (clipmins[1] > leaf->mins[1]) clipmins[1] = leaf->mins[1]; + if (clipmaxs[1] < leaf->maxs[1]) clipmaxs[1] = leaf->maxs[1]; + if (clipmins[2] > leaf->mins[2]) clipmins[2] = leaf->mins[2]; + if (clipmaxs[2] < leaf->maxs[2]) clipmaxs[2] = leaf->maxs[2]; + } } + if (clipmins[0] < wl->mins[0]) clipmins[0] = wl->mins[0]; + if (clipmins[1] < wl->mins[1]) clipmins[1] = wl->mins[1]; + if (clipmins[2] < wl->mins[2]) clipmins[2] = wl->mins[2]; + if (clipmaxs[0] > wl->maxs[0]) clipmaxs[0] = wl->maxs[0]; + if (clipmaxs[1] > wl->maxs[1]) clipmaxs[1] = wl->maxs[1]; + if (clipmaxs[2] > wl->maxs[2]) clipmaxs[2] = wl->maxs[2]; + } + else + { + VectorCopy(wl->mins, clipmins); + VectorCopy(wl->maxs, clipmaxs); } - if (clipmins[0] < wl->mins[0]) clipmins[0] = wl->mins[0]; - if (clipmins[1] < wl->mins[1]) clipmins[1] = wl->mins[1]; - if (clipmins[2] < wl->mins[2]) clipmins[2] = wl->mins[2]; - if (clipmaxs[0] > wl->maxs[0]) clipmaxs[0] = wl->maxs[0]; - if (clipmaxs[1] > wl->maxs[1]) clipmaxs[1] = wl->maxs[1]; - if (clipmaxs[2] > wl->maxs[2]) clipmaxs[2] = wl->maxs[2]; if (R_Shadow_ScissorForBBoxAndSphere(clipmins, clipmaxs, wl->origin, wl->cullradius)) continue; // mark the leafs we care about so only things in those leafs will matter - for (i = 0;i < wl->numleafs;i++) - wl->leafs[i]->worldnodeframe = shadowframecount; - + if (cl.worldmodel != NULL) + for (i = 0;i < wl->numleafs;i++) + wl->leafs[i]->worldnodeframe = shadowframecount; f = d_lightstylevalue[wl->style] * (1.0f / 256.0f); VectorScale(wl->light, f, lightcolor); @@ -888,28 +982,26 @@ void R_ShadowVolumeLighting (int visiblevolumes) VectorScale(lightcolor, f, lightcolor); } - if (!visiblevolumes) - R_Shadow_Stage_ShadowVolumes(); - if (wl->shadowvolume && r_staticworldlights.integer) - R_Shadow_DrawWorldLightShadowVolume(&cl_entities[0].render.matrix, wl); - else - R_TestAndDrawShadowVolume(&cl_entities[0].render, wl->origin, cullradius, lightradius, clipmins, clipmaxs); - if (r_drawentities.integer) + if (wl->castshadows) { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent->maxs[0] >= wl->mins[0] && ent->mins[0] <= wl->maxs[0] - && ent->maxs[1] >= wl->mins[1] && ent->mins[1] <= wl->maxs[1] - && ent->maxs[2] >= wl->mins[2] && ent->mins[2] <= wl->maxs[2] - && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - R_TestAndDrawShadowVolume(r_refdef.entities[i], wl->origin, cullradius, lightradius, clipmins, clipmaxs); - } + if (!visiblevolumes) + R_Shadow_Stage_ShadowVolumes(); + ent = &cl_entities[0].render; + if (wl->shadowvolume && r_shadow_staticworldlights.integer) + R_Shadow_DrawWorldLightShadowVolume(&ent->matrix, wl); + else + R_TestAndDrawShadowVolume(ent, wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs); + if (r_drawentities.integer) + for (i = 0;i < r_refdef.numentities;i++) + R_TestAndDrawShadowVolume(r_refdef.entities[i], wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs); } if (!visiblevolumes) { - R_Shadow_Stage_Light(); + if (wl->castshadows) + R_Shadow_Stage_LightWithShadows(); + else + R_Shadow_Stage_LightWithoutShadows(); ent = &cl_entities[0].render; if (ent->model && ent->model->DrawLight) { @@ -918,7 +1010,7 @@ void R_ShadowVolumeLighting (int visiblevolumes) if (wl->numsurfaces) R_Model_Brush_DrawLightForSurfaceList(ent, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, wl->surfaces, wl->numsurfaces); else - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, lightcolor); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor); } if (r_drawentities.integer) { @@ -933,27 +1025,7 @@ void R_ShadowVolumeLighting (int visiblevolumes) { Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, lightcolor); - } - } - } - - if (R_Shadow_Stage_EraseShadowVolumes()) - { - if (wl->shadowvolume && r_staticworldlights.integer) - R_Shadow_DrawWorldLightShadowVolume(&cl_entities[0].render.matrix, wl); - else - R_TestAndDrawShadowVolume(&cl_entities[0].render, wl->origin, cullradius, lightradius, clipmins, clipmaxs); - if (r_drawentities.integer) - { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent->maxs[0] >= wl->mins[0] && ent->mins[0] <= wl->maxs[0] - && ent->maxs[1] >= wl->mins[1] && ent->mins[1] <= wl->maxs[1] - && ent->maxs[2] >= wl->mins[2] && ent->mins[2] <= wl->maxs[2] - && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - R_TestAndDrawShadowVolume(r_refdef.entities[i], wl->origin, cullradius, lightradius, clipmins, clipmaxs); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor); } } } @@ -976,7 +1048,7 @@ void R_ShadowVolumeLighting (int visiblevolumes) if (!visiblevolumes) R_Shadow_Stage_ShadowVolumes(); - if (sl->shadowvolume && r_staticworldlights.integer) + if (sl->shadowvolume && r_shadow_staticworldlights.integer) R_DrawWorldLightShadowVolume(&cl_entities[0].render.matrix, sl->shadowvolume); else R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, cullradius, lightradius); @@ -1020,24 +1092,6 @@ void R_ShadowVolumeLighting (int visiblevolumes) } } } - - R_Shadow_Stage_EraseShadowVolumes(); - if (sl->shadowvolume && r_staticworldlights.integer) - R_DrawWorldLightShadowVolume(&cl_entities[0].render.matrix, sl->shadowvolume); - else - R_TestAndDrawShadowVolume(&cl_entities[0].render, sl->origin, cullradius, lightradius); - if (r_drawentities.integer) - { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent->maxs[0] >= sl->mins[0] && ent->mins[0] <= sl->maxs[0] - && ent->maxs[1] >= sl->mins[1] && ent->mins[1] <= sl->maxs[1] - && ent->maxs[2] >= sl->mins[2] && ent->mins[2] <= sl->maxs[2] - && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - R_TestAndDrawShadowVolume(r_refdef.entities[i], sl->origin, cullradius, lightradius); - } - } } } */ @@ -1061,26 +1115,27 @@ void R_ShadowVolumeLighting (int visiblevolumes) if (!visiblevolumes) R_Shadow_Stage_ShadowVolumes(); - R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, cullradius, lightradius, clipmins, clipmaxs); + ent = &cl_entities[0].render; + R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs); if (r_drawentities.integer) { for (i = 0;i < r_refdef.numentities;i++) { ent = r_refdef.entities[i]; - if (ent != rd->ent && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs); + if (ent != rd->ent) + R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs); } } if (!visiblevolumes) { - R_Shadow_Stage_Light(); + R_Shadow_Stage_LightWithShadows(); ent = &cl_entities[0].render; if (ent->model && ent->model->DrawLight) { Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, lightcolor); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor); } if (r_drawentities.integer) { @@ -1092,21 +1147,7 @@ void R_ShadowVolumeLighting (int visiblevolumes) { Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius, lightcolor); - } - } - } - - if (R_Shadow_Stage_EraseShadowVolumes()) - { - R_TestAndDrawShadowVolume(&cl_entities[0].render, rd->origin, cullradius, lightradius, clipmins, clipmaxs); - if (r_drawentities.integer) - { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent != rd->ent && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor); } } } @@ -1115,31 +1156,35 @@ void R_ShadowVolumeLighting (int visiblevolumes) if (!visiblevolumes) R_Shadow_Stage_End(); + qglEnable(GL_CULL_FACE); qglDisable(GL_SCISSOR_TEST); } static void R_SetFrustum (void) { - int i; - // LordHavoc: note to all quake engine coders, the special case for 90 // degrees assumed a square view (wrong), so I removed it, Quake2 has it // disabled as well. + // rotate VPN right by FOV_X/2 degrees RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) ); + frustum[0].dist = DotProduct (r_origin, frustum[0].normal); + PlaneClassify(&frustum[0]); + // rotate VPN left by FOV_X/2 degrees RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 ); + frustum[1].dist = DotProduct (r_origin, frustum[1].normal); + PlaneClassify(&frustum[1]); + // rotate VPN up by FOV_X/2 degrees RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 ); + frustum[2].dist = DotProduct (r_origin, frustum[2].normal); + PlaneClassify(&frustum[2]); + // rotate VPN down by FOV_X/2 degrees RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) ); - - for (i = 0;i < 4;i++) - { - frustum[i].type = PLANE_ANYZ; - frustum[i].dist = DotProduct (r_origin, frustum[i].normal); - PlaneClassify(&frustum[i]); - } + frustum[3].dist = DotProduct (r_origin, frustum[3].normal); + PlaneClassify(&frustum[3]); } /* @@ -1206,6 +1251,7 @@ R_RenderView r_refdef must be set before the first call ================ */ +extern void R_DrawLightningBeams (void); void R_RenderView (void) { entity_render_t *world; @@ -1226,7 +1272,7 @@ void R_RenderView (void) } else if (!gl_stencil) { - Con_Printf("Stencil not enabled, turning off r_shadow_realtime, please type vid_stencil 1;vid_restart and try again\n"); + Con_Printf("Stencil not enabled, turning off r_shadow_realtime, please type vid_stencil 1;vid_bitsperpixel 32;vid_restart and try again\n"); Cvar_SetValueQuick(&r_shadow_realtime, 0); } else if (!gl_combine.integer) @@ -1271,8 +1317,7 @@ void R_RenderView (void) R_Mesh_Start(); R_MeshQueue_BeginScene(); - if (r_shadow_lightingmode) - R_Shadow_UpdateWorldLightSelection(); + R_Shadow_UpdateWorldLightSelection(); if (R_DrawBrushModelsSky()) R_TimeReport("bmodelsky"); @@ -1288,7 +1333,7 @@ void R_RenderView (void) R_DrawModels(r_shadow_lightingmode > 0); R_TimeReport("models"); - if (r_shadows.integer == 1) + if (r_shadows.integer == 1 && r_shadow_lightingmode <= 0) { R_DrawFakeShadows(); R_TimeReport("fakeshadow"); @@ -1300,6 +1345,9 @@ void R_RenderView (void) R_TimeReport("dynlight"); } + R_DrawLightningBeams(); + R_TimeReport("lightning"); + R_DrawParticles(); R_TimeReport("particles"); @@ -1320,7 +1368,7 @@ void R_RenderView (void) R_MeshQueue_Render(); R_MeshQueue_EndScene(); - if (r_shadow_realtime.integer == 2) + if (r_shadow_realtime.integer >= 2) { R_ShadowVolumeLighting(true); R_TimeReport("shadowvolume"); @@ -1445,7 +1493,7 @@ void R_DrawNoModel(entity_render_t *ent) // R_DrawNoModelCallback(ent, 0); } -void R_CalcBeamVerts (float *vert, vec3_t org1, vec3_t org2, float width) +void R_CalcBeamVerts (float *vert, const vec3_t org1, const vec3_t org2, float width) { vec3_t right1, right2, diff, normal;