X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rsurf.c;h=6ba68f2ad33e419d6f40330a1c06cd5f0f4560be;hb=a53125498eeac71ffa52aa0160c3de455799877b;hp=c5abc25bed29d65f39213ea65977fe1eb4c8a300;hpb=89b0d4ee9a14ab10465fae7e8a314dfb09d83124;p=xonotic%2Fdarkplaces.git diff --git a/gl_rsurf.c b/gl_rsurf.c index c5abc25b..6ba68f2a 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -25,14 +25,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_LIGHTMAP_SIZE 256 -cvar_t r_ambient = {0, "r_ambient", "0"}; -cvar_t r_drawportals = {0, "r_drawportals", "0"}; -cvar_t r_lockpvs = {0, "r_testpvs", "0"}; -cvar_t r_lockvisibility = {0, "r_lockvisibility", "0"}; -cvar_t r_useportalculling = {0, "r_useportalculling", "0"}; -cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygonfactor", "-1"}; -cvar_t r_drawcollisionbrushes_polygonoffset = {0, "r_drawcollisionbrushes_polygonoffset", "0"}; -cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0"}; +cvar_t r_ambient = {0, "r_ambient", "0", "brighter world cheat (not allowed in multiplayer), value is 0-128"}; +cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"}; +cvar_t r_lockpvs = {0, "r_lockpvs", "0", "disables pvs switching, allows you to walk around and inspect what is visible from a given location in the map (anything not visible from your current location will not be drawn)"}; +cvar_t r_lockvisibility = {0, "r_lockvisibility", "0", "disables visibility updates, allows you to walk around and inspect what is visible from a given viewpoint in the map (anything offscreen at the moment this is enabled will not be drawn)"}; +cvar_t r_useportalculling = {0, "r_useportalculling", "1", "use advanced portal culling visibility method to improve performance over just Potentially Visible Set, provides an even more significant speed improvement in unvised maps"}; +cvar_t r_q3bsp_renderskydepth = {0, "r_q3bsp_renderskydepth", "0", "draws sky depth masking in q3 maps (as in q1 maps), this means for example that sky polygons can hide other things"}; // flag arrays used for visibility checking on world model // (all other entities have no per-surface/per-leaf visibility checks) @@ -270,9 +268,9 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int R_StainNode(r_refdef.worldmodel->brush.data_nodes + r_refdef.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.worldmodel, origin, radius, fcolor); // look for embedded bmodels - for (n = 0;n < cl_num_brushmodel_entities;n++) + for (n = 0;n < cl.num_brushmodel_entities;n++) { - ent = &cl_entities[cl_brushmodel_entities[n]].render; + ent = &cl.entities[cl.brushmodel_entities[n]].render; model = ent->model; if (model && model->name[0] == '*') { @@ -294,22 +292,22 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int ============================================================= */ -static void R_DrawPortal_Callback(const void *calldata1, int calldata2) +static void R_DrawPortal_Callback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) { + const mportal_t *portal = (mportal_t *)ent; int i; float *v; rmeshstate_t m; - const mportal_t *portal = (mportal_t *)calldata1; GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); GL_DepthTest(true); - R_Mesh_Matrix(&r_identitymatrix); + R_Mesh_Matrix(&identitymatrix); memset(&m, 0, sizeof(m)); m.pointer_vertex = varray_vertex3f; R_Mesh_State(&m); - i = calldata2; + i = surfacenumber; GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f), ((i & 0x0038) >> 3) * (1.0f / 7.0f), ((i & 0x01C0) >> 6) * (1.0f / 7.0f), @@ -330,7 +328,7 @@ static void R_DrawPortal_Callback(const void *calldata1, int calldata2) // LordHavoc: this is just a nice debugging tool, very slow static void R_DrawPortals(void) { - int i, leafnum;//, portalnum; + int i, leafnum; mportal_t *portal; float center[3], f; model_t *model = r_refdef.worldmodel; @@ -351,8 +349,7 @@ static void R_DrawPortals(void) VectorAdd(center, portal->points[i].position, center); f = ixtable[portal->numpoints]; VectorScale(center, f, center); - //R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, portal, portalnum); - R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, portal, leafnum); + R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, (entity_render_t *)portal, leafnum, r_shadow_rtlight); } } } @@ -502,8 +499,7 @@ void R_Q1BSP_DrawSky(entity_render_t *ent) { if (ent->model == NULL) return; - if (r_drawcollisionbrushes.integer < 2) - R_DrawSurfaces(ent, true); + R_DrawSurfaces(ent, true); } void R_Q1BSP_Draw(entity_render_t *ent) @@ -511,9 +507,8 @@ void R_Q1BSP_Draw(entity_render_t *ent) model_t *model = ent->model; if (model == NULL) return; - if (r_drawcollisionbrushes.integer < 2) - R_DrawSurfaces(ent, false); - if (r_drawcollisionbrushes.integer >= 1 && model->brush.num_brushes) + R_DrawSurfaces(ent, false); + if (r_showcollisionbrushes.integer && model->brush.num_brushes && !r_showtrispass) { int i; msurface_t *surface; @@ -521,8 +516,8 @@ void R_Q1BSP_Draw(entity_render_t *ent) R_Mesh_Matrix(&ent->matrix); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); GL_DepthMask(false); - GL_DepthTest(true); - qglPolygonOffset(r_drawcollisionbrushes_polygonfactor.value, r_drawcollisionbrushes_polygonoffset.value); + GL_DepthTest(!r_showdisabledepthtest.integer); + qglPolygonOffset(r_showcollisionbrushes_polygonfactor.value, r_showcollisionbrushes_polygonoffset.value); for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++) if (brush->colbrushf && brush->colbrushf->numtriangles) R_DrawCollisionBrush(brush->colbrushf); @@ -572,6 +567,8 @@ void R_Q1BSP_RecursiveGetLightInfo(r_q1bsp_getlightinfo_t *info, mnode_t *node) R_Q1BSP_RecursiveGetLightInfo(info, node->children[0]); node = node->children[1]; } + else if (sides == 0) + return; // ERROR: NAN bounding box! else node = node->children[sides - 1]; } @@ -603,7 +600,6 @@ void R_Q1BSP_RecursiveGetLightInfo(r_q1bsp_getlightinfo_t *info, mnode_t *node) { msurface_t *surface = info->model->data_surfaces + surfaceindex; if (BoxesOverlap(info->lightmins, info->lightmaxs, surface->mins, surface->maxs)) - if ((surface->texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT)) == MATERIALFLAG_WALL) { int triangleindex, t; const int *e; @@ -705,7 +701,7 @@ void R_Q1BSP_CompileShadowVolume(entity_render_t *ent, vec3_t relativelightorigi texture = surface->texture; if ((texture->basematerialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL) continue; - if (texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + if ((texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) || (ent->flags & RENDER_NOCULLFACE)) continue; R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, r_shadow_compilingrtlight->cullmins, r_shadow_compilingrtlight->cullmaxs, surface->mins, surface->maxs); } @@ -717,7 +713,7 @@ extern float *rsurface_vertex3f; extern float *rsurface_svector3f; extern float *rsurface_tvector3f; extern float *rsurface_normal3f; -extern void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg); +extern void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg, qboolean generatenormals, qboolean generatetangents); void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs) { @@ -730,8 +726,6 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, // check the box in modelspace, it was already checked in worldspace if (!BoxesOverlap(ent->model->normalmins, ent->model->normalmaxs, lightmins, lightmaxs)) return; - if (r_drawcollisionbrushes.integer >= 2) - return; R_UpdateAllTextureInfo(ent); if (model->brush.shadowmesh) { @@ -742,7 +736,7 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, texture = surface->texture->currentframe; if ((texture->currentmaterialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL) continue; - if (texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + if ((texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) || (ent->flags & RENDER_NOCULLFACE)) continue; R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs); } @@ -759,7 +753,7 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, texture = surface->texture;//R_FetchAliasSkin(ent, surface->groupmesh); if (texture->currentmaterialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT) || !surface->num_triangles) continue; - RSurf_SetVertexPointer(ent, texture, surface, modelorg); + RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false); // identify lit faces within the bounding box R_Shadow_PrepareShadowMark(surface->groupmesh->num_triangles); R_Shadow_MarkVolumeFromBox(surface->num_firsttriangle, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs); @@ -768,9 +762,39 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, } } +static void R_Q1BSP_DrawLight_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) +{ + msurface_t *surface = ent->model->data_surfaces + surfacenumber; + texture_t *texture = surface->texture; + R_UpdateTextureInfo(ent, texture); + texture = texture->currentframe; + R_Shadow_RenderMode_Begin(); + R_Shadow_RenderMode_ActiveLight((rtlight_t *)rtlight); + R_Shadow_RenderMode_Lighting(false, true); + R_Shadow_SetupEntityLight(ent); + R_Shadow_RenderSurfacesLighting(ent, texture, 1, &surface); + R_Shadow_RenderMode_End(); +} + +static void R_Q1BSP_DrawLight_TransparentBatch(const entity_render_t *ent, texture_t *texture, int batchnumsurfaces, msurface_t **batchsurfacelist) +{ + int batchsurfaceindex; + msurface_t *batchsurface; + vec3_t tempcenter, center; + for (batchsurfaceindex = 0;batchsurfaceindex < batchnumsurfaces;batchsurfaceindex++) + { + batchsurface = batchsurfacelist[batchsurfaceindex]; + tempcenter[0] = (batchsurface->mins[0] + batchsurface->maxs[0]) * 0.5f; + tempcenter[1] = (batchsurface->mins[1] + batchsurface->maxs[1]) * 0.5f; + tempcenter[2] = (batchsurface->mins[2] + batchsurface->maxs[2]) * 0.5f; + Matrix4x4_Transform(&ent->matrix, tempcenter, center); + R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, batchsurface - ent->model->data_surfaces, r_shadow_rtlight); + } +} + #define RSURF_MAX_BATCHSURFACES 1024 -void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolorbase, float *lightcolorpants, float *lightcolorshirt, int numsurfaces, const int *surfacelist) +void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surfacelist) { model_t *model = ent->model; msurface_t *surface; @@ -779,14 +803,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolorbase, float *light msurface_t *batchsurfacelist[RSURF_MAX_BATCHSURFACES]; vec3_t modelorg; texture_t *tex; - rtexture_t *basetexture = NULL; - rtexture_t *glosstexture = NULL; - float specularscale = 0; qboolean skip; - if (r_drawcollisionbrushes.integer >= 2) - return; - if (VectorLength2(lightcolorbase) + VectorLength2(lightcolorpants) + VectorLength2(lightcolorshirt) < 0.0001) - return; R_UpdateAllTextureInfo(ent); Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg); tex = NULL; @@ -803,46 +820,26 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolorbase, float *light { if (batchnumsurfaces > 0) { - R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, modelorg); + if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) + R_Q1BSP_DrawLight_TransparentBatch(ent, texture, batchnumsurfaces, batchsurfacelist); + else + R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist); batchnumsurfaces = 0; } tex = surface->texture; texture = surface->texture->currentframe; - // FIXME: transparent surfaces need to be lit later - skip = (texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) != MATERIALFLAG_WALL; + skip = (texture->currentmaterialflags & MATERIALFLAG_SKY) != 0; if (skip) continue; - if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) - qglDisable(GL_CULL_FACE); - else - qglEnable(GL_CULL_FACE); - glosstexture = r_texture_black; - specularscale = 0; - if (texture->skin.gloss) - { - if (r_shadow_gloss.integer >= 1 && r_shadow_glossintensity.value > 0 && r_shadow_rtlight->specularscale > 0) - { - glosstexture = texture->skin.gloss; - specularscale = r_shadow_rtlight->specularscale * r_shadow_glossintensity.value; - } - } - else - { - if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0 && r_shadow_glossintensity.value > 0 && r_shadow_rtlight->specularscale > 0) - { - glosstexture = r_texture_white; - specularscale = r_shadow_rtlight->specularscale * r_shadow_gloss2intensity.value; - } - } - basetexture = (ent->colormap < 0 && texture->skin.merged) ? texture->skin.merged : texture->skin.base; - if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * (VectorLength2(lightcolorbase) + VectorLength2(lightcolorpants) + VectorLength2(lightcolorshirt)) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f)) - skip = true; } if (!skip && surface->num_triangles) { if (batchnumsurfaces == RSURF_MAX_BATCHSURFACES) { - R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, modelorg); + if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) + R_Q1BSP_DrawLight_TransparentBatch(ent, texture, batchnumsurfaces, batchsurfacelist); + else + R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist); batchnumsurfaces = 0; } batchsurfacelist[batchnumsurfaces++] = surface; @@ -850,12 +847,72 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolorbase, float *light } if (batchnumsurfaces > 0) { - R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, modelorg); + if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) + R_Q1BSP_DrawLight_TransparentBatch(ent, texture, batchnumsurfaces, batchsurfacelist); + else + R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist); batchnumsurfaces = 0; } qglEnable(GL_CULL_FACE); } +//Made by [515] +void R_ReplaceWorldTexture (void) +{ + model_t *m; + texture_t *t; + int i; + const char *r, *newt; + m = r_refdef.worldmodel; + + if(Cmd_Argc() < 2) + { + Con_Print("r_replacemaptexture - replaces texture\n"); + Con_Print("r_replacemaptexture - switch back to default texture\n"); + return; + } + if(!cl.islocalgame || !cl.worldmodel) + { + Con_Print("This command works only in singleplayer\n"); + return; + } + r = Cmd_Argv(1); + newt = Cmd_Argv(2); + if(!newt[0]) + newt = r; + for(i=0,t=m->data_textures;inum_textures;i++,t++) + { + if(t->width && !strcasecmp(t->name, r)) + { + if(Mod_LoadSkinFrame(&t->skin, (char*)newt, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, false, r_fullbrights.integer)) + { + Con_Printf("%s replaced with %s\n", r, newt); + return; + } + else + { + Con_Printf("%s was not found\n", newt); + Mod_LoadSkinFrame(&t->skin, (char*)r, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, false, r_fullbrights.integer);//back to default + return; + } + } + } +} + +//Made by [515] +void R_ListWorldTextures (void) +{ + model_t *m; + texture_t *t; + int i; + m = r_refdef.worldmodel; + + Con_Print("Worldmodel textures :\n"); + for(i=0,t=m->data_textures;inum_textures;i++,t++) + if(t->skin.base != r_texture_notexture) + Con_Printf("%s\n", t->name); +} + #if 0 static void gl_surf_start(void) { @@ -878,10 +935,11 @@ void GL_Surf_Init(void) Cvar_RegisterVariable(&r_lockpvs); Cvar_RegisterVariable(&r_lockvisibility); Cvar_RegisterVariable(&r_useportalculling); - Cvar_RegisterVariable(&r_drawcollisionbrushes_polygonfactor); - Cvar_RegisterVariable(&r_drawcollisionbrushes_polygonoffset); Cvar_RegisterVariable(&r_q3bsp_renderskydepth); + Cmd_AddCommand ("r_replacemaptexture", R_ReplaceWorldTexture, "override a map texture for testing purposes"); // By [515] + Cmd_AddCommand ("r_listmaptextures", R_ListWorldTextures, "list all textures used by the current map"); // By [515] + //R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap); }