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"
31 #include "cl_collision.h"
35 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
39 // Enable NVIDIA High Performance Graphics while using Integrated Graphics.
43 __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
49 mempool_t *r_main_mempool;
50 rtexturepool_t *r_main_texturepool;
52 static int r_textureframe = 0; ///< used only by R_GetCurrentTexture
54 static qboolean r_loadnormalmap;
55 static qboolean r_loadgloss;
57 static qboolean r_loaddds;
58 static qboolean r_savedds;
59 static qboolean r_gpuskeletal;
66 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!"};
67 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!"};
68 cvar_t r_motionblur_averaging = {CVAR_SAVE, "r_motionblur_averaging", "0.1", "sliding average reaction time for velocity (higher = slower adaption to change)"};
69 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
70 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)"};
71 cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.9", "maxmimum amount of blur"};
72 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"};
73 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"};
74 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"};
75 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"};
76 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"};
77 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"};
79 // TODO do we want a r_equalize_entities cvar that works on all ents, or would that be a cheat?
80 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"};
81 cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio"};
82 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)"};
83 cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level"};
85 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"};
86 cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
87 cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
88 cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
89 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
90 cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
91 cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
92 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"};
93 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"};
94 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"};
95 cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"};
96 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"};
97 cvar_t r_showbboxes_client = { 0, "r_showbboxes_client", "0", "shows bounding boxes of clientside qc entities, value controls opacity scaling (1 = 10%, 10 = 100%)" };
98 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)"};
99 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
100 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
101 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"};
102 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"};
103 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
104 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"};
105 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"};
106 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"};
107 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
108 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
109 cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
110 cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
111 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
112 cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
113 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
114 cvar_t r_cullentities_trace_entityocclusion = { 0, "r_cullentities_trace_entityocclusion", "1", "check for occluding entities such as doors, not just world hull" };
115 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)"};
116 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)"};
117 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
118 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
119 cvar_t r_cullentities_trace_eyejitter = {0, "r_cullentities_trace_eyejitter", "16", "randomly offset rays from the eye by this much to reduce the odds of flickering"};
120 cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
121 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
122 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
124 cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"};
125 cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"};
126 #define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
128 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
129 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
130 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
131 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."};
132 cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
133 cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
134 cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
135 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."};
136 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
137 cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
138 cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
139 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."};
140 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
141 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"};
142 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"};
143 cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
144 cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
145 cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
146 cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
147 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
148 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"};
149 cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
150 cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
151 cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
152 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
153 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
155 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
156 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
157 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
158 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
159 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
160 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
161 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
162 cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
164 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)"};
165 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"};
167 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"};
168 static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
169 static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
171 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"};
172 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"};
173 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"};
174 cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
175 cvar_t r_viewscale_fpsscaling_min = {CVAR_SAVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"};
176 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"};
177 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)"};
178 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)"};
179 cvar_t r_viewscale_fpsscaling_target = {CVAR_SAVE, "r_viewscale_fpsscaling_target", "70", "desired framerate"};
181 cvar_t r_glsl_skeletal = {CVAR_SAVE, "r_glsl_skeletal", "1", "render skeletal models faster using a gpu-skinning technique"};
182 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)"};
183 cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
184 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)"};
185 cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
186 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)"};
187 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)"};
188 cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
189 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"};
190 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."};
191 cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
192 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)"};
193 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)"};
194 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)"};
195 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)"};
196 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)"};
197 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)"};
198 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)"};
199 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)"};
201 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)"};
202 cvar_t r_water_cameraentitiesonly = {CVAR_SAVE, "r_water_cameraentitiesonly", "0", "whether to only show QC-defined reflections/refractions (typically used for camera- or portal-like effects)"};
203 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
204 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"};
205 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
206 cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
207 cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
208 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"};
209 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"};
210 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)"};
212 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
213 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
214 cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
215 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
217 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
218 cvar_t r_bloom_colorscale = {CVAR_SAVE, "r_bloom_colorscale", "1", "how bright the glow is"};
220 cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
221 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
222 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
223 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
224 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
225 cvar_t r_bloom_scenebrightness = {CVAR_SAVE, "r_bloom_scenebrightness", "1", "global rendering brightness when bloom is enabled"};
227 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
228 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
229 cvar_t r_hdr_irisadaptation = {CVAR_SAVE, "r_hdr_irisadaptation", "0", "adjust scene brightness according to light intensity at player location"};
230 cvar_t r_hdr_irisadaptation_multiplier = {CVAR_SAVE, "r_hdr_irisadaptation_multiplier", "2", "brightness at which value will be 1.0"};
231 cvar_t r_hdr_irisadaptation_minvalue = {CVAR_SAVE, "r_hdr_irisadaptation_minvalue", "0.5", "minimum value that can result from multiplier / brightness"};
232 cvar_t r_hdr_irisadaptation_maxvalue = {CVAR_SAVE, "r_hdr_irisadaptation_maxvalue", "4", "maximum value that can result from multiplier / brightness"};
233 cvar_t r_hdr_irisadaptation_value = {0, "r_hdr_irisadaptation_value", "1", "current value as scenebrightness multiplier, changes continuously when irisadaptation is active"};
234 cvar_t r_hdr_irisadaptation_fade_up = {CVAR_SAVE, "r_hdr_irisadaptation_fade_up", "0.1", "fade rate at which value adjusts to darkness"};
235 cvar_t r_hdr_irisadaptation_fade_down = {CVAR_SAVE, "r_hdr_irisadaptation_fade_down", "0.5", "fade rate at which value adjusts to brightness"};
236 cvar_t r_hdr_irisadaptation_radius = {CVAR_SAVE, "r_hdr_irisadaptation_radius", "15", "lighting within this many units of the eye is averaged"};
238 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"};
240 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"};
242 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers), a value of 2 keeps normalmap shading"};
244 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
246 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)"};
247 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)"};
248 cvar_t r_batch_debugdynamicvertexpath = {CVAR_SAVE, "r_batch_debugdynamicvertexpath", "0", "force the dynamic batching code path for debugging purposes"};
249 cvar_t r_batch_dynamicbuffer = {CVAR_SAVE, "r_batch_dynamicbuffer", "0", "use vertex/index buffers for drawing dynamic and copytriangles batches"};
251 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
252 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"};
254 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."};
256 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)"};
257 cvar_t r_buffermegs[R_BUFFERDATA_COUNT] =
259 {CVAR_SAVE, "r_buffermegs_vertex", "4", "vertex buffer size for one frame"},
260 {CVAR_SAVE, "r_buffermegs_index16", "1", "index buffer size for one frame (16bit indices)"},
261 {CVAR_SAVE, "r_buffermegs_index32", "1", "index buffer size for one frame (32bit indices)"},
262 {CVAR_SAVE, "r_buffermegs_uniform", "0.25", "uniform buffer size for one frame"},
265 extern cvar_t v_glslgamma;
266 extern cvar_t v_glslgamma_2d;
268 extern qboolean v_flipped_state;
270 r_framebufferstate_t r_fb;
272 /// shadow volume bsp struct with automatically growing nodes buffer
275 int r_uniformbufferalignment = 32; // dynamically updated to match GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
277 rtexture_t *r_texture_blanknormalmap;
278 rtexture_t *r_texture_white;
279 rtexture_t *r_texture_grey128;
280 rtexture_t *r_texture_black;
281 rtexture_t *r_texture_notexture;
282 rtexture_t *r_texture_whitecube;
283 rtexture_t *r_texture_normalizationcube;
284 rtexture_t *r_texture_fogattenuation;
285 rtexture_t *r_texture_fogheighttexture;
286 rtexture_t *r_texture_gammaramps;
287 unsigned int r_texture_gammaramps_serial;
288 //rtexture_t *r_texture_fogintensity;
289 rtexture_t *r_texture_reflectcube;
291 // TODO: hash lookups?
292 typedef struct cubemapinfo_s
299 int r_texture_numcubemaps;
300 cubemapinfo_t *r_texture_cubemaps[MAX_CUBEMAPS];
302 unsigned int r_queries[MAX_OCCLUSION_QUERIES];
303 unsigned int r_numqueries;
304 unsigned int r_maxqueries;
306 typedef struct r_qwskincache_s
308 char name[MAX_QPATH];
309 skinframe_t *skinframe;
313 static r_qwskincache_t *r_qwskincache;
314 static int r_qwskincache_size;
316 /// vertex coordinates for a quad that covers the screen exactly
317 extern const float r_screenvertex3f[12];
318 extern const float r_d3dscreenvertex3f[12];
319 const float r_screenvertex3f[12] =
326 const float r_d3dscreenvertex3f[12] =
334 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
337 for (i = 0;i < verts;i++)
348 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
351 for (i = 0;i < verts;i++)
361 // FIXME: move this to client?
364 if (gamemode == GAME_NEHAHRA)
366 Cvar_Set("gl_fogenable", "0");
367 Cvar_Set("gl_fogdensity", "0.2");
368 Cvar_Set("gl_fogred", "0.3");
369 Cvar_Set("gl_foggreen", "0.3");
370 Cvar_Set("gl_fogblue", "0.3");
372 r_refdef.fog_density = 0;
373 r_refdef.fog_red = 0;
374 r_refdef.fog_green = 0;
375 r_refdef.fog_blue = 0;
376 r_refdef.fog_alpha = 1;
377 r_refdef.fog_start = 0;
378 r_refdef.fog_end = 16384;
379 r_refdef.fog_height = 1<<30;
380 r_refdef.fog_fadedepth = 128;
381 memset(r_refdef.fog_height_texturename, 0, sizeof(r_refdef.fog_height_texturename));
384 static void R_BuildBlankTextures(void)
386 unsigned char data[4];
387 data[2] = 128; // normal X
388 data[1] = 128; // normal Y
389 data[0] = 255; // normal Z
390 data[3] = 255; // height
391 r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
396 r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
401 r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
406 r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
409 static void R_BuildNoTexture(void)
412 unsigned char pix[16][16][4];
413 // this makes a light grey/dark grey checkerboard texture
414 for (y = 0;y < 16;y++)
416 for (x = 0;x < 16;x++)
418 if ((y < 8) ^ (x < 8))
434 r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, -1, NULL);
437 static void R_BuildWhiteCube(void)
439 unsigned char data[6*1*1*4];
440 memset(data, 255, sizeof(data));
441 r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
444 static void R_BuildNormalizationCube(void)
448 vec_t s, t, intensity;
451 data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
452 for (side = 0;side < 6;side++)
454 for (y = 0;y < NORMSIZE;y++)
456 for (x = 0;x < NORMSIZE;x++)
458 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
459 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
494 intensity = 127.0f / sqrt(DotProduct(v, v));
495 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
496 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
497 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
498 data[((side*64+y)*64+x)*4+3] = 255;
502 r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
506 static void R_BuildFogTexture(void)
510 unsigned char data1[FOGWIDTH][4];
511 //unsigned char data2[FOGWIDTH][4];
514 r_refdef.fogmasktable_start = r_refdef.fog_start;
515 r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
516 r_refdef.fogmasktable_range = r_refdef.fogrange;
517 r_refdef.fogmasktable_density = r_refdef.fog_density;
519 r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
520 for (x = 0;x < FOGMASKTABLEWIDTH;x++)
522 d = (x * r - r_refdef.fogmasktable_start);
523 if(developer_extra.integer)
524 Con_DPrintf("%f ", d);
526 if (r_fog_exp2.integer)
527 alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
529 alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
530 if(developer_extra.integer)
531 Con_DPrintf(" : %f ", alpha);
532 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
533 if(developer_extra.integer)
534 Con_DPrintf(" = %f\n", alpha);
535 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
538 for (x = 0;x < FOGWIDTH;x++)
540 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
545 //data2[x][0] = 255 - b;
546 //data2[x][1] = 255 - b;
547 //data2[x][2] = 255 - b;
550 if (r_texture_fogattenuation)
552 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
553 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
557 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
558 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
562 static void R_BuildFogHeightTexture(void)
564 unsigned char *inpixels;
572 strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename));
573 if (r_refdef.fogheighttexturename[0])
574 inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false, NULL);
577 r_refdef.fog_height_tablesize = 0;
578 if (r_texture_fogheighttexture)
579 R_FreeTexture(r_texture_fogheighttexture);
580 r_texture_fogheighttexture = NULL;
581 if (r_refdef.fog_height_table2d)
582 Mem_Free(r_refdef.fog_height_table2d);
583 r_refdef.fog_height_table2d = NULL;
584 if (r_refdef.fog_height_table1d)
585 Mem_Free(r_refdef.fog_height_table1d);
586 r_refdef.fog_height_table1d = NULL;
590 r_refdef.fog_height_tablesize = size;
591 r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
592 r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
593 memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
595 // LordHavoc: now the magic - what is that table2d for? it is a cooked
596 // average fog color table accounting for every fog layer between a point
597 // and the camera. (Note: attenuation is handled separately!)
598 for (y = 0;y < size;y++)
600 for (x = 0;x < size;x++)
606 for (j = x;j <= y;j++)
608 Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
614 for (j = x;j >= y;j--)
616 Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
621 r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f);
622 r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f);
623 r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f);
624 r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
627 r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, -1, NULL);
630 //=======================================================================================================================================================
632 static const char *builtinshaderstrings[] =
634 #include "shader_glsl.h"
638 const char *builtinhlslshaderstrings[] =
640 #include "shader_hlsl.h"
644 //=======================================================================================================================================================
646 typedef struct shaderpermutationinfo_s
651 shaderpermutationinfo_t;
653 typedef struct shadermodeinfo_s
655 const char *sourcebasename;
656 const char *extension;
657 const char **builtinshaderstrings;
666 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
667 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
669 {"#define USEDIFFUSE\n", " diffuse"},
670 {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
671 {"#define USEVIEWTINT\n", " viewtint"},
672 {"#define USECOLORMAPPING\n", " colormapping"},
673 {"#define USESATURATION\n", " saturation"},
674 {"#define USEFOGINSIDE\n", " foginside"},
675 {"#define USEFOGOUTSIDE\n", " fogoutside"},
676 {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
677 {"#define USEFOGALPHAHACK\n", " fogalphahack"},
678 {"#define USEGAMMARAMPS\n", " gammaramps"},
679 {"#define USECUBEFILTER\n", " cubefilter"},
680 {"#define USEGLOW\n", " glow"},
681 {"#define USEBLOOM\n", " bloom"},
682 {"#define USESPECULAR\n", " specular"},
683 {"#define USEPOSTPROCESSING\n", " postprocessing"},
684 {"#define USEREFLECTION\n", " reflection"},
685 {"#define USEOFFSETMAPPING\n", " offsetmapping"},
686 {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
687 {"#define USESHADOWMAP2D\n", " shadowmap2d"},
688 {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm
689 {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
690 {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
691 {"#define USEALPHAKILL\n", " alphakill"},
692 {"#define USEREFLECTCUBE\n", " reflectcube"},
693 {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
694 {"#define USEBOUNCEGRID\n", " bouncegrid"},
695 {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm
696 {"#define USETRIPPY\n", " trippy"},
697 {"#define USEDEPTHRGB\n", " depthrgb"},
698 {"#define USEALPHAGENVERTEX\n", " alphagenvertex"},
699 {"#define USESKELETAL\n", " skeletal"},
700 {"#define USEOCCLUDE\n", " occlude"}
703 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
704 shadermodeinfo_t shadermodeinfo[SHADERLANGUAGE_COUNT][SHADERMODE_COUNT] =
706 // SHADERLANGUAGE_GLSL
708 {"combined", "glsl", builtinshaderstrings, "#define MODE_GENERIC\n", " generic"},
709 {"combined", "glsl", builtinshaderstrings, "#define MODE_POSTPROCESS\n", " postprocess"},
710 {"combined", "glsl", builtinshaderstrings, "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
711 {"combined", "glsl", builtinshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"},
712 {"combined", "glsl", builtinshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
713 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"},
714 {"combined", "glsl", builtinshaderstrings, "#define MODE_FAKELIGHT\n", " fakelight"},
715 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
716 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
717 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
718 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
719 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
720 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTSOURCE\n", " lightsource"},
721 {"combined", "glsl", builtinshaderstrings, "#define MODE_REFRACTION\n", " refraction"},
722 {"combined", "glsl", builtinshaderstrings, "#define MODE_WATER\n", " water"},
723 {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
724 {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
726 // SHADERLANGUAGE_HLSL
728 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_GENERIC\n", " generic"},
729 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_POSTPROCESS\n", " postprocess"},
730 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
731 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"},
732 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
733 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"},
734 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_FAKELIGHT\n", " fakelight"},
735 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
736 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
737 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
738 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
739 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
740 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_LIGHTSOURCE\n", " lightsource"},
741 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_REFRACTION\n", " refraction"},
742 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_WATER\n", " water"},
743 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
744 {"combined", "hlsl", builtinhlslshaderstrings, "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
748 struct r_glsl_permutation_s;
749 typedef struct r_glsl_permutation_s
752 struct r_glsl_permutation_s *hashnext;
754 dpuint64 permutation;
756 /// indicates if we have tried compiling this permutation already
758 /// 0 if compilation failed
760 // texture units assigned to each detected uniform
761 int tex_Texture_First;
762 int tex_Texture_Second;
763 int tex_Texture_GammaRamps;
764 int tex_Texture_Normal;
765 int tex_Texture_Color;
766 int tex_Texture_Gloss;
767 int tex_Texture_Glow;
768 int tex_Texture_SecondaryNormal;
769 int tex_Texture_SecondaryColor;
770 int tex_Texture_SecondaryGloss;
771 int tex_Texture_SecondaryGlow;
772 int tex_Texture_Pants;
773 int tex_Texture_Shirt;
774 int tex_Texture_FogHeightTexture;
775 int tex_Texture_FogMask;
776 int tex_Texture_Lightmap;
777 int tex_Texture_Deluxemap;
778 int tex_Texture_Attenuation;
779 int tex_Texture_Cube;
780 int tex_Texture_Refraction;
781 int tex_Texture_Reflection;
782 int tex_Texture_ShadowMap2D;
783 int tex_Texture_CubeProjection;
784 int tex_Texture_ScreenNormalMap;
785 int tex_Texture_ScreenDiffuse;
786 int tex_Texture_ScreenSpecular;
787 int tex_Texture_ReflectMask;
788 int tex_Texture_ReflectCube;
789 int tex_Texture_BounceGrid;
790 /// locations of detected uniforms in program object, or -1 if not found
791 int loc_Texture_First;
792 int loc_Texture_Second;
793 int loc_Texture_GammaRamps;
794 int loc_Texture_Normal;
795 int loc_Texture_Color;
796 int loc_Texture_Gloss;
797 int loc_Texture_Glow;
798 int loc_Texture_SecondaryNormal;
799 int loc_Texture_SecondaryColor;
800 int loc_Texture_SecondaryGloss;
801 int loc_Texture_SecondaryGlow;
802 int loc_Texture_Pants;
803 int loc_Texture_Shirt;
804 int loc_Texture_FogHeightTexture;
805 int loc_Texture_FogMask;
806 int loc_Texture_Lightmap;
807 int loc_Texture_Deluxemap;
808 int loc_Texture_Attenuation;
809 int loc_Texture_Cube;
810 int loc_Texture_Refraction;
811 int loc_Texture_Reflection;
812 int loc_Texture_ShadowMap2D;
813 int loc_Texture_CubeProjection;
814 int loc_Texture_ScreenNormalMap;
815 int loc_Texture_ScreenDiffuse;
816 int loc_Texture_ScreenSpecular;
817 int loc_Texture_ReflectMask;
818 int loc_Texture_ReflectCube;
819 int loc_Texture_BounceGrid;
821 int loc_BloomBlur_Parameters;
823 int loc_Color_Ambient;
824 int loc_Color_Diffuse;
825 int loc_Color_Specular;
829 int loc_DeferredColor_Ambient;
830 int loc_DeferredColor_Diffuse;
831 int loc_DeferredColor_Specular;
832 int loc_DeferredMod_Diffuse;
833 int loc_DeferredMod_Specular;
834 int loc_DistortScaleRefractReflect;
837 int loc_FogHeightFade;
839 int loc_FogPlaneViewDist;
840 int loc_FogRangeRecip;
843 int loc_LightPosition;
844 int loc_OffsetMapping_ScaleSteps;
845 int loc_OffsetMapping_LodDistance;
846 int loc_OffsetMapping_Bias;
848 int loc_ReflectColor;
849 int loc_ReflectFactor;
850 int loc_ReflectOffset;
851 int loc_RefractColor;
853 int loc_ScreenCenterRefractReflect;
854 int loc_ScreenScaleRefractReflect;
855 int loc_ScreenToDepth;
856 int loc_ShadowMap_Parameters;
857 int loc_ShadowMap_TextureScale;
858 int loc_SpecularPower;
859 int loc_Skeletal_Transform12;
864 int loc_ViewTintColor;
866 int loc_ModelToLight;
868 int loc_BackgroundTexMatrix;
869 int loc_ModelViewProjectionMatrix;
870 int loc_ModelViewMatrix;
871 int loc_PixelToScreenTexCoord;
872 int loc_ModelToReflectCube;
873 int loc_ShadowMapMatrix;
874 int loc_BloomColorSubtract;
875 int loc_NormalmapScrollBlend;
876 int loc_BounceGridMatrix;
877 int loc_BounceGridIntensity;
878 /// uniform block bindings
879 int ubibind_Skeletal_Transform12_UniformBlock;
880 /// uniform block indices
881 int ubiloc_Skeletal_Transform12_UniformBlock;
883 r_glsl_permutation_t;
885 #define SHADERPERMUTATION_HASHSIZE 256
888 // non-degradable "lightweight" shader parameters to keep the permutations simpler
889 // these can NOT degrade! only use for simple stuff
892 SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0, ///< red compensation filter for saturation
893 SHADERSTATICPARM_EXACTSPECULARMATH = 1, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
894 SHADERSTATICPARM_POSTPROCESS_USERVEC1 = 2, ///< postprocess uservec1 is enabled
895 SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
896 SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
897 SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5, ///< postprocess uservec4 is enabled
898 SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
899 SHADERSTATICPARM_OFFSETMAPPING_USELOD = 7, ///< LOD for offsetmapping
900 SHADERSTATICPARM_SHADOWMAPPCF_1 = 8, ///< PCF 1
901 SHADERSTATICPARM_SHADOWMAPPCF_2 = 9, ///< PCF 2
902 SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler
903 SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math)
904 SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines)
905 SHADERSTATICPARM_FXAA = 13 ///< fast approximate anti aliasing
907 #define SHADERSTATICPARMS_COUNT 14
909 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
910 static int shaderstaticparms_count = 0;
912 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
913 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
915 extern qboolean r_shadow_shadowmapsampler;
916 extern int r_shadow_shadowmappcf;
917 qboolean R_CompileShader_CheckStaticParms(void)
919 static int r_compileshader_staticparms_save[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5];
920 memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
921 memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
924 if (r_glsl_saturation_redcompensate.integer)
925 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
926 if (r_glsl_vertextextureblend_usebothalphas.integer)
927 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS);
928 if (r_shadow_glossexact.integer)
929 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_EXACTSPECULARMATH);
930 if (r_glsl_postprocess.integer)
932 if (r_glsl_postprocess_uservec1_enable.integer)
933 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC1);
934 if (r_glsl_postprocess_uservec2_enable.integer)
935 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC2);
936 if (r_glsl_postprocess_uservec3_enable.integer)
937 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC3);
938 if (r_glsl_postprocess_uservec4_enable.integer)
939 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
942 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_FXAA);
943 if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
944 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
946 if (r_shadow_shadowmapsampler)
947 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWSAMPLER);
948 if (r_shadow_shadowmappcf > 1)
949 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_2);
950 else if (r_shadow_shadowmappcf)
951 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SHADOWMAPPCF_1);
952 if (r_celshading.integer)
953 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELSHADING);
954 if (r_celoutlines.integer)
955 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_CELOUTLINES);
957 return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
960 #define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
961 if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
962 shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
964 shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
965 static void R_CompileShader_AddStaticParms(unsigned int mode, dpuint64 permutation)
967 shaderstaticparms_count = 0;
970 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
971 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_EXACTSPECULARMATH, "USEEXACTSPECULARMATH");
972 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC1, "USERVEC1");
973 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC2, "USERVEC2");
974 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
975 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
976 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
977 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_OFFSETMAPPING_USELOD, "USEOFFSETMAPPING_LOD");
978 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_1, "USESHADOWMAPPCF 1");
979 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWMAPPCF_2, "USESHADOWMAPPCF 2");
980 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER");
981 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING");
982 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES");
983 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_FXAA, "USEFXAA");
986 /// information about each possible shader permutation
987 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
988 /// currently selected permutation
989 r_glsl_permutation_t *r_glsl_permutation;
990 /// storage for permutations linked in the hash table
991 memexpandablearray_t r_glsl_permutationarray;
993 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, dpuint64 permutation)
995 //unsigned int hashdepth = 0;
996 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
997 r_glsl_permutation_t *p;
998 for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1000 if (p->mode == mode && p->permutation == permutation)
1002 //if (hashdepth > 10)
1003 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1008 p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
1010 p->permutation = permutation;
1011 p->hashnext = r_glsl_permutationhash[mode][hashindex];
1012 r_glsl_permutationhash[mode][hashindex] = p;
1013 //if (hashdepth > 10)
1014 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1018 static char *R_ShaderStrCat(const char **strings)
1021 const char **p = strings;
1024 for (p = strings;(t = *p);p++)
1027 s = string = (char *)Mem_Alloc(r_main_mempool, len);
1029 for (p = strings;(t = *p);p++)
1039 static char *R_ShaderStrCat(const char **strings);
1040 static void R_InitShaderModeInfo(void)
1043 shadermodeinfo_t *modeinfo;
1044 // we have a bunch of things to compute that weren't calculated at engine compile time - all filenames should have a crc of the builtin strings to prevent accidental overrides (any customization must be updated to match engine)
1045 for (language = 0; language < SHADERLANGUAGE_COUNT; language++)
1047 for (i = 0; i < SHADERMODE_COUNT; i++)
1049 char filename[MAX_QPATH];
1050 modeinfo = &shadermodeinfo[language][i];
1051 modeinfo->builtinstring = R_ShaderStrCat(modeinfo->builtinshaderstrings);
1052 modeinfo->builtincrc = CRC_Block((const unsigned char *)modeinfo->builtinstring, strlen(modeinfo->builtinstring));
1053 dpsnprintf(filename, sizeof(filename), "%s/%s_crc%i.%s", modeinfo->extension, modeinfo->sourcebasename, modeinfo->builtincrc, modeinfo->extension);
1054 modeinfo->filename = Mem_strdup(r_main_mempool, filename);
1059 static char *ShaderModeInfo_GetShaderText(shadermodeinfo_t *modeinfo, qboolean printfromdisknotice, qboolean builtinonly)
1062 // if the mode has no filename we have to return the builtin string
1063 if (builtinonly || !modeinfo->filename)
1064 return Mem_strdup(r_main_mempool, modeinfo->builtinstring);
1065 // note that FS_LoadFile appends a 0 byte to make it a valid string
1066 shaderstring = (char *)FS_LoadFile(modeinfo->filename, r_main_mempool, false, NULL);
1069 if (printfromdisknotice)
1070 Con_DPrintf("Loading shaders from file %s...\n", modeinfo->filename);
1071 return shaderstring;
1073 // fall back to builtinstring
1074 return Mem_strdup(r_main_mempool, modeinfo->builtinstring);
1077 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, dpuint64 permutation)
1082 shadermodeinfo_t *modeinfo = &shadermodeinfo[SHADERLANGUAGE_GLSL][mode];
1084 char permutationname[256];
1085 int vertstrings_count = 0;
1086 int geomstrings_count = 0;
1087 int fragstrings_count = 0;
1088 const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1089 const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1090 const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1097 permutationname[0] = 0;
1098 sourcestring = ShaderModeInfo_GetShaderText(modeinfo, true, false);
1100 strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
1102 // we need 140 for r_glsl_skeletal (GL_ARB_uniform_buffer_object)
1103 if(vid.support.glshaderversion >= 140)
1105 vertstrings_list[vertstrings_count++] = "#version 140\n";
1106 geomstrings_list[geomstrings_count++] = "#version 140\n";
1107 fragstrings_list[fragstrings_count++] = "#version 140\n";
1108 vertstrings_list[vertstrings_count++] = "#define GLSL140\n";
1109 geomstrings_list[geomstrings_count++] = "#define GLSL140\n";
1110 fragstrings_list[fragstrings_count++] = "#define GLSL140\n";
1112 // if we can do #version 130, we should (this improves quality of offset/reliefmapping thanks to textureGrad)
1113 else if(vid.support.glshaderversion >= 130)
1115 vertstrings_list[vertstrings_count++] = "#version 130\n";
1116 geomstrings_list[geomstrings_count++] = "#version 130\n";
1117 fragstrings_list[fragstrings_count++] = "#version 130\n";
1118 vertstrings_list[vertstrings_count++] = "#define GLSL130\n";
1119 geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
1120 fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
1122 // if we can do #version 120, we should (this adds the invariant keyword)
1123 else if(vid.support.glshaderversion >= 120)
1125 vertstrings_list[vertstrings_count++] = "#version 120\n";
1126 geomstrings_list[geomstrings_count++] = "#version 120\n";
1127 fragstrings_list[fragstrings_count++] = "#version 120\n";
1128 vertstrings_list[vertstrings_count++] = "#define GLSL120\n";
1129 geomstrings_list[geomstrings_count++] = "#define GLSL120\n";
1130 fragstrings_list[fragstrings_count++] = "#define GLSL120\n";
1132 // GLES also adds several things from GLSL120
1133 switch(vid.renderpath)
1135 case RENDERPATH_GLES2:
1136 vertstrings_list[vertstrings_count++] = "#define GLES\n";
1137 geomstrings_list[geomstrings_count++] = "#define GLES\n";
1138 fragstrings_list[fragstrings_count++] = "#define GLES\n";
1144 // the first pretext is which type of shader to compile as
1145 // (later these will all be bound together as a program object)
1146 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1147 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1148 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1150 // the second pretext is the mode (for example a light source)
1151 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1152 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1153 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1154 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1156 // now add all the permutation pretexts
1157 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1159 if (permutation & (1ll<<i))
1161 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1162 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1163 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1164 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1168 // keep line numbers correct
1169 vertstrings_list[vertstrings_count++] = "\n";
1170 geomstrings_list[geomstrings_count++] = "\n";
1171 fragstrings_list[fragstrings_count++] = "\n";
1176 R_CompileShader_AddStaticParms(mode, permutation);
1177 memcpy((char *)(vertstrings_list + vertstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1178 vertstrings_count += shaderstaticparms_count;
1179 memcpy((char *)(geomstrings_list + geomstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1180 geomstrings_count += shaderstaticparms_count;
1181 memcpy((char *)(fragstrings_list + fragstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1182 fragstrings_count += shaderstaticparms_count;
1184 // now append the shader text itself
1185 vertstrings_list[vertstrings_count++] = sourcestring;
1186 geomstrings_list[geomstrings_count++] = sourcestring;
1187 fragstrings_list[fragstrings_count++] = sourcestring;
1189 // compile the shader program
1190 if (vertstrings_count + geomstrings_count + fragstrings_count)
1191 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
1195 qglUseProgram(p->program);CHECKGLERROR
1196 // look up all the uniform variable names we care about, so we don't
1197 // have to look them up every time we set them
1202 GLint activeuniformindex = 0;
1203 GLint numactiveuniforms = 0;
1204 char uniformname[128];
1205 GLsizei uniformnamelength = 0;
1206 GLint uniformsize = 0;
1207 GLenum uniformtype = 0;
1208 memset(uniformname, 0, sizeof(uniformname));
1209 qglGetProgramiv(p->program, GL_ACTIVE_UNIFORMS, &numactiveuniforms);
1210 Con_Printf("Shader has %i uniforms\n", numactiveuniforms);
1211 for (activeuniformindex = 0;activeuniformindex < numactiveuniforms;activeuniformindex++)
1213 qglGetActiveUniform(p->program, activeuniformindex, sizeof(uniformname) - 1, &uniformnamelength, &uniformsize, &uniformtype, uniformname);
1214 Con_Printf("Uniform %i name \"%s\" size %i type %i\n", (int)activeuniformindex, uniformname, (int)uniformsize, (int)uniformtype);
1219 p->loc_Texture_First = qglGetUniformLocation(p->program, "Texture_First");
1220 p->loc_Texture_Second = qglGetUniformLocation(p->program, "Texture_Second");
1221 p->loc_Texture_GammaRamps = qglGetUniformLocation(p->program, "Texture_GammaRamps");
1222 p->loc_Texture_Normal = qglGetUniformLocation(p->program, "Texture_Normal");
1223 p->loc_Texture_Color = qglGetUniformLocation(p->program, "Texture_Color");
1224 p->loc_Texture_Gloss = qglGetUniformLocation(p->program, "Texture_Gloss");
1225 p->loc_Texture_Glow = qglGetUniformLocation(p->program, "Texture_Glow");
1226 p->loc_Texture_SecondaryNormal = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
1227 p->loc_Texture_SecondaryColor = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
1228 p->loc_Texture_SecondaryGloss = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
1229 p->loc_Texture_SecondaryGlow = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
1230 p->loc_Texture_Pants = qglGetUniformLocation(p->program, "Texture_Pants");
1231 p->loc_Texture_Shirt = qglGetUniformLocation(p->program, "Texture_Shirt");
1232 p->loc_Texture_FogHeightTexture = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
1233 p->loc_Texture_FogMask = qglGetUniformLocation(p->program, "Texture_FogMask");
1234 p->loc_Texture_Lightmap = qglGetUniformLocation(p->program, "Texture_Lightmap");
1235 p->loc_Texture_Deluxemap = qglGetUniformLocation(p->program, "Texture_Deluxemap");
1236 p->loc_Texture_Attenuation = qglGetUniformLocation(p->program, "Texture_Attenuation");
1237 p->loc_Texture_Cube = qglGetUniformLocation(p->program, "Texture_Cube");
1238 p->loc_Texture_Refraction = qglGetUniformLocation(p->program, "Texture_Refraction");
1239 p->loc_Texture_Reflection = qglGetUniformLocation(p->program, "Texture_Reflection");
1240 p->loc_Texture_ShadowMap2D = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
1241 p->loc_Texture_CubeProjection = qglGetUniformLocation(p->program, "Texture_CubeProjection");
1242 p->loc_Texture_ScreenNormalMap = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
1243 p->loc_Texture_ScreenDiffuse = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
1244 p->loc_Texture_ScreenSpecular = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
1245 p->loc_Texture_ReflectMask = qglGetUniformLocation(p->program, "Texture_ReflectMask");
1246 p->loc_Texture_ReflectCube = qglGetUniformLocation(p->program, "Texture_ReflectCube");
1247 p->loc_Texture_BounceGrid = qglGetUniformLocation(p->program, "Texture_BounceGrid");
1248 p->loc_Alpha = qglGetUniformLocation(p->program, "Alpha");
1249 p->loc_BloomBlur_Parameters = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
1250 p->loc_ClientTime = qglGetUniformLocation(p->program, "ClientTime");
1251 p->loc_Color_Ambient = qglGetUniformLocation(p->program, "Color_Ambient");
1252 p->loc_Color_Diffuse = qglGetUniformLocation(p->program, "Color_Diffuse");
1253 p->loc_Color_Specular = qglGetUniformLocation(p->program, "Color_Specular");
1254 p->loc_Color_Glow = qglGetUniformLocation(p->program, "Color_Glow");
1255 p->loc_Color_Pants = qglGetUniformLocation(p->program, "Color_Pants");
1256 p->loc_Color_Shirt = qglGetUniformLocation(p->program, "Color_Shirt");
1257 p->loc_DeferredColor_Ambient = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
1258 p->loc_DeferredColor_Diffuse = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
1259 p->loc_DeferredColor_Specular = qglGetUniformLocation(p->program, "DeferredColor_Specular");
1260 p->loc_DeferredMod_Diffuse = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
1261 p->loc_DeferredMod_Specular = qglGetUniformLocation(p->program, "DeferredMod_Specular");
1262 p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
1263 p->loc_EyePosition = qglGetUniformLocation(p->program, "EyePosition");
1264 p->loc_FogColor = qglGetUniformLocation(p->program, "FogColor");
1265 p->loc_FogHeightFade = qglGetUniformLocation(p->program, "FogHeightFade");
1266 p->loc_FogPlane = qglGetUniformLocation(p->program, "FogPlane");
1267 p->loc_FogPlaneViewDist = qglGetUniformLocation(p->program, "FogPlaneViewDist");
1268 p->loc_FogRangeRecip = qglGetUniformLocation(p->program, "FogRangeRecip");
1269 p->loc_LightColor = qglGetUniformLocation(p->program, "LightColor");
1270 p->loc_LightDir = qglGetUniformLocation(p->program, "LightDir");
1271 p->loc_LightPosition = qglGetUniformLocation(p->program, "LightPosition");
1272 p->loc_OffsetMapping_ScaleSteps = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
1273 p->loc_OffsetMapping_LodDistance = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
1274 p->loc_OffsetMapping_Bias = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
1275 p->loc_PixelSize = qglGetUniformLocation(p->program, "PixelSize");
1276 p->loc_ReflectColor = qglGetUniformLocation(p->program, "ReflectColor");
1277 p->loc_ReflectFactor = qglGetUniformLocation(p->program, "ReflectFactor");
1278 p->loc_ReflectOffset = qglGetUniformLocation(p->program, "ReflectOffset");
1279 p->loc_RefractColor = qglGetUniformLocation(p->program, "RefractColor");
1280 p->loc_Saturation = qglGetUniformLocation(p->program, "Saturation");
1281 p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
1282 p->loc_ScreenScaleRefractReflect = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
1283 p->loc_ScreenToDepth = qglGetUniformLocation(p->program, "ScreenToDepth");
1284 p->loc_ShadowMap_Parameters = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
1285 p->loc_ShadowMap_TextureScale = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
1286 p->loc_SpecularPower = qglGetUniformLocation(p->program, "SpecularPower");
1287 p->loc_UserVec1 = qglGetUniformLocation(p->program, "UserVec1");
1288 p->loc_UserVec2 = qglGetUniformLocation(p->program, "UserVec2");
1289 p->loc_UserVec3 = qglGetUniformLocation(p->program, "UserVec3");
1290 p->loc_UserVec4 = qglGetUniformLocation(p->program, "UserVec4");
1291 p->loc_ViewTintColor = qglGetUniformLocation(p->program, "ViewTintColor");
1292 p->loc_ViewToLight = qglGetUniformLocation(p->program, "ViewToLight");
1293 p->loc_ModelToLight = qglGetUniformLocation(p->program, "ModelToLight");
1294 p->loc_TexMatrix = qglGetUniformLocation(p->program, "TexMatrix");
1295 p->loc_BackgroundTexMatrix = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
1296 p->loc_ModelViewMatrix = qglGetUniformLocation(p->program, "ModelViewMatrix");
1297 p->loc_ModelViewProjectionMatrix = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
1298 p->loc_PixelToScreenTexCoord = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
1299 p->loc_ModelToReflectCube = qglGetUniformLocation(p->program, "ModelToReflectCube");
1300 p->loc_ShadowMapMatrix = qglGetUniformLocation(p->program, "ShadowMapMatrix");
1301 p->loc_BloomColorSubtract = qglGetUniformLocation(p->program, "BloomColorSubtract");
1302 p->loc_NormalmapScrollBlend = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
1303 p->loc_BounceGridMatrix = qglGetUniformLocation(p->program, "BounceGridMatrix");
1304 p->loc_BounceGridIntensity = qglGetUniformLocation(p->program, "BounceGridIntensity");
1305 // initialize the samplers to refer to the texture units we use
1306 p->tex_Texture_First = -1;
1307 p->tex_Texture_Second = -1;
1308 p->tex_Texture_GammaRamps = -1;
1309 p->tex_Texture_Normal = -1;
1310 p->tex_Texture_Color = -1;
1311 p->tex_Texture_Gloss = -1;
1312 p->tex_Texture_Glow = -1;
1313 p->tex_Texture_SecondaryNormal = -1;
1314 p->tex_Texture_SecondaryColor = -1;
1315 p->tex_Texture_SecondaryGloss = -1;
1316 p->tex_Texture_SecondaryGlow = -1;
1317 p->tex_Texture_Pants = -1;
1318 p->tex_Texture_Shirt = -1;
1319 p->tex_Texture_FogHeightTexture = -1;
1320 p->tex_Texture_FogMask = -1;
1321 p->tex_Texture_Lightmap = -1;
1322 p->tex_Texture_Deluxemap = -1;
1323 p->tex_Texture_Attenuation = -1;
1324 p->tex_Texture_Cube = -1;
1325 p->tex_Texture_Refraction = -1;
1326 p->tex_Texture_Reflection = -1;
1327 p->tex_Texture_ShadowMap2D = -1;
1328 p->tex_Texture_CubeProjection = -1;
1329 p->tex_Texture_ScreenNormalMap = -1;
1330 p->tex_Texture_ScreenDiffuse = -1;
1331 p->tex_Texture_ScreenSpecular = -1;
1332 p->tex_Texture_ReflectMask = -1;
1333 p->tex_Texture_ReflectCube = -1;
1334 p->tex_Texture_BounceGrid = -1;
1335 // bind the texture samplers in use
1337 if (p->loc_Texture_First >= 0) {p->tex_Texture_First = sampler;qglUniform1i(p->loc_Texture_First , sampler);sampler++;}
1338 if (p->loc_Texture_Second >= 0) {p->tex_Texture_Second = sampler;qglUniform1i(p->loc_Texture_Second , sampler);sampler++;}
1339 if (p->loc_Texture_GammaRamps >= 0) {p->tex_Texture_GammaRamps = sampler;qglUniform1i(p->loc_Texture_GammaRamps , sampler);sampler++;}
1340 if (p->loc_Texture_Normal >= 0) {p->tex_Texture_Normal = sampler;qglUniform1i(p->loc_Texture_Normal , sampler);sampler++;}
1341 if (p->loc_Texture_Color >= 0) {p->tex_Texture_Color = sampler;qglUniform1i(p->loc_Texture_Color , sampler);sampler++;}
1342 if (p->loc_Texture_Gloss >= 0) {p->tex_Texture_Gloss = sampler;qglUniform1i(p->loc_Texture_Gloss , sampler);sampler++;}
1343 if (p->loc_Texture_Glow >= 0) {p->tex_Texture_Glow = sampler;qglUniform1i(p->loc_Texture_Glow , sampler);sampler++;}
1344 if (p->loc_Texture_SecondaryNormal >= 0) {p->tex_Texture_SecondaryNormal = sampler;qglUniform1i(p->loc_Texture_SecondaryNormal , sampler);sampler++;}
1345 if (p->loc_Texture_SecondaryColor >= 0) {p->tex_Texture_SecondaryColor = sampler;qglUniform1i(p->loc_Texture_SecondaryColor , sampler);sampler++;}
1346 if (p->loc_Texture_SecondaryGloss >= 0) {p->tex_Texture_SecondaryGloss = sampler;qglUniform1i(p->loc_Texture_SecondaryGloss , sampler);sampler++;}
1347 if (p->loc_Texture_SecondaryGlow >= 0) {p->tex_Texture_SecondaryGlow = sampler;qglUniform1i(p->loc_Texture_SecondaryGlow , sampler);sampler++;}
1348 if (p->loc_Texture_Pants >= 0) {p->tex_Texture_Pants = sampler;qglUniform1i(p->loc_Texture_Pants , sampler);sampler++;}
1349 if (p->loc_Texture_Shirt >= 0) {p->tex_Texture_Shirt = sampler;qglUniform1i(p->loc_Texture_Shirt , sampler);sampler++;}
1350 if (p->loc_Texture_FogHeightTexture>= 0) {p->tex_Texture_FogHeightTexture = sampler;qglUniform1i(p->loc_Texture_FogHeightTexture, sampler);sampler++;}
1351 if (p->loc_Texture_FogMask >= 0) {p->tex_Texture_FogMask = sampler;qglUniform1i(p->loc_Texture_FogMask , sampler);sampler++;}
1352 if (p->loc_Texture_Lightmap >= 0) {p->tex_Texture_Lightmap = sampler;qglUniform1i(p->loc_Texture_Lightmap , sampler);sampler++;}
1353 if (p->loc_Texture_Deluxemap >= 0) {p->tex_Texture_Deluxemap = sampler;qglUniform1i(p->loc_Texture_Deluxemap , sampler);sampler++;}
1354 if (p->loc_Texture_Attenuation >= 0) {p->tex_Texture_Attenuation = sampler;qglUniform1i(p->loc_Texture_Attenuation , sampler);sampler++;}
1355 if (p->loc_Texture_Cube >= 0) {p->tex_Texture_Cube = sampler;qglUniform1i(p->loc_Texture_Cube , sampler);sampler++;}
1356 if (p->loc_Texture_Refraction >= 0) {p->tex_Texture_Refraction = sampler;qglUniform1i(p->loc_Texture_Refraction , sampler);sampler++;}
1357 if (p->loc_Texture_Reflection >= 0) {p->tex_Texture_Reflection = sampler;qglUniform1i(p->loc_Texture_Reflection , sampler);sampler++;}
1358 if (p->loc_Texture_ShadowMap2D >= 0) {p->tex_Texture_ShadowMap2D = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D , sampler);sampler++;}
1359 if (p->loc_Texture_CubeProjection >= 0) {p->tex_Texture_CubeProjection = sampler;qglUniform1i(p->loc_Texture_CubeProjection , sampler);sampler++;}
1360 if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
1361 if (p->loc_Texture_ScreenDiffuse >= 0) {p->tex_Texture_ScreenDiffuse = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse , sampler);sampler++;}
1362 if (p->loc_Texture_ScreenSpecular >= 0) {p->tex_Texture_ScreenSpecular = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular , sampler);sampler++;}
1363 if (p->loc_Texture_ReflectMask >= 0) {p->tex_Texture_ReflectMask = sampler;qglUniform1i(p->loc_Texture_ReflectMask , sampler);sampler++;}
1364 if (p->loc_Texture_ReflectCube >= 0) {p->tex_Texture_ReflectCube = sampler;qglUniform1i(p->loc_Texture_ReflectCube , sampler);sampler++;}
1365 if (p->loc_Texture_BounceGrid >= 0) {p->tex_Texture_BounceGrid = sampler;qglUniform1i(p->loc_Texture_BounceGrid , sampler);sampler++;}
1366 // get the uniform block indices so we can bind them
1367 #ifndef USE_GLES2 /* FIXME: GLES3 only */
1368 if (vid.support.arb_uniform_buffer_object)
1369 p->ubiloc_Skeletal_Transform12_UniformBlock = qglGetUniformBlockIndex(p->program, "Skeletal_Transform12_UniformBlock");
1372 p->ubiloc_Skeletal_Transform12_UniformBlock = -1;
1373 // clear the uniform block bindings
1374 p->ubibind_Skeletal_Transform12_UniformBlock = -1;
1375 // bind the uniform blocks in use
1377 #ifndef USE_GLES2 /* FIXME: GLES3 only */
1378 if (p->ubiloc_Skeletal_Transform12_UniformBlock >= 0) {p->ubibind_Skeletal_Transform12_UniformBlock = ubibind;qglUniformBlockBinding(p->program, p->ubiloc_Skeletal_Transform12_UniformBlock, ubibind);ubibind++;}
1380 // we're done compiling and setting up the shader, at least until it is used
1382 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
1385 Con_Printf("^1GLSL shader %s failed! some features may not work properly.\n", permutationname);
1389 Mem_Free(sourcestring);
1392 static void R_SetupShader_SetPermutationGLSL(unsigned int mode, dpuint64 permutation)
1394 r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
1395 if (r_glsl_permutation != perm)
1397 r_glsl_permutation = perm;
1398 if (!r_glsl_permutation->program)
1400 if (!r_glsl_permutation->compiled)
1402 Con_DPrintf("Compiling shader mode %u permutation %u\n", mode, permutation);
1403 R_GLSL_CompilePermutation(perm, mode, permutation);
1405 if (!r_glsl_permutation->program)
1407 // remove features until we find a valid permutation
1409 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1411 // reduce i more quickly whenever it would not remove any bits
1412 dpuint64 j = 1ll<<(SHADERPERMUTATION_COUNT-1-i);
1413 if (!(permutation & j))
1416 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1417 if (!r_glsl_permutation->compiled)
1418 R_GLSL_CompilePermutation(perm, mode, permutation);
1419 if (r_glsl_permutation->program)
1422 if (i >= SHADERPERMUTATION_COUNT)
1424 //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].filename, shadermodeinfo[mode].pretext);
1425 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
1426 qglUseProgram(0);CHECKGLERROR
1427 return; // no bit left to clear, entire mode is broken
1432 qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
1434 if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
1435 if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
1436 if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
1444 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
1445 extern D3DCAPS9 vid_d3d9caps;
1448 struct r_hlsl_permutation_s;
1449 typedef struct r_hlsl_permutation_s
1451 /// hash lookup data
1452 struct r_hlsl_permutation_s *hashnext;
1454 dpuint64 permutation;
1456 /// indicates if we have tried compiling this permutation already
1458 /// NULL if compilation failed
1459 IDirect3DVertexShader9 *vertexshader;
1460 IDirect3DPixelShader9 *pixelshader;
1462 r_hlsl_permutation_t;
1464 typedef enum D3DVSREGISTER_e
1466 D3DVSREGISTER_TexMatrix = 0, // float4x4
1467 D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
1468 D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
1469 D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
1470 D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
1471 D3DVSREGISTER_ModelToLight = 20, // float4x4
1472 D3DVSREGISTER_EyePosition = 24,
1473 D3DVSREGISTER_FogPlane = 25,
1474 D3DVSREGISTER_LightDir = 26,
1475 D3DVSREGISTER_LightPosition = 27,
1479 typedef enum D3DPSREGISTER_e
1481 D3DPSREGISTER_Alpha = 0,
1482 D3DPSREGISTER_BloomBlur_Parameters = 1,
1483 D3DPSREGISTER_ClientTime = 2,
1484 D3DPSREGISTER_Color_Ambient = 3,
1485 D3DPSREGISTER_Color_Diffuse = 4,
1486 D3DPSREGISTER_Color_Specular = 5,
1487 D3DPSREGISTER_Color_Glow = 6,
1488 D3DPSREGISTER_Color_Pants = 7,
1489 D3DPSREGISTER_Color_Shirt = 8,
1490 D3DPSREGISTER_DeferredColor_Ambient = 9,
1491 D3DPSREGISTER_DeferredColor_Diffuse = 10,
1492 D3DPSREGISTER_DeferredColor_Specular = 11,
1493 D3DPSREGISTER_DeferredMod_Diffuse = 12,
1494 D3DPSREGISTER_DeferredMod_Specular = 13,
1495 D3DPSREGISTER_DistortScaleRefractReflect = 14,
1496 D3DPSREGISTER_EyePosition = 15, // unused
1497 D3DPSREGISTER_FogColor = 16,
1498 D3DPSREGISTER_FogHeightFade = 17,
1499 D3DPSREGISTER_FogPlane = 18,
1500 D3DPSREGISTER_FogPlaneViewDist = 19,
1501 D3DPSREGISTER_FogRangeRecip = 20,
1502 D3DPSREGISTER_LightColor = 21,
1503 D3DPSREGISTER_LightDir = 22, // unused
1504 D3DPSREGISTER_LightPosition = 23,
1505 D3DPSREGISTER_OffsetMapping_ScaleSteps = 24,
1506 D3DPSREGISTER_PixelSize = 25,
1507 D3DPSREGISTER_ReflectColor = 26,
1508 D3DPSREGISTER_ReflectFactor = 27,
1509 D3DPSREGISTER_ReflectOffset = 28,
1510 D3DPSREGISTER_RefractColor = 29,
1511 D3DPSREGISTER_Saturation = 30,
1512 D3DPSREGISTER_ScreenCenterRefractReflect = 31,
1513 D3DPSREGISTER_ScreenScaleRefractReflect = 32,
1514 D3DPSREGISTER_ScreenToDepth = 33,
1515 D3DPSREGISTER_ShadowMap_Parameters = 34,
1516 D3DPSREGISTER_ShadowMap_TextureScale = 35,
1517 D3DPSREGISTER_SpecularPower = 36,
1518 D3DPSREGISTER_UserVec1 = 37,
1519 D3DPSREGISTER_UserVec2 = 38,
1520 D3DPSREGISTER_UserVec3 = 39,
1521 D3DPSREGISTER_UserVec4 = 40,
1522 D3DPSREGISTER_ViewTintColor = 41,
1523 D3DPSREGISTER_PixelToScreenTexCoord = 42,
1524 D3DPSREGISTER_BloomColorSubtract = 43,
1525 D3DPSREGISTER_ViewToLight = 44, // float4x4
1526 D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
1527 D3DPSREGISTER_NormalmapScrollBlend = 52,
1528 D3DPSREGISTER_OffsetMapping_LodDistance = 53,
1529 D3DPSREGISTER_OffsetMapping_Bias = 54,
1534 /// information about each possible shader permutation
1535 r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
1536 /// currently selected permutation
1537 r_hlsl_permutation_t *r_hlsl_permutation;
1538 /// storage for permutations linked in the hash table
1539 memexpandablearray_t r_hlsl_permutationarray;
1541 static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, dpuint64 permutation)
1543 //unsigned int hashdepth = 0;
1544 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
1545 r_hlsl_permutation_t *p;
1546 for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
1548 if (p->mode == mode && p->permutation == permutation)
1550 //if (hashdepth > 10)
1551 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1556 p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
1558 p->permutation = permutation;
1559 p->hashnext = r_hlsl_permutationhash[mode][hashindex];
1560 r_hlsl_permutationhash[mode][hashindex] = p;
1561 //if (hashdepth > 10)
1562 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
1567 //#include <d3dx9shader.h>
1568 //#include <d3dx9mesh.h>
1570 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
1572 DWORD *vsbin = NULL;
1573 DWORD *psbin = NULL;
1574 fs_offset_t vsbinsize;
1575 fs_offset_t psbinsize;
1576 // IDirect3DVertexShader9 *vs = NULL;
1577 // IDirect3DPixelShader9 *ps = NULL;
1578 ID3DXBuffer *vslog = NULL;
1579 ID3DXBuffer *vsbuffer = NULL;
1580 ID3DXConstantTable *vsconstanttable = NULL;
1581 ID3DXBuffer *pslog = NULL;
1582 ID3DXBuffer *psbuffer = NULL;
1583 ID3DXConstantTable *psconstanttable = NULL;
1586 char temp[MAX_INPUTLINE];
1587 const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
1589 qboolean debugshader = gl_paranoid.integer != 0;
1590 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1591 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
1594 vsbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
1595 psbin = (DWORD *)FS_LoadFile(va(vabuf, sizeof(vabuf), "%s.psbin", cachename), r_main_mempool, true, &psbinsize);
1597 if ((!vsbin && vertstring) || (!psbin && fragstring))
1599 const char* dllnames_d3dx9 [] =
1623 dllhandle_t d3dx9_dll = NULL;
1624 HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1625 HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
1626 HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
1627 dllfunction_t d3dx9_dllfuncs[] =
1629 {"D3DXCompileShaderFromFileA", (void **) &qD3DXCompileShaderFromFileA},
1630 {"D3DXPreprocessShader", (void **) &qD3DXPreprocessShader},
1631 {"D3DXCompileShader", (void **) &qD3DXCompileShader},
1634 // 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...
1635 #ifndef ID3DXBuffer_GetBufferPointer
1636 #if !defined(__cplusplus) || defined(CINTERFACE)
1637 #define ID3DXBuffer_GetBufferPointer(p) (p)->lpVtbl->GetBufferPointer(p)
1638 #define ID3DXBuffer_GetBufferSize(p) (p)->lpVtbl->GetBufferSize(p)
1639 #define ID3DXBuffer_Release(p) (p)->lpVtbl->Release(p)
1641 #define ID3DXBuffer_GetBufferPointer(p) (p)->GetBufferPointer()
1642 #define ID3DXBuffer_GetBufferSize(p) (p)->GetBufferSize()
1643 #define ID3DXBuffer_Release(p) (p)->Release()
1646 if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
1648 DWORD shaderflags = 0;
1650 shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
1651 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1652 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1653 if (vertstring && vertstring[0])
1657 FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_vs.fx", cachename), vertstring, strlen(vertstring));
1658 vsresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1661 vsresult = qD3DXCompileShader(vertstring, (unsigned int)strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
1664 vsbinsize = ID3DXBuffer_GetBufferSize(vsbuffer);
1665 vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
1666 memcpy(vsbin, ID3DXBuffer_GetBufferPointer(vsbuffer), vsbinsize);
1667 ID3DXBuffer_Release(vsbuffer);
1671 strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(vslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(vslog)));
1672 Con_DPrintf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
1673 ID3DXBuffer_Release(vslog);
1676 if (fragstring && fragstring[0])
1680 FS_WriteFile(va(vabuf, sizeof(vabuf), "%s_ps.fx", cachename), fragstring, strlen(fragstring));
1681 psresult = qD3DXCompileShaderFromFileA(va(vabuf, sizeof(vabuf), "%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1684 psresult = qD3DXCompileShader(fragstring, (unsigned int)strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
1687 psbinsize = ID3DXBuffer_GetBufferSize(psbuffer);
1688 psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
1689 memcpy(psbin, ID3DXBuffer_GetBufferPointer(psbuffer), psbinsize);
1690 ID3DXBuffer_Release(psbuffer);
1694 strlcpy(temp, (const char *)ID3DXBuffer_GetBufferPointer(pslog), min(sizeof(temp), ID3DXBuffer_GetBufferSize(pslog)));
1695 Con_DPrintf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
1696 ID3DXBuffer_Release(pslog);
1699 Sys_UnloadLibrary(&d3dx9_dll);
1702 Con_DPrintf("Unable to compile shader - D3DXCompileShader function not found\n");
1706 vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
1707 if (FAILED(vsresult))
1708 Con_DPrintf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
1709 psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
1710 if (FAILED(psresult))
1711 Con_DPrintf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
1713 // free the shader data
1714 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
1715 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
1718 static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, dpuint64 permutation)
1721 shadermodeinfo_t *modeinfo = &shadermodeinfo[SHADERLANGUAGE_HLSL][mode];
1722 int vertstring_length = 0;
1723 int geomstring_length = 0;
1724 int fragstring_length = 0;
1727 char *vertstring, *geomstring, *fragstring;
1728 char permutationname[256];
1729 char cachename[256];
1730 int vertstrings_count = 0;
1731 int geomstrings_count = 0;
1732 int fragstrings_count = 0;
1733 const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1734 const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1735 const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1740 p->vertexshader = NULL;
1741 p->pixelshader = NULL;
1743 permutationname[0] = 0;
1745 sourcestring = ShaderModeInfo_GetShaderText(modeinfo, true, false);
1747 strlcat(permutationname, modeinfo->filename, sizeof(permutationname));
1748 strlcat(cachename, "hlsl/", sizeof(cachename));
1750 // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
1751 vertstrings_count = 0;
1752 geomstrings_count = 0;
1753 fragstrings_count = 0;
1754 vertstrings_list[vertstrings_count++] = "#define HLSL\n";
1755 geomstrings_list[geomstrings_count++] = "#define HLSL\n";
1756 fragstrings_list[fragstrings_count++] = "#define HLSL\n";
1758 // the first pretext is which type of shader to compile as
1759 // (later these will all be bound together as a program object)
1760 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1761 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1762 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1764 // the second pretext is the mode (for example a light source)
1765 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
1766 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
1767 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
1768 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
1769 strlcat(cachename, modeinfo->name, sizeof(cachename));
1771 // now add all the permutation pretexts
1772 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1774 if (permutation & (1ll<<i))
1776 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
1777 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
1778 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
1779 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
1780 strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
1784 // keep line numbers correct
1785 vertstrings_list[vertstrings_count++] = "\n";
1786 geomstrings_list[geomstrings_count++] = "\n";
1787 fragstrings_list[fragstrings_count++] = "\n";
1792 R_CompileShader_AddStaticParms(mode, permutation);
1793 memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1794 vertstrings_count += shaderstaticparms_count;
1795 memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1796 geomstrings_count += shaderstaticparms_count;
1797 memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
1798 fragstrings_count += shaderstaticparms_count;
1800 // replace spaces in the cachename with _ characters
1801 for (i = 0;cachename[i];i++)
1802 if (cachename[i] == ' ')
1805 // now append the shader text itself
1806 vertstrings_list[vertstrings_count++] = sourcestring;
1807 geomstrings_list[geomstrings_count++] = sourcestring;
1808 fragstrings_list[fragstrings_count++] = sourcestring;
1810 vertstring_length = 0;
1811 for (i = 0;i < vertstrings_count;i++)
1812 vertstring_length += (int)strlen(vertstrings_list[i]);
1813 vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
1814 for (i = 0;i < vertstrings_count;t += (int)strlen(vertstrings_list[i]), i++)
1815 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
1817 geomstring_length = 0;
1818 for (i = 0;i < geomstrings_count;i++)
1819 geomstring_length += (int)strlen(geomstrings_list[i]);
1820 geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
1821 for (i = 0;i < geomstrings_count;t += (int)strlen(geomstrings_list[i]), i++)
1822 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
1824 fragstring_length = 0;
1825 for (i = 0;i < fragstrings_count;i++)
1826 fragstring_length += (int)strlen(fragstrings_list[i]);
1827 fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
1828 for (i = 0;i < fragstrings_count;t += (int)strlen(fragstrings_list[i]), i++)
1829 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
1831 // try to load the cached shader, or generate one
1832 R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
1834 if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
1835 Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
1837 Con_Printf("^1HLSL shader %s failed! some features may not work properly.\n", permutationname);
1841 Mem_Free(vertstring);
1843 Mem_Free(geomstring);
1845 Mem_Free(fragstring);
1847 Mem_Free(sourcestring);
1850 static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
1851 static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
1852 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);}
1853 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);}
1854 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);}
1855 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);}
1857 static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
1858 static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
1859 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);}
1860 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);}
1861 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);}
1862 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);}
1864 void R_SetupShader_SetPermutationHLSL(unsigned int mode, dpuint64 permutation)
1866 r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
1867 if (r_hlsl_permutation != perm)
1869 r_hlsl_permutation = perm;
1870 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1872 if (!r_hlsl_permutation->compiled)
1873 R_HLSL_CompilePermutation(perm, mode, permutation);
1874 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
1876 // remove features until we find a valid permutation
1878 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1880 // reduce i more quickly whenever it would not remove any bits
1881 dpuint64 j = 1ll<<(SHADERPERMUTATION_COUNT-1-i);
1882 if (!(permutation & j))
1885 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1886 if (!r_hlsl_permutation->compiled)
1887 R_HLSL_CompilePermutation(perm, mode, permutation);
1888 if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
1891 if (i >= SHADERPERMUTATION_COUNT)
1893 //Con_Printf("Could not find a working HLSL shader for permutation %s %s\n", shadermodeinfo[mode].filename, shadermodeinfo[mode].pretext);
1894 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
1895 return; // no bit left to clear, entire mode is broken
1899 IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
1900 IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
1902 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
1903 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
1904 hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
1908 static void R_SetupShader_SetPermutationSoft(unsigned int mode, dpuint64 permutation)
1910 DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer);
1911 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
1912 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
1913 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
1916 void R_GLSL_Restart_f(void)
1918 unsigned int i, limit;
1919 switch(vid.renderpath)
1921 case RENDERPATH_D3D9:
1924 r_hlsl_permutation_t *p;
1925 r_hlsl_permutation = NULL;
1926 limit = (unsigned int)Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
1927 for (i = 0;i < limit;i++)
1929 if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
1931 if (p->vertexshader)
1932 IDirect3DVertexShader9_Release(p->vertexshader);
1934 IDirect3DPixelShader9_Release(p->pixelshader);
1935 Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
1938 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
1942 case RENDERPATH_D3D10:
1943 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1945 case RENDERPATH_D3D11:
1946 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
1948 case RENDERPATH_GL20:
1949 case RENDERPATH_GLES2:
1951 r_glsl_permutation_t *p;
1952 r_glsl_permutation = NULL;
1953 limit = (unsigned int)Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
1954 for (i = 0;i < limit;i++)
1956 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
1958 GL_Backend_FreeProgram(p->program);
1959 Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
1962 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
1965 case RENDERPATH_GL11:
1966 case RENDERPATH_GL13:
1967 case RENDERPATH_GLES1:
1969 case RENDERPATH_SOFT:
1974 static void R_GLSL_DumpShader_f(void)
1976 int i, language, mode, dupe;
1978 shadermodeinfo_t *modeinfo;
1981 for (language = 0;language < SHADERLANGUAGE_COUNT;language++)
1983 modeinfo = shadermodeinfo[language];
1984 for (mode = 0;mode < SHADERMODE_COUNT;mode++)
1986 // don't dump the same file multiple times (most or all shaders come from the same file)
1987 for (dupe = mode - 1;dupe >= 0;dupe--)
1988 if (!strcmp(modeinfo[mode].filename, modeinfo[dupe].filename))
1992 text = modeinfo[mode].builtinstring;
1995 file = FS_OpenRealFile(modeinfo[mode].filename, "w", false);
1998 FS_Print(file, "/* The engine may define the following macros:\n");
1999 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
2000 for (i = 0;i < SHADERMODE_COUNT;i++)
2001 FS_Print(file, modeinfo[i].pretext);
2002 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
2003 FS_Print(file, shaderpermutationinfo[i].pretext);
2004 FS_Print(file, "*/\n");
2005 FS_Print(file, text);
2007 Con_Printf("%s written\n", modeinfo[mode].filename);
2010 Con_Printf("failed to write to %s\n", modeinfo[mode].filename);
2015 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha)
2017 dpuint64 permutation = 0;
2018 if (r_trippy.integer && !notrippy)
2019 permutation |= SHADERPERMUTATION_TRIPPY;
2020 permutation |= SHADERPERMUTATION_VIEWTINT;
2022 permutation |= SHADERPERMUTATION_DIFFUSE;
2024 permutation |= SHADERPERMUTATION_SPECULAR;
2025 if (texturemode == GL_MODULATE)
2026 permutation |= SHADERPERMUTATION_COLORMAPPING;
2027 else if (texturemode == GL_ADD)
2028 permutation |= SHADERPERMUTATION_GLOW;
2029 else if (texturemode == GL_DECAL)
2030 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2031 if (usegamma && v_glslgamma.integer && v_glslgamma_2d.integer && !vid.sRGB2D && r_texture_gammaramps && !vid_gammatables_trivial)
2032 permutation |= SHADERPERMUTATION_GAMMARAMPS;
2033 if (suppresstexalpha)
2034 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2036 texturemode = GL_MODULATE;
2037 if (vid.allowalphatocoverage)
2038 GL_AlphaToCoverage(false);
2039 switch (vid.renderpath)
2041 case RENDERPATH_D3D9:
2043 R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, permutation);
2044 R_Mesh_TexBind(GL20TU_FIRST , first );
2045 R_Mesh_TexBind(GL20TU_SECOND, second);
2046 if (permutation & SHADERPERMUTATION_GAMMARAMPS)
2047 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
2050 case RENDERPATH_D3D10:
2051 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2053 case RENDERPATH_D3D11:
2054 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2056 case RENDERPATH_GL20:
2057 case RENDERPATH_GLES2:
2058 R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, permutation);
2059 if (r_glsl_permutation->tex_Texture_First >= 0)
2060 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
2061 if (r_glsl_permutation->tex_Texture_Second >= 0)
2062 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
2063 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0)
2064 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps);
2066 case RENDERPATH_GL13:
2067 case RENDERPATH_GLES1:
2068 R_Mesh_TexBind(0, first );
2069 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
2070 R_Mesh_TexMatrix(0, NULL);
2071 R_Mesh_TexBind(1, second);
2074 R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
2075 R_Mesh_TexMatrix(1, NULL);
2078 case RENDERPATH_GL11:
2079 R_Mesh_TexBind(0, first );
2080 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
2081 R_Mesh_TexMatrix(0, NULL);
2083 case RENDERPATH_SOFT:
2084 R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, permutation);
2085 R_Mesh_TexBind(GL20TU_FIRST , first );
2086 R_Mesh_TexBind(GL20TU_SECOND, second);
2091 void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy)
2093 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false);
2096 void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean skeletal)
2098 dpuint64 permutation = 0;
2099 if (r_trippy.integer && !notrippy)
2100 permutation |= SHADERPERMUTATION_TRIPPY;
2102 permutation |= SHADERPERMUTATION_DEPTHRGB;
2104 permutation |= SHADERPERMUTATION_SKELETAL;
2106 if (vid.allowalphatocoverage)
2107 GL_AlphaToCoverage(false);
2108 switch (vid.renderpath)
2110 case RENDERPATH_D3D9:
2112 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2115 case RENDERPATH_D3D10:
2116 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2118 case RENDERPATH_D3D11:
2119 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2121 case RENDERPATH_GL20:
2122 case RENDERPATH_GLES2:
2123 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2124 #ifndef USE_GLES2 /* FIXME: GLES3 only */
2125 if (r_glsl_permutation->ubiloc_Skeletal_Transform12_UniformBlock >= 0 && rsurface.batchskeletaltransform3x4buffer) qglBindBufferRange(GL_UNIFORM_BUFFER, r_glsl_permutation->ubibind_Skeletal_Transform12_UniformBlock, rsurface.batchskeletaltransform3x4buffer->bufferobject, rsurface.batchskeletaltransform3x4offset, rsurface.batchskeletaltransform3x4size);
2128 case RENDERPATH_GL13:
2129 case RENDERPATH_GLES1:
2130 R_Mesh_TexBind(0, 0);
2131 R_Mesh_TexBind(1, 0);
2133 case RENDERPATH_GL11:
2134 R_Mesh_TexBind(0, 0);
2136 case RENDERPATH_SOFT:
2137 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, permutation);
2142 extern qboolean r_shadow_usingdeferredprepass;
2143 extern rtexture_t *r_shadow_attenuationgradienttexture;
2144 extern rtexture_t *r_shadow_attenuation2dtexture;
2145 extern rtexture_t *r_shadow_attenuation3dtexture;
2146 extern qboolean r_shadow_usingshadowmap2d;
2147 extern qboolean r_shadow_usingshadowmaportho;
2148 extern float r_shadow_modelshadowmap_texturescale[4];
2149 extern float r_shadow_modelshadowmap_parameters[4];
2150 extern float r_shadow_lightshadowmap_texturescale[4];
2151 extern float r_shadow_lightshadowmap_parameters[4];
2152 extern qboolean r_shadow_shadowmapvsdct;
2153 extern rtexture_t *r_shadow_shadowmap2ddepthbuffer;
2154 extern rtexture_t *r_shadow_shadowmap2ddepthtexture;
2155 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
2156 extern matrix4x4_t r_shadow_shadowmapmatrix;
2157 extern int r_shadow_prepass_width;
2158 extern int r_shadow_prepass_height;
2159 extern rtexture_t *r_shadow_prepassgeometrydepthbuffer;
2160 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
2161 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
2162 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
2164 #define BLENDFUNC_ALLOWS_COLORMOD 1
2165 #define BLENDFUNC_ALLOWS_FOG 2
2166 #define BLENDFUNC_ALLOWS_FOG_HACK0 4
2167 #define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
2168 #define BLENDFUNC_ALLOWS_ANYFOG (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2169 static int R_BlendFuncFlags(int src, int dst)
2173 // a blendfunc allows colormod if:
2174 // a) it can never keep the destination pixel invariant, or
2175 // b) it can keep the destination pixel invariant, and still can do so if colormodded
2176 // this is to prevent unintended side effects from colormod
2178 // a blendfunc allows fog if:
2179 // blend(fog(src), fog(dst)) == fog(blend(src, dst))
2180 // this is to prevent unintended side effects from fog
2182 // these checks are the output of fogeval.pl
2184 r |= BLENDFUNC_ALLOWS_COLORMOD;
2185 if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2186 if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2187 if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2188 if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2189 if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2190 if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2191 if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2192 if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2193 if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
2194 if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
2195 if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2196 if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2197 if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
2198 if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2199 if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2200 if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2201 if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2202 if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
2203 if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
2204 if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
2205 if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
2210 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)
2212 // select a permutation of the lighting shader appropriate to this
2213 // combination of texture, entity, light source, and fogging, only use the
2214 // minimum features necessary to avoid wasting rendering time in the
2215 // fragment shader on features that are not being used
2216 dpuint64 permutation = 0;
2217 unsigned int mode = 0;
2219 static float dummy_colormod[3] = {1, 1, 1};
2220 float *colormod = rsurface.colormod;
2222 matrix4x4_t tempmatrix;
2223 r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
2224 if (r_trippy.integer && !notrippy)
2225 permutation |= SHADERPERMUTATION_TRIPPY;
2226 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
2227 permutation |= SHADERPERMUTATION_ALPHAKILL;
2228 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_OCCLUDE)
2229 permutation |= SHADERPERMUTATION_OCCLUDE;
2230 if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
2231 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
2232 if (rsurfacepass == RSURFPASS_BACKGROUND)
2234 // distorted background
2235 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
2237 mode = SHADERMODE_WATER;
2238 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2239 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2240 if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
2242 // this is the right thing to do for wateralpha
2243 GL_BlendFunc(GL_ONE, GL_ZERO);
2244 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2248 // this is the right thing to do for entity alpha
2249 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2250 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2253 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
2255 mode = SHADERMODE_REFRACTION;
2256 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2257 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2258 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2259 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2263 mode = SHADERMODE_GENERIC;
2264 permutation |= SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_ALPHAKILL;
2265 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2266 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2268 if (vid.allowalphatocoverage)
2269 GL_AlphaToCoverage(false);
2271 else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
2273 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2275 switch(rsurface.texture->offsetmapping)
2277 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2278 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2279 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2280 case OFFSETMAPPING_OFF: break;
2283 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2284 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2285 // normalmap (deferred prepass), may use alpha test on diffuse
2286 mode = SHADERMODE_DEFERREDGEOMETRY;
2287 GL_BlendFunc(GL_ONE, GL_ZERO);
2288 blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
2289 if (vid.allowalphatocoverage)
2290 GL_AlphaToCoverage(false);
2292 else if (rsurfacepass == RSURFPASS_RTLIGHT)
2294 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2296 switch(rsurface.texture->offsetmapping)
2298 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2299 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2300 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2301 case OFFSETMAPPING_OFF: break;
2304 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2305 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2306 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2307 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2309 mode = SHADERMODE_LIGHTSOURCE;
2310 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
2311 permutation |= SHADERPERMUTATION_CUBEFILTER;
2312 if (diffusescale > 0)
2313 permutation |= SHADERPERMUTATION_DIFFUSE;
2314 if (specularscale > 0)
2315 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2316 if (r_refdef.fogenabled)
2317 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2318 if (rsurface.texture->colormapping)
2319 permutation |= SHADERPERMUTATION_COLORMAPPING;
2320 if (r_shadow_usingshadowmap2d)
2322 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2323 if(r_shadow_shadowmapvsdct)
2324 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2326 if (r_shadow_shadowmap2ddepthbuffer)
2327 permutation |= SHADERPERMUTATION_DEPTHRGB;
2329 if (rsurface.texture->reflectmasktexture)
2330 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2331 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
2332 blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
2333 if (vid.allowalphatocoverage)
2334 GL_AlphaToCoverage(false);
2336 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
2338 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2340 switch(rsurface.texture->offsetmapping)
2342 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2343 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2344 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2345 case OFFSETMAPPING_OFF: break;
2348 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2349 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2350 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2351 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2352 // unshaded geometry (fullbright or ambient model lighting)
2353 mode = SHADERMODE_FLATCOLOR;
2354 ambientscale = diffusescale = specularscale = 0;
2355 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2356 permutation |= SHADERPERMUTATION_GLOW;
2357 if (r_refdef.fogenabled)
2358 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2359 if (rsurface.texture->colormapping)
2360 permutation |= SHADERPERMUTATION_COLORMAPPING;
2361 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2363 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2364 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2366 if (r_shadow_shadowmap2ddepthbuffer)
2367 permutation |= SHADERPERMUTATION_DEPTHRGB;
2369 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2370 permutation |= SHADERPERMUTATION_REFLECTION;
2371 if (rsurface.texture->reflectmasktexture)
2372 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2373 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2374 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2375 // when using alphatocoverage, we don't need alphakill
2376 if (vid.allowalphatocoverage)
2378 if (r_transparent_alphatocoverage.integer)
2380 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2381 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2384 GL_AlphaToCoverage(false);
2387 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
2389 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2391 switch(rsurface.texture->offsetmapping)
2393 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2394 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2395 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2396 case OFFSETMAPPING_OFF: break;
2399 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2400 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2401 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2402 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2403 // directional model lighting
2404 mode = SHADERMODE_LIGHTDIRECTION;
2405 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2406 permutation |= SHADERPERMUTATION_GLOW;
2407 permutation |= SHADERPERMUTATION_DIFFUSE;
2408 if (specularscale > 0)
2409 permutation |= SHADERPERMUTATION_SPECULAR;
2410 if (r_refdef.fogenabled)
2411 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2412 if (rsurface.texture->colormapping)
2413 permutation |= SHADERPERMUTATION_COLORMAPPING;
2414 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2416 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2417 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2419 if (r_shadow_shadowmap2ddepthbuffer)
2420 permutation |= SHADERPERMUTATION_DEPTHRGB;
2422 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2423 permutation |= SHADERPERMUTATION_REFLECTION;
2424 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2425 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2426 if (rsurface.texture->reflectmasktexture)
2427 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2428 if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
2430 permutation |= SHADERPERMUTATION_BOUNCEGRID;
2431 if (r_shadow_bouncegrid_state.directional)
2432 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2434 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2435 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2436 // when using alphatocoverage, we don't need alphakill
2437 if (vid.allowalphatocoverage)
2439 if (r_transparent_alphatocoverage.integer)
2441 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2442 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2445 GL_AlphaToCoverage(false);
2448 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
2450 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2452 switch(rsurface.texture->offsetmapping)
2454 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2455 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2456 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2457 case OFFSETMAPPING_OFF: break;
2460 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2461 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2462 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2463 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2464 // ambient model lighting
2465 mode = SHADERMODE_LIGHTDIRECTION;
2466 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2467 permutation |= SHADERPERMUTATION_GLOW;
2468 if (r_refdef.fogenabled)
2469 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2470 if (rsurface.texture->colormapping)
2471 permutation |= SHADERPERMUTATION_COLORMAPPING;
2472 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2474 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2475 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2477 if (r_shadow_shadowmap2ddepthbuffer)
2478 permutation |= SHADERPERMUTATION_DEPTHRGB;
2480 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2481 permutation |= SHADERPERMUTATION_REFLECTION;
2482 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2483 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2484 if (rsurface.texture->reflectmasktexture)
2485 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2486 if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
2488 permutation |= SHADERPERMUTATION_BOUNCEGRID;
2489 if (r_shadow_bouncegrid_state.directional)
2490 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2492 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2493 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2494 // when using alphatocoverage, we don't need alphakill
2495 if (vid.allowalphatocoverage)
2497 if (r_transparent_alphatocoverage.integer)
2499 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2500 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2503 GL_AlphaToCoverage(false);
2508 if (r_glsl_offsetmapping.integer && ((R_TextureFlags(rsurface.texture->nmaptexture) & TEXF_ALPHA) || rsurface.texture->offsetbias != 0.0f))
2510 switch(rsurface.texture->offsetmapping)
2512 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
2513 case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2514 case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
2515 case OFFSETMAPPING_OFF: break;
2518 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
2519 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
2520 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHAGEN_VERTEX)
2521 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
2523 if ((rsurface.texture->glowtexture || rsurface.texture->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
2524 permutation |= SHADERPERMUTATION_GLOW;
2525 if (r_refdef.fogenabled)
2526 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
2527 if (rsurface.texture->colormapping)
2528 permutation |= SHADERPERMUTATION_COLORMAPPING;
2529 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
2531 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
2532 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2534 if (r_shadow_shadowmap2ddepthbuffer)
2535 permutation |= SHADERPERMUTATION_DEPTHRGB;
2537 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
2538 permutation |= SHADERPERMUTATION_REFLECTION;
2539 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
2540 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
2541 if (rsurface.texture->reflectmasktexture)
2542 permutation |= SHADERPERMUTATION_REFLECTCUBE;
2543 if (FAKELIGHT_ENABLED)
2545 // fake lightmapping (q1bsp, q3bsp, fullbright map)
2546 mode = SHADERMODE_FAKELIGHT;
2547 permutation |= SHADERPERMUTATION_DIFFUSE;
2548 if (specularscale > 0)
2549 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2551 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
2553 // deluxemapping (light direction texture)
2554 if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
2555 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
2557 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
2558 permutation |= SHADERPERMUTATION_DIFFUSE;
2559 if (specularscale > 0)
2560 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2562 else if (r_glsl_deluxemapping.integer >= 2)
2564 // fake deluxemapping (uniform light direction in tangentspace)
2565 if (rsurface.uselightmaptexture)
2566 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP;
2568 mode = SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR;
2569 permutation |= SHADERPERMUTATION_DIFFUSE;
2570 if (specularscale > 0)
2571 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
2573 else if (rsurface.uselightmaptexture)
2575 // ordinary lightmapping (q1bsp, q3bsp)
2576 mode = SHADERMODE_LIGHTMAP;
2580 // ordinary vertex coloring (q3bsp)
2581 mode = SHADERMODE_VERTEXCOLOR;
2583 if (r_shadow_bouncegrid_state.texture && cl.csqc_vidvars.drawworld)
2585 permutation |= SHADERPERMUTATION_BOUNCEGRID;
2586 if (r_shadow_bouncegrid_state.directional)
2587 permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
2589 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2590 blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
2591 // when using alphatocoverage, we don't need alphakill
2592 if (vid.allowalphatocoverage)
2594 if (r_transparent_alphatocoverage.integer)
2596 GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
2597 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
2600 GL_AlphaToCoverage(false);
2603 if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
2604 colormod = dummy_colormod;
2605 if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
2606 permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
2607 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
2608 permutation |= SHADERPERMUTATION_FOGALPHAHACK;
2609 switch(vid.renderpath)
2611 case RENDERPATH_D3D9:
2613 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);
2614 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmesh_vertexbuffer, rsurface.batchvertexmesh_bufferoffset);
2615 R_SetupShader_SetPermutationHLSL(mode, permutation);
2616 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
2617 if (mode == SHADERMODE_LIGHTSOURCE)
2619 Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
2620 hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2624 if (mode == SHADERMODE_LIGHTDIRECTION)
2626 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2629 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
2630 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
2631 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
2632 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2633 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2635 if (mode == SHADERMODE_LIGHTSOURCE)
2637 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2638 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2639 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2640 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2641 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
2643 // additive passes are only darkened by fog, not tinted
2644 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2645 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f);
2649 if (mode == SHADERMODE_FLATCOLOR)
2651 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2653 else if (mode == SHADERMODE_LIGHTDIRECTION)
2655 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]);
2656 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
2657 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);
2658 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2659 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2660 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
2661 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
2665 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
2666 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
2667 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);
2668 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2669 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale, specularscale, specularscale);
2671 // additive passes are only darkened by fog, not tinted
2672 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2673 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
2675 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2676 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);
2677 hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_fb.water.screenscale[0], r_fb.water.screenscale[1], r_fb.water.screenscale[0], r_fb.water.screenscale[1]);
2678 hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_fb.water.screencenter[0], r_fb.water.screencenter[1], r_fb.water.screencenter[0], r_fb.water.screencenter[1]);
2679 hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2680 hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
2681 hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2682 hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
2683 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (rsurface.texture->specularpower - 1.0f) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
2684 if (mode == SHADERMODE_WATER)
2685 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
2687 if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
2689 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]);
2690 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]);
2694 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
2695 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
2697 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2698 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));
2699 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
2700 if (rsurface.texture->pantstexture)
2701 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
2703 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
2704 if (rsurface.texture->shirttexture)
2705 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
2707 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
2708 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
2709 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
2710 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
2711 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
2712 hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
2713 r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
2714 max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2715 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
2716 max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
2718 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality);
2719 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Bias, rsurface.texture->offsetbias);
2720 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
2721 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
2723 R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
2724 R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
2725 R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
2726 R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
2727 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
2728 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
2729 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
2730 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
2731 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
2732 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
2733 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
2734 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
2735 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
2736 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
2737 R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
2738 R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
2739 if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
2740 if (rsurfacepass == RSURFPASS_BACKGROUND)
2742 R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
2743 if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
2744 R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2748 if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
2750 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
2751 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
2752 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
2753 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
2755 R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture);
2756 if (rsurface.rtlight)
2758 if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
2759 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
2764 case RENDERPATH_D3D10:
2765 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2767 case RENDERPATH_D3D11:
2768 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
2770 case RENDERPATH_GL20:
2771 case RENDERPATH_GLES2:
2772 if (!vid.useinterleavedarrays)
2774 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);
2775 R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
2776 R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
2777 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
2778 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
2779 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
2780 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
2781 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
2782 R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
2783 R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE | 0x80000000, sizeof(unsigned char[4]), rsurface.batchskeletalindex4ub, rsurface.batchskeletalindex4ub_vertexbuffer, rsurface.batchskeletalindex4ub_bufferoffset);
2784 R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), rsurface.batchskeletalweight4ub, rsurface.batchskeletalweight4ub_vertexbuffer, rsurface.batchskeletalweight4ub_bufferoffset);
2788 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);
2789 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmesh_vertexbuffer, rsurface.batchvertexmesh_bufferoffset);
2791 // this has to be after RSurf_PrepareVerticesForBatch
2792 if (rsurface.batchskeletaltransform3x4buffer)
2793 permutation |= SHADERPERMUTATION_SKELETAL;
2794 R_SetupShader_SetPermutationGLSL(mode, permutation);
2795 #ifndef USE_GLES2 /* FIXME: GLES3 only */
2796 if (r_glsl_permutation->ubiloc_Skeletal_Transform12_UniformBlock >= 0 && rsurface.batchskeletaltransform3x4buffer) qglBindBufferRange(GL_UNIFORM_BUFFER, r_glsl_permutation->ubibind_Skeletal_Transform12_UniformBlock, rsurface.batchskeletaltransform3x4buffer->bufferobject, rsurface.batchskeletaltransform3x4offset, rsurface.batchskeletaltransform3x4size);
2798 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
2799 if (mode == SHADERMODE_LIGHTSOURCE)
2801 if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
2802 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
2803 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
2804 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
2805 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2806 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);
2808 // additive passes are only darkened by fog, not tinted
2809 if (r_glsl_permutation->loc_FogColor >= 0)
2810 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2811 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);
2815 if (mode == SHADERMODE_FLATCOLOR)
2817 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
2819 else if (mode == SHADERMODE_LIGHTDIRECTION)
2821 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]);
2822 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]);
2823 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);
2824 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0], colormod[1], colormod[2]);
2825 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2826 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]);
2827 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]);
2831 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]);
2832 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]);
2833 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);
2834 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
2835 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale, specularscale, specularscale);
2837 // additive passes are only darkened by fog, not tinted
2838 if (r_glsl_permutation->loc_FogColor >= 0)
2840 if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
2841 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
2843 qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
2845 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);
2846 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]);
2847 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]);
2848 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]);
2849 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]);
2850 if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
2851 if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
2852 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);
2853 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]);
2855 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
2856 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
2857 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
2858 if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
2860 if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_modelshadowmap_texturescale[0], r_shadow_modelshadowmap_texturescale[1], r_shadow_modelshadowmap_texturescale[2], r_shadow_modelshadowmap_texturescale[3]);
2861 if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_modelshadowmap_parameters[0], r_shadow_modelshadowmap_parameters[1], r_shadow_modelshadowmap_parameters[2], r_shadow_modelshadowmap_parameters[3]);
2865 if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_lightshadowmap_texturescale[0], r_shadow_lightshadowmap_texturescale[1], r_shadow_lightshadowmap_texturescale[2], r_shadow_lightshadowmap_texturescale[3]);
2866 if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]);
2869 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
2870 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));