From: vortex Date: Thu, 24 May 2012 17:32:00 +0000 (+0000) Subject: New shader keyword dptransparentsort (can be "sky", "distance", "hud") which forces... X-Git-Tag: xonotic-v0.8.0~96^2~216 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=2048a824c4d5c5d4d031e519dd3a125db35415fd;p=xonotic%2Fdarkplaces.git New shader keyword dptransparentsort (can be "sky", "distance", "hud") which forces one of transparent sort techniques. EF_NODEPTHTEST and RENDER_WORLDOBJECT entity flags have greater priority and override shader-set transparent sort technique. New cvar q3shader_force_terrain_alphaflag which sets TEXF_ALPHA on both vertextextureblend textures (fixes r_glsl_vertextextureblend_usebothalphas). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11822 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_particles.c b/cl_particles.c index 14b0cb43..d1b3b7a2 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -2551,7 +2551,7 @@ void R_DrawDecals (void) continue; if (DotProduct(r_refdef.view.origin, decal->normal) > DotProduct(decal->org, decal->normal) && VectorDistance2(decal->org, r_refdef.view.origin) < drawdist2 * (decal->size * decal->size)) - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, decal->org, R_DrawDecal_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, decal->org, R_DrawDecal_TransparentCallback, NULL, i, NULL); continue; killdecal: decal->typeindex = 0; @@ -3039,7 +3039,7 @@ void R_DrawParticles (void) { case pt_beam: // beams have no culling - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); break; default: if(cl_particles_visculling.integer) @@ -3053,7 +3053,7 @@ void R_DrawParticles (void) } // anything else just has to be in front of the viewer and visible at this distance if (DotProduct(p->org, r_refdef.view.forward) >= minparticledist_start && VectorDistance2(p->org, r_refdef.view.origin) < drawdist2 * (p->size * p->size)) - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL); break; } diff --git a/clvm_cmds.c b/clvm_cmds.c index 92db59dc..d49eab56 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -3429,7 +3429,7 @@ void VM_CL_AddPolygonsToMeshQueue (prvm_prog_t *prog) for (i = 0;i < polys->num_triangles;i++) { VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[2], center); - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL); } /*polys->num_triangles = 0; // now done after rendering the scene, diff --git a/gl_rmain.c b/gl_rmain.c index 62222a73..770f0196 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -227,7 +227,7 @@ cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alon cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"}; cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"}; -cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer."}; +cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer, requires mod_q3shader_force_terrain_alphaflag on."}; cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"}; @@ -7357,7 +7357,7 @@ static void R_DrawEntityBBoxes(void) if(PRVM_serveredictedict(edict, viewmodelforclient) != 0) continue; VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center); - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL); } } @@ -7465,7 +7465,7 @@ void R_DrawNoModel(entity_render_t *ent) vec3_t org; Matrix4x4_OriginFromMatrix(&ent->matrix, org); if ((ent->flags & RENDER_ADDITIVE) || (ent->alpha < 1)) - R_MeshQueue_AddTransparent((ent->flags & RENDER_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : MESHQUEUE_SORT_DISTANCE, org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight); + R_MeshQueue_AddTransparent((ent->flags & RENDER_NODEPTHTEST) ? TRANSPARENTSORT_HUD : rsurface.texture->transparentsort, org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight); else R_DrawNoModel_TransparentCallback(ent, rsurface.rtlight, 0, NULL); } @@ -10501,7 +10501,7 @@ static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const center[1] += r_refdef.view.forward[1]*rsurface.entity->transparent_offset; center[2] += r_refdef.view.forward[2]*rsurface.entity->transparent_offset; } - R_MeshQueue_AddTransparent((rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : ((rsurface.entity->flags & RENDER_WORLDOBJECT) ? MESHQUEUE_SORT_SKY : MESHQUEUE_SORT_DISTANCE), center, R_DrawSurface_TransparentCallback, rsurface.entity, surface - rsurface.modelsurfaces, rsurface.rtlight); + R_MeshQueue_AddTransparent((rsurface.entity->flags & RENDER_WORLDOBJECT) ? TRANSPARENTSORT_SKY : (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? TRANSPARENTSORT_HUD : rsurface.texture->transparentsort, center, R_DrawSurface_TransparentCallback, rsurface.entity, surface - rsurface.modelsurfaces, rsurface.rtlight); } } @@ -10748,7 +10748,7 @@ void R_DrawLocs(void) for (loc = cl.locnodes, index = 0;loc;loc = loc->next, index++) { VectorLerp(loc->mins, 0.5f, loc->maxs, center); - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL); } } diff --git a/gl_rsurf.c b/gl_rsurf.c index 123e12fe..611320b5 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -393,7 +393,7 @@ void R_DrawPortals(void) VectorAdd(center, portal->points[i].position, center); f = ixtable[portal->numpoints]; VectorScale(center, f, center); - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawPortal_Callback, (entity_render_t *)portal, leafnum, rsurface.rtlight); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, R_DrawPortal_Callback, (entity_render_t *)portal, leafnum, rsurface.rtlight); } } } @@ -1535,7 +1535,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface center[1] += r_refdef.view.forward[1]*ent->transparent_offset; center[2] += r_refdef.view.forward[2]*ent->transparent_offset; } - R_MeshQueue_AddTransparent((rsurface.entity->flags & RENDER_WORLDOBJECT) ? MESHQUEUE_SORT_SKY : ((rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : MESHQUEUE_SORT_DISTANCE), center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); + R_MeshQueue_AddTransparent((rsurface.entity->flags & RENDER_WORLDOBJECT) ? TRANSPARENTSORT_SKY : ((rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? TRANSPARENTSORT_HUD : rsurface.texture->transparentsort), center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight); } continue; } diff --git a/meshqueue.c b/meshqueue.c index 69bb6919..2ba5c518 100644 --- a/meshqueue.c +++ b/meshqueue.c @@ -10,7 +10,7 @@ typedef struct meshqueue_s int surfacenumber; const rtlight_t *rtlight; float dist; - meshqueue_sortcategory_t category; + dptransparentsortcategory_t category; } meshqueue_t; @@ -31,7 +31,7 @@ void R_MeshQueue_BeginScene(void) mqt_viewmaxdist = 0; } -void R_MeshQueue_AddTransparent(meshqueue_sortcategory_t category, const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) +void R_MeshQueue_AddTransparent(dptransparentsortcategory_t category, const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) { meshqueue_t *mq; if (mqt_count >= mqt_total || !mqt_array) @@ -104,14 +104,14 @@ void R_MeshQueue_RenderTransparent(void) switch(mqt->category) { default: - case MESHQUEUE_SORT_HUD: + case TRANSPARENTSORT_HUD: hashindex = 0; break; - case MESHQUEUE_SORT_DISTANCE: + case TRANSPARENTSORT_DISTANCE: // this could use a reduced range if we need more categories hashindex = bound(0, (int)(bound(0, mqt->dist - r_transparent_sortmindist.integer, r_transparent_sortmaxdist.integer) * distscale), maxhashindex); break; - case MESHQUEUE_SORT_SKY: + case TRANSPARENTSORT_SKY: hashindex = maxhashindex; break; } diff --git a/meshqueue.h b/meshqueue.h index 9a727f30..68fa4d0d 100644 --- a/meshqueue.h +++ b/meshqueue.h @@ -5,16 +5,8 @@ // VorteX: seems this value is hardcoded in other several defines as it's changing makes mess #define MESHQUEUE_TRANSPARENT_BATCHSIZE 256 -typedef enum meshqueue_sortcategory_e -{ - MESHQUEUE_SORT_SKY, - MESHQUEUE_SORT_DISTANCE, - MESHQUEUE_SORT_HUD, -} -meshqueue_sortcategory_t; - void R_MeshQueue_BeginScene(void); -void R_MeshQueue_AddTransparent(meshqueue_sortcategory_t category, const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight); +void R_MeshQueue_AddTransparent(dptransparentsortcategory_t category, const vec3_t center, void (*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight); void R_MeshQueue_RenderTransparent(void); #endif diff --git a/model_brush.c b/model_brush.c index 5892cc09..35f4b39f 100644 --- a/model_brush.c +++ b/model_brush.c @@ -56,6 +56,8 @@ cvar_t mod_q3shader_default_offsetmapping_bias = {CVAR_SAVE, "mod_q3shader_defau cvar_t mod_q3shader_default_polygonfactor = {0, "mod_q3shader_default_polygonfactor", "0", "biases depth values of 'polygonoffset' shaders to prevent z-fighting artifacts"}; cvar_t mod_q3shader_default_polygonoffset = {0, "mod_q3shader_default_polygonoffset", "-2", "biases depth values of 'polygonoffset' shaders to prevent z-fighting artifacts"}; cvar_t mod_q3shader_force_addalpha = {0, "mod_q3shader_force_addalpha", "0", "treat GL_ONE GL_ONE (or add) blendfunc as GL_SRC_ALPHA GL_ONE for compatibility with older DarkPlaces releases"}; +cvar_t mod_q3shader_force_terrain_alphaflag = {0, "mod_q3shader_force_terrain_alphaflag", "0", "for multilayered terrain shaders force TEXF_ALPHA flag on both layers"}; + cvar_t mod_q1bsp_polygoncollisions = {0, "mod_q1bsp_polygoncollisions", "0", "disables use of precomputed cliphulls and instead collides with polygons (uses Bounding Interval Hierarchy optimizations)"}; cvar_t mod_collision_bih = {0, "mod_collision_bih", "1", "enables use of generated Bounding Interval Hierarchy tree instead of compiled bsp tree in collision code"}; cvar_t mod_recalculatenodeboxes = {0, "mod_recalculatenodeboxes", "1", "enables use of generated node bounding boxes based on BSP tree portal reconstruction, rather than the node boxes supplied by the map compiler"}; @@ -98,6 +100,7 @@ void Mod_BrushInit(void) Cvar_RegisterVariable(&mod_q3shader_default_polygonfactor); Cvar_RegisterVariable(&mod_q3shader_default_polygonoffset); Cvar_RegisterVariable(&mod_q3shader_force_addalpha); + Cvar_RegisterVariable(&mod_q3shader_force_terrain_alphaflag); Cvar_RegisterVariable(&mod_q1bsp_polygoncollisions); Cvar_RegisterVariable(&mod_collision_bih); Cvar_RegisterVariable(&mod_recalculatenodeboxes); diff --git a/model_shared.c b/model_shared.c index 5d06edc5..e49b1b10 100644 --- a/model_shared.c +++ b/model_shared.c @@ -1653,6 +1653,7 @@ extern cvar_t mod_q3shader_default_offsetmapping_bias; extern cvar_t mod_q3shader_default_polygonoffset; extern cvar_t mod_q3shader_default_polygonfactor; extern cvar_t mod_q3shader_force_addalpha; +extern cvar_t mod_q3shader_force_terrain_alphaflag; void Mod_LoadQ3Shaders(void) { int j; @@ -1747,6 +1748,7 @@ void Mod_LoadQ3Shaders(void) shader.specularpowermod = 1; shader.biaspolygonoffset = mod_q3shader_default_polygonoffset.value; shader.biaspolygonfactor = mod_q3shader_default_polygonfactor.value; + shader.transparentsort = TRANSPARENTSORT_DISTANCE; strlcpy(shader.name, com_token, sizeof(shader.name)); if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{")) @@ -1999,6 +2001,8 @@ void Mod_LoadQ3Shaders(void) { // multilayer terrain shader or similar shader.textureblendalpha = true; + if (mod_q3shader_force_terrain_alphaflag.integer) + shader.layers[0].texflags |= TEXF_ALPHA; } } @@ -2009,7 +2013,7 @@ void Mod_LoadQ3Shaders(void) if(layer->blendfunc[0] == GL_ONE && layer->blendfunc[1] == GL_ONE) layer->blendfunc[0] = GL_SRC_ALPHA; } - + layer->texflags = 0; if (layer->alphatest) layer->texflags |= TEXF_ALPHA; @@ -2245,6 +2249,18 @@ void Mod_LoadQ3Shaders(void) shader.biaspolygonoffset = 0; } } + else if (!strcasecmp(parameter[0], "dptransparentsort") && numparameters >= 2) + { + shader.textureflags |= Q3TEXTUREFLAG_TRANSPARENTSORT; + if (!strcasecmp(parameter[1], "sky")) + shader.transparentsort = TRANSPARENTSORT_SKY; + else if (!strcasecmp(parameter[1], "distance")) + shader.transparentsort = TRANSPARENTSORT_DISTANCE; + else if (!strcasecmp(parameter[1], "hud")) + shader.transparentsort = TRANSPARENTSORT_HUD; + else + Con_DPrintf("%s parsing warning: unknown dptransparentsort category \"%s\", or not enough arguments\n", search->filenames[fileindex], parameter[1]); + } else if (!strcasecmp(parameter[0], "dprefract") && numparameters >= 5) { shader.textureflags |= Q3TEXTUREFLAG_REFRACTION; @@ -2484,6 +2500,7 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool texture->basematerialflags |= MATERIALFLAG_CAMERA; texture->customblendfunc[0] = GL_ONE; texture->customblendfunc[1] = GL_ZERO; + texture->transparentsort = shader->transparentsort; if (shader->numlayers > 0) { texture->customblendfunc[0] = shader->layers[0].blendfunc[0]; diff --git a/model_shared.h b/model_shared.h index f4e2e3c5..dedd4d8c 100644 --- a/model_shared.h +++ b/model_shared.h @@ -251,6 +251,7 @@ shadowmesh_t; #define Q3TEXTUREFLAG_REFLECTION 512 #define Q3TEXTUREFLAG_WATERSHADER 1024 #define Q3TEXTUREFLAG_CAMERA 2048 +#define Q3TEXTUREFLAG_TRANSPARENTSORT 4096 #define Q3PATHLENGTH 64 #define TEXTURE_MAXFRAMES 64 @@ -426,6 +427,12 @@ typedef enum dpoffsetmapping_technique_s OFFSETMAPPING_RELIEF // relief }dpoffsetmapping_technique_t; +typedef enum dptransparentsort_category_e +{ + TRANSPARENTSORT_SKY, + TRANSPARENTSORT_DISTANCE, + TRANSPARENTSORT_HUD, +}dptransparentsortcategory_t; typedef struct q3shaderinfo_s { @@ -477,6 +484,9 @@ typedef struct q3shaderinfo_s // polygonoffset (only used if Q3TEXTUREFLAG_POLYGONOFFSET) float biaspolygonoffset, biaspolygonfactor; + // transparent sort category + dptransparentsortcategory_t transparentsort; + // gloss float specularscalemod; float specularpowermod; @@ -618,6 +628,9 @@ typedef struct texture_s float offsetscale; float offsetbias; + // transparent sort category + dptransparentsortcategory_t transparentsort; + // gloss float specularscalemod; float specularpowermod; diff --git a/r_explosion.c b/r_explosion.c index b8f8152f..3c40edbf 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -275,7 +275,7 @@ void R_DrawExplosions(void) { R_MoveExplosion(&explosion[i]); if (explosion[i].alpha) - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, explosion[i].origin, R_DrawExplosion_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, explosion[i].origin, R_DrawExplosion_TransparentCallback, NULL, i, NULL); } } while (numexplosions > 0 && explosion[i-1].alpha <= 0) diff --git a/r_lightning.c b/r_lightning.c index 5ef3ed14..8568292d 100644 --- a/r_lightning.c +++ b/r_lightning.c @@ -320,7 +320,7 @@ void R_DrawLightningBeams(void) dist = bound(0, dist, 1); VectorLerp(start, dist, end, org); // now we have the nearest point on the line, so sort with it - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, org, R_DrawLightningBeam_TransparentCallback, NULL, i, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, org, R_DrawLightningBeam_TransparentCallback, NULL, i, NULL); } } } diff --git a/r_shadow.c b/r_shadow.c index 0e12a967..08b01150 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -5472,10 +5472,10 @@ void R_Shadow_DrawLightSprites(void) { light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); if (light) - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight); } if (!r_editlights_lockcursor) - R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL); + R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL); } int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color) diff --git a/r_sprites.c b/r_sprites.c index 2695c39f..cf57c30c 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -424,6 +424,6 @@ void R_Model_Sprite_Draw(entity_render_t *ent) return; Matrix4x4_OriginFromMatrix(&ent->matrix, org); - R_MeshQueue_AddTransparent((ent->flags & RENDER_WORLDOBJECT) ? MESHQUEUE_SORT_SKY : ((ent->flags & RENDER_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : MESHQUEUE_SORT_DISTANCE), org, R_Model_Sprite_Draw_TransparentCallback, ent, 0, rsurface.rtlight); + R_MeshQueue_AddTransparent((ent->flags & RENDER_WORLDOBJECT) ? TRANSPARENTSORT_SKY : (ent->flags & RENDER_NODEPTHTEST) ? TRANSPARENTSORT_HUD : rsurface.texture->transparentsort, org, R_Model_Sprite_Draw_TransparentCallback, ent, 0, rsurface.rtlight); }