2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "cl_dyntexture.h"
30 #include "dpsoftrast.h"
34 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
37 mempool_t *r_main_mempool;
38 rtexturepool_t *r_main_texturepool;
40 static int r_textureframe = 0; ///< used only by R_GetCurrentTexture
42 static qboolean r_loadnormalmap;
43 static qboolean r_loadgloss;
45 static qboolean r_loaddds;
46 static qboolean r_savedds;
53 cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "screen motionblur - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
54 cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "screen motionblur based on damage - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
55 cvar_t r_motionblur_averaging = {CVAR_SAVE, "r_motionblur_averaging", "0.1", "sliding average reaction time for velocity (higher = slower adaption to change)"};
56 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
57 cvar_t r_motionblur_minblur = {CVAR_SAVE, "r_motionblur_minblur", "0.5", "factor of blur to apply at all times (always have this amount of blur no matter what the other factors are)"};
58 cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.9", "maxmimum amount of blur"};
59 cvar_t r_motionblur_velocityfactor = {CVAR_SAVE, "r_motionblur_velocityfactor", "1", "factoring in of player velocity to the blur equation - the faster the player moves around the map, the more blur they get"};
60 cvar_t r_motionblur_velocityfactor_minspeed = {CVAR_SAVE, "r_motionblur_velocityfactor_minspeed", "400", "lower value of velocity when it starts to factor into blur equation"};
61 cvar_t r_motionblur_velocityfactor_maxspeed = {CVAR_SAVE, "r_motionblur_velocityfactor_maxspeed", "800", "upper value of velocity when it reaches the peak factor into blur equation"};
62 cvar_t r_motionblur_mousefactor = {CVAR_SAVE, "r_motionblur_mousefactor", "2", "factoring in of mouse acceleration to the blur equation - the faster the player turns their mouse, the more blur they get"};
63 cvar_t r_motionblur_mousefactor_minspeed = {CVAR_SAVE, "r_motionblur_mousefactor_minspeed", "0", "lower value of mouse acceleration when it starts to factor into blur equation"};
64 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"};
66 // TODO do we want a r_equalize_entities cvar that works on all ents, or would that be a cheat?
67 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"};
68 cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio"};
69 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)"};
70 cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level"};
72 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"};
73 cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
74 cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
75 cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
76 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
77 cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
78 cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
79 cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"};
80 cvar_t r_transparent_sortsurfacesbynearest = {0, "r_transparent_sortsurfacesbynearest", "1", "sort entity and world surfaces by nearest point on bounding box instead of using the center of the bounding box, usually reduces sorting artifacts"};
81 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"};
82 cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"};
83 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"};
84 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)"};
85 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
86 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
87 cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
88 cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
89 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
90 cvar_t r_showcollisionbrushes_polygonfactor = {0, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"};
91 cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"};
92 cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
93 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
94 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
95 cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
96 cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
97 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
98 cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
99 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
100 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)"};
101 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)"};
102 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
103 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
104 cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
105 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
106 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
108 cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"};
109 cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"};
110 #define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
112 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
113 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
114 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
115 cvar_t r_shadows = {CVAR_SAVE, "r_shadows", "0", "casts fake stencil shadows from models onto the world (rtlights are unaffected by this); when set to 2, always cast the shadows in the direction set by r_shadows_throwdirection, otherwise use the model lighting."};
116 cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
117 cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
118 cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
119 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."};
120 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
121 cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
122 cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
123 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."};
124 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
125 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"};
126 cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "14", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
127 cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
128 cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
129 cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
130 cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
131 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
132 cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
133 cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
134 cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
135 cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
136 cvar_t r_celshading = {CVAR_SAVE, "r_celshading", "0", "cartoon-style light shading (OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
137 cvar_t r_celoutlines = {CVAR_SAVE, "r_celoutlines", "0", "cartoon-style outlines (requires r_shadow_deferred; OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
139 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
140 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
141 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
142 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
143 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
144 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
145 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
146 cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
148 cvar_t r_texture_dds_load = {CVAR_SAVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"};
149 cvar_t r_texture_dds_save = {CVAR_SAVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"};
151 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"};
152 static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
153 static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
155 cvar_t r_usedepthtextures = {CVAR_SAVE, "r_usedepthtextures", "1", "use depth texture instead of depth renderbuffer where possible, uses less video memory but may render slower (or faster) depending on hardware"};
156 cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"};
157 cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"};
158 cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
159 cvar_t r_viewscale_fpsscaling_min = {CVAR_SAVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"};
160 cvar_t r_viewscale_fpsscaling_multiply = {CVAR_SAVE, "r_viewscale_fpsscaling_multiply", "5", "adjust quality up or down by the frametime difference from 1.0/target, multiplied by this factor"};
161 cvar_t r_viewscale_fpsscaling_stepsize = {CVAR_SAVE, "r_viewscale_fpsscaling_stepsize", "0.01", "smallest adjustment to hit the target framerate (this value prevents minute oscillations)"};
162 cvar_t r_viewscale_fpsscaling_stepmax = {CVAR_SAVE, "r_viewscale_fpsscaling_stepmax", "1.00", "largest adjustment to hit the target framerate (this value prevents wild overshooting of the estimate)"};
163 cvar_t r_viewscale_fpsscaling_target = {CVAR_SAVE, "r_viewscale_fpsscaling_target", "70", "desired framerate"};
165 cvar_t r_glsl_skeletal = {CVAR_SAVE, "r_glsl_skeletal", "1", "render skeletal models faster using a gpu-skinning technique"};
166 cvar_t r_glsl_deluxemapping = {CVAR_SAVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
167 cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
168 cvar_t r_glsl_offsetmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_steps", "2", "offset mapping steps (note: too high values may be not supported by your GPU)"};
169 cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
170 cvar_t r_glsl_offsetmapping_reliefmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_steps", "10", "relief mapping steps (note: too high values may be not supported by your GPU)"};
171 cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_refinesteps", "5", "relief mapping refine steps (these are a binary search executed as the last step as given by r_glsl_offsetmapping_reliefmapping_steps)"};
172 cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
173 cvar_t r_glsl_offsetmapping_lod = {CVAR_SAVE, "r_glsl_offsetmapping_lod", "0", "apply distance-based level-of-detail correction to number of offsetmappig steps, effectively making it render faster on large open-area maps"};
174 cvar_t r_glsl_offsetmapping_lod_distance = {CVAR_SAVE, "r_glsl_offsetmapping_lod_distance", "32", "first LOD level distance, second level (-50% steps) is 2x of this, third (33%) - 3x etc."};
175 cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
176 cvar_t r_glsl_postprocess_uservec1 = {CVAR_SAVE, "r_glsl_postprocess_uservec1", "0 0 0 0", "a 4-component vector to pass as uservec1 to the postprocessing shader (only useful if default.glsl has been customized)"};
177 cvar_t r_glsl_postprocess_uservec2 = {CVAR_SAVE, "r_glsl_postprocess_uservec2", "0 0 0 0", "a 4-component vector to pass as uservec2 to the postprocessing shader (only useful if default.glsl has been customized)"};
178 cvar_t r_glsl_postprocess_uservec3 = {CVAR_SAVE, "r_glsl_postprocess_uservec3", "0 0 0 0", "a 4-component vector to pass as uservec3 to the postprocessing shader (only useful if default.glsl has been customized)"};
179 cvar_t r_glsl_postprocess_uservec4 = {CVAR_SAVE, "r_glsl_postprocess_uservec4", "0 0 0 0", "a 4-component vector to pass as uservec4 to the postprocessing shader (only useful if default.glsl has been customized)"};
180 cvar_t r_glsl_postprocess_uservec1_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec1_enable", "1", "enables postprocessing uservec1 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
181 cvar_t r_glsl_postprocess_uservec2_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec2_enable", "1", "enables postprocessing uservec2 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
182 cvar_t r_glsl_postprocess_uservec3_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec3_enable", "1", "enables postprocessing uservec3 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
183 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)"};
185 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)"};
186 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
187 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"};
188 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
189 cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
190 cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
191 cvar_t r_water_lowquality = {0, "r_water_lowquality", "0", "special option to accelerate water rendering, 1 disables shadows and particles, 2 disables all dynamic lights"};
192 cvar_t r_water_hideplayer = {CVAR_SAVE, "r_water_hideplayer", "0", "if set to 1 then player will be hidden in refraction views, if set to 2 then player will also be hidden in reflection views, player is always visible in camera views"};
193 cvar_t r_water_fbo = {CVAR_SAVE, "r_water_fbo", "1", "enables use of render to texture for water effects, otherwise copy to texture is used (slower)"};
195 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
196 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
197 cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
198 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
200 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
201 cvar_t r_bloom_colorscale = {CVAR_SAVE, "r_bloom_colorscale", "1", "how bright the glow is"};
203 cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
204 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
205 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
206 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
207 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
208 cvar_t r_bloom_scenebrightness = {CVAR_SAVE, "r_bloom_scenebrightness", "1", "global rendering brightness when bloom is enabled"};
210 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
211 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
212 cvar_t r_hdr_irisadaptation = {CVAR_SAVE, "r_hdr_irisadaptation", "0", "adjust scene brightness according to light intensity at player location"};
213 cvar_t r_hdr_irisadaptation_multiplier = {CVAR_SAVE, "r_hdr_irisadaptation_multiplier", "2", "brightness at which value will be 1.0"};
214 cvar_t r_hdr_irisadaptation_minvalue = {CVAR_SAVE, "r_hdr_irisadaptation_minvalue", "0.5", "minimum value that can result from multiplier / brightness"};
215 cvar_t r_hdr_irisadaptation_maxvalue = {CVAR_SAVE, "r_hdr_irisadaptation_maxvalue", "4", "maximum value that can result from multiplier / brightness"};
216 cvar_t r_hdr_irisadaptation_value = {0, "r_hdr_irisadaptation_value", "1", "current value as scenebrightness multiplier, changes continuously when irisadaptation is active"};
217 cvar_t r_hdr_irisadaptation_fade_up = {CVAR_SAVE, "r_hdr_irisadaptation_fade_up", "0.1", "fade rate at which value adjusts to darkness"};
218 cvar_t r_hdr_irisadaptation_fade_down = {CVAR_SAVE, "r_hdr_irisadaptation_fade_down", "0.5", "fade rate at which value adjusts to brightness"};
219 cvar_t r_hdr_irisadaptation_radius = {CVAR_SAVE, "r_hdr_irisadaptation_radius", "15", "lighting within this many units of the eye is averaged"};
221 cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1", "uses significantly faster (and supposedly higher quality) area-weighted vertex normals and tangent vectors rather than summing normalized triangle normals and tangents"};
223 cvar_t developer_texturelogging = {0, "developer_texturelogging", "0", "produces a textures.log file containing names of skins and map textures the engine tried to load"};
225 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers), a value of 2 keeps normalmap shading"};
227 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
229 cvar_t r_batch_multidraw = {CVAR_SAVE, "r_batch_multidraw", "1", "issue multiple glDrawElements calls when rendering a batch of surfaces with the same texture (otherwise the index data is copied to make it one draw)"};
230 cvar_t r_batch_multidraw_mintriangles = {CVAR_SAVE, "r_batch_multidraw_mintriangles", "0", "minimum number of triangles to activate multidraw path (copying small groups of triangles may be faster)"};
231 cvar_t r_batch_debugdynamicvertexpath = {CVAR_SAVE, "r_batch_debugdynamicvertexpath", "0", "force the dynamic batching code path for debugging purposes"};
233 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
234 cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"};
236 cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer, requires mod_q3shader_force_terrain_alphaflag on."};
238 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
240 extern cvar_t v_glslgamma;
241 extern cvar_t v_glslgamma_2d;
243 extern qboolean v_flipped_state;
245 r_framebufferstate_t r_fb;
247 /// shadow volume bsp struct with automatically growing nodes buffer
250 rtexture_t *r_texture_blanknormalmap;
251 rtexture_t *r_texture_white;
252 rtexture_t *r_texture_grey128;
253 rtexture_t *r_texture_black;
254 rtexture_t *r_texture_notexture;
255 rtexture_t *r_texture_whitecube;
256 rtexture_t *r_texture_normalizationcube;
257 rtexture_t *r_texture_fogattenuation;
258 rtexture_t *r_texture_fogheighttexture;
259 rtexture_t *r_texture_gammaramps;
260 unsigned int r_texture_gammaramps_serial;
261 //rtexture_t *r_texture_fogintensity;
262 rtexture_t *r_texture_reflectcube;
264 // TODO: hash lookups?
265 typedef struct cubemapinfo_s
272 int r_texture_numcubemaps;
273 cubemapinfo_t *r_texture_cubemaps[MAX_CUBEMAPS];
275 unsigned int r_queries[MAX_OCCLUSION_QUERIES];
276 unsigned int r_numqueries;
277 unsigned int r_maxqueries;
279 typedef struct r_qwskincache_s
281 char name[MAX_QPATH];
282 skinframe_t *skinframe;
286 static r_qwskincache_t *r_qwskincache;
287 static int r_qwskincache_size;
289 /// vertex coordinates for a quad that covers the screen exactly
290 extern const float r_screenvertex3f[12];
291 extern const float r_d3dscreenvertex3f[12];
292 const float r_screenvertex3f[12] =
299 const float r_d3dscreenvertex3f[12] =
307 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
310 for (i = 0;i < verts;i++)
321 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
324 for (i = 0;i < verts;i++)
334 // FIXME: move this to client?
337 if (gamemode == GAME_NEHAHRA)
339 Cvar_Set("gl_fogenable", "0");
340 Cvar_Set("gl_fogdensity", "0.2");
341 Cvar_Set("gl_fogred", "0.3");
342 Cvar_Set("gl_foggreen", "0.3");
343 Cvar_Set("gl_fogblue", "0.3");
345 r_refdef.fog_density = 0;
346 r_refdef.fog_red = 0;
347 r_refdef.fog_green = 0;
348 r_refdef.fog_blue = 0;
349 r_refdef.fog_alpha = 1;
350 r_refdef.fog_start = 0;
351 r_refdef.fog_end = 16384;
352 r_refdef.fog_height = 1<<30;
353 r_refdef.fog_fadedepth = 128;
354 memset(r_refdef.fog_height_texturename, 0, sizeof(r_refdef.fog_height_texturename));
357 static void R_BuildBlankTextures(void)
359 unsigned char data[4];
360 data[2] = 128; // normal X
361 data[1] = 128; // normal Y
362 data[0] = 255; // normal Z
363 data[3] = 255; // height
364 r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
369 r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
374 r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
379 r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
382 static void R_BuildNoTexture(void)
385 unsigned char pix[16][16][4];
386 // this makes a light grey/dark grey checkerboard texture
387 for (y = 0;y < 16;y++)
389 for (x = 0;x < 16;x++)
391 if ((y < 8) ^ (x < 8))
407 r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, -1, NULL);
410 static void R_BuildWhiteCube(void)
412 unsigned char data[6*1*1*4];
413 memset(data, 255, sizeof(data));
414 r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
417 static void R_BuildNormalizationCube(void)
421 vec_t s, t, intensity;
424 data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
425 for (side = 0;side < 6;side++)
427 for (y = 0;y < NORMSIZE;y++)
429 for (x = 0;x < NORMSIZE;x++)
431 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
432 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
467 intensity = 127.0f / sqrt(DotProduct(v, v));
468 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
469 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
470 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
471 data[((side*64+y)*64+x)*4+3] = 255;
475 r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
479 static void R_BuildFogTexture(void)
483 unsigned char data1[FOGWIDTH][4];
484 //unsigned char data2[FOGWIDTH][4];
487 r_refdef.fogmasktable_start = r_refdef.fog_start;
488 r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
489 r_refdef.fogmasktable_range = r_refdef.fogrange;
490 r_refdef.fogmasktable_density = r_refdef.fog_density;
492 r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
493 for (x = 0;x < FOGMASKTABLEWIDTH;x++)
495 d = (x * r - r_refdef.fogmasktable_start);
496 if(developer_extra.integer)
497 Con_DPrintf("%f ", d);
499 if (r_fog_exp2.integer)
500 alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
502 alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
503 if(developer_extra.integer)
504 Con_DPrintf(" : %f ", alpha);
505 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
506 if(developer_extra.integer)
507 Con_DPrintf(" = %f\n", alpha);
508 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
511 for (x = 0;x < FOGWIDTH;x++)
513 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
518 //data2[x][0] = 255 - b;
519 //data2[x][1] = 255 - b;
520 //data2[x][2] = 255 - b;
523 if (r_texture_fogattenuation)
525 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
526 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
530 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
531 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
535 static void R_BuildFogHeightTexture(void)
537 unsigned char *inpixels;
545 strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename));
546 if (r_refdef.fogheighttexturename[0])
547 inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false, NULL);
550 r_refdef.fog_height_tablesize = 0;
551 if (r_texture_fogheighttexture)
552 R_FreeTexture(r_texture_fogheighttexture);
553 r_texture_fogheighttexture = NULL;
554 if (r_refdef.fog_height_table2d)
555 Mem_Free(r_refdef.fog_height_table2d);
556 r_refdef.fog_height_table2d = NULL;
557 if (r_refdef.fog_height_table1d)
558 Mem_Free(r_refdef.fog_height_table1d);
559 r_refdef.fog_height_table1d = NULL;
563 r_refdef.fog_height_tablesize = size;
564 r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
565 r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
566 memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
568 // LordHavoc: now the magic - what is that table2d for? it is a cooked
569 // average fog color table accounting for every fog layer between a point
570 // and the camera. (Note: attenuation is handled separately!)
571 for (y = 0;y < size;y++)
573 for (x = 0;x < size;x++)
579 for (j = x;j <= y;j++)
581 Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
587 for (j = x;j >= y;j--)
589 Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
594 r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f);
595 r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f);
596 r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f);
597 r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
600 r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, -1, NULL);
603 //=======================================================================================================================================================
605 static const char *builtinshaderstrings[] =
607 #include "shader_glsl.h"
611 const char *builtinhlslshaderstrings[] =
613 #include "shader_hlsl.h"
617 char *glslshaderstring = NULL;
618 char *hlslshaderstring = NULL;
620 //=======================================================================================================================================================
622 typedef struct shaderpermutationinfo_s
627 shaderpermutationinfo_t;
629 typedef struct shadermodeinfo_s
631 const char *filename;
637 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
638 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
640 {"#define USEDIFFUSE\n", " diffuse"},
641 {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
642 {"#define USEVIEWTINT\n", " viewtint"},
643 {"#define USECOLORMAPPING\n", " colormapping"},
644 {"#define USESATURATION\n", " saturation"},
645 {"#define USEFOGINSIDE\n", " foginside"},
646 {"#define USEFOGOUTSIDE\n", " fogoutside"},
647 {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
648 {"#define USEFOGALPHAHACK\n", " fogalphahack"},
649 {"#define USEGAMMARAMPS\n", " gammaramps"},
650 {"#define USECUBEFILTER\n", " cubefilter"},
651 {"#define USEGLOW\n", " glow"},
652 {"#define USEBLOOM\n", " bloom"},
653 {"#define USESPECULAR\n", " specular"},
654 {"#define USEPOSTPROCESSING\n", " postprocessing"},
655 {"#define USEREFLECTION\n", " reflection"},
656 {"#define USEOFFSETMAPPING\n", " offsetmapping"},
657 {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
658 {"#define USESHADOWMAP2D\n", " shadowmap2d"},
659 {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm
660 {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
661 {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
662 {"#define USEALPHAKILL\n", " alphakill"},
663 {"#define USEREFLECTCUBE\n", " reflectcube"},
664 {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
665 {"#define USEBOUNCEGRID\n", " bouncegrid"},
666 {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm
667 {"#define USETRIPPY\n", " trippy"},
668 {"#define USEDEPTHRGB\n", " depthrgb"},
669 {"#define USEALPHAGENVERTEX\n", " alphagenvertex"},
670 {"#define USESKELETAL\n", " skeletal"}
673 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
674 shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
676 {"glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
677 {"glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
678 {"glsl/default.glsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
679 {"glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
680 {"glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
681 {"glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
682 {"glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
683 {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
684 {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
685 {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
686 {"glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
687 {"glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
688 {"glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
689 {"glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
690 {"glsl/default.glsl", "#define MODE_WATER\n", " water"},
691 {"glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
692 {"glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
695 shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
697 {"hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"},
698 {"hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"},
699 {"hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
700 {"hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
701 {"hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
702 {"hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"},
703 {"hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
704 {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
705 {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
706 {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
707 {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
708 {"hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
709 {"hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
710 {"hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
711 {"hlsl/default.hlsl", "#define MODE_WATER\n", " water"},
712 {"hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
713 {"hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
716 struct r_glsl_permutation_s;
717 typedef struct r_glsl_permutation_s
720 struct r_glsl_permutation_s *hashnext;
722 unsigned int permutation;
724 /// indicates if we have tried compiling this permutation already
726 /// 0 if compilation failed
728 // texture units assigned to each detected uniform
729 int tex_Texture_First;
730 int tex_Texture_Second;
731 int tex_Texture_GammaRamps;
732 int tex_Texture_Normal;
733 int tex_Texture_Color;
734 int tex_Texture_Gloss;
735 int tex_Texture_Glow;
736 int tex_Texture_SecondaryNormal;
737 int tex_Texture_SecondaryColor;
738 int tex_Texture_SecondaryGloss;
739 int tex_Texture_SecondaryGlow;
740 int tex_Texture_Pants;
741 int tex_Texture_Shirt;
742 int tex_Texture_FogHeightTexture;
743 int tex_Texture_FogMask;
744 int tex_Texture_Lightmap;
745 int tex_Texture_Deluxemap;
746 int tex_Texture_Attenuation;
747 int tex_Texture_Cube;
748 int tex_Texture_Refraction;
749 int tex_Texture_Reflection;
750 int tex_Texture_ShadowMap2D;
751 int tex_Texture_CubeProjection;
752 int tex_Texture_ScreenNormalMap;
753 int tex_Texture_ScreenDiffuse;
754 int tex_Texture_ScreenSpecular;
755 int tex_Texture_ReflectMask;
756 int tex_Texture_ReflectCube;
757 int tex_Texture_BounceGrid;
758 /// locations of detected uniforms in program object, or -1 if not found
759 int loc_Texture_First;
760 int loc_Texture_Second;
761 int loc_Texture_GammaRamps;
762 int loc_Texture_Normal;
763 int loc_Texture_Color;
764 int loc_Texture_Gloss;
765 int loc_Texture_Glow;
766 int loc_Texture_SecondaryNormal;
767 int loc_Texture_SecondaryColor;
768 int loc_Texture_SecondaryGloss;
769 int loc_Texture_SecondaryGlow;
770 int loc_Texture_Pants;
771 int loc_Texture_Shirt;
772 int loc_Texture_FogHeightTexture;
773 int loc_Texture_FogMask;
774 int loc_Texture_Lightmap;
775 int loc_Texture_Deluxemap;
776 int loc_Texture_Attenuation;
777 int loc_Texture_Cube;
778 int loc_Texture_Refraction;
779 int loc_Texture_Reflection;
780 int loc_Texture_ShadowMap2D;
781 int loc_Texture_CubeProjection;
782 int loc_Texture_ScreenNormalMap;
783 int loc_Texture_ScreenDiffuse;
784 int loc_Texture_ScreenSpecular;
785 int loc_Texture_ReflectMask;
786 int loc_Texture_ReflectCube;
787 int loc_Texture_BounceGrid;
789 int loc_BloomBlur_Parameters;
791 int loc_Color_Ambient;
792 int loc_Color_Diffuse;
793 int loc_Color_Specular;
797 int loc_DeferredColor_Ambient;
798 int loc_DeferredColor_Diffuse;
799 int loc_DeferredColor_Specular;
800 int loc_DeferredMod_Diffuse;
801 int loc_DeferredMod_Specular;
802 int loc_DistortScaleRefractReflect;
805 int loc_FogHeightFade;
807 int loc_FogPlaneViewDist;
808 int loc_FogRangeRecip;
811 int loc_LightPosition;
812 int loc_OffsetMapping_ScaleSteps;
813 int loc_OffsetMapping_LodDistance;
814 int loc_OffsetMapping_Bias;
816 int loc_ReflectColor;
817 int loc_ReflectFactor;
818 int loc_ReflectOffset;
819 int loc_RefractColor;
821 int loc_ScreenCenterRefractReflect;
822 int loc_ScreenScaleRefractReflect;
823 int loc_ScreenToDepth;
824 int loc_ShadowMap_Parameters;
825 int loc_ShadowMap_TextureScale;
826 int loc_SpecularPower;
827 int loc_Skeletal_Transform12;
832 int loc_ViewTintColor;
834 int loc_ModelToLight;
836 int loc_BackgroundTexMatrix;
837 int loc_ModelViewProjectionMatrix;
838 int loc_ModelViewMatrix;
839 int loc_PixelToScreenTexCoord;
840 int loc_ModelToReflectCube;
841 int loc_ShadowMapMatrix;
842 int loc_BloomColorSubtract;
843 int loc_NormalmapScrollBlend;
844 int loc_BounceGridMatrix;
845 int loc_BounceGridIntensity;
847 r_glsl_permutation_t;
849 #define SHADERPERMUTATION_HASHSIZE 256
852 // non-degradable "lightweight" shader parameters to keep the permutations simpler
853 // these can NOT degrade! only use for simple stuff
856 SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0, ///< red compensation filter for saturation
857 SHADERSTATICPARM_EXACTSPECULARMATH = 1, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
858 SHADERSTATICPARM_POSTPROCESS_USERVEC1 = 2, ///< postprocess uservec1 is enabled
859 SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
860 SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
861 SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5, ///< postprocess uservec4 is enabled
862 SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
863 SHADERSTATICPARM_OFFSETMAPPING_USELOD = 7, ///< LOD for offsetmapping
864 SHADERSTATICPARM_SHADOWMAPPCF_1 = 8, ///< PCF 1
865 SHADERSTATICPARM_SHADOWMAPPCF_2 = 9, ///< PCF 2
866 SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler
867 SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math)
868 SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines)
870 #define SHADERSTATICPARMS_COUNT 13
872 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
873 static int shaderstaticparms_count = 0;
875 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
876 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
878 extern qboolean r_shadow_shadowmapsampler;
879 extern int r_shadow_shadowmappcf;
880 qboolean R_CompileShader_CheckStaticParms(void)
882 static int r_compileshader_staticparms_save[1];
883 memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
884 memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
887 if (r_glsl_saturation_redcompensate.integer)
888 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
889 if (r_glsl_vertextextureblend_usebothalphas.integer)
890 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS);
891 if (r_shadow_glossexact.integer)
892 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_EXACTSPECULARMATH);
893 if (r_glsl_postprocess.integer)
895 if (r_glsl_postprocess_uservec1_enable.integer)
896 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC1);
897 if (r_glsl_postprocess_uservec2_enable.integer)
898 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC2);
899 if (r_glsl_postprocess_uservec3_enable.integer)
900 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC3);
901 if (r_glsl_postprocess_uservec4_enable.integer)
902 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
904 if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
905 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
907 if (r_shadow_shadowmapsampler)
908 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWSAMPLER);
909 if (r_shadow_shadowmappcf > 1)
910 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_2);
911 else if (r_shadow_shadowmappcf)
912 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_1);
913 if (r_celshading.integer)
914 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELSHADING);
915 if (r_celoutlines.integer)
916 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELOUTLINES);
918 return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
921 #define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
922 if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
923 shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
925 shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
926 static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
928 shaderstaticparms_count = 0;
931 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
932 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_EXACTSPECULARMATH, "USEEXACTSPECULARMATH");
933 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC1, "USERVEC1");
934 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC2, "USERVEC2");
935 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
936 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
937 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
938 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_OFFSETMAPPING_USELOD, "USEOFFSETMAPPING_LOD");
939 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_1, "USESHADOWMAPPCF 1");
940 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_2, "USESHADOWMAPPCF 2");
941 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER");
942 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING");
943 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES");
946 /// information about each possible shader permutation
947 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
948 /// currently selected permutation
949 r_glsl_permutation_t *r_glsl_permutation;
950 /// storage for permutations linked in the hash table
951 memexpandablearray_t r_glsl_permutationarray;
953 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation)
955 //unsigned int hashdepth = 0;
956 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
957 r_glsl_permutation_t *p;
958 for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
960 if (p->mode == mode && p->permutation == permutation)
962 //if (hashdepth > 10)
963 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
968 p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
970 p->permutation = permutation;
971 p->hashnext = r_glsl_permutationhash[mode][hashindex];
972 r_glsl_permutationhash[mode][hashindex] = p;
973 //if (hashdepth > 10)
974 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
978 static char *R_ShaderStrCat(const char **strings)
981 const char **p = strings;
984 for (p = strings;(t = *p);p++)
987 s = string = (char *)Mem_Alloc(r_main_mempool, len);
989 for (p = strings;(t = *p);p++)
999 static char *R_GetShaderText(const char *filename, qboolean printfromdisknotice, qboolean builtinonly)
1002 if (!filename || !filename[0])
1004 // LordHavoc: note that FS_LoadFile appends a 0 byte to make it a valid string, so does R_ShaderStrCat
1005 if (!strcmp(filename, "glsl/default.glsl"))
1008 return R_ShaderStrCat(builtinshaderstrings);
1009 if (!glslshaderstring)
1011 glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1012 if (glslshaderstring)
1013 Con_DPrintf("Loading shaders from file %s...\n", filename);
1015 glslshaderstring = R_ShaderStrCat(builtinshaderstrings);
1017 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1);
1018 memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1);
1019 return shaderstring;
1021 if (!strcmp(filename, "hlsl/default.hlsl"))
1024 return R_ShaderStrCat(builtinhlslshaderstrings);
1025 if (!hlslshaderstring)
1027 hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1028 if (hlslshaderstring)
1029 Con_DPrintf("Loading shaders from file %s...\n", filename);
1031 hlslshaderstring = R_ShaderStrCat(builtinhlslshaderstrings);
1033 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
1034 memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
1035 return shaderstring;
1037 // we don't have builtin strings for any other files
1040 shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
1043 if (printfromdisknotice)
1044 Con_DPrintf("from disk %s... ", filename);
1045 return shaderstring;
1047 return shaderstring;
1050 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1054 shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
1056 char permutationname[256];
1057 int vertstrings_count = 0;
1058 int geomstrings_count = 0;
1059 int fragstrings_count = 0;
1060 const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1061 const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1062 const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1069 permutationname[0] = 0;
1070 sourcestring = R_GetShaderText(modeinfo->filename, true, false);
1072 strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
1074 // if we can do #version 130, we should (this improves quality of offset/reliefmapping thanks to textureGrad)
1075 if(vid.support.gl20shaders130)
1077 vertstrings_list[vertstrings_count++] = "#version 130\n";
1078 geomstrings_list[geomstrings_count++] = "#version 130\n";
1079 fragstrings_list[fragstrings_count++] = "#version 130\n";
1080 vertstrings_list[vertstrings_count++] = "#define GLSL130\n";
1081 geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
1082 fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
1085 // the first pretext is which type of shader to compile as
1086 // (later these will all be bound together as a program object)
1087 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1088 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1089 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1091 // the second pretext is the mode (for example a light source)
1092 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1093 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1094 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1095 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1097 // now add all the permutation pretexts
1098 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1100 if (permutation & (1<<i))
1102 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1103 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1104 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1105 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1109 // keep line numbers correct
1110 vertstrings_list[vertstrings_count++] = "\n";
1111 geomstrings_list[geomstrings_count++] = "\n";
1112 fragstrings_list[fragstrings_count++] = "\n";
1117 R_CompileShader_AddStaticParms(mode, permutation);
1118 memcpy((char *)(vertstrings_list + vertstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1119 vertstrings_count += shaderstaticparms_count;
1120 memcpy((char *)(geomstrings_list + geomstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1121 geomstrings_count += shaderstaticparms_count;
1122 memcpy((char *)(fragstrings_list + fragstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1123 fragstrings_count += shaderstaticparms_count;
1125 // now append the shader text itself
1126 vertstrings_list[vertstrings_count++] = sourcestring;
1127 geomstrings_list[geomstrings_count++] = sourcestring;
1128 fragstrings_list[fragstrings_count++] = sourcestring;
1130 // compile the shader program
1131 if (vertstrings_count + geomstrings_count + fragstrings_count)
1132 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1136 qglUseProgram(p->program);CHECKGLERROR
1137 // look up all the uniform variable names we care about, so we don't
1138 // have to look them up every time we set them
1140 p->loc_Texture_First = qglGetUniformLocation(p->program, "Texture_First");
1141 p->loc_Texture_Second = qglGetUniformLocation(p->program, "Texture_Second");
1142 p->loc_Texture_GammaRamps = qglGetUniformLocation(p->program, "Texture_GammaRamps");
1143 p->loc_Texture_Normal = qglGetUniformLocation(p->program, "Texture_Normal");
1144 p->loc_Texture_Color = qglGetUniformLocation(p->program, "Texture_Color");
1145 p->loc_Texture_Gloss = qglGetUniformLocation(p->program, "Texture_Gloss");
1146 p->loc_Texture_Glow = qglGetUniformLocation(p->program, "Texture_Glow");
1147 p->loc_Texture_SecondaryNormal = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
1148 p->loc_Texture_SecondaryColor = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
1149 p->loc_Texture_SecondaryGloss = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
1150 p->loc_Texture_SecondaryGlow = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
1151 p->loc_Texture_Pants = qglGetUniformLocation(p->program, "Texture_Pants");
1152 p->loc_Texture_Shirt = qglGetUniformLocation(p->program, "Texture_Shirt");
1153 p->loc_Texture_FogHeightTexture = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
1154 p->loc_Texture_FogMask = qglGetUniformLocation(p->program, "Texture_FogMask");
1155 p->loc_Texture_Lightmap = qglGetUniformLocation(p->program, "Texture_Lightmap");
1156 p->loc_Texture_Deluxemap = qglGetUniformLocation(p->program, "Texture_Deluxemap");
1157 p->loc_Texture_Attenuation = qglGetUniformLocation(p->program, "Texture_Attenuation");
1158 p->loc_Texture_Cube = qglGetUniformLocation(p->program, "Texture_Cube");
1159 p->loc_Texture_Refraction = qglGetUniformLocation(p->program, "Texture_Refraction");
1160 p->loc_Texture_Reflection = qglGetUniformLocation(p->program, "Texture_Reflection");
1161 p->loc_Texture_ShadowMap2D = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
1162 p->loc_Texture_CubeProjection = qglGetUniformLocation(p->program, "Texture_CubeProjection");
1163 p->loc_Texture_ScreenNormalMap = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
1164 p->loc_Texture_ScreenDiffuse = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
1165 p->loc_Texture_ScreenSpecular = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
1166 p->loc_Texture_ReflectMask = qglGetUniformLocation(p->program, "Texture_ReflectMask");
1167 p->loc_Texture_ReflectCube = qglGetUniformLocation(p->program, "Texture_ReflectCube");
1168 p->loc_Texture_BounceGrid = qglGetUniformLocation(p->program, "Texture_BounceGrid");
1169 p->loc_Alpha = qglGetUniformLocation(p->program, "Alpha");
1170 p->loc_BloomBlur_Parameters = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
1171 p->loc_ClientTime = qglGetUniformLocation(p->program, "ClientTime");
1172 p->loc_Color_Ambient = qglGetUniformLocation(p->program, "Color_Ambient");
1173 p->loc_Color_Diffuse = qglGetUniformLocation(p->program, "Color_Diffuse");
1174 p->loc_Color_Specular = qglGetUniformLocation(p->program, "Color_Specular");
1175 p->loc_Color_Glow = qglGetUniformLocation(p->program, "Color_Glow");
1176 p->loc_Color_Pants = qglGetUniformLocation(p->program, "Color_Pants");
1177 p->loc_Color_Shirt = qglGetUniformLocation(p->program, "Color_Shirt");
1178 p->loc_DeferredColor_Ambient = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
1179 p->loc_DeferredColor_Diffuse = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
1180 p->loc_DeferredColor_Specular = qglGetUniformLocation(p->program, "DeferredColor_Specular");
1181 p->loc_DeferredMod_Diffuse = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
1182 p->loc_DeferredMod_Specular = qglGetUniformLocation(p->program, "DeferredMod_Specular");
1183 p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
1184 p->loc_EyePosition = qglGetUniformLocation(p->program, "EyePosition");
1185 p->loc_FogColor = qglGetUniformLocation(p->program, "FogColor");
1186 p->loc_FogHeightFade = qglGetUniformLocation(p->program, "FogHeightFade");
1187 p->loc_FogPlane = qglGetUniformLocation(p->program, "FogPlane");
1188 p->loc_FogPlaneViewDist = qglGetUniformLocation(p->program, "FogPlaneViewDist");
1189 p->loc_FogRangeRecip = qglGetUniformLocation(p->program, "FogRangeRecip");
1190 p->loc_LightColor = qglGetUniformLocation(p->program, "LightColor");
1191 p->loc_LightDir = qglGetUniformLocation(p->program, "LightDir");
1192 p->loc_LightPosition = qglGetUniformLocation(p->program, "LightPosition");
1193 p->loc_OffsetMapping_ScaleSteps = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
1194 p->loc_OffsetMapping_LodDistance = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
1195 p->loc_OffsetMapping_Bias = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
1196 p->loc_PixelSize = qglGetUniformLocation(p->program, "PixelSize");
1197 p->loc_ReflectColor = qglGetUniformLocation(p->program, "ReflectColor");
1198 p->loc_ReflectFactor = qglGetUniformLocation(p->program, "ReflectFactor");
1199 p->loc_ReflectOffset = qglGetUniformLocation(p->program, "ReflectOffset");
1200 p->loc_RefractColor = qglGetUniformLocation(p->program, "RefractColor");
1201 p->loc_Saturation = qglGetUniformLocation(p->program, "Saturation");
1202 p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
1203 p->loc_ScreenScaleRefractReflect = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
1204 p->loc_ScreenToDepth = qglGetUniformLocation(p->program, "ScreenToDepth");
1205 p->loc_ShadowMap_Parameters = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
1206 p->loc_ShadowMap_TextureScale = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
1207 p->loc_SpecularPower = qglGetUniformLocation(p->program, "SpecularPower");
1208 p->loc_Skeletal_Transform12 = qglGetUniformLocation(p->program, "Skeletal_Transform12");
1209 p->loc_UserVec1 = qglGetUniformLocation(p->program, "UserVec1");
1210 p->loc_UserVec2 = qglGetUniformLocation(p->program, "UserVec2");
1211 p->loc_UserVec3 = qglGetUniformLocation(p->program, "UserVec3");
1212 p->loc_UserVec4 = qglGetUniformLocation(p->program, "UserVec4");
1213 p->loc_ViewTintColor = qglGetUniformLocation(p->program, "ViewTintColor");
1214 p->loc_ViewToLight = qglGetUniformLocation(p->program, "ViewToLight");
1215 p->loc_ModelToLight = qglGetUniformLocation(p->program, "ModelToLight");
1216 p->loc_TexMatrix = qglGetUniformLocation(p->program, "TexMatrix");
1217 p->loc_BackgroundTexMatrix = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
1218 p->loc_ModelViewMatrix = qglGetUniformLocation(p->program, "ModelViewMatrix");
1219 p->loc_ModelViewProjectionMatrix = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
1220 p->loc_PixelToScreenTexCoord = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
1221 p->loc_ModelToReflectCube = qglGetUniformLocation(p->program, "ModelToReflectCube");
1222 p->loc_ShadowMapMatrix = qglGetUniformLocation(p->program, "ShadowMapMatrix");
1223 p->loc_BloomColorSubtract = qglGetUniformLocation(p->program, "BloomColorSubtract");
1224 p->loc_NormalmapScrollBlend = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
1225 p->loc_BounceGridMatrix = qglGetUniformLocation(p->program, "BounceGridMatrix");
1226 p->loc_BounceGridIntensity = qglGetUniformLocation(p->program, "BounceGridIntensity");
1227 // initialize the samplers to refer to the texture units we use
1228 p->tex_Texture_First = -1;
1229 p->tex_Texture_Second = -1;
1230 p->tex_Texture_GammaRamps = -1;
1231 p->tex_Texture_Normal = -1;
1232 p->tex_Texture_Color = -1;
1233 p->tex_Texture_Gloss = -1;
1234 p->tex_Texture_Glow = -1;
1235 p->tex_Texture_SecondaryNormal = -1;
1236 p->tex_Texture_SecondaryColor = -1;
1237 p->tex_Texture_SecondaryGloss = -1;
1238 p->tex_Texture_SecondaryGlow = -1;
1239 p->tex_Texture_Pants = -1;
1240 p->tex_Texture_Shirt = -1;
1241 p->tex_Texture_FogHeightTexture = -1;
1242 p->tex_Texture_FogMask = -1;
1243 p->tex_Texture_Lightmap = -1;
1244 p->tex_Texture_Deluxemap = -1;
1245 p->tex_Texture_Attenuation = -1;
1246 p->tex_Texture_Cube = -1;
1247 p->tex_Texture_Refraction = -1;
1248 p->tex_Texture_Reflection = -1;
1249 p->tex_Texture_ShadowMap2D = -1;
1250 p->tex_Texture_CubeProjection = -1;
1251 p->tex_Texture_ScreenNormalMap = -1;
1252 p->tex_Texture_ScreenDiffuse = -1;
1253 p->tex_Texture_ScreenSpecular = -1;
1254 p->tex_Texture_ReflectMask = -1;
1255 p->tex_Texture_ReflectCube = -1;
1256 p->tex_Texture_BounceGrid = -1;
1258 if (p->loc_Texture_First >= 0) {p->tex_Texture_First = sampler;qglUniform1i(p->loc_Texture_First , sampler);sampler++;}
1259 if (p->loc_Texture_Second >= 0) {p->tex_Texture_Second = sampler;qglUniform1i(p->loc_Texture_Second , sampler);sampler++;}
1260 if (p->loc_Texture_GammaRamps >= 0) {p->tex_Texture_GammaRamps = sampler;qglUniform1i(p->loc_Texture_GammaRamps , sampler);sampler++;}
1261 if (p->loc_Texture_Normal >= 0) {p->tex_Texture_Normal = sampler;qglUniform1i(p->loc_Texture_Normal , sampler);sampler++;}
1262 if (p->loc_Texture_Color >= 0) {p->tex_Texture_Color = sampler;qglUniform1i(p->loc_Texture_Color , sampler);sampler++;}
1263 if (p->loc_Texture_Gloss >= 0) {p->tex_Texture_Gloss = sampler;qglUniform1i(p->loc_Texture_Gloss , sampler);sampler++;}
1264 if (p->loc_Texture_Glow >= 0) {p->tex_Texture_Glow = sampler;qglUniform1i(p->loc_Texture_Glow , sampler);sampler++;}
1265 if (p->loc_Texture_SecondaryNormal >= 0) {p->tex_Texture_SecondaryNormal = sampler;qglUniform1i(p->loc_Texture_SecondaryNormal , sampler);sampler++;}
1266 if (p->loc_Texture_SecondaryColor >= 0) {p->tex_Texture_SecondaryColor = sampler;qglUniform1i(p->loc_Texture_SecondaryColor , sampler);sampler++;}
1267 if (p->loc_Texture_SecondaryGloss >= 0) {p->tex_Texture_SecondaryGloss = sampler;qglUniform1i(p->loc_Texture_SecondaryGloss , sampler);sampler++;}
1268 if (p->loc_Texture_SecondaryGlow >= 0) {p->tex_Texture_SecondaryGlow = sampler;qglUniform1i(p->loc_Texture_SecondaryGlow , sampler);sampler++;}
1269 if (p->loc_Texture_Pants >= 0) {p->tex_Texture_Pants = sampler;qglUniform1i(p->loc_Texture_Pants , sampler);sampler++;}
1270 if (p->loc_Texture_Shirt >= 0) {p->tex_Texture_Shirt = sampler;qglUniform1i(p->loc_Texture_Shirt , sampler);sampler++;}
1271 if (p->loc_Texture_FogHeightTexture>= 0) {p->tex_Texture_FogHeightTexture = sampler;qglUniform1i(p->loc_Texture_FogHeightTexture, sampler);sampler++;}
1272 if (p->loc_Texture_FogMask >= 0) {p->tex_Texture_FogMask = sampler;qglUniform1i(p->loc_Texture_FogMask , sampler);sampler++;}
1273 if (p->loc_Texture_Lightmap >= 0) {p->tex_Texture_Lightmap = sampler;qglUniform1i(p->loc_Texture_Lightmap , sampler);sampler++;}
1274 if (p->loc_Texture_Deluxemap >= 0) {p->tex_Texture_Deluxemap = sampler;qglUniform1i(p->loc_Texture_Deluxemap , sampler);sampler++;}
1275 if (p->loc_Texture_Attenuation >= 0) {p->tex_Texture_Attenuation = sampler;qglUniform1i(p->loc_Texture_Attenuation , sampler);sampler++;}
1276 if (p->loc_Texture_Cube >= 0) {p->tex_Texture_Cube = sampler;qglUniform1i(p->loc_Texture_Cube , sampler);sampler++;}
1277 if (p->loc_Texture_Refraction >= 0) {p->tex_Texture_Refraction = sampler;qglUniform1i(p->loc_Texture_Refraction , sampler);sampler++;}
1278 if (p->loc_Texture_Reflection >= 0) {p->tex_Texture_Reflection = sampler;qglUniform1i(p->loc_Texture_Reflection , sampler);sampler++;}
1279 if (p->loc_Texture_ShadowMap2D >= 0) {p->tex_Texture_ShadowMap2D = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D , sampler);sampler++;}
1280 if (p->loc_Texture_CubeProjection >= 0) {p->tex_Texture_CubeProjection = sampler;qglUniform1i(p->loc_Texture_CubeProjection , sampler);sampler++;}
1281 if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
1282 if (p->loc_Texture_ScreenDiffuse >= 0) {p->tex_Texture_ScreenDiffuse = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse , sampler);sampler++;}
1283 if (p->loc_Texture_ScreenSpecular >= 0) {p->tex_Texture_ScreenSpecular = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular , sampler);sampler++;}
1284 if (p->loc_Texture_ReflectMask >= 0) {p->tex_Texture_ReflectMask = sampler;qglUniform1i(p->loc_Texture_ReflectMask , sampler);sampler++;}
1285 if (p->loc_Texture_ReflectCube >= 0) {p->tex_Texture_ReflectCube = sampler;qglUniform1i(p->loc_Texture_ReflectCube , sampler);sampler++;}
1286 if (p->loc_Texture_BounceGrid >= 0) {p->tex_Texture_BounceGrid = sampler;qglUniform1i(p->loc_Texture_BounceGrid , sampler);sampler++;}
1288 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
1291 Con_Printf("^1GLSL shader %s failed! some features may not work properly.\n", permutationname);
1295 Mem_Free(sourcestring);
1298 static void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
1300 r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
1301 if (r_glsl_permutation != perm)
1303 r_glsl_permutation = perm;
1304 if (!r_glsl_permutation->program)
1306 if (!r_glsl_permutation->compiled)
1307 R_GLSL_CompilePermutation(perm, mode, permutation);
1308 if (!r_glsl_permutation->program)
1310 // remove features until we find a valid permutation
1312 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1314 // reduce i more quickly whenever it would not remove any bits
1315 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1316 if (!(permutation & j))
1319 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1320 if (!r_glsl_permutation->compiled)
1321 R_GLSL_CompilePermutation(perm, mode, permutation);
1322 if (r_glsl_permutation->program)
1325 if (i >= SHADERPERMUTATION_COUNT)
1327 //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].filename, shadermodeinfo[mode].pretext);
1328 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1329 qglUseProgram(0);CHECKGLERROR
1330 return; // no bit left to clear, entire mode is broken
1335 qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
1337 if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
1338 if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
1339 if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
1346 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
1347 extern D3DCAPS9 vid_d3d9caps;
1350 struct r_hlsl_permutation_s;
1351 typedef struct r_hlsl_permutation_s
1353 /// hash lookup data
1354 struct r_hlsl_permutation_s *hashnext;
1356 unsigned int permutation;
1358 /// indicates if we have tried compiling this permutation already
1360 /// NULL if compilation failed
1361 IDirect3DVertexShader9 *vertexshader;
1362 IDirect3DPixelShader9 *pixelshader;
1364 r_hlsl_permutation_t;
1366 typedef enum D3DVSREGISTER_e
1368 D3DVSREGISTER_TexMatrix = 0, // float4x4
1369 D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
1370 D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
1371 D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
1372 D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
1373 D3DVSREGISTER_ModelToLight = 20, // float4x4
1374 D3DVSREGISTER_EyePosition = 24,
1375 D3DVSREGISTER_FogPlane = 25,
1376 D3DVSREGISTER_LightDir = 26,
1377 D3DVSREGISTER_LightPosition = 27,
1381 typedef enum D3DPSREGISTER_e
1383 D3DPSREGISTER_Alpha = 0,
1384 D3DPSREGISTER_BloomBlur_Parameters = 1,
1385 D3DPSREGISTER_ClientTime = 2,
1386 D3DPSREGISTER_Color_Ambient = 3,
1387 D3DPSREGISTER_Color_Diffuse = 4,
1388 D3DPSREGISTER_Color_Specular = 5,
1389 D3DPSREGISTER_Color_Glow = 6,
1390 D3DPSREGISTER_Color_Pants = 7,
1391 D3DPSREGISTER_Color_Shirt = 8,
1392 D3DPSREGISTER_DeferredColor_Ambient = 9,
1393 D3DPSREGISTER_DeferredColor_Diffuse = 10,
1394 D3DPSREGISTER_DeferredColor_Specular = 11,
1395 D3DPSREGISTER_DeferredMod_Diffuse = 12,
1396 D3DPSREGISTER_DeferredMod_Specular = 13,
1397 D3DPSREGISTER_DistortScaleRefractReflect = 14,
1398 D3DPSREGISTER_EyePosition = 15, // unused
1399 D3DPSREGISTER_FogColor = 16,
1400 D3DPSREGISTER_FogHeightFade = 17,
1401 D3DPSREGISTER_FogPlane = 18,
1402 D3DPSREGISTER_FogPlaneViewDist = 19,
1403 D3DPSREGISTER_FogRangeRecip = 20,
1404 D3DPSREGISTER_LightColor = 21,
1405 D3DPSREGISTER_LightDir = 22, // unused
1406 D3DPSREGISTER_LightPosition = 23,
1407 D3DPSREGISTER_OffsetMapping_ScaleSteps = 24,
1408 D3DPSREGISTER_PixelSize = 25,
1409 D3DPSREGISTER_ReflectColor = 26,
1410 D3DPSREGISTER_ReflectFactor = 27,
1411 D3DPSREGISTER_ReflectOffset = 28,
1412 D3DPSREGISTER_RefractColor = 29,
1413 D3DPSREGISTER_Saturation = 30,
1414 D3DPSREGISTER_ScreenCenterRefractReflect = 31,
1415 D3DPSREGISTER_ScreenScaleRefractReflect = 32,
1416 D3DPSREGISTER_ScreenToDepth = 33,
1417 D3DPSREGISTER_ShadowMap_Parameters = 34,
1418 D3DPSREGISTER_ShadowMap_TextureScale = 35,
1419 D3DPSREGISTER_SpecularPower = 36,
1420 D3DPSREGISTER_UserVec1 = 37,
1421 D3DPSREGISTER_UserVec2 = 38,
1422 D3DPSREGISTER_UserVec3 = 39,
1423 D3DPSREGISTER_UserVec4 = 40,
1424 D3DPSREGISTER_ViewTintColor = 41,
1425 D3DPSREGISTER_PixelToScreenTexCoord = 42,
1426 D3DPSREGISTER_BloomColorSubtract = 43,
1427 D3DPSREGISTER_ViewToLight = 44, // float4x4
1428 D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
1429 D3DPSREGISTER_NormalmapScrollBlend = 52,
1430 D3DPSREGISTER_OffsetMapping_LodDistance = 53,
1431 D3DPSREGISTER_OffsetMapping_Bias = 54,
1436 /// information about each possible shader permutation
1437 r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
1438 /// currently selected permutation
1439 r_hlsl_permutation_t *r_hlsl_permutation;
1440 /// storage for permutations linked in the hash table
1441 memexpandablearray_t r_hlsl_permutationarray;
1443 static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, unsigned int permutation)
1445 //unsigned int hashdepth = 0;
1446 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
1447 r_hlsl_permutation_t *p;
1448 for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1450 if (p->mode == mode && p->permutation == permutation)
1452 //if (hashdepth > 10)
1453 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1458 p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
1460 p->permutation = permutation;
1461 p->hashnext = r_hlsl_permutationhash[mode][hashindex];
1462 r_hlsl_permutationhash[mode][hashindex] = p;
1463 //if (hashdepth > 10)
1464 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1469 //#include <d3dx9shader.h>
1470 //#include <d3dx9mesh.h>
1472 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
1474 DWORD *vsbin = NULL;
1475 DWORD *psbin = NULL;
1476 fs_offset_t vsbinsize;
1477 fs_offset_t psbinsize;
1478 // IDirect3DVertexShader9 *vs = NULL;
1479 // IDirect3DPixelShader9 *ps = NULL;
1480 ID3DXBuffer *vslog = NULL;
1481 ID3DXBuffer *vsbuffer = NULL;
1482 ID3DXConstantTable *vsconstanttable = NULL;
1483 ID3DXBuffer *pslog = NULL;
1484 ID3DXBuffer *psbuffer = NULL;
1485 ID3DXConstantTable *psconstanttable = NULL;
1488 char temp[MAX_INPUTLINE];
1489 const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
1491 qboolean debugshader = gl_paranoid.integer != 0;
1492 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1493 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1496 vsbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
1497 psbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.psbin", cachename), r_main_mempool, true, &psbinsize);
1499 if ((!vsbin && vertstring) || (!psbin && fragstring))
1501 const char* dllnames_d3dx9 [] =
1525 dllhandle_t d3dx9_dll = NULL;
1526 HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1527 HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
1528 HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1529 dllfunction_t d3dx9_dllfuncs[] =
1531 {"D3DXCompileShaderFromFileA", (void **) &qD3DXCompileShaderFromFileA},
1532 {"D3DXPreprocessShader", (void **) &qD3DXPreprocessShader},
1533 {"D3DXCompileShader", (void **) &qD3DXCompileShader},
1536 // LordHavoc: the June 2010 SDK lacks these macros to make ID3DXBuffer usable in C, and to make it work in both C and C++ the macros are needed...
1537 #ifndef ID3DXBuffer_GetBufferPointer
1538 #if !defined(__cplusplus) || defined(CINTERFACE)
1539 #define ID3DXBuffer_GetBufferPointer(p) (p)->lpVtbl->GetBufferPointer(p)
1540 #define ID3DXBuffer_GetBufferSize(p) (p)->lpVtbl->GetBufferSize(p)
1541 #define ID3DXBuffer_Release(p) (p)->lpVtbl->Release(p)
1543 #define ID3DXBuffer_GetBufferPointer(p) (p)->GetBufferPointer()
1544 #define ID3DXBuffer_GetBufferSize(p) (p)->GetBufferSize()
1545 #define ID3DXBuffer_Release(p) (p)->Release()
1548 if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
1550 DWORD shaderflags = 0;
1552 shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
1553 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1554 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1555 if (vertstring && vertstring[0])
1559 FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vertstring, strlen(vertstring));
1560 vsresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1563 vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1566 vsbinsize = ID3DXBuffer_GetBufferSize(vsbuffer);
1567 vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
1568 memcpy(vsbin, ID3DXBuffer_GetBufferPointer(vsbuffer), vsbinsize);
1569 ID3DXBuffer_Release(vsbuffer);
1573 strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(vslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(vslog)));
1574 Con_DPrintf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
1575 ID3DXBuffer_Release(vslog);
1578 if (fragstring && fragstring[0])
1582 FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), fragstring, strlen(fragstring));
1583 psresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1586 psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1589 psbinsize = ID3DXBuffer_GetBufferSize(psbuffer);
1590 psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
1591 memcpy(psbin, ID3DXBuffer_GetBufferPointer(psbuffer), psbinsize);
1592 ID3DXBuffer_Release(psbuffer);
1596 strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(pslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(pslog)));
1597 Con_DPrintf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
1598 ID3DXBuffer_Release(pslog);
1601 Sys_UnloadLibrary(&d3dx9_dll);
1604 Con_DPrintf("Unable to compile shader - D3DXCompileShader function not found\n");
1608 vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
1609 if (FAILED(vsresult))
1610 Con_DPrintf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
1611 psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
1612 if (FAILED(psresult))
1613 Con_DPrintf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
1615 // free the shader data
1616 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1617 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1620 static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
1623 shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
1624 int vertstring_length = 0;
1625 int geomstring_length = 0;
1626 int fragstring_length = 0;
1629 char *vertstring, *geomstring, *fragstring;
1630 char permutationname[256];
1631 char cachename[256];
1632 int vertstrings_count = 0;
1633 int geomstrings_count = 0;
1634 int fragstrings_count = 0;
1635 const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1636 const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1637 const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1642 p->vertexshader = NULL;
1643 p->pixelshader = NULL;
1645 permutationname[0] = 0;
1647 sourcestring = R_GetShaderText(modeinfo->filename, true, false);
1649 strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
1650 strlcat(cachename, "hlsl/", sizeof(cachename));
1652 // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
1653 vertstrings_count = 0;
1654 geomstrings_count = 0;
1655 fragstrings_count = 0;
1656 vertstrings_list[vertstrings_count++] = "#define HLSL\n";
1657 geomstrings_list[geomstrings_count++] = "#define HLSL\n";
1658 fragstrings_list[fragstrings_count++] = "#define HLSL\n";
1660 // the first pretext is which type of shader to compile as
1661 // (later these will all be bound together as a program object)
1662 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1663 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1664 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1666 // the second pretext is the mode (for example a light source)
1667 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1668 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1669 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1670 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1671 strlcat(cachename, modeinfo->name, sizeof(cachename));
1673 // now add all the permutation pretexts
1674 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1676 if (permutation & (1<<i))
1678 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1679 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1680 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1681 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1682 strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
1686 // keep line numbers correct
1687 vertstrings_list[vertstrings_count++] = "\n";
1688 geomstrings_list[geomstrings_count++] = "\n";
1689 fragstrings_list[fragstrings_count++] = "\n";
1694 R_CompileShader_AddStaticParms(mode, permutation);
1695 memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1696 vertstrings_count += shaderstaticparms_count;
1697 memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1698 geomstrings_count += shaderstaticparms_count;
1699 memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1700 fragstrings_count += shaderstaticparms_count;
1702 // replace spaces in the cachename with _ characters
1703 for (i = 0;cachename[i];i++)
1704 if (cachename[i] == ' ')
1707 // now append the shader text itself
1708 vertstrings_list[vertstrings_count++] = sourcestring;
1709 geomstrings_list[geomstrings_count++] = sourcestring;
1710 fragstrings_list[fragstrings_count++] = sourcestring;
1712 vertstring_length = 0;
1713 for (i = 0;i < vertstrings_count;i++)
1714 vertstring_length += strlen(vertstrings_list[i]);
1715 vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
1716 for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
1717 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
1719 geomstring_length = 0;
1720 for (i = 0;i < geomstrings_count;i++)
1721 geomstring_length += strlen(geomstrings_list[i]);
1722 geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
1723 for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
1724 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
1726 fragstring_length = 0;
1727 for (i = 0;i < fragstrings_count;i++)
1728 fragstring_length += strlen(fragstrings_list[i]);
1729 fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
1730 for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
1731 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
1733 // try to load the cached shader, or generate one
1734 R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
1736 if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
1737 Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
1739 Con_Printf("^1HLSL shader %s failed! some features may not work properly.\n", permutationname);
1743 Mem_Free(vertstring);
1745 Mem_Free(geomstring);
1747 Mem_Free(fragstring);
1749 Mem_Free(sourcestring);
1752 static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
1753 static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
1754 static inline void hlslVSSetParameter4f(D3DVSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1755 static inline void hlslVSSetParameter3f(D3DVSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1756 static inline void hlslVSSetParameter2f(D3DVSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1757 static inline void hlslVSSetParameter1f(D3DVSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, temp, 1);}
1759 static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
1760 static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
1761 static inline void hlslPSSetParameter4f(D3DPSREGISTER_t r, float x, float y, float z, float w) {float temp[4];Vector4Set(temp, x, y, z, w);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1762 static inline void hlslPSSetParameter3f(D3DPSREGISTER_t r, float x, float y, float z) {float temp[4];Vector4Set(temp, x, y, z, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1763 static inline void hlslPSSetParameter2f(D3DPSREGISTER_t r, float x, float y) {float temp[4];Vector4Set(temp, x, y, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1764 static inline void hlslPSSetParameter1f(D3DPSREGISTER_t r, float x) {float temp[4];Vector4Set(temp, x, 0, 0, 0);IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, temp, 1);}
1766 void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
1768 r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
1769 if (r_hlsl_permutation != perm)
1771 r_hlsl_permutation = perm;
1772 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1774 if (!r_hlsl_permutation->compiled)
1775 R_HLSL_CompilePermutation(perm, mode, permutation);
1776 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1778 // remove features until we find a valid permutation
1780 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1782 // reduce i more quickly whenever it would not remove any bits
1783 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
1784 if (!(permutation & j))
1787 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1788 if (!r_hlsl_permutation->compiled)
1789 R_HLSL_CompilePermutation(perm, mode, permutation);
1790 if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
1793 if (i >= SHADERPERMUTATION_COUNT)
1795 //Con_Printf("Could not find a working HLSL shader for permutation %s %s\n", shadermodeinfo[mode].filename, shadermodeinfo[mode].pretext);
1796 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1797 return; // no bit left to clear, entire mode is broken
1801 IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
1802 IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
1804 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
1805 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
1806 hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
1810 static void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
1812 DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer);
1813 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
1814 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
1815 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
1818 void R_GLSL_Restart_f(void)
1820 unsigned int i, limit;
1821 if (glslshaderstring)
1822 Mem_Free(glslshaderstring);
1823 glslshaderstring = NULL;
1824 if (hlslshaderstring)
1825 Mem_Free(hlslshaderstring);
1826 hlslshaderstring = NULL;
1827 switch(vid.renderpath)
1829 case RENDERPATH_D3D9:
1832 r_hlsl_permutation_t *p;
1833 r_hlsl_permutation = NULL;
1834 limit = Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
1835 for (i = 0;i < limit;i++)
1837 if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
1839 if (p->vertexshader)
1840 IDirect3DVertexShader9_Release(p->vertexshader);
1842 IDirect3DPixelShader9_Release(p->pixelshader);
1843 Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
1846 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
1850 case RENDERPATH_D3D10:
1851 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1853 case RENDERPATH_D3D11:
1854 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1856 case RENDERPATH_GL20:
1857 case RENDERPATH_GLES2:
1859 r_glsl_permutation_t *p;
1860 r_glsl_permutation = NULL;
1861 limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
1862 for (i = 0;i < limit;i++)
1864 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
1866 GL_Backend_FreeProgram(p->program);
1867 Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
1870 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
1873 case RENDERPATH_GL11:
1874 case RENDERPATH_GL13:
1875 case RENDERPATH_GLES1:
1877 case RENDERPATH_SOFT:
1882 static void R_GLSL_DumpShader_f(void)
1884 int i, language, mode, dupe;
1886 shadermodeinfo_t *modeinfo;
1889 for (language = 0;language < 2;language++)
1891 modeinfo = (language == 0 ? glslshadermodeinfo : hlslshadermodeinfo);
1892 for (mode = 0;mode < SHADERMODE_COUNT;mode++)
1894 // don't dump the same file multiple times (most or all shaders come from the same file)
1895 for (dupe = mode - 1;dupe >= 0;dupe--)
1896 if (!strcmp(modeinfo[mode].filename, modeinfo[dupe].filename))
1900 text = R_GetShaderText(modeinfo[mode].filename, false, true);
1903 file = FS_OpenRealFile(modeinfo[mode].filename, "w", false);
1906 FS_Print(file, "/* The engine may define the following macros:\n");
1907 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1908 for (i = 0;i < SHADERMODE_COUNT;i++)
1909 FS_Print(file, modeinfo[i].pretext);
1910 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1911 FS_Print(file, shaderpermutationinfo[i].pretext);
1912 FS_Print(file, "*/\n");
1913 FS_Print(file, text);
1915 Con_Printf("%s written\n", modeinfo[mode].filename);
1918 Con_Printf("failed to write to %s\n", modeinfo[mode].filename);
1924 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha)
1926 unsigned int permutation = 0;
1927 if (r_trippy.integer && !notrippy)
1928 permutation |= SHADERPERMUTATION_TRIPPY;
1929 permutation |= SHADERPERMUTATION_VIEWTINT;
1931 permutation |= SHADERPERMUTATION_DIFFUSE;
1933 permutation |= SHADERPERMUTATION_SPECULAR;
1934 if (texturemode == GL_MODULATE)
1935 permutation |= SHADERPERMUTATION_COLORMAPPING;
1936 else if (texturemode == GL_ADD)
1937 permutation |= SHADERPERMUTATION_GLOW;
1938 else if (texturemode == GL_DECAL)
1939 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
1940 if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
1941 permutation |= SHADERPERMUTATION_GAMMARAMPS;
1942 if (suppresstexalpha)
1943 permutation |= SHADERPERMUTATION_REFLECTCUBE;
1945 texturemode = GL_MODULATE;
1946 if (vid.allowalphatocoverage)
1947 GL_AlphaToCoverage(false);
1948 switch (vid.renderpath)
1950 case RENDERPATH_D3D9:
1952 R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, permutation);
1953 R_Mesh_TexBind(GL20TU_FIRST , first );
1954 R_Mesh_TexBind(GL20TU_SECOND, second);
1955 if (permutation & SHADERPERMUTATION_GAMMARAMPS)
1956 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
1959 case RENDERPATH_D3D10:
1960 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1962 case RENDERPATH_D3D11:
1963 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1965 case RENDERPATH_GL20:
1966 case RENDERPATH_GLES2:
1967 R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, permutation);
1968 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
1969 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
1970 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0)
1971 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
1973 case RENDERPATH_GL13:
1974 case RENDERPATH_GLES1:
1975 R_Mesh_TexBind(0, first );
1976 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
1977 R_Mesh_TexBind(1, second);
1979 R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
1981 case RENDERPATH_GL11:
1982 R_Mesh_TexBind(0, first );
1984 case RENDERPATH_SOFT:
1985 R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, permutation);
1986 R_Mesh_TexBind(GL20TU_FIRST , first );
1987 R_Mesh_TexBind(GL20TU_SECOND, second);
1992 void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy)
1994 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false);
1997 void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean skeletal)
1999 unsigned int permutation = 0;
2000 if (r_trippy.integer && !notrippy)
2001 permutation |= SHADERPERMUTATION_TRIPPY;
2003 permutation |= SHADERPERMUTATION_DEPTHRGB;
2005 permutation |= SHADERPERMUTATION_SKELETAL;
2007 if (vid.allowalphatocoverage)
2008 GL_AlphaToCoverage(false);
2009 switch (vid.renderpath)
2011 case RENDERPATH_D3D9:
2013 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2016 case RENDERPATH_D3D10:
2017 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2019 case RENDERPATH_D3D11:
2020 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2022 case RENDERPATH_GL20:
2023 case RENDERPATH_GLES2:
2024 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2026 case RENDERPATH_GL13:
2027 case RENDERPATH_GLES1:
2028 R_Mesh_TexBind(0, 0);
2029 R_Mesh_TexBind(1, 0);
2031 case RENDERPATH_GL11:
2032 R_Mesh_TexBind(0, 0);
2034 case RENDERPATH_SOFT:
2035 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2040 extern qboolean r_shadow_usingdeferredprepass;
2041 extern rtexture_t *r_shadow_attenuationgradienttexture;
2042 extern rtexture_t *r_shadow_attenuation2dtexture;
2043 extern rtexture_t *r_shadow_attenuation3dtexture;
2044 extern qboolean r_shadow_usingshadowmap2d;
2045 extern qboolean r_shadow_usingshadowmaportho;
2046 extern float r_shadow_shadowmap_texturescale[2];
2047 extern float r_shadow_shadowmap_parameters[4];
2048 extern qboolean r_shadow_shadowmapvsdct;
2049 extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
2050 extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
2051 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
2052 extern matrix4x4_t r_shadow_shadowmapmatrix;
2053 extern int r_shadow_shadowmaplod; // changes for each light based on distance
2054 extern int r_shadow_prepass_width;
2055 extern int r_shadow_prepass_height;
2056 extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
2057 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
2058 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
2059 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
2061 #define BLENDFUNC_ALLOWS_COLORMOD 1
2062 #define BLENDFUNC_ALLOWS_FOG 2
2063 #define BLENDFUNC_ALLOWS_FOG_HACK0 4
2064 #define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
2065 #define BLENDFUNC_ALLOWS_ANYFOG (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2066 static int R_BlendFuncFlags(int src, int dst)
2070 // a blendfunc allows colormod if:
2071 // a) it can never keep the destination pixel invariant, or
2072 // b) it can keep the destination pixel invariant, and still can do so if colormodded
2073 // this is to prevent unintended side effects from colormod
2075 // a blendfunc allows fog if:
2076 // blend(fog(src), fog(dst)) == fog(blend(src, dst))
2077 // this is to prevent unintended side effects from fog
2079 // these checks are the output of fogeval.pl
2081 r |= BLENDFUNC_ALLOWS_COLORMOD;
2082 if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2083 if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2084 if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2085 if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2086 if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2087 if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2088 if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2089 if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2090 if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
2091 if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
2092 if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2093 if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2094 if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2095 if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2096 if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2097 if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2098 if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2099 if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2100 if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2101 if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
2102 if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2107 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)
2109 // select a permutation of the lighting shader appropriate to this
2110 // combination of texture, entity, light source, and fogging, only use the
2111 // minimum features necessary to avoid wasting rendering time in the
2112 // fragment shader on features that are not being used
2113 unsigned int permutation = 0;
2114 unsigned int mode = 0;
2116 static float dummy_colormod[3] = {1, 1, 1};
2117 float *colormod = rsurface.colormod;
2119 matrix4x4_t tempmatrix;
2120 r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
2121 if (r_trippy.integer && !notrippy)
2122 permutation |= SHADERPERMUTATION_TRIPPY;
2123 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2124 permutation |= SHADERPERMUTATION_ALPHAKILL;
2125 if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
2126 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
2127 if (rsurfacepass == RSURFPASS_BACKGROUND)
2129 // distorted background
2130 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2132 mode = SHADERMODE_WATER;
2133 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2134 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2135 if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
2137 // this is the right thing to do for wateralpha
2138 GL_BlendFunc(GL_ONE, GL_ZERO);
2139 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2143 // this is the right thing to do for entity alpha
2144 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2145 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2148 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
2150 mode = SHADERMODE_REFRACTION;
2151 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2152 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2153 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2154 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2158 mode = SHADERMODE_GENERIC;
2159 permutation |= SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_ALPHAKILL;
2160 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2161 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2163 if (vid.allowalphatocoverage)
2164 GL_AlphaToCoverage(false);
2166 else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2168 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2170 switch(rsurface.texture->offsetmapping)
2172 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2173 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2174 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2175 case OFFSETMAPPING_OFF: break;
2178 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2179 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2180 // normalmap (deferred prepass), may use alpha test on diffuse
2181 mode = SHADERMODE_DEFERREDGEOMETRY;
2182 GL_BlendFunc(GL_ONE, GL_ZERO);
2183 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2184 if (vid.allowalphatocoverage)
2185 GL_AlphaToCoverage(false);
2187 else if (rsurfacepass == RSURFPASS_RTLIGHT)
2189 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2191 switch(rsurface.texture->offsetmapping)
2193 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2194 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2195 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2196 case OFFSETMAPPING_OFF: break;
2199 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2200 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2201 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2202 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2204 mode = SHADERMODE_LIGHTSOURCE;
2205 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2206 permutation |= SHADERPERMUTATION_CUBEFILTER;
2207 if (diffusescale > 0)
2208 permutation |= SHADERPERMUTATION_DIFFUSE;
2209 if (specularscale > 0)
2210 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2211 if (r_refdef.fogenabled)
2212 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2213 if (rsurface.texture->colormapping)
2214 permutation |= SHADERPERMUTATION_COLORMAPPING;
2215 if (r_shadow_usingshadowmap2d)
2217 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2218 if(r_shadow_shadowmapvsdct)
2219 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2221 if (r_shadow_shadowmap2ddepthbuffer)
2222 permutation |= SHADERPERMUTATION_DEPTHRGB;
2224 if (rsurface.texture->reflectmasktexture)
2225 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2226 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2227 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
2228 if (vid.allowalphatocoverage)
2229 GL_AlphaToCoverage(false);
2231 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2233 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2235 switch(rsurface.texture->offsetmapping)
2237 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2238 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2239 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2240 case OFFSETMAPPING_OFF: break;
2243 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2244 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2245 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2246 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2247 // unshaded geometry (fullbright or ambient model lighting)
2248 mode = SHADERMODE_FLATCOLOR;
2249 ambientscale = diffusescale = specularscale = 0;
2250 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2251 permutation |= SHADERPERMUTATION_GLOW;
2252 if (r_refdef.fogenabled)
2253 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2254 if (rsurface.texture->colormapping)
2255 permutation |= SHADERPERMUTATION_COLORMAPPING;
2256 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2258 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2259 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2261 if (r_shadow_shadowmap2ddepthbuffer)
2262 permutation |= SHADERPERMUTATION_DEPTHRGB;
2264 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2265 permutation |= SHADERPERMUTATION_REFLECTION;
2266 if (rsurface.texture->reflectmasktexture)
2267 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2268 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2269 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2270 // when using alphatocoverage, we don't need alphakill
2271 if (vid.allowalphatocoverage)
2273 if (r_transparent_alphatocoverage.integer)
2275 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2276 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2279 GL_AlphaToCoverage(false);
2282 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2284 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2286 switch(rsurface.texture->offsetmapping)
2288 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2289 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2290 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2291 case OFFSETMAPPING_OFF: break;
2294 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2295 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2296 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2297 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2298 // directional model lighting
2299 mode = SHADERMODE_LIGHTDIRECTION;
2300 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2301 permutation |= SHADERPERMUTATION_GLOW;
2302 permutation |= SHADERPERMUTATION_DIFFUSE;
2303 if (specularscale > 0)
2304 permutation |= SHADERPERMUTATION_SPECULAR;
2305 if (r_refdef.fogenabled)
2306 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2307 if (rsurface.texture->colormapping)
2308 permutation |= SHADERPERMUTATION_COLORMAPPING;
2309 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2311 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2312 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2314 if (r_shadow_shadowmap2ddepthbuffer)
2315 permutation |= SHADERPERMUTATION_DEPTHRGB;
2317 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2318 permutation |= SHADERPERMUTATION_REFLECTION;
2319 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2320 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2321 if (rsurface.texture->reflectmasktexture)
2322 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2323 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2325 permutation |= SHADERPERMUTATION_BOUNCEGRID;
2326 if (r_shadow_bouncegriddirectional)
2327 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2329 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2330 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2331 // when using alphatocoverage, we don't need alphakill
2332 if (vid.allowalphatocoverage)
2334 if (r_transparent_alphatocoverage.integer)
2336 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2337 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2340 GL_AlphaToCoverage(false);
2343 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2345 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2347 switch(rsurface.texture->offsetmapping)
2349 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2350 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2351 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2352 case OFFSETMAPPING_OFF: break;
2355 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2356 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2357 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2358 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2359 // ambient model lighting
2360 mode = SHADERMODE_LIGHTDIRECTION;
2361 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2362 permutation |= SHADERPERMUTATION_GLOW;
2363 if (r_refdef.fogenabled)
2364 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2365 if (rsurface.texture->colormapping)
2366 permutation |= SHADERPERMUTATION_COLORMAPPING;
2367 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2369 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2370 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2372 if (r_shadow_shadowmap2ddepthbuffer)
2373 permutation |= SHADERPERMUTATION_DEPTHRGB;
2375 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2376 permutation |= SHADERPERMUTATION_REFLECTION;
2377 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2378 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2379 if (rsurface.texture->reflectmasktexture)
2380 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2381 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2383 permutation |= SHADERPERMUTATION_BOUNCEGRID;
2384 if (r_shadow_bouncegriddirectional)
2385 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2387 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2388 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2389 // when using alphatocoverage, we don't need alphakill
2390 if (vid.allowalphatocoverage)
2392 if (r_transparent_alphatocoverage.integer)
2394 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2395 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2398 GL_AlphaToCoverage(false);
2403 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2405 switch(rsurface.texture->offsetmapping)
2407 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2408 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2409 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2410 case OFFSETMAPPING_OFF: break;
2413 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2414 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2415 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2416 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2418 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2419 permutation |= SHADERPERMUTATION_GLOW;
2420 if (r_refdef.fogenabled)
2421 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2422 if (rsurface.texture->colormapping)
2423 permutation |= SHADERPERMUTATION_COLORMAPPING;
2424 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2426 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2427 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2429 if (r_shadow_shadowmap2ddepthbuffer)
2430 permutation |= SHADERPERMUTATION_DEPTHRGB;
2432 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2433 permutation |= SHADERPERMUTATION_REFLECTION;
2434 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2435 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2436 if (rsurface.texture->reflectmasktexture)
2437 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2438 if (FAKELIGHT_ENABLED)
2440 // fake lightmapping (q1bsp, q3bsp, fullbright map)
2441 mode = SHADERMODE_FAKELIGHT;
2442 permutation |= SHADERPERMUTATION_DIFFUSE;
2443 if (specularscale > 0)
2444 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2446 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2448 // deluxemapping (light direction texture)
2449 if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2450 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2452 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2453 permutation |= SHADERPERMUTATION_DIFFUSE;
2454 if (specularscale > 0)
2455 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2457 else if (r_glsl_deluxemapping.integer >= 2)
2459 // fake deluxemapping (uniform light direction in tangentspace)
2460 if (rsurface.uselightmaptexture)
2461 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP;
2463 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
2464 permutation |= SHADERPERMUTATION_DIFFUSE;
2465 if (specularscale > 0)
2466 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2468 else if (rsurface.uselightmaptexture)
2470 // ordinary lightmapping (q1bsp, q3bsp)
2471 mode = SHADERMODE_LIGHTMAP;
2475 // ordinary vertex coloring (q3bsp)
2476 mode = SHADERMODE_VERTEXCOLOR;
2478 if (r_shadow_bouncegridtexture && cl.csqc_vidvars.drawworld)
2480 permutation |= SHADERPERMUTATION_BOUNCEGRID;
2481 if (r_shadow_bouncegriddirectional)
2482 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2484 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2485 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2486 // when using alphatocoverage, we don't need alphakill
2487 if (vid.allowalphatocoverage)
2489 if (r_transparent_alphatocoverage.integer)
2491 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2492 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2495 GL_AlphaToCoverage(false);
2498 if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
2499 colormod = dummy_colormod;
2500 if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
2501 permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
2502 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2503 permutation |= SHADERPERMUTATION_FOGALPHAHACK;
2504 switch(vid.renderpath)
2506 case RENDERPATH_D3D9:
2508 RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2509 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2510 R_SetupShader_SetPermutationHLSL(mode, permutation);
2511 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
2512 if (mode == SHADERMODE_LIGHTSOURCE)
2514 Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
2515 hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2519 if (mode == SHADERMODE_LIGHTDIRECTION)
2521 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2524 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
2525 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
2526 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
2527 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2528 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2530 if (mode == SHADERMODE_LIGHTSOURCE)
2532 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2533 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2534 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2535 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2536 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2538 // additive passes are only darkened by fog, not tinted
2539 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2540 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2544 if (mode == SHADERMODE_FLATCOLOR)
2546 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2548 else if (mode == SHADERMODE_LIGHTDIRECTION)
2550 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]);
2551 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2552 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);
2553 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2554 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2555 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
2556 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2560 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2561 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2562 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);
2563 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2564 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2566 // additive passes are only darkened by fog, not tinted
2567 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2568 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2570 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2571 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);
2572 hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2573 hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2574 hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2575 hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2576 hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2577 hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
2578 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
2579 if (mode == SHADERMODE_WATER)
2580 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2582 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2583 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
2584 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2585 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));
2586 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2587 if (rsurface.texture->pantstexture)
2588 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2590 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
2591 if (rsurface.texture->shirttexture)
2592 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2594 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
2595 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2596 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
2597 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
2598 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
2599 hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
2600 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2601 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2602 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2603 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2605 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2606 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
2607 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2608 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
2610 R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
2611 R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
2612 R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
2613 R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
2614 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
2615 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
2616 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
2617 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
2618 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
2619 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
2620 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
2621 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2622 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
2623 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
2624 R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2625 R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2626 if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
2627 if (rsurfacepass == RSURFPASS_BACKGROUND)
2629 R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2630 if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2631 R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2635 if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2637 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
2638 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
2639 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
2640 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2642 R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2643 if (rsurface.rtlight)
2645 if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
2646 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
2651 case RENDERPATH_D3D10:
2652 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2654 case RENDERPATH_D3D11:
2655 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2657 case RENDERPATH_GL20:
2658 case RENDERPATH_GLES2:
2659 if (!vid.useinterleavedarrays)
2661 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2662 R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
2663 R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
2664 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
2665 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
2666 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
2667 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
2668 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
2669 R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
2670 R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, rsurface.batchskeletalindex4ub_vertexbuffer, rsurface.batchskeletalindex4ub_bufferoffset);
2671 R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, rsurface.batchskeletalweight4ub_vertexbuffer, rsurface.batchskeletalweight4ub_bufferoffset);
2675 RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0) | (rsurface.entityskeletaltransform3x4 ? BATCHNEED_VERTEXMESH_SKELETAL : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2676 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
2678 // this has to be after RSurf_PrepareVerticesForBatch
2679 if (rsurface.batchskeletaltransform3x4)
2680 permutation |= SHADERPERMUTATION_SKELETAL;
2681 R_SetupShader_SetPermutationGLSL(mode, permutation);
2682 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
2683 if (mode == SHADERMODE_LIGHTSOURCE)
2685 if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2686 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2687 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2688 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2689 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2690 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);
2692 // additive passes are only darkened by fog, not tinted
2693 if (r_glsl_permutation->loc_FogColor >= 0)
2694 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2695 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);
2699 if (mode == SHADERMODE_FLATCOLOR)
2701 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2703 else if (mode == SHADERMODE_LIGHTDIRECTION)
2705 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]);
2706 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]);
2707 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);
2708 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2709 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2710 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]);
2711 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]);
2715 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]);
2716 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]);
2717 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);
2718 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2719 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2721 // additive passes are only darkened by fog, not tinted
2722 if (r_glsl_permutation->loc_FogColor >= 0)
2724 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2725 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2727 qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2729 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);
2730 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]);
2731 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]);
2732 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]);
2733 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]);
2734 if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2735 if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2736 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);
2737 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]);
2739 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
2740 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
2741 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
2742 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]);
2743 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]);
2745 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2746 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));
2747 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2748 if (r_glsl_permutation->loc_Color_Pants >= 0)
2750 if (rsurface.texture->pantstexture)
2751 qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2753 qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
2755 if (r_glsl_permutation->loc_Color_Shirt >= 0)
2757 if (rsurface.texture->shirttexture)
2758 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2760 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
2762 if (r_glsl_permutation->loc_FogPlane >= 0) qglUniform4f(r_glsl_permutation->loc_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2763 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
2764 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
2765 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
2766 if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps,
2767 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2768 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2769 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2770 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2772 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);
2773 if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, rsurface.texture->offsetbias);
2774 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]);
2775 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
2776 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);}
2777 if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale);
2779 if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white );
2780 if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white );
2781 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps , r_texture_gammaramps );
2782 if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , rsurface.texture->nmaptexture );
2783 if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , rsurface.texture->basetexture );
2784 if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , rsurface.texture->glosstexture );
2785 if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , rsurface.texture->glowtexture );
2786 if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , rsurface.texture->backgroundnmaptexture );
2787 if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );
2788 if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );
2789 if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );
2790 if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , rsurface.texture->pantstexture );
2791 if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , rsurface.texture->shirttexture );
2792 if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , rsurface.texture->reflectmasktexture );
2793 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);
2794 if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture );
2795 if (r_glsl_permutation->tex_Texture_FogMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask , r_texture_fogattenuation );
2796 if (r_glsl_permutation->tex_Texture_Lightmap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2797 if (r_glsl_permutation->tex_Texture_Deluxemap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2798 if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
2799 if (rsurfacepass == RSURFPASS_BACKGROUND)
2801 if (r_glsl_permutation->tex_Texture_Refraction >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Refraction , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2802 if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2803 if (r_glsl_permutation->tex_Texture_Reflection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2807 if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2809 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
2810 if (r_glsl_permutation->tex_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );
2811 if (r_glsl_permutation->tex_Texture_ScreenSpecular >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );
2812 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2814 if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2ddepthtexture );
2815 if (rsurface.rtlight)
2817 if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
2818 if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
2821 if (r_glsl_permutation->tex_Texture_BounceGrid >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture);
2822 if (r_glsl_permutation->loc_Skeletal_Transform12 >= 0 && rsurface.batchskeletalnumtransforms > 0)
2823 qglUniform4fv(r_glsl_permutation->loc_Skeletal_Transform12, rsurface.batchskeletalnumtransforms*3, rsurface.batchskeletaltransform3x4);
2826 case RENDERPATH_GL11:
2827 case RENDERPATH_GL13:
2828 case RENDERPATH_GLES1:
2830 case RENDERPATH_SOFT:
2831 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist);
2832 R_Mesh_PrepareVertices_Mesh_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchsvector3f, rsurface.batchtvector3f, rsurface.batchnormal3f, rsurface.batchlightmapcolor4f, rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f);
2833 R_SetupShader_SetPermutationSoft(mode, permutation);
2834 {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
2835 if (mode == SHADERMODE_LIGHTSOURCE)
2837 {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
2838 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2839 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2840 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2841 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2842 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2844 // additive passes are only darkened by fog, not tinted
2845 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
2846 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2850 if (mode == SHADERMODE_FLATCOLOR)
2852 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2854 else if (mode == SHADERMODE_LIGHTDIRECTION)
2856 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]);
2857 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2858 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);
2859 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2860 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
2861 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]);
2862 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2866 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2867 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2868 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);
2869 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2870 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale, specularscale, specularscale);
2872 // additive passes are only darkened by fog, not tinted
2873 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2874 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
2876 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2877 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);
2878 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]);
2879 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]);
2880 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]);
2881 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]);
2882 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2883 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
2884 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2885 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2887 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
2888 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
2889 {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
2890 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
2891 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]);
2893 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2894 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));
2895 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2896 if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
2898 if (rsurface.texture->pantstexture)
2899 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2901 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
2903 if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
2905 if (rsurface.texture->shirttexture)
2906 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2908 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
2910 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2911 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist);
2912 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
2913 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
2914 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps,
2915 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2916 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2917 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2918 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2920 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2921 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Bias, rsurface.texture->offsetbias);
2922 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2923 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
2925 R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
2926 R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
2927 R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
2928 R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
2929 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
2930 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
2931 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
2932 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
2933 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
2934 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
2935 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
2936 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2937 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
2938 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
2939 R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2940 R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2941 if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
2942 if (rsurfacepass == RSURFPASS_BACKGROUND)
2944 R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2945 if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2946 R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2950 if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2952 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
2953 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
2954 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
2955 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2957 R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2958 if (rsurface.rtlight)
2960 if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
2961 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
2968 void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
2970 // select a permutation of the lighting shader appropriate to this
2971 // combination of texture, entity, light source, and fogging, only use the
2972 // minimum features necessary to avoid wasting rendering time in the
2973 // fragment shader on features that are not being used
2974 unsigned int permutation = 0;
2975 unsigned int mode = 0;
2976 const float *lightcolorbase = rtlight->currentcolor;
2977 float ambientscale = rtlight->ambientscale;
2978 float diffusescale = rtlight->diffusescale;
2979 float specularscale = rtlight->specularscale;
2980 // this is the location of the light in view space
2981 vec3_t viewlightorigin;
2982 // this transforms from view space (camera) to light space (cubemap)
2983 matrix4x4_t viewtolight;
2984 matrix4x4_t lighttoview;
2985 float viewtolight16f[16];
2987 mode = SHADERMODE_DEFERREDLIGHTSOURCE;
2988 if (rtlight->currentcubemap != r_texture_whitecube)
2989 permutation |= SHADERPERMUTATION_CUBEFILTER;
2990 if (diffusescale > 0)
2991 permutation |= SHADERPERMUTATION_DIFFUSE;
2992 if (specularscale > 0 && r_shadow_gloss.integer > 0)
2993 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2994 if (r_shadow_usingshadowmap2d)
2996 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2997 if (r_shadow_shadowmapvsdct)
2998 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
3000 if (r_shadow_shadowmap2ddepthbuffer)
3001 permutation |= SHADERPERMUTATION_DEPTHRGB;
3003 if (vid.allowalphatocoverage)
3004 GL_AlphaToCoverage(false);
3005 Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
3006 Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
3007 Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
3008 Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
3009 switch(vid.renderpath)
3011 case RENDERPATH_D3D9:
3013 R_SetupShader_SetPermutationHLSL(mode, permutation);
3014 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3015 hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f);
3016 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3017 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3018 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3019 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3020 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
3021 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);
3022 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3023 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
3025 R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
3026 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
3027 R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
3028 R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2ddepthtexture );
3029 R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
3032 case RENDERPATH_D3D10:
3033 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3035 case RENDERPATH_D3D11:
3036 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
3038 case RENDERPATH_GL20:
3039 case RENDERPATH_GLES2:
3040 R_SetupShader_SetPermutationGLSL(mode, permutation);
3041 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f( r_glsl_permutation->loc_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3042 if (r_glsl_permutation->loc_ViewToLight >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ViewToLight , 1, false, viewtolight16f);
3043 if (r_glsl_permutation->loc_DeferredColor_Ambient >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3044 if (r_glsl_permutation->loc_DeferredColor_Diffuse >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3045 if (r_glsl_permutation->loc_DeferredColor_Specular >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Specular , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3046 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]);
3047 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]);
3048 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);
3049 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]);
3050 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height);
3052 if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
3053 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
3054 if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
3055 if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D , r_shadow_shadowmap2ddepthtexture );
3056 if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
3058 case RENDERPATH_GL11:
3059 case RENDERPATH_GL13:
3060 case RENDERPATH_GLES1:
3062 case RENDERPATH_SOFT:
3063 R_SetupShader_SetPermutationGLSL(mode, permutation);
3064 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
3065 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ViewToLightM1 , 1, false, viewtolight16f);
3066 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale );
3067 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale );
3068 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale);
3069 DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
3070 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]);
3071 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);
3072 DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
3073 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
3075 R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
3076 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
3077 R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
3078 R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2ddepthtexture );
3079 R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
3084 #define SKINFRAME_HASH 1024
3088 int loadsequence; // incremented each level change
3089 memexpandablearray_t array;
3090 skinframe_t *hash[SKINFRAME_HASH];
3093 r_skinframe_t r_skinframe;
3095 void R_SkinFrame_PrepareForPurge(void)
3097 r_skinframe.loadsequence++;
3098 // wrap it without hitting zero
3099 if (r_skinframe.loadsequence >= 200)
3100 r_skinframe.loadsequence = 1;
3103 void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
3107 // mark the skinframe as used for the purging code
3108 skinframe->loadsequence = r_skinframe.loadsequence;
3111 void R_SkinFrame_Purge(void)
3115 for (i = 0;i < SKINFRAME_HASH;i++)
3117 for (s = r_skinframe.hash[i];s;s = s->next)
3119 if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
3121 if (s->merged == s->base)
3123 // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
3124 R_PurgeTexture(s->stain );s->stain = NULL;
3125 R_PurgeTexture(s->merged);s->merged = NULL;
3126 R_PurgeTexture(s->base );s->base = NULL;
3127 R_PurgeTexture(s->pants );s->pants = NULL;
3128 R_PurgeTexture(s->shirt );s->shirt = NULL;
3129 R_PurgeTexture(s->nmap );s->nmap = NULL;
3130 R_PurgeTexture(s->gloss );s->gloss = NULL;
3131 R_PurgeTexture(s->glow );s->glow = NULL;
3132 R_PurgeTexture(s->fog );s->fog = NULL;
3133 R_PurgeTexture(s->reflect);s->reflect = NULL;
3134 s->loadsequence = 0;
3140 skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
3142 char basename[MAX_QPATH];
3144 Image_StripImageExtension(name, basename, sizeof(basename));
3146 if( last == NULL ) {
3148 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
3149 item = r_skinframe.hash[hashindex];
3154 // linearly search through the hash bucket
3155 for( ; item ; item = item->next ) {
3156 if( !strcmp( item->basename, basename ) ) {
3163 skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
3167 char basename[MAX_QPATH];
3169 Image_StripImageExtension(name, basename, sizeof(basename));
3171 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
3172 for (item = r_skinframe.hash[hashindex];item;item = item->next)
3173 if (!strcmp(item->basename, basename) && (comparecrc < 0 || (item->te