X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=a51d300f7b29d179c85922face966f0aef22f9b0;hb=d6eabf6e35a6bda7d47b2acb87e3c5d2f5bde567;hp=9b498cb830000244289a2f27cc66016f8cdcf255;hpb=dd2a1456eec1f8bbf7a0cc99e13e941e2d179d15;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 9b498cb8..a51d300f 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -28,12 +28,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "csprogs.h" #include "cl_video.h" #include "dpsoftrast.h" +#include "cl_collision.h" #ifdef SUPPORTD3D #include extern LPDIRECT3DDEVICE9 vid_d3d9dev; #endif +#ifdef WIN32 +// Enable NVIDIA High Performance Graphics while using Integrated Graphics. +#ifdef __cplusplus +extern "C" { +#endif +__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +#ifdef __cplusplus +} +#endif +#endif + mempool_t *r_main_mempool; rtexturepool_t *r_main_texturepool; @@ -65,10 +77,10 @@ cvar_t r_motionblur_mousefactor_minspeed = {CVAR_SAVE, "r_motionblur_mousefactor cvar_t r_motionblur_mousefactor_maxspeed = {CVAR_SAVE, "r_motionblur_mousefactor_maxspeed", "50", "upper value of mouse acceleration when it reaches the peak factor into blur equation"}; // TODO do we want a r_equalize_entities cvar that works on all ents, or would that be a cheat? -cvar_t r_equalize_entities_fullbright = {CVAR_SAVE, "r_equalize_entities_fullbright", "0", "render fullbright entities by equalizing their lightness, not by not rendering light"}; -cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio"}; -cvar_t r_equalize_entities_by = {CVAR_SAVE, "r_equalize_entities_by", "0.7", "light equalizing: exponent of dynamics compression (0 = no compression, 1 = full compression)"}; -cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level"}; +cvar_t r_equalize_entities_fullbright = {CVAR_SAVE, "r_equalize_entities_fullbright", "0", "render fullbright entities by equalizing their lightness, not by not rendering light (DEPRECATED)"}; +cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio (DEPRECATED)"}; +cvar_t r_equalize_entities_by = {CVAR_SAVE, "r_equalize_entities_by", "0.7", "light equalizing: exponent of dynamics compression (0 = no compression, 1 = full compression) (DEPRECATED)"}; +cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level (DEPRECATED)"}; cvar_t r_depthfirst = {CVAR_SAVE, "r_depthfirst", "0", "renders a depth-only version of the scene before normal rendering begins to eliminate overdraw, values: 0 = off, 1 = world depth, 2 = world and model depth"}; cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"}; @@ -82,6 +94,7 @@ cvar_t r_transparent_sortsurfacesbynearest = {0, "r_transparent_sortsurfacesbyne cvar_t r_transparent_useplanardistance = {0, "r_transparent_useplanardistance", "0", "sort transparent meshes by distance from view plane rather than spherical distance to the chosen point"}; cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"}; cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"}; +cvar_t r_showbboxes_client = { 0, "r_showbboxes_client", "0", "shows bounding boxes of clientside qc entities, value controls opacity scaling (1 = 10%, 10 = 100%)" }; cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"}; cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"}; cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"}; @@ -98,18 +111,26 @@ cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"}; cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"}; cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"}; cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"}; +cvar_t r_cullentities_trace_entityocclusion = { 0, "r_cullentities_trace_entityocclusion", "1", "check for occluding entities such as doors, not just world hull" }; cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling (in addition to center sample)"}; cvar_t r_cullentities_trace_tempentitysamples = {0, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"}; cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"}; cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"}; +cvar_t r_cullentities_trace_eyejitter = {0, "r_cullentities_trace_eyejitter", "16", "randomly offset rays from the eye by this much to reduce the odds of flickering"}; cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"}; cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"}; cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"}; -cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"}; -cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"}; +cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps (DEPRECATED)"}; +cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier (DEPRECATED)"}; #define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit)) +cvar_t r_fullbright_directed = {0, "r_fullbright_directed", "0", "render fullbright things (unlit worldmodel and EF_FULLBRIGHT entities, but not fullbright shaders) using a constant light direction instead to add more depth while keeping uniform brightness"}; +cvar_t r_fullbright_directed_ambient = {0, "r_fullbright_directed_ambient", "0.5", "ambient light multiplier for directed fullbright"}; +cvar_t r_fullbright_directed_diffuse = {0, "r_fullbright_directed_diffuse", "0.75", "diffuse light multiplier for directed fullbright"}; +cvar_t r_fullbright_directed_pitch = {0, "r_fullbright_directed_pitch", "20", "constant pitch direction ('height') of the fake light source to use for fullbright"}; +cvar_t r_fullbright_directed_pitch_relative = {0, "r_fullbright_directed_pitch_relative", "0", "whether r_fullbright_directed_pitch is interpreted as absolute (0) or relative (1) pitch"}; + cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"}; cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"}; cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"}; @@ -120,7 +141,7 @@ cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 - cvar_t r_shadows_drawafterrtlighting = {CVAR_SAVE, "r_shadows_drawafterrtlighting", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."}; cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"}; cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"}; -cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."}; +cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "0.25", "higher values increase shadowmap quality at a cost of area covered (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."}; cvar_t r_shadows_shadowmapbias = {CVAR_SAVE, "r_shadows_shadowmapbias", "-1", "sets shadowmap bias for fake shadows. -1 sets the value of r_shadow_shadowmapping_bias. Needs shadowmapping ON."}; cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"}; cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"}; @@ -184,6 +205,7 @@ cvar_t r_glsl_postprocess_uservec3_enable = {CVAR_SAVE, "r_glsl_postprocess_user cvar_t r_glsl_postprocess_uservec4_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"}; cvar_t r_water = {CVAR_SAVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"}; +cvar_t r_water_cameraentitiesonly = {CVAR_SAVE, "r_water_cameraentitiesonly", "0", "whether to only show QC-defined reflections/refractions (typically used for camera- or portal-like effects)"}; cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"}; cvar_t r_water_resolutionmultiplier = {CVAR_SAVE, "r_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"}; cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"}; @@ -625,9 +647,6 @@ const char *builtinhlslshaderstrings[] = 0 }; -char *glslshaderstring = NULL; -char *hlslshaderstring = NULL; - //======================================================================================================================================================= typedef struct shaderpermutationinfo_s @@ -639,9 +658,14 @@ shaderpermutationinfo_t; typedef struct shadermodeinfo_s { - const char *filename; + const char *sourcebasename; + const char *extension; + const char **builtinshaderstrings; const char *pretext; const char *name; + char *filename; + char *builtinstring; + int builtincrc; } shadermodeinfo_t; @@ -678,50 +702,53 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = {"#define USETRIPPY\n", " trippy"}, {"#define USEDEPTHRGB\n", " depthrgb"}, {"#define USEALPHAGENVERTEX\n", " alphagenvertex"}, - {"#define USESKELETAL\n", " skeletal"} + {"#define USESKELETAL\n", " skeletal"}, + {"#define USEOCCLUDE\n", " occlude"} }; // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS! -shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] = -{ - {"glsl/default.glsl", "#define MODE_GENERIC\n", " generic"}, - {"glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"}, - {"glsl/default.glsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"}, - {"glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"}, - {"glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"}, - {"glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"}, - {"glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"}, - {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, - {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, - {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"}, - {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"}, - {"glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"}, - {"glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"}, - {"glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"}, - {"glsl/default.glsl", "#define MODE_WATER\n", " water"}, - {"glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"}, - {"glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"}, -}; - -shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] = -{ - {"hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"}, - {"hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"}, - {"hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"}, - {"hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"}, - {"hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"}, - {"hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"}, - {"hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"}, - {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, - {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, - {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"}, - {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"}, - {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"}, - {"hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"}, - {"hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"}, - {"hlsl/default.hlsl", "#define MODE_WATER\n", " water"}, - {"hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"}, - {"hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"}, +shadermodeinfo_t shadermodeinfo[SHADERLANGUAGE_COUNT][SHADERMODE_COUNT] = +{ + // SHADERLANGUAGE_GLSL + { + {"combined", "glsl", builtinshaderstrings, "#define MODE_GENERIC\n", " generic"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_POSTPROCESS\n", " postprocess"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_FAKELIGHT\n", " fakelight"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTION\n", " lightdirection"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTSOURCE\n", " lightsource"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_REFRACTION\n", " refraction"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_WATER\n", " water"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"}, + {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"}, + }, + // SHADERLANGUAGE_HLSL + { + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_GENERIC\n", " generic"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_POSTPROCESS\n", " postprocess"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_FAKELIGHT\n", " fakelight"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTION\n", " lightdirection"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTSOURCE\n", " lightsource"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_REFRACTION\n", " refraction"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_WATER\n", " water"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"}, + {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"}, + }, }; struct r_glsl_permutation_s; @@ -730,7 +757,7 @@ typedef struct r_glsl_permutation_s /// hash lookup data struct r_glsl_permutation_s *hashnext; unsigned int mode; - unsigned int permutation; + dpuint64 permutation; /// indicates if we have tried compiling this permutation already qboolean compiled; @@ -895,7 +922,7 @@ extern qboolean r_shadow_shadowmapsampler; extern int r_shadow_shadowmappcf; qboolean R_CompileShader_CheckStaticParms(void) { - static int r_compileshader_staticparms_save[1]; + static int r_compileshader_staticparms_save[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5]; memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms)); memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms)); @@ -941,7 +968,7 @@ qboolean R_CompileShader_CheckStaticParms(void) shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \ else \ shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n" -static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation) +static void R_CompileShader_AddStaticParms(unsigned int mode, dpuint64 permutation) { shaderstaticparms_count = 0; @@ -969,7 +996,7 @@ r_glsl_permutation_t *r_glsl_permutation; /// storage for permutations linked in the hash table memexpandablearray_t r_glsl_permutationarray; -static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation) +static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, dpuint64 permutation) { //unsigned int hashdepth = 0; unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1); @@ -1015,63 +1042,50 @@ static char *R_ShaderStrCat(const char **strings) return string; } -static char *R_GetShaderText(const char *filename, qboolean printfromdisknotice, qboolean builtinonly) +static char *R_ShaderStrCat(const char **strings); +static void R_InitShaderModeInfo(void) { - char *shaderstring; - if (!filename || !filename[0]) - return NULL; - // LordHavoc: note that FS_LoadFile appends a 0 byte to make it a valid string, so does R_ShaderStrCat - if (!strcmp(filename, "glsl/default.glsl")) - { - if (builtinonly) - return R_ShaderStrCat(builtinshaderstrings); - if (!glslshaderstring) - { - glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL); - if (glslshaderstring) - Con_DPrintf("Loading shaders from file %s...\n", filename); - else - glslshaderstring = R_ShaderStrCat(builtinshaderstrings); - } - shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1); - memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1); - return shaderstring; - } - if (!strcmp(filename, "hlsl/default.hlsl")) + int i, language; + shadermodeinfo_t *modeinfo; + // we have a bunch of things to compute that weren't calculated at engine compile time - all filenames should have a crc of the builtin strings to prevent accidental overrides (any customization must be updated to match engine) + for (language = 0; language < SHADERLANGUAGE_COUNT; language++) { - if (builtinonly) - return R_ShaderStrCat(builtinhlslshaderstrings); - if (!hlslshaderstring) + for (i = 0; i < SHADERMODE_COUNT; i++) { - hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL); - if (hlslshaderstring) - Con_DPrintf("Loading shaders from file %s...\n", filename); - else - hlslshaderstring = R_ShaderStrCat(builtinhlslshaderstrings); + char filename[MAX_QPATH]; + modeinfo = &shadermodeinfo[language][i]; + modeinfo->builtinstring = R_ShaderStrCat(modeinfo->builtinshaderstrings); + modeinfo->builtincrc = CRC_Block((const unsigned char *)modeinfo->builtinstring, strlen(modeinfo->builtinstring)); + dpsnprintf(filename, sizeof(filename), "%s/%s_crc%i.%s", modeinfo->extension, modeinfo->sourcebasename, modeinfo->builtincrc, modeinfo->extension); + modeinfo->filename = Mem_strdup(r_main_mempool, filename); } - shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1); - memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1); - return shaderstring; } - // we don't have builtin strings for any other files - if (builtinonly) - return NULL; - shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL); +} + +static char *ShaderModeInfo_GetShaderText(shadermodeinfo_t *modeinfo, qboolean printfromdisknotice, qboolean builtinonly) +{ + char *shaderstring; + // if the mode has no filename we have to return the builtin string + if (builtinonly || !modeinfo->filename) + return Mem_strdup(r_main_mempool, modeinfo->builtinstring); + // note that FS_LoadFile appends a 0 byte to make it a valid string + shaderstring = (char *)FS_LoadFile(modeinfo->filename, r_main_mempool, false, NULL); if (shaderstring) { if (printfromdisknotice) - Con_DPrintf("from disk %s... ", filename); + Con_DPrintf("Loading shaders from file %s...\n", modeinfo->filename); return shaderstring; } - return shaderstring; + // fall back to builtinstring + return Mem_strdup(r_main_mempool, modeinfo->builtinstring); } -static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation) +static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, dpuint64 permutation) { int i; int ubibind; int sampler; - shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode; + shadermodeinfo_t *modeinfo = &shadermodeinfo[SHADERLANGUAGE_GLSL][mode]; char *sourcestring; char permutationname[256]; int vertstrings_count = 0; @@ -1087,7 +1101,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode p->program = 0; permutationname[0] = 0; - sourcestring = R_GetShaderText(modeinfo->filename, true, false); + sourcestring = ShaderModeInfo_GetShaderText(modeinfo, true, false); strlcat(permutationname, modeinfo->filename, sizeof(permutationname)); @@ -1111,6 +1125,27 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode geomstrings_list[geomstrings_count++] = "#define GLSL130\n"; fragstrings_list[fragstrings_count++] = "#define GLSL130\n"; } + // if we can do #version 120, we should (this adds the invariant keyword) + else if(vid.support.glshaderversion >= 120) + { + vertstrings_list[vertstrings_count++] = "#version 120\n"; + geomstrings_list[geomstrings_count++] = "#version 120\n"; + fragstrings_list[fragstrings_count++] = "#version 120\n"; + vertstrings_list[vertstrings_count++] = "#define GLSL120\n"; + geomstrings_list[geomstrings_count++] = "#define GLSL120\n"; + fragstrings_list[fragstrings_count++] = "#define GLSL120\n"; + } + // GLES also adds several things from GLSL120 + switch(vid.renderpath) + { + case RENDERPATH_GLES2: + vertstrings_list[vertstrings_count++] = "#define GLES\n"; + geomstrings_list[geomstrings_count++] = "#define GLES\n"; + fragstrings_list[fragstrings_count++] = "#define GLES\n"; + break; + default: + break; + } // the first pretext is which type of shader to compile as // (later these will all be bound together as a program object) @@ -1127,7 +1162,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode // now add all the permutation pretexts for (i = 0;i < SHADERPERMUTATION_COUNT;i++) { - if (permutation & (1<filename, true, false); + sourcestring = ShaderModeInfo_GetShaderText(modeinfo, true, false); strlcat(permutationname, modeinfo->filename, sizeof(permutationname)); strlcat(cachename, "hlsl/", sizeof(cachename)); @@ -1742,7 +1777,7 @@ static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode // now add all the permutation pretexts for (i = 0;i < SHADERPERMUTATION_COUNT;i++) { - if (permutation & (1<= 0) continue; - text = R_GetShaderText(modeinfo[mode].filename, false, true); + text = modeinfo[mode].builtinstring; if (!text) continue; file = FS_OpenRealFile(modeinfo[mode].filename, "w", false); @@ -1985,14 +2014,13 @@ static void R_GLSL_DumpShader_f(void) } else Con_Printf("failed to write to %s\n", modeinfo[mode].filename); - Mem_Free(text); } } } void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha) { - unsigned int permutation = 0; + dpuint64 permutation = 0; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; permutation |= SHADERPERMUTATION_VIEWTINT; @@ -2073,7 +2101,7 @@ void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy) void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean skeletal) { - unsigned int permutation = 0; + dpuint64 permutation = 0; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; if (depthrgb) @@ -2123,14 +2151,15 @@ extern rtexture_t *r_shadow_attenuation2dtexture; extern rtexture_t *r_shadow_attenuation3dtexture; extern qboolean r_shadow_usingshadowmap2d; extern qboolean r_shadow_usingshadowmaportho; -extern float r_shadow_shadowmap_texturescale[2]; -extern float r_shadow_shadowmap_parameters[4]; +extern float r_shadow_modelshadowmap_texturescale[4]; +extern float r_shadow_modelshadowmap_parameters[4]; +extern float r_shadow_lightshadowmap_texturescale[4]; +extern float r_shadow_lightshadowmap_parameters[4]; extern qboolean r_shadow_shadowmapvsdct; extern rtexture_t *r_shadow_shadowmap2ddepthbuffer; extern rtexture_t *r_shadow_shadowmap2ddepthtexture; extern rtexture_t *r_shadow_shadowmapvsdcttexture; extern matrix4x4_t r_shadow_shadowmapmatrix; -extern int r_shadow_shadowmaplod; // changes for each light based on distance extern int r_shadow_prepass_width; extern int r_shadow_prepass_height; extern rtexture_t *r_shadow_prepassgeometrydepthbuffer; @@ -2184,35 +2213,36 @@ static int R_BlendFuncFlags(int src, int dst) return r; } -void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy) +void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdiffuse[3], const float rtlightspecular[3], rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy) { // select a permutation of the lighting shader appropriate to this // combination of texture, entity, light source, and fogging, only use the // minimum features necessary to avoid wasting rendering time in the // fragment shader on features that are not being used - unsigned int permutation = 0; + dpuint64 permutation = 0; unsigned int mode = 0; int blendfuncflags; - static float dummy_colormod[3] = {1, 1, 1}; - float *colormod = rsurface.colormod; + texture_t *t = rsurface.texture; float m16f[16]; matrix4x4_t tempmatrix; r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + if (t->currentmaterialflags & MATERIALFLAG_ALPHATEST) permutation |= SHADERPERMUTATION_ALPHAKILL; - if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1]) + if (t->currentmaterialflags & MATERIALFLAG_OCCLUDE) + permutation |= SHADERPERMUTATION_OCCLUDE; + if (t->r_water_waterscroll[0] && t->r_water_waterscroll[1]) permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic if (rsurfacepass == RSURFPASS_BACKGROUND) { // distorted background - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER) + if (t->currentmaterialflags & MATERIALFLAG_WATERSHADER) { mode = SHADERMODE_WATER; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; - if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA)) + if((r_wateralpha.value < 1) && (t->currentmaterialflags & MATERIALFLAG_WATERALPHA)) { // this is the right thing to do for wateralpha GL_BlendFunc(GL_ONE, GL_ZERO); @@ -2225,10 +2255,10 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION) + else if (t->currentmaterialflags & MATERIALFLAG_REFRACTION) { mode = SHADERMODE_REFRACTION; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2245,9 +2275,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY) { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2255,7 +2285,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; // normalmap (deferred prepass), may use alpha test on diffuse mode = SHADERMODE_DEFERREDGEOMETRY; @@ -2266,9 +2296,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else if (rsurfacepass == RSURFPASS_RTLIGHT) { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2276,21 +2306,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; // light source mode = SHADERMODE_LIGHTSOURCE; if (rsurface.rtlight->currentcubemap != r_texture_whitecube) permutation |= SHADERPERMUTATION_CUBEFILTER; - if (diffusescale > 0) + if (VectorLength2(rtlightdiffuse) > 0) permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(rtlightspecular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; if (r_refdef.fogenabled) permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) + if (t->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmap2d) { @@ -2301,69 +2331,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_shadowmap2ddepthbuffer) permutation |= SHADERPERMUTATION_DEPTHRGB; } - if (rsurface.texture->reflectmasktexture) + if (t->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE); if (vid.allowalphatocoverage) GL_AlphaToCoverage(false); } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) - { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) - { - switch(rsurface.texture->offsetmapping) - { - case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; - case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_OFF: break; - } - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) - permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; - // unshaded geometry (fullbright or ambient model lighting) - mode = SHADERMODE_FLATCOLOR; - ambientscale = diffusescale = specularscale = 0; - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) - permutation |= SHADERPERMUTATION_GLOW; - if (r_refdef.fogenabled) - permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) - permutation |= SHADERPERMUTATION_COLORMAPPING; - if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) - { - permutation |= SHADERPERMUTATION_SHADOWMAPORTHO; - permutation |= SHADERPERMUTATION_SHADOWMAP2D; - - if (r_shadow_shadowmap2ddepthbuffer) - permutation |= SHADERPERMUTATION_DEPTHRGB; - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - permutation |= SHADERPERMUTATION_REFLECTION; - if (rsurface.texture->reflectmasktexture) - permutation |= SHADERPERMUTATION_REFLECTCUBE; - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - // when using alphatocoverage, we don't need alphakill - if (vid.allowalphatocoverage) - { - if (r_transparent_alphatocoverage.integer) - { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); - permutation &= ~SHADERPERMUTATION_ALPHAKILL; - } - else - GL_AlphaToCoverage(false); - } - } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL) + else if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2371,78 +2350,21 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; // directional model lighting mode = SHADERMODE_LIGHTDIRECTION; - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) + if ((t->glowtexture || t->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; - permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_modellight_diffuse)) + permutation |= SHADERPERMUTATION_DIFFUSE; + if (VectorLength2(t->render_modellight_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR; if (r_refdef.fogenabled) permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) - permutation |= SHADERPERMUTATION_COLORMAPPING; - if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) - { - permutation |= SHADERPERMUTATION_SHADOWMAPORTHO; - permutation |= SHADERPERMUTATION_SHADOWMAP2D; - - if (r_shadow_shadowmap2ddepthbuffer) - permutation |= SHADERPERMUTATION_DEPTHRGB; - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - permutation |= SHADERPERMUTATION_REFLECTION; - if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) - permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; - if (rsurface.texture->reflectmasktexture) - permutation |= SHADERPERMUTATION_REFLECTCUBE; - if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld) - { - permutation |= SHADERPERMUTATION_BOUNCEGRID; - if (r_shadow_bouncegriddirectional) - permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL; - } - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - // when using alphatocoverage, we don't need alphakill - if (vid.allowalphatocoverage) - { - if (r_transparent_alphatocoverage.integer) - { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); - permutation &= ~SHADERPERMUTATION_ALPHAKILL; - } - else - GL_AlphaToCoverage(false); - } - } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) - { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) - { - switch(rsurface.texture->offsetmapping) - { - case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; - case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; - case OFFSETMAPPING_OFF: break; - } - } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) - permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; - // ambient model lighting - mode = SHADERMODE_LIGHTDIRECTION; - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) - permutation |= SHADERPERMUTATION_GLOW; - if (r_refdef.fogenabled) - permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) + if (t->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) { @@ -2452,26 +2374,26 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_shadowmap2ddepthbuffer) permutation |= SHADERPERMUTATION_DEPTHRGB; } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) + if (t->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; - if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) + if (r_shadow_usingdeferredprepass && !(t->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; - if (rsurface.texture->reflectmasktexture) + if (t->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; - if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld) + if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld) { permutation |= SHADERPERMUTATION_BOUNCEGRID; - if (r_shadow_bouncegriddirectional) + if (r_shadow_bouncegrid_state.directional) permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL; } - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); + GL_BlendFunc(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); + blendfuncflags = R_BlendFuncFlags(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); // when using alphatocoverage, we don't need alphakill if (vid.allowalphatocoverage) { if (r_transparent_alphatocoverage.integer) { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_AlphaToCoverage((t->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); permutation &= ~SHADERPERMUTATION_ALPHAKILL; } else @@ -2480,9 +2402,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else { - if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f)) + if (r_glsl_offsetmapping.integer && ((R_TextureFlags(t->nmaptexture) & TEXF_ALPHA) || t->offsetbias != 0.0f)) { - switch(rsurface.texture->offsetmapping) + switch(t->offsetmapping) { case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; @@ -2490,16 +2412,16 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case OFFSETMAPPING_OFF: break; } } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + if (t->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) + if (t->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX) permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX; // lightmapped wall - if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) + if ((t->glowtexture || t->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); - if (rsurface.texture->colormapping) + if (t->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)) { @@ -2509,18 +2431,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_shadow_shadowmap2ddepthbuffer) permutation |= SHADERPERMUTATION_DEPTHRGB; } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) + if (t->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; - if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) + if (r_shadow_usingdeferredprepass && !(t->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; - if (rsurface.texture->reflectmasktexture) + if (t->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; if (FAKELIGHT_ENABLED) { // fake lightmapping (q1bsp, q3bsp, fullbright map) mode = SHADERMODE_FAKELIGHT; permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_lightmap_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; } else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping) @@ -2531,7 +2453,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE; permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_lightmap_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; } else if (r_glsl_deluxemapping.integer >= 2) @@ -2542,7 +2464,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR; permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (VectorLength2(t->render_lightmap_specular) > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; } else if (rsurface.uselightmaptexture) @@ -2555,28 +2477,26 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, // ordinary vertex coloring (q3bsp) mode = SHADERMODE_VERTEXCOLOR; } - if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld) + if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld) { permutation |= SHADERPERMUTATION_BOUNCEGRID; - if (r_shadow_bouncegriddirectional) + if (r_shadow_bouncegrid_state.directional) permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL; } - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); + GL_BlendFunc(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); + blendfuncflags = R_BlendFuncFlags(t->currentlayers[0].blendfunc1, t->currentlayers[0].blendfunc2); // when using alphatocoverage, we don't need alphakill if (vid.allowalphatocoverage) { if (r_transparent_alphatocoverage.integer) { - GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_AlphaToCoverage((t->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); permutation &= ~SHADERPERMUTATION_ALPHAKILL; } else GL_AlphaToCoverage(false); } } - if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD)) - colormod = dummy_colormod; if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG)) permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE); if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA) @@ -2598,11 +2518,11 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (mode == SHADERMODE_LIGHTDIRECTION) { - hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + hlslVSSetParameter3f(D3DVSREGISTER_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } } - Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f); - Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f); + Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f); + Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f); Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f); hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]); @@ -2610,66 +2530,72 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (mode == SHADERMODE_LIGHTSOURCE) { hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]); - hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale); + hlslPSSetParameter3f(D3DPSREGISTER_LightColor, 1, 1, 1); // DEPRECATED + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]); // additive passes are only darkened by fog, not tinted hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0); - hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); } else { + hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); if (mode == SHADERMODE_FLATCOLOR) { - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); } else if (mode == SHADERMODE_LIGHTDIRECTION) { - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale); - hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]); - hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]); + hlslPSSetParameter3f(D3DPSREGISTER_LightColor, 1, 1, 1); // DEPRECATED + hlslPSSetParameter3f(D3DPSREGISTER_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } else { - hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]); } // additive passes are only darkened by fog, not tinted if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0) hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0); else hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]); - hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor); + hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor); hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]); hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]); - hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]); - hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]); - hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin); - hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin); - hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f)); + hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha); + hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha); + hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, t->reflectmax - t->reflectmin); + hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, t->reflectmin); + hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (t->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f)); if (mode == SHADERMODE_WATER) - hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]); + hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]); + } + if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO) + { + hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]); + hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]); + } + else + { + hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]); + hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); } - hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]); - hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]); - hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]); - hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1)); + hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]); + hlslPSSetParameter1f(D3DPSREGISTER_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1)); hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); - if (rsurface.texture->pantstexture) - hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]); + if (t->pantstexture) + hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]); else hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0); - if (rsurface.texture->shirttexture) - hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]); + if (t->shirttexture) + hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]); else hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0); hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]); @@ -2677,28 +2603,28 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip); hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade); hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps, - r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + r_glsl_offsetmapping_scale.value*t->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) ); hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality); - hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias); + hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, t->offsetbias); hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height); - R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture ); - R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture ); - R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture ); - R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube); + R_Mesh_TexBind(GL20TU_NORMAL , t->nmaptexture ); + R_Mesh_TexBind(GL20TU_COLOR , t->basetexture ); + R_Mesh_TexBind(GL20TU_GLOSS , t->glosstexture ); + R_Mesh_TexBind(GL20TU_GLOW , t->glowtexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , t->backgroundnmaptexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , t->backgroundbasetexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , t->backgroundglosstexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , t->backgroundglowtexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , t->pantstexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , t->shirttexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , t->reflectmasktexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube); if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture ); if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation ); R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white); @@ -2767,39 +2693,39 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);} if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]); - if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale); - if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale); + if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, 1, 1, 1); // DEPRECATED + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]); + if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]); // additive passes are only darkened by fog, not tinted if (r_glsl_permutation->loc_FogColor >= 0) qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0); - if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); } else { if (mode == SHADERMODE_FLATCOLOR) { - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]); + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); } else if (mode == SHADERMODE_LIGHTDIRECTION) { - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]); - if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]); - if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale); - if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]); - if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); + if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]); + if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); + if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, 1, 1, 1); // DEPRECATED + if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } else { - if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]); - if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale); + if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]); + if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]); + if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); } // additive passes are only darkened by fog, not tinted if (r_glsl_permutation->loc_FogColor >= 0) @@ -2809,36 +2735,44 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]); } - if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor); + if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor); if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]); if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]); - if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]); - if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]); - if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin); - if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin); - if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); - if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]); - } - if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);} - if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);} + if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha); + if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha); + if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, t->reflectmax - t->reflectmin); + if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, t->reflectmin); + if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]); + } + if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);} + if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);} if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);} - if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]); - if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]); + if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO) + { + if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]); + if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]); + } + else + { + if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]); + if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); + } - if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]); - if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1)); + if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]); + if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1)); if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); if (r_glsl_permutation->loc_Color_Pants >= 0) { - if (rsurface.texture->pantstexture) - qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]); + if (t->pantstexture) + qglUniform3f(r_glsl_permutation->loc_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]); else qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0); } if (r_glsl_permutation->loc_Color_Shirt >= 0) { - if (rsurface.texture->shirttexture) - qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]); + if (t->shirttexture) + qglUniform3f(r_glsl_permutation->loc_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]); else qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0); } @@ -2847,33 +2781,33 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip); if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade); if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps, - r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + r_glsl_offsetmapping_scale.value*t->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) ); if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality); - if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias); + if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, t->offsetbias); if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); - if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);} - if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale); + if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegrid_state.matrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);} + if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegrid_state.intensity*r_refdef.view.colorscale); if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white ); if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white ); if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps , r_texture_gammaramps ); - if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , rsurface.texture->nmaptexture ); - if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , rsurface.texture->basetexture ); - if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , rsurface.texture->glosstexture ); - if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , rsurface.texture->glowtexture ); - if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , rsurface.texture->backgroundnmaptexture ); - if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture ); - if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture ); - if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture ); - if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , rsurface.texture->pantstexture ); - if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , rsurface.texture->shirttexture ); - if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , rsurface.texture->reflectmasktexture ); - if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube); + if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , t->nmaptexture ); + if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , t->basetexture ); + if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , t->glosstexture ); + if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , t->glowtexture ); + if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , t->backgroundnmaptexture ); + if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , t->backgroundbasetexture ); + if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , t->backgroundglosstexture ); + if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , t->backgroundglowtexture ); + if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , t->pantstexture ); + if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , t->shirttexture ); + if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , t->reflectmasktexture ); + if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube); if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture ); if (r_glsl_permutation->tex_Texture_FogMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask , r_texture_fogattenuation ); if (r_glsl_permutation->tex_Texture_Lightmap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white); @@ -2901,7 +2835,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture ); } } - if (r_glsl_permutation->tex_Texture_BounceGrid >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture); + if (r_glsl_permutation->tex_Texture_BounceGrid >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegrid_state.texture); CHECKGLERROR break; case RENDERPATH_GL11: @@ -2917,74 +2851,80 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);} DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, 1, 1, 1); // DEPRECATED + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rtlightdiffuse[0], rtlightdiffuse[1], rtlightdiffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, rtlightspecular[0], rtlightspecular[1], rtlightspecular[2]); // additive passes are only darkened by fog, not tinted DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); } else { if (mode == SHADERMODE_FLATCOLOR) { - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); } else if (mode == SHADERMODE_LIGHTDIRECTION) { - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_modellight_ambient[0], t->render_modellight_ambient[1], t->render_modellight_ambient[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, t->render_modellight_diffuse[0], t->render_modellight_diffuse[1], t->render_modellight_diffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, t->render_modellight_specular[0], t->render_modellight_specular[1], t->render_modellight_specular[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, 1, 1, 1); // DEPRECATED + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); } else { - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, t->render_lightmap_specular[0], t->render_lightmap_specular[1], t->render_lightmap_specular[2]); } + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); // additive passes are only darkened by fog, not tinted if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0) DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0); else DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]); - DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor); + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * t->refractfactor, r_water_refractdistort.value * t->refractfactor, r_water_reflectdistort.value * t->reflectfactor, r_water_reflectdistort.value * t->reflectfactor); DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]); DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]); - DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]); - DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); - DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]); - } - {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);} - {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);} + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, t->refractcolor4f[0], t->refractcolor4f[1], t->refractcolor4f[2], t->refractcolor4f[3] * t->currentalpha); + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, t->reflectcolor4f[0], t->reflectcolor4f[1], t->reflectcolor4f[2], t->reflectcolor4f[3] * t->currentalpha); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, t->reflectmax - t->reflectmin); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, t->reflectmin); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, t->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); + DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, t->r_water_waterscroll[0], t->r_water_waterscroll[1]); + } + {Matrix4x4_ToArrayFloatGL(&t->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);} + {Matrix4x4_ToArrayFloatGL(&t->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);} {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);} - DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]); - DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]); + if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO) + { + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]); + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]); + } + else + { + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]); + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); + } - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1)); + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1)); DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); if (DPSOFTRAST_UNIFORM_Color_Pants >= 0) { - if (rsurface.texture->pantstexture) - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]); + if (t->pantstexture) + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, t->render_colormap_pants[0], t->render_colormap_pants[1], t->render_colormap_pants[2]); else DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0); } if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0) { - if (rsurface.texture->shirttexture) - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]); + if (t->shirttexture) + DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, t->render_colormap_shirt[0], t->render_colormap_shirt[1], t->render_colormap_shirt[2]); else DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0); } @@ -2993,28 +2933,28 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade); DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps, - r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + r_glsl_offsetmapping_scale.value*t->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) ); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality); - DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias); + DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, t->offsetbias); DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); - R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture ); - R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture ); - R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture ); - R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture ); - if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture ); - if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture ); - if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube); + R_Mesh_TexBind(GL20TU_NORMAL , t->nmaptexture ); + R_Mesh_TexBind(GL20TU_COLOR , t->basetexture ); + R_Mesh_TexBind(GL20TU_GLOSS , t->glosstexture ); + R_Mesh_TexBind(GL20TU_GLOW , t->glowtexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , t->backgroundnmaptexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , t->backgroundbasetexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , t->backgroundglosstexture ); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , t->backgroundglowtexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , t->pantstexture ); + if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , t->shirttexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , t->reflectmasktexture ); + if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , t->reflectcubetexture ? t->reflectcubetexture : r_texture_whitecube); if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture ); if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation ); R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white); @@ -3052,7 +2992,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) // combination of texture, entity, light source, and fogging, only use the // minimum features necessary to avoid wasting rendering time in the // fragment shader on features that are not being used - unsigned int permutation = 0; + dpuint64 permutation = 0; unsigned int mode = 0; const float *lightcolorbase = rtlight->currentcolor; float ambientscale = rtlight->ambientscale; @@ -3085,7 +3025,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) GL_AlphaToCoverage(false); Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin); Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld); - Matrix4x4_Invert_Simple(&viewtolight, &lighttoview); + Matrix4x4_Invert_Full(&viewtolight, &lighttoview); Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f); switch(vid.renderpath) { @@ -3097,8 +3037,8 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale ); hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale ); hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale); - hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]); - hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]); + hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]); + hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height); @@ -3124,8 +3064,8 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) if (r_glsl_permutation->loc_DeferredColor_Ambient >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale ); if (r_glsl_permutation->loc_DeferredColor_Diffuse >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale ); if (r_glsl_permutation->loc_DeferredColor_Specular >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Specular , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale); - if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]); - if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]); + if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]); + if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f( r_glsl_permutation->loc_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f( r_glsl_permutation->loc_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height); @@ -3147,8 +3087,8 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale ); DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale ); DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale); - DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]); - DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]); + DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]); + DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_Parameters , r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); DPSOFTRAST_Uniform1f( DPSOFTRAST_UNIFORM_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); @@ -3166,7 +3106,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) typedef struct { - int loadsequence; // incremented each level change + unsigned int loadsequence; // incremented each level change memexpandablearray_t array; skinframe_t *hash[SKINFRAME_HASH]; } @@ -3189,6 +3129,23 @@ void R_SkinFrame_MarkUsed(skinframe_t *skinframe) skinframe->loadsequence = r_skinframe.loadsequence; } +void R_SkinFrame_PurgeSkinFrame(skinframe_t *s) +{ + if (s->merged == s->base) + s->merged = NULL; + R_PurgeTexture(s->stain); s->stain = NULL; + R_PurgeTexture(s->merged); s->merged = NULL; + R_PurgeTexture(s->base); s->base = NULL; + R_PurgeTexture(s->pants); s->pants = NULL; + R_PurgeTexture(s->shirt); s->shirt = NULL; + R_PurgeTexture(s->nmap); s->nmap = NULL; + R_PurgeTexture(s->gloss); s->gloss = NULL; + R_PurgeTexture(s->glow); s->glow = NULL; + R_PurgeTexture(s->fog); s->fog = NULL; + R_PurgeTexture(s->reflect); s->reflect = NULL; + s->loadsequence = 0; +} + void R_SkinFrame_Purge(void) { int i; @@ -3198,22 +3155,7 @@ void R_SkinFrame_Purge(void) for (s = r_skinframe.hash[i];s;s = s->next) { if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence) - { - if (s->merged == s->base) - s->merged = NULL; - // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black] - R_PurgeTexture(s->stain );s->stain = NULL; - R_PurgeTexture(s->merged);s->merged = NULL; - R_PurgeTexture(s->base );s->base = NULL; - R_PurgeTexture(s->pants );s->pants = NULL; - R_PurgeTexture(s->shirt );s->shirt = NULL; - R_PurgeTexture(s->nmap );s->nmap = NULL; - R_PurgeTexture(s->gloss );s->gloss = NULL; - R_PurgeTexture(s->glow );s->glow = NULL; - R_PurgeTexture(s->fog );s->fog = NULL; - R_PurgeTexture(s->reflect);s->reflect = NULL; - s->loadsequence = 0; - } + R_SkinFrame_PurgeSkinFrame(s); } } } @@ -3278,20 +3220,7 @@ skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewid dyntexture = CL_GetDynTexture( basename ); if (!add && !dyntexture) return NULL; - if (item->merged == item->base) - item->merged = NULL; - // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black] - R_PurgeTexture(item->stain );item->stain = NULL; - R_PurgeTexture(item->merged);item->merged = NULL; - R_PurgeTexture(item->base );item->base = NULL; - R_PurgeTexture(item->pants );item->pants = NULL; - R_PurgeTexture(item->shirt );item->shirt = NULL; - R_PurgeTexture(item->nmap );item->nmap = NULL; - R_PurgeTexture(item->gloss );item->gloss = NULL; - R_PurgeTexture(item->glow );item->glow = NULL; - R_PurgeTexture(item->fog );item->fog = NULL; - R_PurgeTexture(item->reflect);item->reflect = NULL; - item->loadsequence = 0; + R_SkinFrame_PurgeSkinFrame(item); } else if( item->base == NULL ) { @@ -3400,6 +3329,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole skinframe->fog = NULL; skinframe->reflect = NULL; skinframe->hasalpha = false; + // we could store the q2animname here too if (ddsbase) { @@ -3565,7 +3495,6 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, qboolean sRGB) { int i; - unsigned char *temp1, *temp2; skinframe_t *skinframe; char vabuf[1024]; @@ -3599,11 +3528,11 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co if (r_loadnormalmap && r_shadow_bumpscale_basetexture.value > 0) { - temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); - temp2 = temp1 + width * height * 4; - Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value); - skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL); - Mem_Free(temp1); + unsigned char *a = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); + unsigned char *b = a + width * height * 4; + Image_HeightmapToNormalmap_BGRA(skindata, b, width, height, false, r_shadow_bumpscale_basetexture.value); + skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, b, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL); + Mem_Free(a); } skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, sRGB ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags, -1, NULL); if (textureflags & TEXF_ALPHA) @@ -3678,6 +3607,9 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i featuresmask |= palette_featureflags[skindata[i]]; skinframe->hasalpha = false; + // fence textures + if (name[0] == '{') + skinframe->hasalpha = true; skinframe->qhascolormapping = loadpantsandshirt && (featuresmask & (PALETTEFEATURE_PANTS | PALETTEFEATURE_SHIRT)); skinframe->qgeneratenmap = r_shadow_bumpscale_basetexture.value > 0; skinframe->qgeneratemerged = true; @@ -3720,21 +3652,24 @@ static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboo if (skinframe->qgeneratenmap) { - unsigned char *temp1, *temp2; + unsigned char *a, *b; skinframe->qgeneratenmap = false; - temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); - temp2 = temp1 + width * height * 4; + a = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8); + b = a + width * height * 4; // use either a custom palette or the quake palette - Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete); - Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value); - skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL); - Mem_Free(temp1); + Image_Copy8bitBGRA(skindata, a, width * height, palette_bgra_complete); + Image_HeightmapToNormalmap_BGRA(a, b, width, height, false, r_shadow_bumpscale_basetexture.value); + skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, b, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL); + Mem_Free(a); } if (skinframe->qgenerateglow) { skinframe->qgenerateglow = false; - skinframe->glow = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow + if (skinframe->hasalpha) // fence textures + skinframe->glow = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags | TEXF_ALPHA, -1, palette_bgra_onlyfullbrights_transparent); // glow + else + skinframe->glow = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow } if (colormapped) @@ -3747,7 +3682,10 @@ static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboo else { skinframe->qgeneratemerged = false; - skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete); + if (skinframe->hasalpha) // fence textures + skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags | TEXF_ALPHA, -1, skinframe->glow ? palette_bgra_nofullbrights_transparent : palette_bgra_transparent); + else + skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete); } if (!skinframe->qgeneratemerged && !skinframe->qgeneratebase) @@ -4102,13 +4040,11 @@ static void gl_main_start(void) r_glsl_permutation = NULL; memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash)); Mem_ExpandableArray_NewArray(&r_glsl_permutationarray, r_main_mempool, sizeof(r_glsl_permutation_t), 256); - glslshaderstring = NULL; #ifdef SUPPORTD3D r_hlsl_permutation = NULL; memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash)); Mem_ExpandableArray_NewArray(&r_hlsl_permutationarray, r_main_mempool, sizeof(r_hlsl_permutation_t), 256); #endif - hlslshaderstring = NULL; memset(&r_svbsp, 0, sizeof (r_svbsp)); memset(r_texture_cubemaps, 0, sizeof(r_texture_cubemaps)); @@ -4204,13 +4140,11 @@ static void gl_main_shutdown(void) r_glsl_permutation = NULL; memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash)); Mem_ExpandableArray_FreeArray(&r_glsl_permutationarray); - glslshaderstring = NULL; #ifdef SUPPORTD3D r_hlsl_permutation = NULL; memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash)); Mem_ExpandableArray_FreeArray(&r_hlsl_permutationarray); #endif - hlslshaderstring = NULL; } static void gl_main_newmap(void) @@ -4243,6 +4177,7 @@ void GL_Main_Init(void) { int i; r_main_mempool = Mem_AllocPool("Renderer", 0, NULL); + R_InitShaderModeInfo(); Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed"); Cmd_AddCommand("r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl"); @@ -4286,6 +4221,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_transparent_useplanardistance); Cvar_RegisterVariable(&r_showoverdraw); Cvar_RegisterVariable(&r_showbboxes); + Cvar_RegisterVariable(&r_showbboxes_client); Cvar_RegisterVariable(&r_showsurfaces); Cvar_RegisterVariable(&r_showtris); Cvar_RegisterVariable(&r_shownormals); @@ -4300,10 +4236,12 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_draw2d); Cvar_RegisterVariable(&r_drawworld); Cvar_RegisterVariable(&r_cullentities_trace); + Cvar_RegisterVariable(&r_cullentities_trace_entityocclusion); Cvar_RegisterVariable(&r_cullentities_trace_samples); Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples); Cvar_RegisterVariable(&r_cullentities_trace_enlarge); Cvar_RegisterVariable(&r_cullentities_trace_delay); + Cvar_RegisterVariable(&r_cullentities_trace_eyejitter); Cvar_RegisterVariable(&r_sortentities); Cvar_RegisterVariable(&r_drawviewmodel); Cvar_RegisterVariable(&r_drawexteriormodel); @@ -4313,6 +4251,11 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_dynamic); Cvar_RegisterVariable(&r_fakelight); Cvar_RegisterVariable(&r_fakelight_intensity); + Cvar_RegisterVariable(&r_fullbright_directed); + Cvar_RegisterVariable(&r_fullbright_directed_ambient); + Cvar_RegisterVariable(&r_fullbright_directed_diffuse); + Cvar_RegisterVariable(&r_fullbright_directed_pitch); + Cvar_RegisterVariable(&r_fullbright_directed_pitch_relative); Cvar_RegisterVariable(&r_fullbright); Cvar_RegisterVariable(&r_shadows); Cvar_RegisterVariable(&r_shadows_darken); @@ -4371,6 +4314,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_celoutlines); Cvar_RegisterVariable(&r_water); + Cvar_RegisterVariable(&r_water_cameraentitiesonly); Cvar_RegisterVariable(&r_water_resolutionmultiplier); Cvar_RegisterVariable(&r_water_clippingplanebias); Cvar_RegisterVariable(&r_water_refractdistort); @@ -4658,7 +4602,13 @@ void *R_FrameData_Alloc(size_t size) while (!r_framedata_mem || r_framedata_mem->current + size > r_framedata_mem->size) { // emergency - we ran out of space, allocate more memory - newvalue = bound(0.25f, r_framedatasize.value * 2.0f, 256.0f); + // note: this has no upper-bound, we'll fail to allocate memory eventually and just die + newvalue = r_framedatasize.value * 2.0f; + // upper bound based on architecture - if we try to allocate more than this we could overflow, better to loop until we error out on allocation failure + if (sizeof(size_t) >= 8) + newvalue = bound(0.25f, newvalue, (float)(1ll << 42)); + else + newvalue = bound(0.25f, newvalue, (float)(1 << 10)); // this might not be a growing it, but we'll allocate another buffer every time Cvar_SetValueQuick(&r_framedatasize, newvalue); R_FrameData_Resize(true); @@ -4832,7 +4782,7 @@ r_meshbuffer_t *R_BufferData_Store(size_t datasize, const void *data, r_bufferda Sys_Error("R_BufferData_Store: failed to create a new buffer of sufficient size\n"); mem = r_bufferdata_buffer[r_bufferdata_cycle][type]; - offset = mem->current; + offset = (int)mem->current; mem->current += padsize; // upload the data to the buffer at the chosen offset @@ -5047,155 +4997,88 @@ void R_AnimCache_CacheVisibleEntities(void) //================================================================================== -extern cvar_t r_overheadsprites_pushback; - -static void R_View_UpdateEntityLighting (void) -{ - int i; - entity_render_t *ent; - vec3_t tempdiffusenormal, avg; - vec_t f, fa, fd, fdd; - qboolean skipunseen = r_shadows.integer != 1; //|| R_Shadow_ShadowMappingEnabled(); - - for (i = 0;i < r_refdef.scene.numentities;i++) - { - ent = r_refdef.scene.entities[i]; - - // skip unseen models - if ((!r_refdef.viewcache.entityvisible[i] && skipunseen)) - continue; - - // skip bsp models - if (ent->model && ent->model == cl.worldmodel) - { - // TODO: use modellight for r_ambient settings on world? - VectorSet(ent->modellight_ambient, 0, 0, 0); - VectorSet(ent->modellight_diffuse, 0, 0, 0); - VectorSet(ent->modellight_lightdir, 0, 0, 1); - continue; - } - - if (ent->flags & RENDER_CUSTOMIZEDMODELLIGHT) - { - // aleady updated by CSQC - // TODO: force modellight on BSP models in this case? - VectorCopy(ent->modellight_lightdir, tempdiffusenormal); - } - else - { - // fetch the lighting from the worldmodel data - VectorClear(ent->modellight_ambient); - VectorClear(ent->modellight_diffuse); - VectorClear(tempdiffusenormal); - if (ent->flags & RENDER_LIGHT) - { - vec3_t org; - Matrix4x4_OriginFromMatrix(&ent->matrix, org); - - // complete lightning for lit sprites - // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)? - if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT)) - { - if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites - org[2] = org[2] + r_overheadsprites_pushback.value; - R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); - } - else - R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP); - - if(ent->flags & RENDER_EQUALIZE) - { - // first fix up ambient lighting... - if(r_equalize_entities_minambient.value > 0) - { - fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2]; - if(fd > 0) - { - fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]); - if(fa < r_equalize_entities_minambient.value * fd) - { - // solve: - // fa'/fd' = minambient - // fa'+0.25*fd' = fa+0.25*fd - // ... - // fa' = fd' * minambient - // fd'*(0.25+minambient) = fa+0.25*fd - // ... - // fd' = (fa+0.25*fd) * 1 / (0.25+minambient) - // fa' = (fa+0.25*fd) * minambient / (0.25+minambient) - // ... - fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value); - f = fdd / fd; // f>0 because all this is additive; f<1 because fddmodellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient); - VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse); - } - } - } - - if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0) - { - fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]; - fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2]; - f = fa + 0.25 * fd; - if(f > 0) - { - // adjust brightness and saturation to target - avg[0] = avg[1] = avg[2] = fa / f; - VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient); - avg[0] = avg[1] = avg[2] = fd / f; - VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse); - } - } - } - } - else // highly rare - VectorSet(ent->modellight_ambient, 1, 1, 1); - } - - // move the light direction into modelspace coordinates for lighting code - Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir); - if(VectorLength2(ent->modellight_lightdir) == 0) - VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here - VectorNormalize(ent->modellight_lightdir); - } -} - -#define MAX_LINEOFSIGHTTRACES 64 - -static qboolean R_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs) +qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs) { int i; + vec3_t eyemins, eyemaxs; vec3_t boxmins, boxmaxs; vec3_t start; vec3_t end; dp_model_t *model = r_refdef.scene.worldmodel; + static vec3_t positions[] = { + { 0.5f, 0.5f, 0.5f }, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f }, + { 1.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f }, + { 1.0f, 1.0f, 1.0f }, + }; + + // sample count can be set to -1 to skip this logic, for flicker-prone objects + if (numsamples < 0) + return true; + + // view origin is not used for culling in portal/reflection/refraction renders or isometric views + if (r_refdef.view.useclipplane || !r_refdef.view.useperspective || r_trippy.integer) + return true; - if (!model || !model->brush.TraceLineOfSight) + if (!r_cullentities_trace_entityocclusion.integer && (!model || !model->brush.TraceLineOfSight)) return true; + // expand the eye box a little + eyemins[0] = eye[0] - eyejitter; + eyemaxs[0] = eye[0] + eyejitter; + eyemins[1] = eye[1] - eyejitter; + eyemaxs[1] = eye[1] + eyejitter; + eyemins[2] = eye[2] - eyejitter; + eyemaxs[2] = eye[2] + eyejitter; // expand the box a little - boxmins[0] = (enlarge+1) * entboxmins[0] - enlarge * entboxmaxs[0]; - boxmaxs[0] = (enlarge+1) * entboxmaxs[0] - enlarge * entboxmins[0]; - boxmins[1] = (enlarge+1) * entboxmins[1] - enlarge * entboxmaxs[1]; - boxmaxs[1] = (enlarge+1) * entboxmaxs[1] - enlarge * entboxmins[1]; - boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2]; - boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2]; - - // return true if eye is inside enlarged box - if (BoxesOverlap(boxmins, boxmaxs, eye, eye)) + boxmins[0] = (entboxenlarge + 1) * entboxmins[0] - entboxenlarge * entboxmaxs[0]; + boxmaxs[0] = (entboxenlarge + 1) * entboxmaxs[0] - entboxenlarge * entboxmins[0]; + boxmins[1] = (entboxenlarge + 1) * entboxmins[1] - entboxenlarge * entboxmaxs[1]; + boxmaxs[1] = (entboxenlarge + 1) * entboxmaxs[1] - entboxenlarge * entboxmins[1]; + boxmins[2] = (entboxenlarge + 1) * entboxmins[2] - entboxenlarge * entboxmaxs[2]; + boxmaxs[2] = (entboxenlarge + 1) * entboxmaxs[2] - entboxenlarge * entboxmins[2]; + + // return true if eye overlaps enlarged box + if (BoxesOverlap(boxmins, boxmaxs, eyemins, eyemaxs)) return true; - // try center - VectorCopy(eye, start); - VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, end); - if (model->brush.TraceLineOfSight(model, start, end)) + // try specific positions in the box first - note that these can be cached + if (r_cullentities_trace_entityocclusion.integer) + { + for (i = 0; i < sizeof(positions) / sizeof(positions[0]); i++) + { + VectorCopy(eye, start); + end[0] = boxmins[0] + (boxmaxs[0] - boxmins[0]) * positions[i][0]; + end[1] = boxmins[1] + (boxmaxs[1] - boxmins[1]) * positions[i][1]; + end[2] = boxmins[2] + (boxmaxs[2] - boxmins[2]) * positions[i][2]; + //trace_t trace = CL_TraceLine(start, end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, 0.0f, true, false, NULL, true, true); + trace_t trace = CL_Cache_TraceLineSurfaces(start, end, MOVE_NORMAL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT); + // not picky - if the trace ended anywhere in the box we're good + if (BoxesOverlap(trace.endpos, trace.endpos, boxmins, boxmaxs)) + return true; + } + } + else if (model->brush.TraceLineOfSight(model, start, end, boxmins, boxmaxs)) return true; // try various random positions - for (i = 0;i < numsamples;i++) + for (i = 0; i < numsamples; i++) { + VectorSet(start, lhrandom(eyemins[0], eyemaxs[0]), lhrandom(eyemins[1], eyemaxs[1]), lhrandom(eyemins[2], eyemaxs[2])); VectorSet(end, lhrandom(boxmins[0], boxmaxs[0]), lhrandom(boxmins[1], boxmaxs[1]), lhrandom(boxmins[2], boxmaxs[2])); - if (model->brush.TraceLineOfSight(model, start, end)) + if (r_cullentities_trace_entityocclusion.integer) + { + trace_t trace = CL_Cache_TraceLineSurfaces(start, end, MOVE_NORMAL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT); + // not picky - if the trace ended anywhere in the box we're good + if (BoxesOverlap(trace.endpos, trace.endpos, boxmins, boxmaxs)) + return true; + } + else if (model->brush.TraceLineOfSight(model, start, end, boxmins, boxmaxs)) return true; } @@ -5244,22 +5127,19 @@ static void R_View_UpdateEntityVisible (void) r_refdef.viewcache.entityvisible[i] = true; } } - if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane && !r_trippy.integer) - // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling + if (r_cullentities_trace.integer) { for (i = 0;i < r_refdef.scene.numentities;i++) { if (!r_refdef.viewcache.entityvisible[i]) continue; ent = r_refdef.scene.entities[i]; - if(!(ent->flags & (RENDER_VIEWMODEL | RENDER_WORLDOBJECT | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*'))) + if (!(ent->flags & (RENDER_VIEWMODEL | RENDER_WORLDOBJECT | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*'))) { - samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer; - if (samples < 0) - continue; // temp entities do pvs only - if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs)) + samples = ent->last_trace_visibility == 0 ? r_cullentities_trace_tempentitysamples.integer : r_cullentities_trace_samples.integer; + if (R_CanSeeBox(samples, r_cullentities_trace_eyejitter.value, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs)) ent->last_trace_visibility = realtime; - if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value) + if (ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value) r_refdef.viewcache.entityvisible[i] = 0; } } @@ -5383,7 +5263,7 @@ void R_HDR_UpdateIrisAdaptation(const vec3_t point) p[0] = point[0] + irisvecs[c][0] * r_hdr_irisadaptation_radius.value; p[1] = point[1] + irisvecs[c][1] * r_hdr_irisadaptation_radius.value; p[2] = point[2] + irisvecs[c][2] * r_hdr_irisadaptation_radius.value; - R_CompleteLightPoint(ambient, diffuse, diffusenormal, p, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); + R_CompleteLightPoint(ambient, diffuse, diffusenormal, p, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity); d = DotProduct(forward, diffusenormal); brightness += VectorLength(ambient); if (d > 0) @@ -5614,7 +5494,6 @@ static void R_View_UpdateWithScissor(const int *myscissor) R_View_SetFrustum(myscissor); R_View_WorldVisibility(r_refdef.view.useclipplane); R_View_UpdateEntityVisible(); - R_View_UpdateEntityLighting(); } static void R_View_Update(void) @@ -5623,7 +5502,6 @@ static void R_View_Update(void) R_View_SetFrustum(NULL); R_View_WorldVisibility(r_refdef.view.useclipplane); R_View_UpdateEntityVisible(); - R_View_UpdateEntityLighting(); } float viewscalefpsadjusted = 1.0f; @@ -5823,7 +5701,7 @@ void R_RenderView_UpdateViewVectors(void) Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin); VectorNegate(r_refdef.view.left, r_refdef.view.right); // make an inverted copy of the view matrix for tracking sprites - Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix); + Matrix4x4_Invert_Full(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix); } void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); @@ -5997,25 +5875,33 @@ void R_Water_AddWaterPlane(msurface_t *surface, int entno) } } planeindex = bestplaneindex; - p = r_fb.water.waterplanes + planeindex; // if this surface does not fit any known plane rendered this frame, add one - if ((planeindex < 0 || bestplanescore > 0.001f) && r_fb.water.numwaterplanes < r_fb.water.maxwaterplanes) + if (planeindex < 0 || bestplanescore > 0.001f) { - // store the new plane - planeindex = r_fb.water.numwaterplanes++; - p = r_fb.water.waterplanes + planeindex; - p->plane = plane; - // clear materialflags and pvs - p->materialflags = 0; - p->pvsvalid = false; - p->camera_entity = t->camera_entity; - VectorCopy(mins, p->mins); - VectorCopy(maxs, p->maxs); + if (r_fb.water.numwaterplanes < r_fb.water.maxwaterplanes) + { + // store the new plane + planeindex = r_fb.water.numwaterplanes++; + p = r_fb.water.waterplanes + planeindex; + p->plane = plane; + // clear materialflags and pvs + p->materialflags = 0; + p->pvsvalid = false; + p->camera_entity = t->camera_entity; + VectorCopy(mins, p->mins); + VectorCopy(maxs, p->maxs); + } + else + { + // We're totally screwed. + return; + } } else { // merge mins/maxs when we're adding this surface to the plane + p = r_fb.water.waterplanes + planeindex; p->mins[0] = min(p->mins[0], mins[0]); p->mins[1] = min(p->mins[1], mins[1]); p->mins[2] = min(p->mins[2], mins[2]); @@ -6028,7 +5914,7 @@ void R_Water_AddWaterPlane(msurface_t *surface, int entno) if(!(p->materialflags & MATERIALFLAG_CAMERA)) { // merge this surface's PVS into the waterplane - if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS + if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS && r_refdef.scene.worldmodel->brush.PointInLeaf && r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, center)->clusterindex >= 0) { r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, center, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid); @@ -6080,6 +5966,8 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t // make sure enough textures are allocated for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++) { + if (r_water_cameraentitiesonly.value != 0 && !p->camera_entity) + continue; if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) { if (!p->texture_refraction) @@ -6135,6 +6023,8 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t r_fb.water.renderingscene = true; for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++) { + if (r_water_cameraentitiesonly.value != 0 && !p->camera_entity) + continue; if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION)) { r_refdef.view = myview; @@ -6412,7 +6302,7 @@ static void R_Bloom_StartFrame(void) Cvar_SetValueQuick(&r_damageblur, 0); } - if (!(r_glsl_postprocess.integer || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial)) + if (!((r_glsl_postprocess.integer || r_fxaa.integer) || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial)) && !r_bloom.integer && (R_Stereo_Active() || (r_motionblur.value <= 0 && r_damageblur.value <= 0)) && !useviewfbo @@ -6576,6 +6466,7 @@ static void R_Bloom_MakeTexture(void) r_fb.bloomindex = 0; R_Mesh_SetRenderTargets(r_fb.bloomfbo[r_fb.bloomindex], NULL, r_fb.bloomtexture[r_fb.bloomindex], NULL, NULL, NULL); R_SetViewport(&r_fb.bloomviewport); + GL_CullFace(GL_NONE); GL_DepthTest(false); GL_BlendFunc(GL_ONE, GL_ZERO); GL_Color(colorscale, colorscale, colorscale, 1); @@ -6699,7 +6590,7 @@ static void R_Bloom_MakeTexture(void) static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) { - unsigned int permutation; + dpuint64 permutation; float uservecs[4][4]; R_EntityMatrix(&identitymatrix); @@ -7018,7 +6909,7 @@ void R_UpdateVariables(void) { R_Textures_Frame(); - r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f); + r_refdef.scene.ambientintensity = r_ambient.value * (1.0f / 64.0f); r_refdef.farclip = r_farclip_base.value; if (r_refdef.scene.worldmodel) @@ -7036,14 +6927,14 @@ void R_UpdateVariables(void) r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil; r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer; r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil; - r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1; + r_refdef.scene.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1; if (FAKELIGHT_ENABLED) { - r_refdef.lightmapintensity *= r_fakelight_intensity.value; + r_refdef.scene.lightmapintensity *= r_fakelight_intensity.value; } else if (r_refdef.scene.worldmodel) { - r_refdef.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale; + r_refdef.scene.lightmapintensity *= r_refdef.scene.worldmodel->lightmapscale; } if (r_showsurfaces.integer) { @@ -7051,7 +6942,7 @@ void R_UpdateVariables(void) r_refdef.scene.rtworldshadows = false; r_refdef.scene.rtdlight = false; r_refdef.scene.rtdlightshadows = false; - r_refdef.lightmapintensity = 0; + r_refdef.scene.lightmapintensity = 0; } r_gpuskeletal = false; @@ -7188,7 +7079,7 @@ void R_RenderView(void) if (r_timereport_active) R_TimeReport("start"); r_textureframe++; // used only by R_GetCurrentTexture - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity if(R_CompileShader_CheckStaticParms()) R_GLSL_Restart_f(); @@ -7331,10 +7222,11 @@ void R_RenderWaterPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortex extern cvar_t cl_locs_show; static void R_DrawLocs(void); -static void R_DrawEntityBBoxes(void); +static void R_DrawEntityBBoxes(prvm_prog_t *prog); static void R_DrawModelDecals(void); extern cvar_t cl_decals_newsystem; extern qboolean r_shadow_usingdeferredprepass; +extern int r_shadow_shadowmapatlas_modelshadows_size; void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) { qboolean shadowmapping = false; @@ -7386,18 +7278,25 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) } } + R_Shadow_PrepareModelShadows(); R_Shadow_PrepareLights(fbo, depthtexture, colortexture); - if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0) - R_Shadow_PrepareModelShadows(); if (r_timereport_active) R_TimeReport("preparelights"); - if (R_Shadow_ShadowMappingEnabled()) - shadowmapping = true; + // render all the shadowmaps that will be used for this view + shadowmapping = R_Shadow_ShadowMappingEnabled(); + if (shadowmapping || r_shadow_shadowmapatlas_modelshadows_size) + { + R_Shadow_DrawShadowMaps(); + if (r_timereport_active) + R_TimeReport("shadowmaps"); + } + // render prepass deferred lighting if r_shadow_deferred is on, this produces light buffers that will be sampled in forward pass if (r_shadow_usingdeferredprepass) R_Shadow_DrawPrepass(); + // now we begin the forward pass of the view render if (r_depthfirst.integer >= 1 && cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDepth) { r_refdef.scene.worldmodel->DrawDepth(r_refdef.scene.worldentity); @@ -7411,16 +7310,6 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) R_TimeReport("modeldepth"); } - if (r_shadows.integer >= 2 && shadowmapping && r_refdef.lightmapintensity > 0) - { - R_ResetViewRendering3D(fbo, depthtexture, colortexture); - R_DrawModelShadowMaps(fbo, depthtexture, colortexture); - R_ResetViewRendering3D(fbo, depthtexture, colortexture); - // don't let sound skip if going slow - if (r_refdef.scene.extraupdate) - S_ExtraUpdate (); - } - if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->Draw) { r_refdef.scene.worldmodel->Draw(r_refdef.scene.worldentity); @@ -7440,10 +7329,10 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) if (r_refdef.scene.extraupdate) S_ExtraUpdate (); - if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0) + if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) { R_ResetViewRendering3D(fbo, depthtexture, colortexture); - R_DrawModelShadows(fbo, depthtexture, colortexture); + R_Shadow_DrawModelShadows(); R_ResetViewRendering3D(fbo, depthtexture, colortexture); // don't let sound skip if going slow if (r_refdef.scene.extraupdate) @@ -7461,10 +7350,10 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) if (r_refdef.scene.extraupdate) S_ExtraUpdate (); - if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0) + if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) { R_ResetViewRendering3D(fbo, depthtexture, colortexture); - R_DrawModelShadows(fbo, depthtexture, colortexture); + R_Shadow_DrawModelShadows(); R_ResetViewRendering3D(fbo, depthtexture, colortexture); // don't let sound skip if going slow if (r_refdef.scene.extraupdate) @@ -7493,10 +7382,6 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) R_DrawExplosions(); if (r_timereport_active) R_TimeReport("explosions"); - - R_DrawLightningBeams(); - if (r_timereport_active) - R_TimeReport("lightning"); } if (cl.csqc_loaded) @@ -7518,11 +7403,17 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) R_TimeReport("portals"); } + if (r_showbboxes_client.value > 0) + { + R_DrawEntityBBoxes(CLVM_prog); + if (r_timereport_active) + R_TimeReport("clbboxes"); + } if (r_showbboxes.value > 0) { - R_DrawEntityBBoxes(); + R_DrawEntityBBoxes(SVVM_prog); if (r_timereport_active) - R_TimeReport("bboxes"); + R_TimeReport("svbboxes"); } } @@ -7586,31 +7477,66 @@ static const unsigned short bboxelements[36] = 1, 0, 2, 1, 2, 3, }; +#define BBOXEDGES 13 +static const float bboxedges[BBOXEDGES][6] = +{ + // whole box + { 0, 0, 0, 1, 1, 1 }, + // bottom edges + { 0, 0, 0, 0, 1, 0 }, + { 0, 0, 0, 1, 0, 0 }, + { 0, 1, 0, 1, 1, 0 }, + { 1, 0, 0, 1, 1, 0 }, + // top edges + { 0, 0, 1, 0, 1, 1 }, + { 0, 0, 1, 1, 0, 1 }, + { 0, 1, 1, 1, 1, 1 }, + { 1, 0, 1, 1, 1, 1 }, + // vertical edges + { 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 1, 0, 1 }, + { 0, 1, 0, 0, 1, 1 }, + { 1, 1, 0, 1, 1, 1 }, +}; + static void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca) { - int i; - float *v, *c, f1, f2, vertex3f[8*3], color4f[8*4]; + int numvertices = BBOXEDGES * 8; + float vertex3f[BBOXEDGES * 8 * 3], color4f[BBOXEDGES * 8 * 4]; + int numtriangles = BBOXEDGES * 12; + unsigned short elements[BBOXEDGES * 36]; + int i, edge; + float *v, *c, f1, f2, edgemins[3], edgemaxs[3]; - RSurf_ActiveWorldEntity(); + RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); GL_DepthRange(0, 1); GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset); -// R_Mesh_ResetTextureState(); - vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2]; // - vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2]; - vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2]; - vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2]; - vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2]; - vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2]; - vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2]; - vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2]; - R_FillColors(color4f, 8, cr, cg, cb, ca); + for (edge = 0; edge < BBOXEDGES; edge++) + { + for (i = 0; i < 3; i++) + { + edgemins[i] = mins[i] + (maxs[i] - mins[i]) * bboxedges[edge][i] - 0.25f; + edgemaxs[i] = mins[i] + (maxs[i] - mins[i]) * bboxedges[edge][3 + i] + 0.25f; + } + vertex3f[edge * 24 + 0] = edgemins[0]; vertex3f[edge * 24 + 1] = edgemins[1]; vertex3f[edge * 24 + 2] = edgemins[2]; + vertex3f[edge * 24 + 3] = edgemaxs[0]; vertex3f[edge * 24 + 4] = edgemins[1]; vertex3f[edge * 24 + 5] = edgemins[2]; + vertex3f[edge * 24 + 6] = edgemins[0]; vertex3f[edge * 24 + 7] = edgemaxs[1]; vertex3f[edge * 24 + 8] = edgemins[2]; + vertex3f[edge * 24 + 9] = edgemaxs[0]; vertex3f[edge * 24 + 10] = edgemaxs[1]; vertex3f[edge * 24 + 11] = edgemins[2]; + vertex3f[edge * 24 + 12] = edgemins[0]; vertex3f[edge * 24 + 13] = edgemins[1]; vertex3f[edge * 24 + 14] = edgemaxs[2]; + vertex3f[edge * 24 + 15] = edgemaxs[0]; vertex3f[edge * 24 + 16] = edgemins[1]; vertex3f[edge * 24 + 17] = edgemaxs[2]; + vertex3f[edge * 24 + 18] = edgemins[0]; vertex3f[edge * 24 + 19] = edgemaxs[1]; vertex3f[edge * 24 + 20] = edgemaxs[2]; + vertex3f[edge * 24 + 21] = edgemaxs[0]; vertex3f[edge * 24 + 22] = edgemaxs[1]; vertex3f[edge * 24 + 23] = edgemaxs[2]; + for (i = 0; i < 36; i++) + elements[edge * 36 + i] = edge * 8 + bboxelements[i]; + } + R_FillColors(color4f, numvertices, cr, cg, cb, ca); if (r_refdef.fogenabled) { - for (i = 0, v = vertex3f, c = color4f;i < 8;i++, v += 3, c += 4) + for (i = 0, v = vertex3f, c = color4f; i < numvertices; i++, v += 3, c += 4) { f1 = RSurf_FogVertex(v); f2 = 1 - f1; @@ -7619,23 +7545,20 @@ static void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float c c[2] = c[2] * f1 + r_refdef.fogcolor[2] * f2; } } - R_Mesh_PrepareVertices_Generic_Arrays(8, vertex3f, color4f, NULL); + R_Mesh_PrepareVertices_Generic_Arrays(numvertices, vertex3f, color4f, NULL); R_Mesh_ResetTextureState(); R_SetupShader_Generic_NoTexture(false, false); - R_Mesh_Draw(0, 8, 0, 12, NULL, NULL, 0, bboxelements, NULL, 0); + R_Mesh_Draw(0, numvertices, 0, numtriangles, NULL, NULL, 0, elements, NULL, 0); } static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) { - prvm_prog_t *prog = SVVM_prog; + // hacky overloading of the parameters + prvm_prog_t *prog = (prvm_prog_t *)rtlight; int i; float color[4]; prvm_edict_t *edict; - // this function draws bounding boxes of server entities - if (!sv.active) - return; - GL_CullFace(GL_NONE); R_SetupShader_Generic_NoTexture(false, false); @@ -7652,37 +7575,37 @@ static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtligh case SOLID_CORPSE: Vector4Set(color, 1, 0.5, 0, 0.05);break; default: Vector4Set(color, 0, 0, 0, 0.50);break; } - color[3] *= r_showbboxes.value; + if (prog == CLVM_prog) + color[3] *= r_showbboxes_client.value; + else + color[3] *= r_showbboxes.value; color[3] = bound(0, color[3], 1); GL_DepthTest(!r_showdisabledepthtest.integer); - GL_CullFace(r_refdef.view.cullface_front); R_DrawBBoxMesh(edict->priv.server->areamins, edict->priv.server->areamaxs, color[0], color[1], color[2], color[3]); } } -static void R_DrawEntityBBoxes(void) +static void R_DrawEntityBBoxes(prvm_prog_t *prog) { int i; prvm_edict_t *edict; vec3_t center; - prvm_prog_t *prog = SVVM_prog; - // this function draws bounding boxes of server entities - if (!sv.active) + if (prog == NULL) return; - for (i = 0;i < prog->num_edicts;i++) + for (i = 0; i < prog->num_edicts; i++) { edict = PRVM_EDICT_NUM(i); if (edict->priv.server->free) continue; // exclude the following for now, as they don't live in world coordinate space and can't be solid: - if(PRVM_serveredictedict(edict, tag_entity) != 0) + if (PRVM_serveredictedict(edict, tag_entity) != 0) continue; - if(PRVM_serveredictedict(edict, viewmodelforclient) != 0) + if (PRVM_serveredictedict(edict, viewmodelforclient) != 0) continue; VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center); - R_MeshQueue_AddTransparent(TRANSPARENTSORT_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 *)prog); } } @@ -7746,7 +7669,7 @@ static void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); GL_DepthMask(false); } - else if (rsurface.colormod[3] < 1) + else if (ent->alpha < 1) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); @@ -7763,10 +7686,10 @@ static void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); for (i = 0, c = color4f;i < 6;i++, c += 4) { - c[0] *= rsurface.colormod[0]; - c[1] *= rsurface.colormod[1]; - c[2] *= rsurface.colormod[2]; - c[3] *= rsurface.colormod[3]; + c[0] *= ent->render_fullbright[0] * r_refdef.view.colorscale; + c[1] *= ent->render_fullbright[1] * r_refdef.view.colorscale; + c[2] *= ent->render_fullbright[2] * r_refdef.view.colorscale; + c[3] *= ent->alpha; } if (r_refdef.fogenabled) { @@ -8109,10 +8032,11 @@ static void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname) texture_t *R_GetCurrentTexture(texture_t *t) { - int i; + int i, q; const entity_render_t *ent = rsurface.entity; dp_model_t *model = ent->model; // when calling this, ent must not be NULL q3shaderinfo_layer_tcmod_t *tcmod; + float specularscale = 0.0f; if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent && !rsurface.forcecurrenttextureupdate) return t->currentframe; @@ -8143,7 +8067,9 @@ texture_t *R_GetCurrentTexture(texture_t *t) { // use an alternate animation if the entity's frame is not 0, // and only if the texture has an alternate animation - if (rsurface.ent_alttextures && t->anim_total[1]) + if (t->animated == 2) // q2bsp + t = t->anim_frames[0][ent->framegroupblend[0].frame % t->anim_total[0]]; + else if (rsurface.ent_alttextures && t->anim_total[1]) t = t->anim_frames[1][(t->anim_total[1] >= 2) ? ((int)(rsurface.shadertime * 5.0f) % t->anim_total[1]) : 0]; else t = t->anim_frames[0][(t->anim_total[0] >= 2) ? ((int)(rsurface.shadertime * 5.0f) % t->anim_total[0]) : 0]; @@ -8165,36 +8091,124 @@ texture_t *R_GetCurrentTexture(texture_t *t) if (strcmp(r_qwskincache[i].name, cl.scores[i].qw_skin)) R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin); t->currentskinframe = r_qwskincache[i].skinframe; - if (t->currentskinframe == NULL) - t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)]; + if (t->materialshaderpass && t->currentskinframe == NULL) + t->currentskinframe = t->materialshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->materialshaderpass->framerate, t->materialshaderpass->numframes)]; } - else if (t->numskinframes >= 2) - t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)]; - if (t->backgroundnumskinframes >= 2) - t->backgroundcurrentskinframe = t->backgroundskinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundskinframerate, t->backgroundnumskinframes)]; + else if (t->materialshaderpass && t->materialshaderpass->numframes >= 2) + t->currentskinframe = t->materialshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->materialshaderpass->framerate, t->materialshaderpass->numframes)]; + if (t->backgroundshaderpass && t->backgroundshaderpass->numframes >= 2) + t->backgroundcurrentskinframe = t->backgroundshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundshaderpass->framerate, t->backgroundshaderpass->numframes)]; t->currentmaterialflags = t->basematerialflags; - t->currentalpha = rsurface.colormod[3]; + t->currentalpha = rsurface.entity->alpha * t->basealpha; if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer || r_trippy.integer)) t->currentalpha *= r_wateralpha.value; if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // we apply wateralpha later if(!r_fb.water.enabled || r_refdef.view.isoverlay) t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA); - if (!(rsurface.ent_flags & RENDER_LIGHT)) - t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT; + + // decide on which type of lighting to use for this surface + if (rsurface.entity->render_modellight_forced) + t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT; + if (rsurface.entity->render_rtlight_disabled) + t->currentmaterialflags |= MATERIALFLAG_NORTLIGHT; + if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND && !(R_BlendFuncFlags(t->customblendfunc[0], t->customblendfunc[1]) & BLENDFUNC_ALLOWS_COLORMOD)) + { + // some CUSTOMBLEND blendfuncs are too weird for anything but fullbright rendering, and even then we have to ignore colormod and view colorscale + t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_NORTLIGHT; + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->glowmod[q]; + t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_ambient[q] = 1; + t->render_modellight_diffuse[q] = 0; + t->render_modellight_specular[q] = 0; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = 0; + t->render_rtlight_specular[q] = 0; + } + } + else if ((t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) || !(rsurface.ent_flags & RENDER_LIGHT)) + { + // fullbright is basically MATERIALFLAG_MODELLIGHT but with ambient locked to 1,1,1 and no shading + t->currentmaterialflags = t->currentmaterialflags | MATERIALFLAG_NORTLIGHT | MATERIALFLAG_MODELLIGHT; + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_ambient[q] = rsurface.entity->render_fullbright[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_diffuse[q] = 0; + t->render_modellight_specular[q] = 0; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = 0; + t->render_rtlight_specular[q] = 0; + } + } else if (FAKELIGHT_ENABLED) { // no modellight if using fakelight for the map + t->currentmaterialflags = (t->currentmaterialflags | MATERIALFLAG_NORTLIGHT) & ~(MATERIALFLAG_MODELLIGHT); + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q]; + t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale; + t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale; + t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = 0; + t->render_rtlight_specular[q] = 0; + } + } + else if ((rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT)) || rsurface.modeltexcoordlightmap2f == NULL) + { + // ambient + single direction light (modellight) + t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT; + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q]; + t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale; + t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale; + t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale; + t->render_lightmap_ambient[q] = 0; + t->render_lightmap_diffuse[q] = 0; + t->render_lightmap_specular[q] = 0; + t->render_rtlight_diffuse[q] = rsurface.entity->render_rtlight_diffuse[q] * r_refdef.view.colorscale; + t->render_rtlight_specular[q] = rsurface.entity->render_rtlight_specular[q] * r_refdef.view.colorscale; + } } - else if ((rsurface.modeltexcoordlightmap2f == NULL || (rsurface.ent_flags & (RENDER_DYNAMICMODELLIGHT | RENDER_CUSTOMIZEDMODELLIGHT))) && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) + else { - // pick a model lighting mode - if (VectorLength2(rsurface.modellight_diffuse) >= (1.0f / 256.0f)) - t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL; - else - t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT; + // lightmap - 2x diffuse and specular brightness because bsp files have 0-2 colors as 0-1 + for (q = 0; q < 3; q++) + { + t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; + t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q] * r_refdef.view.colorscale; + t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale; + t->render_modellight_diffuse[q] = 0; + t->render_modellight_specular[q] = 0; + t->render_lightmap_ambient[q] = rsurface.entity->render_lightmap_ambient[q] * r_refdef.view.colorscale; + t->render_lightmap_diffuse[q] = rsurface.entity->render_lightmap_diffuse[q] * 2 * r_refdef.view.colorscale; + t->render_lightmap_specular[q] = rsurface.entity->render_lightmap_specular[q] * 2 * r_refdef.view.colorscale; + t->render_rtlight_diffuse[q] = rsurface.entity->render_rtlight_diffuse[q] * r_refdef.view.colorscale; + t->render_rtlight_specular[q] = rsurface.entity->render_rtlight_specular[q] * r_refdef.view.colorscale; + } + } + + for (q = 0; q < 3; q++) + { + t->render_colormap_pants[q] = rsurface.entity->colormap_pantscolor[q]; + t->render_colormap_shirt[q] = rsurface.entity->colormap_shirtcolor[q]; } + if (rsurface.ent_flags & RENDER_ADDITIVE) t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; else if (t->currentalpha < 1) @@ -8206,7 +8220,7 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->currentmaterialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE; if (rsurface.ent_flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL)) t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE; - if (t->backgroundnumskinframes) + if (t->backgroundshaderpass) t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND; if (t->currentmaterialflags & MATERIALFLAG_BLENDED) { @@ -8235,12 +8249,11 @@ texture_t *R_GetCurrentTexture(texture_t *t) Matrix4x4_CreateIdentity(&t->currentbackgroundtexmatrix); } - for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) - R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags); - for (i = 0, tcmod = t->backgroundtcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) - R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags); + if (t->materialshaderpass) + for (i = 0, tcmod = t->materialshaderpass->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) + R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags); - t->colormapping = VectorLength2(rsurface.colormap_pantscolor) + VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f); + t->colormapping = VectorLength2(t->render_colormap_pants) + VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f); if (t->currentskinframe->qpixels) R_SkinFrame_GenerateTexturesFromQPixels(t->currentskinframe, t->colormapping); t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base; @@ -8255,8 +8268,10 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->glowtexture = t->currentskinframe->glow; t->fogtexture = t->currentskinframe->fog; t->reflectmasktexture = t->currentskinframe->reflect; - if (t->backgroundnumskinframes) + if (t->backgroundshaderpass) { + for (i = 0, tcmod = t->backgroundshaderpass->tcmods; i < Q3MAXTCMODS && tcmod->tcmod; i++, tcmod++) + R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags); t->backgroundbasetexture = (!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base; t->backgroundnmaptexture = t->backgroundcurrentskinframe->nmap; t->backgroundglosstexture = r_texture_black; @@ -8278,7 +8293,6 @@ texture_t *R_GetCurrentTexture(texture_t *t) } t->specularpower = r_shadow_glossexponent.value; // TODO: store reference values for these in the texture? - t->specularscale = 0; if (r_shadow_gloss.integer > 0) { if (t->currentskinframe->gloss || (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss)) @@ -8287,20 +8301,19 @@ texture_t *R_GetCurrentTexture(texture_t *t) { t->glosstexture = t->currentskinframe->gloss ? t->currentskinframe->gloss : r_texture_white; t->backgroundglosstexture = (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss) ? t->backgroundcurrentskinframe->gloss : r_texture_white; - t->specularscale = r_shadow_glossintensity.value; + specularscale = r_shadow_glossintensity.value; } } else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0) { t->glosstexture = r_texture_white; t->backgroundglosstexture = r_texture_white; - t->specularscale = r_shadow_gloss2intensity.value; + specularscale = r_shadow_gloss2intensity.value; t->specularpower = r_shadow_gloss2exponent.value; } } - t->specularscale *= t->specularscalemod; + specularscale *= t->specularscalemod; t->specularpower *= t->specularpowermod; - t->rtlightambient = 0; // lightmaps mode looks bad with dlights using actual texturing, so turn // off the colormap and glossmap, but leave the normalmap on as it still @@ -8321,12 +8334,20 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->backgroundnmaptexture = r_texture_blanknormalmap; t->backgroundglosstexture = r_texture_black; t->backgroundglowtexture = NULL; - t->specularscale = 0; - t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE)); + specularscale = 0; + t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE)); + } + + if (specularscale != 1.0f) + { + for (q = 0; q < 3; q++) + { + t->render_modellight_specular[q] *= specularscale; + t->render_lightmap_specular[q] *= specularscale; + t->render_rtlight_specular[q] *= specularscale; + } } - Vector4Set(t->lightmapcolor, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2], t->currentalpha); - VectorClear(t->dlightcolor); t->currentnumlayers = 0; if (t->currentmaterialflags & MATERIALFLAG_WALL) { @@ -8352,54 +8373,38 @@ texture_t *R_GetCurrentTexture(texture_t *t) blendfunc1 = GL_ONE; blendfunc2 = GL_ZERO; } - // don't colormod evilblend textures - if(!(R_BlendFuncFlags(blendfunc1, blendfunc2) & BLENDFUNC_ALLOWS_COLORMOD)) - VectorSet(t->lightmapcolor, 1, 1, 1); depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED); - if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) + if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { - // fullbright is not affected by r_refdef.lightmapintensity - R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + // basic lit geometry + R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2], t->currentalpha); + // add pants/shirt if needed + if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_diffuse[0], t->render_colormap_pants[1] * t->render_lightmap_diffuse[1], t->render_colormap_pants[2] * t->render_lightmap_diffuse[2], t->currentalpha); + if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_diffuse[0], t->render_colormap_shirt[1] * t->render_lightmap_diffuse[1], t->render_colormap_shirt[2] * t->render_lightmap_diffuse[2], t->currentalpha); } else { - vec3_t ambientcolor; - float colorscale; - // set the color tint used for lights affecting this surface - VectorSet(t->dlightcolor, t->lightmapcolor[0] * t->lightmapcolor[3], t->lightmapcolor[1] * t->lightmapcolor[3], t->lightmapcolor[2] * t->lightmapcolor[3]); - colorscale = 2; - // q3bsp has no lightmap updates, so the lightstylevalue that - // would normally be baked into the lightmap must be - // applied to the color - // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright) - if (model->type == mod_brushq3) - colorscale *= r_refdef.scene.rtlightstylevalue[0]; - colorscale *= r_refdef.lightmapintensity; - VectorScale(t->lightmapcolor, r_refdef.scene.ambient, ambientcolor); - VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor); // basic lit geometry - R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_diffuse[0], t->render_lightmap_diffuse[1], t->render_lightmap_diffuse[2], t->currentalpha); // add pants/shirt if needed - if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]); + if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_diffuse[0], t->render_colormap_pants[1] * t->render_lightmap_diffuse[1], t->render_colormap_pants[2] * t->render_lightmap_diffuse[2], t->currentalpha); + if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_diffuse[0], t->render_colormap_shirt[1] * t->render_lightmap_diffuse[1], t->render_colormap_shirt[2] * t->render_lightmap_diffuse[2], t->currentalpha); // now add ambient passes if needed - if (VectorLength2(ambientcolor) >= (1.0f/1048576.0f)) + if (VectorLength2(t->render_lightmap_ambient) >= (1.0f/1048576.0f)) { - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, ambientcolor[0], ambientcolor[1], ambientcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * ambientcolor[0], rsurface.colormap_pantscolor[1] * ambientcolor[1], rsurface.colormap_pantscolor[2] * ambientcolor[2], t->lightmapcolor[3]); - if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * ambientcolor[0], rsurface.colormap_shirtcolor[1] * ambientcolor[1], rsurface.colormap_shirtcolor[2] * ambientcolor[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->render_lightmap_ambient[0], t->render_lightmap_ambient[1], t->render_lightmap_ambient[2], t->currentalpha); + if (VectorLength2(t->render_colormap_pants) >= (1.0f / 1048576.0f) && t->pantstexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, t->render_colormap_pants[0] * t->render_lightmap_ambient[0], t->render_colormap_pants[1] * t->render_lightmap_ambient[1], t->render_colormap_pants[2] * t->render_lightmap_ambient[2], t->currentalpha); + if (VectorLength2(t->render_colormap_shirt) >= (1.0f / 1048576.0f) && t->shirttexture) + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, t->render_colormap_shirt[0] * t->render_lightmap_ambient[0], t->render_colormap_shirt[1] * t->render_lightmap_ambient[1], t->render_colormap_shirt[2] * t->render_lightmap_ambient[2], t->currentalpha); } } if (t->glowtexture != NULL && !gl_lightmaps.integer) - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->glowtexture, &t->currenttexmatrix, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->glowtexture, &t->currenttexmatrix, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2], t->currentalpha); if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD)) { // if this is opaque use alpha blend which will darken the earlier @@ -8413,145 +8418,16 @@ texture_t *R_GetCurrentTexture(texture_t *t) // were darkened by fog already, and we should not add fog color // (because the background was not darkened, there is no fog color // that was lost behind it). - R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->fogtexture, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->lightmapcolor[3]); + R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->fogtexture, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->currentalpha); } } - return t->currentframe; + return t; } rsurfacestate_t rsurface; -void RSurf_ActiveWorldEntity(void) -{ - dp_model_t *model = r_refdef.scene.worldmodel; - //if (rsurface.entity == r_refdef.scene.worldentity) - // return; - rsurface.entity = r_refdef.scene.worldentity; - rsurface.skeleton = NULL; - memset(rsurface.userwavefunc_param, 0, sizeof(rsurface.userwavefunc_param)); - rsurface.ent_skinnum = 0; - rsurface.ent_qwskin = -1; - rsurface.ent_flags = r_refdef.scene.worldentity->flags; - rsurface.shadertime = r_refdef.scene.time; - rsurface.matrix = identitymatrix; - rsurface.inversematrix = identitymatrix; - rsurface.matrixscale = 1; - rsurface.inversematrixscale = 1; - R_EntityMatrix(&identitymatrix); - VectorCopy(r_refdef.view.origin, rsurface.localvieworigin); - Vector4Copy(r_refdef.fogplane, rsurface.fogplane); - rsurface.fograngerecip = r_refdef.fograngerecip; - rsurface.fogheightfade = r_refdef.fogheightfade; - rsurface.fogplaneviewdist = r_refdef.fogplaneviewdist; - rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip; - VectorSet(rsurface.modellight_ambient, 0, 0, 0); - VectorSet(rsurface.modellight_diffuse, 0, 0, 0); - VectorSet(rsurface.modellight_lightdir, 0, 0, 1); - VectorSet(rsurface.colormap_pantscolor, 0, 0, 0); - VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0); - VectorSet(rsurface.colormod, r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale); - rsurface.colormod[3] = 1; - VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value); - memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend)); - rsurface.frameblend[0].lerp = 1; - rsurface.ent_alttextures = false; - rsurface.basepolygonfactor = r_refdef.polygonfactor; - rsurface.basepolygonoffset = r_refdef.polygonoffset; - rsurface.entityskeletaltransform3x4 = NULL; - rsurface.entityskeletaltransform3x4buffer = NULL; - rsurface.entityskeletaltransform3x4offset = 0; - rsurface.entityskeletaltransform3x4size = 0;; - rsurface.entityskeletalnumtransforms = 0; - rsurface.modelvertex3f = model->surfmesh.data_vertex3f; - rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f; - rsurface.modelsvector3f = model->surfmesh.data_svector3f; - rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f; - rsurface.modeltvector3f = model->surfmesh.data_tvector3f; - rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f; - rsurface.modelnormal3f = model->surfmesh.data_normal3f; - rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f; - rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f; - rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f; - rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f; - rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f; - rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f; - rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f; - rsurface.modelskeletalindex4ub = model->surfmesh.data_skeletalindex4ub; - rsurface.modelskeletalindex4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelskeletalindex4ub_bufferoffset = model->surfmesh.vbooffset_skeletalindex4ub; - rsurface.modelskeletalweight4ub = model->surfmesh.data_skeletalweight4ub; - rsurface.modelskeletalweight4ub_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelskeletalweight4ub_bufferoffset = model->surfmesh.vbooffset_skeletalweight4ub; - rsurface.modelelement3i = model->surfmesh.data_element3i; - rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer; - rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset; - rsurface.modelelement3s = model->surfmesh.data_element3s; - rsurface.modelelement3s_indexbuffer = model->surfmesh.data_element3s_indexbuffer; - rsurface.modelelement3s_bufferoffset = model->surfmesh.data_element3s_bufferoffset; - rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets; - rsurface.modelnumvertices = model->surfmesh.num_vertices; - rsurface.modelnumtriangles = model->surfmesh.num_triangles; - rsurface.modelsurfaces = model->data_surfaces; - rsurface.modelvertexmesh = model->surfmesh.data_vertexmesh; - rsurface.modelvertexmesh_vertexbuffer = model->surfmesh.vbo_vertexbuffer; - rsurface.modelvertexmesh_bufferoffset = model->surfmesh.vbooffset_vertex3f; - rsurface.modelgeneratedvertex = false; - rsurface.batchgeneratedvertex = false; - rsurface.batchfirstvertex = 0; - rsurface.batchnumvertices = 0; - rsurface.batchfirsttriangle = 0; - rsurface.batchnumtriangles = 0; - rsurface.batchvertex3f = NULL; - rsurface.batchvertex3f_vertexbuffer = NULL; - rsurface.batchvertex3f_bufferoffset = 0; - rsurface.batchsvector3f = NULL; - rsurface.batchsvector3f_vertexbuffer = NULL; - rsurface.batchsvector3f_bufferoffset = 0; - rsurface.batchtvector3f = NULL; - rsurface.batchtvector3f_vertexbuffer = NULL; - rsurface.batchtvector3f_bufferoffset = 0; - rsurface.batchnormal3f = NULL; - rsurface.batchnormal3f_vertexbuffer = NULL; - rsurface.batchnormal3f_bufferoffset = 0; - rsurface.batchlightmapcolor4f = NULL; - rsurface.batchlightmapcolor4f_vertexbuffer = NULL; - rsurface.batchlightmapcolor4f_bufferoffset = 0; - rsurface.batchtexcoordtexture2f = NULL; - rsurface.batchtexcoordtexture2f_vertexbuffer = NULL; - rsurface.batchtexcoordtexture2f_bufferoffset = 0; - rsurface.batchtexcoordlightmap2f = NULL; - rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL; - rsurface.batchtexcoordlightmap2f_bufferoffset = 0; - rsurface.batchskeletalindex4ub = NULL; - rsurface.batchskeletalindex4ub_vertexbuffer = NULL; - rsurface.batchskeletalindex4ub_bufferoffset = 0; - rsurface.batchskeletalweight4ub = NULL; - rsurface.batchskeletalweight4ub_vertexbuffer = NULL; - rsurface.batchskeletalweight4ub_bufferoffset = 0; - rsurface.batchvertexmesh = NULL; - rsurface.batchvertexmesh_vertexbuffer = NULL; - rsurface.batchvertexmesh_bufferoffset = 0; - rsurface.batchelement3i = NULL; - rsurface.batchelement3i_indexbuffer = NULL; - rsurface.batchelement3i_bufferoffset = 0; - rsurface.batchelement3s = NULL; - rsurface.batchelement3s_indexbuffer = NULL; - rsurface.batchelement3s_bufferoffset = 0; - rsurface.passcolor4f = NULL; - rsurface.passcolor4f_vertexbuffer = NULL; - rsurface.passcolor4f_bufferoffset = 0; - rsurface.forcecurrenttextureupdate = false; -} - -void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass) +void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass) { dp_model_t *model = ent->model; //if (rsurface.entity == ent && (!model->surfmesh.isanimated || (!wantnormals && !wanttangents))) @@ -8562,6 +8438,8 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.ent_skinnum = ent->skinnum; rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1; rsurface.ent_flags = ent->flags; + if (r_fullbright_directed.integer && (r_fullbright.integer || !model->lit)) + rsurface.ent_flags |= RENDER_LIGHT | RENDER_DYNAMICMODELLIGHT; rsurface.shadertime = r_refdef.scene.time - ent->shadertime; rsurface.matrix = ent->matrix; rsurface.inversematrix = ent->inversematrix; @@ -8570,18 +8448,10 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q R_EntityMatrix(&rsurface.matrix); Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.origin, rsurface.localvieworigin); Matrix4x4_TransformStandardPlane(&rsurface.inversematrix, r_refdef.fogplane[0], r_refdef.fogplane[1], r_refdef.fogplane[2], r_refdef.fogplane[3], rsurface.fogplane); - rsurface.fogplaneviewdist *= rsurface.inversematrixscale; + rsurface.fogplaneviewdist = r_refdef.fogplaneviewdist * rsurface.inversematrixscale; rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale; rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale; rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip; - VectorCopy(ent->modellight_ambient, rsurface.modellight_ambient); - VectorCopy(ent->modellight_diffuse, rsurface.modellight_diffuse); - VectorCopy(ent->modellight_lightdir, rsurface.modellight_lightdir); - VectorCopy(ent->colormap_pantscolor, rsurface.colormap_pantscolor); - VectorCopy(ent->colormap_shirtcolor, rsurface.colormap_shirtcolor); - VectorScale(ent->colormod, r_refdef.view.colorscale, rsurface.colormod); - rsurface.colormod[3] = ent->alpha; - VectorScale(ent->glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, rsurface.glowmod); memcpy(rsurface.frameblend, ent->frameblend, sizeof(ent->frameblend)); rsurface.ent_alttextures = ent->framegroupblend[0].frame != 0; rsurface.basepolygonfactor = r_refdef.polygonfactor; @@ -8824,13 +8694,6 @@ void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inve rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale; rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale; rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip; - VectorSet(rsurface.modellight_ambient, 0, 0, 0); - VectorSet(rsurface.modellight_diffuse, 0, 0, 0); - VectorSet(rsurface.modellight_lightdir, 0, 0, 1); - VectorSet(rsurface.colormap_pantscolor, 0, 0, 0); - VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0); - Vector4Set(rsurface.colormod, r * r_refdef.view.colorscale, g * r_refdef.view.colorscale, b * r_refdef.view.colorscale, a); - VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value); memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend)); rsurface.frameblend[0].lerp = 1; rsurface.ent_alttextures = false; @@ -9026,7 +8889,6 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const qboolean dynamicvertex; float amplitude; float animpos; - float scale; float center[3], forward[3], right[3], up[3], v[3], newforward[3], newright[3], newup[3]; float waveparms[4]; unsigned char *ub; @@ -9200,60 +9062,63 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const break; } } - switch(rsurface.texture->tcgen.tcgen) + if (rsurface.texture->materialshaderpass) { - default: - case Q3TCGEN_TEXTURE: - break; - case Q3TCGEN_LIGHTMAP: - if (!dynamicvertex) - { - r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_lightmap] += 1; - r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_lightmap] += batchnumsurfaces; - r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_lightmap] += batchnumvertices; - r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_lightmap] += batchnumtriangles; - } - dynamicvertex = true; - batchneed |= BATCHNEED_ARRAY_LIGHTMAP; - needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP; - break; - case Q3TCGEN_VECTOR: - if (!dynamicvertex) - { - r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_vector] += 1; - r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_vector] += batchnumsurfaces; - r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_vector] += batchnumvertices; - r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_vector] += batchnumtriangles; - } - dynamicvertex = true; - batchneed |= BATCHNEED_ARRAY_VERTEX; - needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD; - break; - case Q3TCGEN_ENVIRONMENT: - if (!dynamicvertex) + switch (rsurface.texture->materialshaderpass->tcgen.tcgen) { - r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_environment] += 1; - r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_environment] += batchnumsurfaces; - r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_environment] += batchnumvertices; - r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_environment] += batchnumtriangles; + default: + case Q3TCGEN_TEXTURE: + break; + case Q3TCGEN_LIGHTMAP: + if (!dynamicvertex) + { + r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_lightmap] += 1; + r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_lightmap] += batchnumsurfaces; + r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_lightmap] += batchnumvertices; + r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_lightmap] += batchnumtriangles; + } + dynamicvertex = true; + batchneed |= BATCHNEED_ARRAY_LIGHTMAP; + needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP; + break; + case Q3TCGEN_VECTOR: + if (!dynamicvertex) + { + r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_vector] += 1; + r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_vector] += batchnumsurfaces; + r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_vector] += batchnumvertices; + r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_vector] += batchnumtriangles; + } + dynamicvertex = true; + batchneed |= BATCHNEED_ARRAY_VERTEX; + needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD; + break; + case Q3TCGEN_ENVIRONMENT: + if (!dynamicvertex) + { + r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_environment] += 1; + r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_environment] += batchnumsurfaces; + r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_environment] += batchnumvertices; + r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_environment] += batchnumtriangles; + } + dynamicvertex = true; + batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL; + needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD; + break; } - dynamicvertex = true; - batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL; - needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD; - break; - } - if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT) - { - if (!dynamicvertex) + if (rsurface.texture->materialshaderpass->tcmods[0].tcmod == Q3TCMOD_TURBULENT) { - r_refdef.stats[r_stat_batch_dynamic_batches_because_tcmod_turbulent] += 1; - r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcmod_turbulent] += batchnumsurfaces; - r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcmod_turbulent] += batchnumvertices; - r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcmod_turbulent] += batchnumtriangles; + if (!dynamicvertex) + { + r_refdef.stats[r_stat_batch_dynamic_batches_because_tcmod_turbulent] += 1; + r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcmod_turbulent] += batchnumsurfaces; + r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcmod_turbulent] += batchnumvertices; + r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcmod_turbulent] += batchnumtriangles; + } + dynamicvertex = true; + batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD; + needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD; } - dynamicvertex = true; - batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD; - needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD; } if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP))) @@ -9824,6 +9689,7 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const // in place for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform && r_deformvertexes.integer;deformindex++, deform++) { + float scale; switch (deform->deform) { default: @@ -10095,10 +9961,10 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const } } - if (rsurface.batchtexcoordtexture2f) + if (rsurface.batchtexcoordtexture2f && rsurface.texture->materialshaderpass) { // generate texcoords based on the chosen texcoord source - switch(rsurface.texture->tcgen.tcgen) + switch(rsurface.texture->materialshaderpass->tcgen.tcgen) { default: case Q3TCGEN_TEXTURE: @@ -10116,8 +9982,8 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const // rsurface.batchtexcoordtexture2f_bufferoffset = 0; for (j = 0;j < batchnumvertices;j++) { - rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms); - rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3); + rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->materialshaderpass->tcgen.parms); + rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->materialshaderpass->tcgen.parms + 3); } break; case Q3TCGEN_ENVIRONMENT: @@ -10157,10 +10023,10 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const // and we only support that as the first one // (handling a mixture of turbulent and other tcmods would be problematic // without punting it entirely to a software path) - if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT) + if (rsurface.texture->materialshaderpass->tcmods[0].tcmod == Q3TCMOD_TURBULENT) { - amplitude = rsurface.texture->tcmods[0].parms[1]; - animpos = rsurface.texture->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->tcmods[0].parms[3]; + amplitude = rsurface.texture->materialshaderpass->tcmods[0].parms[1]; + animpos = rsurface.texture->materialshaderpass->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->materialshaderpass->tcmods[0].parms[3]; // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2])); // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL; // rsurface.batchtexcoordtexture2f_bufferoffset = 0; @@ -10448,9 +10314,9 @@ static void RSurf_DrawBatch_GL11_ApplyAmbient(void) rsurface.passcolor4f_bufferoffset = 0; for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4) { - c2[0] = c[0] + r_refdef.scene.ambient; - c2[1] = c[1] + r_refdef.scene.ambient; - c2[2] = c[2] + r_refdef.scene.ambient; + c2[0] = c[0] + rsurface.texture->render_lightmap_ambient[0]; + c2[1] = c[1] + rsurface.texture->render_lightmap_ambient[1]; + c2[2] = c[2] + rsurface.texture->render_lightmap_ambient[2]; c2[3] = c[3]; } } @@ -10514,7 +10380,7 @@ static void RSurf_DrawBatch_GL11_ClampColor(void) } } -static void RSurf_DrawBatch_GL11_ApplyFakeLight(void) +static void RSurf_DrawBatch_GL11_ApplyFakeLight(float fakelightintensity) { int i; float f; @@ -10532,14 +10398,14 @@ static void RSurf_DrawBatch_GL11_ApplyFakeLight(void) f = -DotProduct(r_refdef.view.forward, n); f = max(0, f); f = f * 0.85 + 0.15; // work around so stuff won't get black - f *= r_refdef.lightmapintensity; + f *= fakelightintensity; Vector4Set(c, f, f, f, 1); } } static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) { - RSurf_DrawBatch_GL11_ApplyFakeLight(); + RSurf_DrawBatch_GL11_ApplyFakeLight(r_refdef.scene.lightmapintensity * r_fakelight_intensity.value); if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a); R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset); @@ -10547,7 +10413,7 @@ static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, q RSurf_DrawBatch(); } -static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor) +static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, float lightmapintensity, qboolean *applycolor) { int i; float f; @@ -10560,14 +10426,14 @@ static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, vec3_t lightdir; // TODO: optimize // model lighting - VectorCopy(rsurface.modellight_lightdir, lightdir); - f = 0.5f * r_refdef.lightmapintensity; - ambientcolor[0] = rsurface.modellight_ambient[0] * *r * f; - ambientcolor[1] = rsurface.modellight_ambient[1] * *g * f; - ambientcolor[2] = rsurface.modellight_ambient[2] * *b * f; - diffusecolor[0] = rsurface.modellight_diffuse[0] * *r * f; - diffusecolor[1] = rsurface.modellight_diffuse[1] * *g * f; - diffusecolor[2] = rsurface.modellight_diffuse[2] * *b * f; + VectorCopy(rsurface.texture->render_modellight_lightdir, lightdir); + f = 0.5f * lightmapintensity; + ambientcolor[0] = rsurface.texture->render_modellight_ambient[0] * *r * f; + ambientcolor[1] = rsurface.texture->render_modellight_ambient[1] * *g * f; + ambientcolor[2] = rsurface.texture->render_modellight_ambient[2] * *b * f; + diffusecolor[0] = rsurface.texture->render_modellight_diffuse[0] * *r * f; + diffusecolor[1] = rsurface.texture->render_modellight_diffuse[1] * *g * f; + diffusecolor[2] = rsurface.texture->render_modellight_diffuse[2] * *b * f; alpha = *a; if (VectorLength2(diffusecolor) > 0) { @@ -10602,7 +10468,7 @@ static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, static void RSurf_DrawBatch_GL11_VertexShade(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) { - RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, &applycolor); + RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, r_refdef.scene.lightmapintensity, &applycolor); if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a); R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset); @@ -10645,6 +10511,7 @@ void RSurf_SetupDepthAndCulling(void) static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist) { + int i, j; // transparent sky would be ridiculous if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) return; @@ -10652,20 +10519,52 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_ skyrenderlater = true; RSurf_SetupDepthAndCulling(); GL_DepthMask(true); - // LordHavoc: HalfLife maps have freaky skypolys so don't use + + // add the vertices of the surfaces to a world bounding box so we can scissor the sky render later + if (r_sky_scissor.integer) + { + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist); + for (i = 0; i < texturenumsurfaces; i++) + { + const msurface_t *surf = texturesurfacelist[i]; + const float *v; + float p[3]; + for (j = 0, v = rsurface.batchvertex3f + 3 * surf->num_firstvertex; j < surf->num_vertices; j++, v += 3) + { + Matrix4x4_Transform(&rsurface.matrix, v, p); + if (skyscissor) + { + if (skyscissormins[0] > p[0]) skyscissormins[0] = p[0]; + if (skyscissormins[1] > p[1]) skyscissormins[1] = p[1]; + if (skyscissormins[2] > p[2]) skyscissormins[2] = p[2]; + if (skyscissormaxs[0] < p[0]) skyscissormaxs[0] = p[0]; + if (skyscissormaxs[1] < p[1]) skyscissormaxs[1] = p[1]; + if (skyscissormaxs[2] < p[2]) skyscissormaxs[2] = p[2]; + } + else + { + VectorCopy(p, skyscissormins); + VectorCopy(p, skyscissormaxs); + skyscissor = true; + } + } + } + } + + // LadyHavoc: HalfLife maps have freaky skypolys so don't use // skymasking on them, and Quake3 never did sky masking (unlike // software Quake and software Quake2), so disable the sky masking // in Quake3 maps as it causes problems with q3map2 sky tricks, // and skymasking also looks very bad when noclipping outside the // level, so don't use it then either. - if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis && !r_trippy.integer) + if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.skymasking && (r_refdef.scene.worldmodel->brush.isq3bsp ? r_q3bsp_renderskydepth.integer : r_q1bsp_skymasking.integer) && !r_refdef.viewcache.world_novis && !r_trippy.integer) { R_Mesh_ResetTextureState(); if (skyrendermasked) { R_SetupShader_DepthOrShadow(false, false, false); // depth-only (masking) - GL_ColorMask(0,0,0,0); + GL_ColorMask(0, 0, 0, 0); // just to make sure that braindead drivers don't draw // anything despite that colormask... GL_BlendFunc(GL_ZERO, GL_ONE); @@ -10699,7 +10598,7 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface { // render screenspace normalmap to texture GL_DepthMask(true); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL, false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL, false); RSurf_DrawBatch(); return; } @@ -10727,18 +10626,18 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface { // render water or distortion background GL_DepthMask(true); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); RSurf_DrawBatch(); // blend surface on top GL_DepthMask(false); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL, false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL, false); RSurf_DrawBatch(); } else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)) { // render surface with reflection texture as input GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, end-start, texturesurfacelist + start, (void *)(r_fb.water.waterplanes + startplaneindex), false); RSurf_DrawBatch(); } } @@ -10747,7 +10646,7 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface // render surface batch normally GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) != 0); + R_SetupShader_Surface(vec3_origin, vec3_origin, vec3_origin, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) != 0); RSurf_DrawBatch(); } @@ -10758,7 +10657,7 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface qboolean applyfog; int layerindex; const texturelayer_t *layer; - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++) @@ -10865,7 +10764,7 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface qboolean applyfog; int layerindex; const texturelayer_t *layer; - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++) @@ -10970,14 +10869,15 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const int j; r_vertexgeneric_t *batchvertex; float c[4]; + texture_t *t = rsurface.texture; // R_Mesh_ResetTextureState(); R_SetupShader_Generic_NoTexture(false, false); - if(rsurface.texture && rsurface.texture->currentskinframe) + if(t && t->currentskinframe) { - memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c)); - c[3] *= rsurface.texture->currentalpha; + memcpy(c, t->currentskinframe->avgcolor, sizeof(c)); + c[3] *= t->currentalpha; } else { @@ -10987,11 +10887,11 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const c[3] = 1; } - if (rsurface.texture->pantstexture || rsurface.texture->shirttexture) + if (t->pantstexture || t->shirttexture) { - c[0] = 0.5 * (rsurface.colormap_pantscolor[0] * 0.3 + rsurface.colormap_shirtcolor[0] * 0.7); - c[1] = 0.5 * (rsurface.colormap_pantscolor[1] * 0.3 + rsurface.colormap_shirtcolor[1] * 0.7); - c[2] = 0.5 * (rsurface.colormap_pantscolor[2] * 0.3 + rsurface.colormap_shirtcolor[2] * 0.7); + c[0] = 0.5 * (t->render_colormap_pants[0] * 0.3 + t->render_colormap_shirt[0] * 0.7); + c[1] = 0.5 * (t->render_colormap_pants[1] * 0.3 + t->render_colormap_shirt[1] * 0.7); + c[2] = 0.5 * (t->render_colormap_pants[2] * 0.3 + t->render_colormap_shirt[2] * 0.7); } // brighten it up (as texture value 127 means "unlit") @@ -10999,27 +10899,27 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const c[1] *= 2 * r_refdef.view.colorscale; c[2] *= 2 * r_refdef.view.colorscale; - if(rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA) + if(t->currentmaterialflags & MATERIALFLAG_WATERALPHA) c[3] *= r_wateralpha.value; - if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1) + if(t->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD) + else if(t->currentmaterialflags & MATERIALFLAG_ADD) { GL_BlendFunc(GL_ONE, GL_ONE); GL_DepthMask(false); } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + else if(t->currentmaterialflags & MATERIALFLAG_ALPHATEST) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // can't do alpha test without texture, so let's blend instead GL_DepthMask(false); } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) + else if(t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) { - GL_BlendFunc(rsurface.texture->customblendfunc[0], rsurface.texture->customblendfunc[1]); + GL_BlendFunc(t->customblendfunc[0], t->customblendfunc[1]); GL_DepthMask(false); } else @@ -11032,32 +10932,20 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const { rsurface.passcolor4f = NULL; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) - { - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); - - rsurface.passcolor4f = NULL; - rsurface.passcolor4f_vertexbuffer = 0; - rsurface.passcolor4f_bufferoffset = 0; - } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) + if (t->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { qboolean applycolor = true; float one = 1.0; RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); - r_refdef.lightmapintensity = 1; - RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor); - r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all + RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, 1.0f, &applycolor); } else if (FAKELIGHT_ENABLED) { RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); - r_refdef.lightmapintensity = r_fakelight_intensity.value; - RSurf_DrawBatch_GL11_ApplyFakeLight(); - r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all + RSurf_DrawBatch_GL11_ApplyFakeLight(r_fakelight_intensity.value); } else { @@ -11066,12 +10954,12 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const rsurface.passcolor4f = rsurface.batchlightmapcolor4f; rsurface.passcolor4f_vertexbuffer = rsurface.batchlightmapcolor4f_vertexbuffer; rsurface.passcolor4f_bufferoffset = rsurface.batchlightmapcolor4f_bufferoffset; + RSurf_DrawBatch_GL11_ApplyAmbient(); } if(!rsurface.passcolor4f) RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray(); - RSurf_DrawBatch_GL11_ApplyAmbient(); RSurf_DrawBatch_GL11_ApplyColor(c[0], c[1], c[2], c[3]); if(r_refdef.fogenabled) RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors(); @@ -11099,9 +10987,9 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchnumvertices); for (j = 0, vi = 0;j < rsurface.batchnumvertices;j++, vi++) { - unsigned char c = (vi << 3) * (1.0f / 256.0f); + unsigned char d = (vi << 3) * (1.0f / 256.0f); VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f); - Vector4Set(batchvertex[vi].color4f, c, c, c, 1); + Vector4Set(batchvertex[vi].color4f, d, d, d, 1); } R_Mesh_PrepareVertices_Generic_Unlock(); RSurf_DrawBatch(); @@ -11113,13 +11001,13 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const batchvertex = R_Mesh_PrepareVertices_Generic_Lock(3*rsurface.batchnumtriangles); for (j = 0, e = rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle;j < rsurface.batchnumtriangles;j++, e += 3) { - unsigned char c = ((j + rsurface.batchfirsttriangle) << 3) * (1.0f / 256.0f); + unsigned char d = ((j + rsurface.batchfirsttriangle) << 3) * (1.0f / 256.0f); VectorCopy(rsurface.batchvertex3f + 3*e[0], batchvertex[j*3+0].vertex3f); VectorCopy(rsurface.batchvertex3f + 3*e[1], batchvertex[j*3+1].vertex3f); VectorCopy(rsurface.batchvertex3f + 3*e[2], batchvertex[j*3+2].vertex3f); - Vector4Set(batchvertex[j*3+0].color4f, c, c, c, 1); - Vector4Set(batchvertex[j*3+1].color4f, c, c, c, 1); - Vector4Set(batchvertex[j*3+2].color4f, c, c, c, 1); + Vector4Set(batchvertex[j*3+0].color4f, d, d, d, 1); + Vector4Set(batchvertex[j*3+1].color4f, d, d, d, 1); + Vector4Set(batchvertex[j*3+2].color4f, d, d, d, 1); } R_Mesh_PrepareVertices_Generic_Unlock(); R_Mesh_Draw(0, rsurface.batchnumtriangles*3, 0, rsurface.batchnumtriangles, NULL, NULL, 0, NULL, NULL, 0); @@ -11150,36 +11038,6 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const } } -static void R_DrawWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass) -{ - CHECKGLERROR - RSurf_SetupDepthAndCulling(); - if (r_showsurfaces.integer) - { - R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist, writedepth); - return; - } - switch (vid.renderpath) - { - case RENDERPATH_GL20: - case RENDERPATH_D3D9: - case RENDERPATH_D3D10: - case RENDERPATH_D3D11: - case RENDERPATH_SOFT: - case RENDERPATH_GLES2: - R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass); - break; - case RENDERPATH_GL13: - case RENDERPATH_GLES1: - R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth); - break; - case RENDERPATH_GL11: - R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist, writedepth); - break; - } - CHECKGLERROR -} - static void R_DrawModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass) { CHECKGLERROR @@ -11218,12 +11076,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const const msurface_t *surface; const msurface_t *texturesurfacelist[MESHQUEUE_TRANSPARENT_BATCHSIZE]; - // if the model is static it doesn't matter what value we give for - // wantnormals and wanttangents, so this logic uses only rules applicable - // to a model, knowing that they are meaningless otherwise - if (ent == r_refdef.scene.worldentity) - RSurf_ActiveWorldEntity(); - else if (r_showsurfaces.integer && r_showsurfaces.integer != 3) + if (r_showsurfaces.integer && r_showsurfaces.integer != 3) RSurf_ActiveModelEntity(ent, false, false, false); else { @@ -11328,12 +11181,9 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const } } // render the range of surfaces - if (ent == r_refdef.scene.worldentity) - R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false); - else - R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false); + R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false); } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist) @@ -11381,84 +11231,6 @@ static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msu RSurf_DrawBatch(); } -static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) -{ - CHECKGLERROR - if (depthonly) - R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist); - else if (prepass) - { - if (!rsurface.texture->currentnumlayers) - return; - if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); - else - R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); - } - else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && (!r_showsurfaces.integer || r_showsurfaces.integer == 3)) - R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); - else if (!rsurface.texture->currentnumlayers) - return; - else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)))) - { - // in the deferred case, transparent surfaces were queued during prepass - if (!r_shadow_usingdeferredprepass) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); - } - else - { - // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier - R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST), prepass); - } - CHECKGLERROR -} - -static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass) -{ - int i, j; - texture_t *texture; - R_FrameData_SetMark(); - // break the surface list down into batches by texture and use of lightmapping - for (i = 0;i < numsurfaces;i = j) - { - j = i + 1; - // texture is the base texture pointer, rsurface.texture is the - // current frame/skin the texture is directing us to use (for example - // if a model has 2 skins and it is on skin 1, then skin 0 tells us to - // use skin 1 instead) - texture = surfacelist[i]->texture; - rsurface.texture = R_GetCurrentTexture(texture); - if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW)) - { - // if this texture is not the kind we want, skip ahead to the next one - for (;j < numsurfaces && texture == surfacelist[j]->texture;j++) - ; - continue; - } - if(FAKELIGHT_ENABLED || depthonly || prepass) - { - rsurface.lightmaptexture = NULL; - rsurface.deluxemaptexture = NULL; - rsurface.uselightmaptexture = false; - // simply scan ahead until we find a different texture or lightmap state - for (;j < numsurfaces && texture == surfacelist[j]->texture;j++) - ; - } - else - { - rsurface.lightmaptexture = surfacelist[i]->lightmaptexture; - rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture; - rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL; - // simply scan ahead until we find a different texture or lightmap state - for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++) - ; - } - // render the range of surfaces - R_ProcessWorldTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass); - } - R_FrameData_ReturnToMark(); -} - static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) { CHECKGLERROR @@ -11620,7 +11392,7 @@ void R_DecalSystem_Reset(decalsystem_t *decalsystem) memset(decalsystem, 0, sizeof(*decalsystem)); } -static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float *v0, const float *v1, const float *v2, const float *t0, const float *t1, const float *t2, const float *c0, const float *c1, const float *c2, int triangleindex, int surfaceindex, int decalsequence) +static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float *v0, const float *v1, const float *v2, const float *t0, const float *t1, const float *t2, const float *c0, const float *c1, const float *c2, int triangleindex, int surfaceindex, unsigned int decalsequence) { tridecal_t *decal; tridecal_t *decals; @@ -11700,7 +11472,7 @@ extern cvar_t cl_decals_bias; extern cvar_t cl_decals_models; extern cvar_t cl_decals_newsystem_intensitymultiplier; // baseparms, parms, temps -static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, int decalsequence, qboolean dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex) +static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, unsigned int decalsequence, qboolean dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex) { int cornerindex; int index; @@ -11793,7 +11565,7 @@ static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, flo for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++) R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence); } -static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence) +static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence) { matrix4x4_t projection; decalsystem_t *decalsystem; @@ -11954,7 +11726,7 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor } // do not call this outside of rendering code - use R_DecalSystem_SplatEntities instead -static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence) +static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence) { int renderentityindex; float worldmins[3]; @@ -11990,7 +11762,7 @@ typedef struct r_decalsystem_splatqueue_s float color[4]; float tcrange[4]; float worldsize; - int decalsequence; + unsigned int decalsequence; } r_decalsystem_splatqueue_t; @@ -12029,7 +11801,7 @@ static void R_DrawModelDecals_FadeEntity(entity_render_t *ent) int i; decalsystem_t *decalsystem = &ent->decalsystem; int numdecals; - int killsequence; + unsigned int killsequence; tridecal_t *decal; float frametime; float lifetime; @@ -12046,7 +11818,7 @@ static void R_DrawModelDecals_FadeEntity(entity_render_t *ent) return; } - killsequence = cl.decalsequence - max(1, cl_decals_max.integer); + killsequence = cl.decalsequence - bound(1, (unsigned int) cl_decals_max.integer, cl.decalsequence); lifetime = cl_decals_time.value + cl_decals_fadetime.value; if (decalsystem->lastupdatetime) @@ -12061,7 +11833,7 @@ static void R_DrawModelDecals_FadeEntity(entity_render_t *ent) if (decal->color4f[0][3]) { decal->lived += frametime; - if (killsequence - decal->decalsequence > 0 || decal->lived >= lifetime) + if (killsequence > decal->decalsequence || decal->lived >= lifetime) { memset(decal, 0, sizeof(*decal)); if (decalsystem->freedecal > i) @@ -12124,10 +11896,7 @@ static void R_DrawModelDecals_Entity(entity_render_t *ent) // if the model is static it doesn't matter what value we give for // wantnormals and wanttangents, so this logic uses only rules applicable // to a model, knowing that they are meaningless otherwise - if (ent == r_refdef.scene.worldentity) - RSurf_ActiveWorldEntity(); - else - RSurf_ActiveModelEntity(ent, false, false, false); + RSurf_ActiveModelEntity(ent, false, false, false); decalsystem->lastupdatetime = r_refdef.scene.time; @@ -12480,101 +12249,6 @@ static void R_DrawDebugModel(void) int r_maxsurfacelist = 0; const msurface_t **r_surfacelist = NULL; -void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass) -{ - int i, j, endj, flagsmask; - dp_model_t *model = r_refdef.scene.worldmodel; - msurface_t *surfaces; - unsigned char *update; - int numsurfacelist = 0; - if (model == NULL) - return; - - if (r_maxsurfacelist < model->num_surfaces) - { - r_maxsurfacelist = model->num_surfaces; - if (r_surfacelist) - Mem_Free((msurface_t**)r_surfacelist); - r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); - } - - RSurf_ActiveWorldEntity(); - - surfaces = model->data_surfaces; - update = model->brushq1.lightmapupdateflags; - - // update light styles on this submodel - if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0) - { - model_brush_lightstyleinfo_t *style; - for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++) - { - if (style->value != r_refdef.scene.lightstylevalue[style->style]) - { - int *list = style->surfacelist; - style->value = r_refdef.scene.lightstylevalue[style->style]; - for (j = 0;j < style->numsurfaces;j++) - update[list[j]] = true; - } - } - } - - flagsmask = skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL; - - if (debug) - { - R_DrawDebugModel(); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity - return; - } - - rsurface.lightmaptexture = NULL; - rsurface.deluxemaptexture = NULL; - rsurface.uselightmaptexture = false; - rsurface.texture = NULL; - rsurface.rtlight = NULL; - numsurfacelist = 0; - // add visible surfaces to draw list - for (i = 0;i < model->nummodelsurfaces;i++) - { - j = model->sortedmodelsurfaces[i]; - if (r_refdef.viewcache.world_surfacevisible[j]) - r_surfacelist[numsurfacelist++] = surfaces + j; - } - // update lightmaps if needed - if (model->brushq1.firstrender) - { - model->brushq1.firstrender = false; - for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++) - if (update[j]) - R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j); - } - else if (update) - { - for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++) - if (r_refdef.viewcache.world_surfacevisible[j]) - if (update[j]) - R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j); - } - // don't do anything if there were no surfaces - if (!numsurfacelist) - { - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity - return; - } - R_QueueWorldSurfaceList(numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass); - - // add to stats if desired - if (r_speeds.integer && !skysurfaces && !depthonly) - { - r_refdef.stats[r_stat_world_surfaces] += numsurfacelist; - for (j = 0;j < numsurfacelist;j++) - r_refdef.stats[r_stat_world_triangles] += r_surfacelist[j]->num_triangles; - } - - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity -} - void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass) { int i, j, endj, flagsmask; @@ -12593,12 +12267,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); } - // if the model is static it doesn't matter what value we give for - // wantnormals and wanttangents, so this logic uses only rules applicable - // to a model, knowing that they are meaningless otherwise - if (ent == r_refdef.scene.worldentity) - RSurf_ActiveWorldEntity(); - else if (r_showsurfaces.integer && r_showsurfaces.integer != 3) + if (r_showsurfaces.integer && r_showsurfaces.integer != 3) RSurf_ActiveModelEntity(ent, false, false, false); else if (prepass) RSurf_ActiveModelEntity(ent, true, true, true); @@ -12645,7 +12314,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr update = model->brushq1.lightmapupdateflags; // update light styles - if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0) + if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.scene.lightmapintensity > 0) { model_brush_lightstyleinfo_t *style; for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++) @@ -12665,7 +12334,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr if (debug) { R_DrawDebugModel(); - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity return; } @@ -12676,12 +12345,26 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr rsurface.rtlight = NULL; numsurfacelist = 0; // add visible surfaces to draw list - for (i = 0;i < model->nummodelsurfaces;i++) - r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i]; + if (ent == r_refdef.scene.worldentity) + { + // for the world entity, check surfacevisible + for (i = 0;i < model->nummodelsurfaces;i++) + { + j = model->sortedmodelsurfaces[i]; + if (r_refdef.viewcache.world_surfacevisible[j]) + r_surfacelist[numsurfacelist++] = surfaces + j; + } + } + else + { + // add all surfaces + for (i = 0; i < model->nummodelsurfaces; i++) + r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i]; + } // don't do anything if there were no surfaces if (!numsurfacelist) { - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity return; } // update lightmaps if needed @@ -12708,11 +12391,12 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr r_refdef.stats[r_stat_entities_triangles] += r_surfacelist[j]->num_triangles; } - rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity + rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity } void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass) { + int q; static texture_t texture; static msurface_t surface; const msurface_t *surfacelist = &surface; @@ -12721,6 +12405,7 @@ void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, i texture.update_lastrenderframe = -1; // regenerate this texture texture.basematerialflags = materialflags | MATERIALFLAG_CUSTOMSURFACE | MATERIALFLAG_WALL; + texture.basealpha = 1.0f; texture.currentskinframe = skinframe; texture.currenttexmatrix = *texmatrix; // requires MATERIALFLAG_CUSTOMSURFACE texture.offsetmapping = OFFSETMAPPING_OFF; @@ -12731,6 +12416,21 @@ void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, i // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS // JUST GREP FOR "specularscalemod = 1". + for (q = 0; q < 3; q++) + { + texture.render_glowmod[q] = r_refdef.view.colorscale * r_hdr_glowintensity.value; + texture.render_modellight_lightdir[q] = q == 2; + texture.render_modellight_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity; + texture.render_modellight_diffuse[q] = r_refdef.view.colorscale; + texture.render_modellight_specular[q] = r_refdef.view.colorscale; + texture.render_lightmap_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity; + texture.render_lightmap_diffuse[q] = r_refdef.view.colorscale * r_refdef.scene.lightmapintensity; + texture.render_lightmap_specular[q] = r_refdef.view.colorscale; + texture.render_rtlight_diffuse[q] = r_refdef.view.colorscale; + texture.render_rtlight_specular[q] = r_refdef.view.colorscale; + } + texture.currentalpha = 1.0f; + surface.texture = &texture; surface.num_triangles = numtriangles; surface.num_firsttriangle = firsttriangle;