2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "cl_dyntexture.h"
30 #include "dpsoftrast.h"
34 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
37 mempool_t *r_main_mempool;
38 rtexturepool_t *r_main_texturepool;
40 static int r_textureframe = 0; ///< used only by R_GetCurrentTexture
42 static qboolean r_loadnormalmap;
43 static qboolean r_loadgloss;
45 static qboolean r_loaddds;
46 static qboolean r_savedds;
53 cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "motionblur value scale - 0.5 recommended"};
54 cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "motionblur based on damage"};
55 cvar_t r_motionblur_vmin = {CVAR_SAVE, "r_motionblur_vmin", "300", "minimum influence from velocity"};
56 cvar_t r_motionblur_vmax = {CVAR_SAVE, "r_motionblur_vmax", "600", "maximum influence from velocity"};
57 cvar_t r_motionblur_bmin = {CVAR_SAVE, "r_motionblur_bmin", "0.5", "velocity at which there is no blur yet (may be negative to always have some blur)"};
58 cvar_t r_motionblur_vcoeff = {CVAR_SAVE, "r_motionblur_vcoeff", "0.05", "sliding average reaction time for velocity"};
59 cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.88", "cap for motionblur alpha value"};
60 cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
62 // TODO do we want a r_equalize_entities cvar that works on all ents, or would that be a cheat?
63 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"};
64 cvar_t r_equalize_entities_minambient = {CVAR_SAVE, "r_equalize_entities_minambient", "0.5", "light equalizing: ensure at least this ambient/diffuse ratio"};
65 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)"};
66 cvar_t r_equalize_entities_to = {CVAR_SAVE, "r_equalize_entities_to", "0.8", "light equalizing: target light level"};
68 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"};
69 cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
70 cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
71 cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
72 cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
73 cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"};
74 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)"};
75 cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
76 cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
77 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"};
78 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"};
79 cvar_t r_showcollisionbrushes = {0, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
80 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"};
81 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"};
82 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"};
83 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
84 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
85 cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
86 cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
87 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
88 cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
89 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
90 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)"};
91 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)"};
92 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
93 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
94 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
95 cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
97 cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"};
98 cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"};
99 #define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
101 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
102 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
103 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
104 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."};
105 cvar_t r_shadows_darken = {CVAR_SAVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
106 cvar_t r_shadows_throwdistance = {CVAR_SAVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
107 cvar_t r_shadows_throwdirection = {CVAR_SAVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
108 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."};
109 cvar_t r_shadows_castfrombmodels = {CVAR_SAVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
110 cvar_t r_shadows_focus = {CVAR_SAVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
111 cvar_t r_shadows_shadowmapscale = {CVAR_SAVE, "r_shadows_shadowmapscale", "1", "increases shadowmap quality (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
112 cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
113 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"};
114 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"};
115 cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
116 cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
117 cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
118 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
119 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"};
121 cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
122 cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
123 cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
124 cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
125 cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
126 cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
127 cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
128 cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
130 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)"};
131 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"};
133 cvar_t r_texture_convertsRGB_2d = {0, "r_texture_convertsRGB_2d", "0", "load textures as sRGB and convert to linear for proper shading"};
134 cvar_t r_texture_convertsRGB_skin = {0, "r_texture_convertsRGB_skin", "0", "load textures as sRGB and convert to linear for proper shading"};
135 cvar_t r_texture_convertsRGB_cubemap = {0, "r_texture_convertsRGB_cubemap", "0", "load textures as sRGB and convert to linear for proper shading"};
136 cvar_t r_texture_convertsRGB_skybox = {0, "r_texture_convertsRGB_skybox", "0", "load textures as sRGB and convert to linear for proper shading"};
137 cvar_t r_texture_convertsRGB_particles = {0, "r_texture_convertsRGB_particles", "0", "load textures as sRGB and convert to linear for proper shading"};
139 cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"};
140 static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
141 static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
143 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)"};
144 cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
145 cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
146 cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
147 cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
148 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)"};
149 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)"};
150 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)"};
151 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)"};
152 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)"};
153 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)"};
154 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)"};
155 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)"};
157 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)"};
158 cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
159 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"};
160 cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
161 cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
162 cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
164 cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
165 cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
166 cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
167 cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
169 cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
170 cvar_t r_bloom_colorscale = {CVAR_SAVE, "r_bloom_colorscale", "1", "how bright the glow is"};
171 cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
172 cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
173 cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
174 cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
175 cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
177 cvar_t r_hdr = {CVAR_SAVE, "r_hdr", "0", "enables High Dynamic Range bloom effect (higher quality version of r_bloom)"};
178 cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
179 cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
180 cvar_t r_hdr_range = {CVAR_SAVE, "r_hdr_range", "4", "how much dynamic range to render bloom with (equivalent to multiplying r_bloom_brighten by this value and dividing r_bloom_colorscale by this value)"};
182 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"};
184 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"};
186 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
188 cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
189 cvar_t r_track_sprites = {CVAR_SAVE, "r_track_sprites", "1", "track SPR_LABEL* sprites by putting them as indicator at the screen border to rotate to"};
190 cvar_t r_track_sprites_flags = {CVAR_SAVE, "r_track_sprites_flags", "1", "1: Rotate sprites accordingly, 2: Make it a continuous rotation"};
191 cvar_t r_track_sprites_scalew = {CVAR_SAVE, "r_track_sprites_scalew", "1", "width scaling of tracked sprites"};
192 cvar_t r_track_sprites_scaleh = {CVAR_SAVE, "r_track_sprites_scaleh", "1", "height scaling of tracked sprites"};
193 cvar_t r_overheadsprites_perspective = {CVAR_SAVE, "r_overheadsprites_perspective", "5", "fake perspective effect for SPR_OVERHEAD sprites"};
194 cvar_t r_overheadsprites_pushback = {CVAR_SAVE, "r_overheadsprites_pushback", "15", "how far to pull the SPR_OVERHEAD sprites toward the eye (used to avoid intersections with 3D models)"};
195 cvar_t r_overheadsprites_scalex = {CVAR_SAVE, "r_overheadsprites_scalex", "1", "additional scale for overhead sprites for x axis"};
196 cvar_t r_overheadsprites_scaley = {CVAR_SAVE, "r_overheadsprites_scaley", "1", "additional scale for overhead sprites for y axis"};
198 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
199 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"};
201 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)"};
203 extern cvar_t v_glslgamma;
205 extern qboolean v_flipped_state;
207 static struct r_bloomstate_s
212 int bloomwidth, bloomheight;
214 int screentexturewidth, screentextureheight;
215 rtexture_t *texture_screen; /// \note also used for motion blur if enabled!
217 int bloomtexturewidth, bloomtextureheight;
218 rtexture_t *texture_bloom;
220 // arrays for rendering the screen passes
221 float screentexcoord2f[8];
222 float bloomtexcoord2f[8];
223 float offsettexcoord2f[8];
225 r_viewport_t viewport;
229 r_waterstate_t r_waterstate;
231 /// shadow volume bsp struct with automatically growing nodes buffer
234 rtexture_t *r_texture_blanknormalmap;
235 rtexture_t *r_texture_white;
236 rtexture_t *r_texture_grey128;
237 rtexture_t *r_texture_black;
238 rtexture_t *r_texture_notexture;
239 rtexture_t *r_texture_whitecube;
240 rtexture_t *r_texture_normalizationcube;
241 rtexture_t *r_texture_fogattenuation;
242 rtexture_t *r_texture_fogheighttexture;
243 rtexture_t *r_texture_gammaramps;
244 unsigned int r_texture_gammaramps_serial;
245 //rtexture_t *r_texture_fogintensity;
246 rtexture_t *r_texture_reflectcube;
248 // TODO: hash lookups?
249 typedef struct cubemapinfo_s
256 int r_texture_numcubemaps;
257 cubemapinfo_t r_texture_cubemaps[MAX_CUBEMAPS];
259 unsigned int r_queries[MAX_OCCLUSION_QUERIES];
260 unsigned int r_numqueries;
261 unsigned int r_maxqueries;
263 typedef struct r_qwskincache_s
265 char name[MAX_QPATH];
266 skinframe_t *skinframe;
270 static r_qwskincache_t *r_qwskincache;
271 static int r_qwskincache_size;
273 /// vertex coordinates for a quad that covers the screen exactly
274 extern const float r_screenvertex3f[12];
275 extern const float r_d3dscreenvertex3f[12];
276 const float r_screenvertex3f[12] =
283 const float r_d3dscreenvertex3f[12] =
291 void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
294 for (i = 0;i < verts;i++)
305 void R_FillColors(float *out, int verts, float r, float g, float b, float a)
308 for (i = 0;i < verts;i++)
318 // FIXME: move this to client?
321 if (gamemode == GAME_NEHAHRA)
323 Cvar_Set("gl_fogenable", "0");
324 Cvar_Set("gl_fogdensity", "0.2");
325 Cvar_Set("gl_fogred", "0.3");
326 Cvar_Set("gl_foggreen", "0.3");
327 Cvar_Set("gl_fogblue", "0.3");
329 r_refdef.fog_density = 0;
330 r_refdef.fog_red = 0;
331 r_refdef.fog_green = 0;
332 r_refdef.fog_blue = 0;
333 r_refdef.fog_alpha = 1;
334 r_refdef.fog_start = 0;
335 r_refdef.fog_end = 16384;
336 r_refdef.fog_height = 1<<30;
337 r_refdef.fog_fadedepth = 128;
338 memset(r_refdef.fog_height_texturename, 0, sizeof(r_refdef.fog_height_texturename));
341 static void R_BuildBlankTextures(void)
343 unsigned char data[4];
344 data[2] = 128; // normal X
345 data[1] = 128; // normal Y
346 data[0] = 255; // normal Z
347 data[3] = 128; // height
348 r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
353 r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
358 r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
363 r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
366 static void R_BuildNoTexture(void)
369 unsigned char pix[16][16][4];
370 // this makes a light grey/dark grey checkerboard texture
371 for (y = 0;y < 16;y++)
373 for (x = 0;x < 16;x++)
375 if ((y < 8) ^ (x < 8))
391 r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, -1, NULL);
394 static void R_BuildWhiteCube(void)
396 unsigned char data[6*1*1*4];
397 memset(data, 255, sizeof(data));
398 r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
401 static void R_BuildNormalizationCube(void)
405 vec_t s, t, intensity;
408 data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
409 for (side = 0;side < 6;side++)
411 for (y = 0;y < NORMSIZE;y++)
413 for (x = 0;x < NORMSIZE;x++)
415 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
416 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
451 intensity = 127.0f / sqrt(DotProduct(v, v));
452 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
453 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
454 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
455 data[((side*64+y)*64+x)*4+3] = 255;
459 r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
463 static void R_BuildFogTexture(void)
467 unsigned char data1[FOGWIDTH][4];
468 //unsigned char data2[FOGWIDTH][4];
471 r_refdef.fogmasktable_start = r_refdef.fog_start;
472 r_refdef.fogmasktable_alpha = r_refdef.fog_alpha;
473 r_refdef.fogmasktable_range = r_refdef.fogrange;
474 r_refdef.fogmasktable_density = r_refdef.fog_density;
476 r = r_refdef.fogmasktable_range / FOGMASKTABLEWIDTH;
477 for (x = 0;x < FOGMASKTABLEWIDTH;x++)
479 d = (x * r - r_refdef.fogmasktable_start);
480 if(developer_extra.integer)
481 Con_DPrintf("%f ", d);
483 if (r_fog_exp2.integer)
484 alpha = exp(-r_refdef.fogmasktable_density * r_refdef.fogmasktable_density * 0.0001 * d * d);
486 alpha = exp(-r_refdef.fogmasktable_density * 0.004 * d);
487 if(developer_extra.integer)
488 Con_DPrintf(" : %f ", alpha);
489 alpha = 1 - (1 - alpha) * r_refdef.fogmasktable_alpha;
490 if(developer_extra.integer)
491 Con_DPrintf(" = %f\n", alpha);
492 r_refdef.fogmasktable[x] = bound(0, alpha, 1);
495 for (x = 0;x < FOGWIDTH;x++)
497 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
502 //data2[x][0] = 255 - b;
503 //data2[x][1] = 255 - b;
504 //data2[x][2] = 255 - b;
507 if (r_texture_fogattenuation)
509 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, FOGWIDTH, 1);
510 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, FOGWIDTH, 1);
514 r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
515 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
519 static void R_BuildFogHeightTexture(void)
521 unsigned char *inpixels;
529 strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename));
530 if (r_refdef.fogheighttexturename[0])
531 inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false, NULL);
534 r_refdef.fog_height_tablesize = 0;
535 if (r_texture_fogheighttexture)
536 R_FreeTexture(r_texture_fogheighttexture);
537 r_texture_fogheighttexture = NULL;
538 if (r_refdef.fog_height_table2d)
539 Mem_Free(r_refdef.fog_height_table2d);
540 r_refdef.fog_height_table2d = NULL;
541 if (r_refdef.fog_height_table1d)
542 Mem_Free(r_refdef.fog_height_table1d);
543 r_refdef.fog_height_table1d = NULL;
547 r_refdef.fog_height_tablesize = size;
548 r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
549 r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
550 memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
552 // LordHavoc: now the magic - what is that table2d for? it is a cooked
553 // average fog color table accounting for every fog layer between a point
554 // and the camera. (Note: attenuation is handled separately!)
555 for (y = 0;y < size;y++)
557 for (x = 0;x < size;x++)
563 for (j = x;j <= y;j++)
565 Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
571 for (j = x;j >= y;j--)
573 Vector4Add(c, r_refdef.fog_height_table1d + j*4, c);
578 r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f);
579 r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f);
580 r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f);
581 r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
584 r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, -1, NULL);
587 //=======================================================================================================================================================
589 static const char *builtinshaderstring =
590 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
591 "// written by Forest 'LordHavoc' Hale\n"
592 "// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
594 "#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE) || defined(USEFOGHEIGHTTEXTURE)\n"
597 "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
598 "#define USELIGHTMAP\n"
600 "#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n"
601 "#define USEEYEVECTOR\n"
604 "#ifdef USESHADOWMAP2D\n"
605 "# ifdef GL_EXT_gpu_shader4\n"
606 "# extension GL_EXT_gpu_shader4 : enable\n"
608 "# ifdef GL_ARB_texture_gather\n"
609 "# extension GL_ARB_texture_gather : enable\n"
611 "# ifdef GL_AMD_texture_texture4\n"
612 "# extension GL_AMD_texture_texture4 : enable\n"
617 "//#ifdef USESHADOWSAMPLER\n"
618 "//# extension GL_ARB_shadow : enable\n"
621 "//#ifdef __GLSL_CG_DATA_TYPES\n"
622 "//# define myhalf half\n"
623 "//# define myhalf2 half2\n"
624 "//# define myhalf3 half3\n"
625 "//# define myhalf4 half4\n"
627 "# define myhalf float\n"
628 "# define myhalf2 vec2\n"
629 "# define myhalf3 vec3\n"
630 "# define myhalf4 vec4\n"
633 "#ifdef VERTEX_SHADER\n"
634 "uniform mat4 ModelViewProjectionMatrix;\n"
637 "#ifdef MODE_DEPTH_OR_SHADOW\n"
638 "#ifdef VERTEX_SHADER\n"
641 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
644 "#else // !MODE_DEPTH_ORSHADOW\n"
649 "#ifdef MODE_SHOWDEPTH\n"
650 "#ifdef VERTEX_SHADER\n"
653 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
654 " gl_FrontColor = vec4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
658 "#ifdef FRAGMENT_SHADER\n"
661 " gl_FragColor = gl_Color;\n"
664 "#else // !MODE_SHOWDEPTH\n"
669 "#ifdef MODE_POSTPROCESS\n"
670 "varying vec2 TexCoord1;\n"
671 "varying vec2 TexCoord2;\n"
673 "#ifdef VERTEX_SHADER\n"
676 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
677 " TexCoord1 = gl_MultiTexCoord0.xy;\n"
679 " TexCoord2 = gl_MultiTexCoord4.xy;\n"
684 "#ifdef FRAGMENT_SHADER\n"
685 "uniform sampler2D Texture_First;\n"
687 "uniform sampler2D Texture_Second;\n"
688 "uniform vec4 BloomColorSubtract;\n"
690 "#ifdef USEGAMMARAMPS\n"
691 "uniform sampler2D Texture_GammaRamps;\n"
693 "#ifdef USESATURATION\n"
694 "uniform float Saturation;\n"
696 "#ifdef USEVIEWTINT\n"
697 "uniform vec4 ViewTintColor;\n"
699 "//uncomment these if you want to use them:\n"
700 "uniform vec4 UserVec1;\n"
701 "uniform vec4 UserVec2;\n"
702 "// uniform vec4 UserVec3;\n"
703 "// uniform vec4 UserVec4;\n"
704 "// uniform float ClientTime;\n"
705 "uniform vec2 PixelSize;\n"
708 " gl_FragColor = texture2D(Texture_First, TexCoord1);\n"
710 " gl_FragColor += max(vec4(0,0,0,0), texture2D(Texture_Second, TexCoord2) - BloomColorSubtract);\n"
712 "#ifdef USEVIEWTINT\n"
713 " gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
716 "#ifdef USEPOSTPROCESSING\n"
717 "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
718 "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
719 " float sobel = 1.0;\n"
720 " // vec2 ts = textureSize(Texture_First, 0);\n"
721 " // vec2 px = vec2(1/ts.x, 1/ts.y);\n"
722 " vec2 px = PixelSize;\n"
723 " vec3 x1 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n"
724 " vec3 x2 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, 0.0)).rgb;\n"
725 " vec3 x3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n"
726 " vec3 x4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n"
727 " vec3 x5 = texture2D(Texture_First, TexCoord1 + vec2( px.x, 0.0)).rgb;\n"
728 " vec3 x6 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n"
729 " vec3 y1 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n"
730 " vec3 y2 = texture2D(Texture_First, TexCoord1 + vec2( 0.0,-px.y)).rgb;\n"
731 " vec3 y3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n"
732 " vec3 y4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n"
733 " vec3 y5 = texture2D(Texture_First, TexCoord1 + vec2( 0.0, px.y)).rgb;\n"
734 " vec3 y6 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n"
735 " float px1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x1);\n"
736 " float px2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), x2);\n"
737 " float px3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x3);\n"
738 " float px4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x4);\n"
739 " float px5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), x5);\n"
740 " float px6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x6);\n"
741 " float py1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y1);\n"
742 " float py2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), y2);\n"
743 " float py3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y3);\n"
744 " float py4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y4);\n"
745 " float py5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), y5);\n"
746 " float py6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y6);\n"
747 " sobel = 0.25 * abs(px1 + px2 + px3 + px4 + px5 + px6) + 0.25 * abs(py1 + py2 + py3 + py4 + py5 + py6);\n"
748 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
749 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
750 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
751 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.707107, 0.707107)) * UserVec1.y;\n"
752 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.453990, 0.891007)) * UserVec1.y;\n"
753 " gl_FragColor /= (1.0 + 5.0 * UserVec1.y);\n"
754 " gl_FragColor.rgb = gl_FragColor.rgb * (1.0 + UserVec2.x) + vec3(max(0.0, sobel - UserVec2.z))*UserVec2.y;\n"
757 "#ifdef USESATURATION\n"
758 " //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
759 " float y = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));\n"
760 " // 'vampire sight' effect, wheres red is compensated\n"
761 " #ifdef SATURATION_REDCOMPENSATE\n"
762 " float rboost = max(0.0, (gl_FragColor.r - max(gl_FragColor.g, gl_FragColor.b))*(1.0 - Saturation));\n"
763 " gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
764 " gl_FragColor.r += rboost;\n"
766 " // normal desaturation\n"
767 " //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
768 " gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
772 "#ifdef USEGAMMARAMPS\n"
773 " gl_FragColor.r = texture2D(Texture_GammaRamps, vec2(gl_FragColor.r, 0)).r;\n"
774 " gl_FragColor.g = texture2D(Texture_GammaRamps, vec2(gl_FragColor.g, 0)).g;\n"
775 " gl_FragColor.b = texture2D(Texture_GammaRamps, vec2(gl_FragColor.b, 0)).b;\n"
779 "#else // !MODE_POSTPROCESS\n"
784 "#ifdef MODE_GENERIC\n"
785 "#ifdef USEDIFFUSE\n"
786 "varying vec2 TexCoord1;\n"
788 "#ifdef USESPECULAR\n"
789 "varying vec2 TexCoord2;\n"
791 "#ifdef VERTEX_SHADER\n"
794 " gl_FrontColor = gl_Color;\n"
795 "#ifdef USEDIFFUSE\n"
796 " TexCoord1 = gl_MultiTexCoord0.xy;\n"
798 "#ifdef USESPECULAR\n"
799 " TexCoord2 = gl_MultiTexCoord1.xy;\n"
801 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
805 "#ifdef FRAGMENT_SHADER\n"
806 "#ifdef USEDIFFUSE\n"
807 "uniform sampler2D Texture_First;\n"
809 "#ifdef USESPECULAR\n"
810 "uniform sampler2D Texture_Second;\n"
815 "#ifdef USEVIEWTINT\n"
816 " gl_FragColor = gl_Color;\n"
818 " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
820 "#ifdef USEDIFFUSE\n"
821 " gl_FragColor *= texture2D(Texture_First, TexCoord1);\n"
824 "#ifdef USESPECULAR\n"
825 " vec4 tex2 = texture2D(Texture_Second, TexCoord2);\n"
826 "# ifdef USECOLORMAPPING\n"
827 " gl_FragColor *= tex2;\n"
830 " gl_FragColor += tex2;\n"
832 "# ifdef USEVERTEXTEXTUREBLEND\n"
833 " gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
838 "#else // !MODE_GENERIC\n"
843 "#ifdef MODE_BLOOMBLUR\n"
844 "varying TexCoord;\n"
845 "#ifdef VERTEX_SHADER\n"
848 " gl_FrontColor = gl_Color;\n"
849 " TexCoord = gl_MultiTexCoord0.xy;\n"
850 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
854 "#ifdef FRAGMENT_SHADER\n"
855 "uniform sampler2D Texture_First;\n"
856 "uniform vec4 BloomBlur_Parameters;\n"
861 " vec2 tc = TexCoord;\n"
862 " vec3 color = texture2D(Texture_First, tc).rgb;\n"
863 " tc += BloomBlur_Parameters.xy;\n"
864 " for (i = 1;i < SAMPLES;i++)\n"
866 " color += texture2D(Texture_First, tc).rgb;\n"
867 " tc += BloomBlur_Parameters.xy;\n"
869 " gl_FragColor = vec4(color * BloomBlur_Parameters.z + vec3(BloomBlur_Parameters.w), 1);\n"
872 "#else // !MODE_BLOOMBLUR\n"
873 "#ifdef MODE_REFRACTION\n"
874 "varying vec2 TexCoord;\n"
875 "varying vec4 ModelViewProjectionPosition;\n"
876 "uniform mat4 TexMatrix;\n"
877 "#ifdef VERTEX_SHADER\n"
881 " TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
882 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
883 " ModelViewProjectionPosition = gl_Position;\n"
887 "#ifdef FRAGMENT_SHADER\n"
888 "uniform sampler2D Texture_Normal;\n"
889 "uniform sampler2D Texture_Refraction;\n"
890 "uniform sampler2D Texture_Reflection;\n"
892 "uniform vec4 DistortScaleRefractReflect;\n"
893 "uniform vec4 ScreenScaleRefractReflect;\n"
894 "uniform vec4 ScreenCenterRefractReflect;\n"
895 "uniform vec4 RefractColor;\n"
896 "uniform vec4 ReflectColor;\n"
897 "uniform float ReflectFactor;\n"
898 "uniform float ReflectOffset;\n"
902 " vec2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
903 " //vec2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
904 " vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
905 " vec2 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
906 " // FIXME temporary hack to detect the case that the reflection\n"
907 " // gets blackened at edges due to leaving the area that contains actual\n"
909 " // Remove this 'ack once we have a better way to stop this thing from\n"
911 " float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
912 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
913 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
914 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
915 " ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
916 " gl_FragColor = vec4(texture2D(Texture_Refraction, ScreenTexCoord).rgb, 1.0) * RefractColor;\n"
919 "#else // !MODE_REFRACTION\n"
924 "#ifdef MODE_WATER\n"
925 "varying vec2 TexCoord;\n"
926 "varying vec3 EyeVector;\n"
927 "varying vec4 ModelViewProjectionPosition;\n"
928 "#ifdef VERTEX_SHADER\n"
929 "uniform vec3 EyePosition;\n"
930 "uniform mat4 TexMatrix;\n"
934 " TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
935 " vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
936 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
937 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
938 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
939 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
940 " ModelViewProjectionPosition = gl_Position;\n"
944 "#ifdef FRAGMENT_SHADER\n"
945 "uniform sampler2D Texture_Normal;\n"
946 "uniform sampler2D Texture_Refraction;\n"
947 "uniform sampler2D Texture_Reflection;\n"
949 "uniform vec4 DistortScaleRefractReflect;\n"
950 "uniform vec4 ScreenScaleRefractReflect;\n"
951 "uniform vec4 ScreenCenterRefractReflect;\n"
952 "uniform vec4 RefractColor;\n"
953 "uniform vec4 ReflectColor;\n"
954 "uniform float ReflectFactor;\n"
955 "uniform float ReflectOffset;\n"
956 "uniform float ClientTime;\n"
957 "#ifdef USENORMALMAPSCROLLBLEND\n"
958 "uniform vec2 NormalmapScrollBlend;\n"
963 " vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
964 " //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
965 " vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
966 " //SafeScreenTexCoord = gl_FragCoord.xyxy * vec4(1.0 / 1920.0, 1.0 / 1200.0, 1.0 / 1920.0, 1.0 / 1200.0);\n"
967 " // slight water animation via 2 layer scrolling (todo: tweak)\n"
968 " #ifdef USENORMALMAPSCROLLBLEND\n"
969 " vec3 normal = texture2D(Texture_Normal, (TexCoord + vec2(0.08, 0.08)*ClientTime*NormalmapScrollBlend.x*0.5)*NormalmapScrollBlend.y).rgb - vec3(1.0);\n"
970 " normal += texture2D(Texture_Normal, (TexCoord + vec2(-0.06, -0.09)*ClientTime*NormalmapScrollBlend.x)*NormalmapScrollBlend.y*0.75).rgb;\n"
971 " vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(normal) + vec3(0.15)).xyxy * DistortScaleRefractReflect;\n"
973 " vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
975 " // FIXME temporary hack to detect the case that the reflection\n"
976 " // gets blackened at edges due to leaving the area that contains actual\n"
978 " // Remove this 'ack once we have a better way to stop this thing from\n"
980 " float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, 0.01)).rgb) / 0.002);\n"
981 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, -0.01)).rgb) / 0.002);\n"
982 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, 0.01)).rgb) / 0.002);\n"
983 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, -0.01)).rgb) / 0.002);\n"
984 " ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
985 " f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, 0.005)).rgb) / 0.002);\n"
986 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, -0.005)).rgb) / 0.002);\n"
987 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, 0.005)).rgb) / 0.002);\n"
988 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, -0.005)).rgb) / 0.002);\n"
989 " ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
990 " float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
991 " gl_FragColor = mix(vec4(texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, vec4(texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
994 "#else // !MODE_WATER\n"
999 "// common definitions between vertex shader and fragment shader:\n"
1001 "varying vec2 TexCoord;\n"
1002 "#ifdef USEVERTEXTEXTUREBLEND\n"
1003 "varying vec2 TexCoord2;\n"
1005 "#ifdef USELIGHTMAP\n"
1006 "varying vec2 TexCoordLightmap;\n"
1009 "#ifdef MODE_LIGHTSOURCE\n"
1010 "varying vec3 CubeVector;\n"
1013 "#if (defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)) && defined(USEDIFFUSE)\n"
1014 "varying vec3 LightVector;\n"
1017 "#ifdef USEEYEVECTOR\n"
1018 "varying vec3 EyeVector;\n"
1021 "varying vec4 EyeVectorModelSpaceFogPlaneVertexDist;\n"
1024 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n"
1025 "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
1026 "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
1027 "varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
1030 "#ifdef USEREFLECTION\n"
1031 "varying vec4 ModelViewProjectionPosition;\n"
1033 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
1034 "uniform vec3 LightPosition;\n"
1035 "varying vec4 ModelViewPosition;\n"
1038 "#ifdef MODE_LIGHTSOURCE\n"
1039 "uniform vec3 LightPosition;\n"
1041 "uniform vec3 EyePosition;\n"
1042 "#ifdef MODE_LIGHTDIRECTION\n"
1043 "uniform vec3 LightDir;\n"
1045 "uniform vec4 FogPlane;\n"
1047 "#ifdef USESHADOWMAPORTHO\n"
1048 "varying vec3 ShadowMapTC;\n"
1055 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
1057 "// fragment shader specific:\n"
1058 "#ifdef FRAGMENT_SHADER\n"
1060 "uniform sampler2D Texture_Normal;\n"
1061 "uniform sampler2D Texture_Color;\n"
1062 "uniform sampler2D Texture_Gloss;\n"
1064 "uniform sampler2D Texture_Glow;\n"
1066 "#ifdef USEVERTEXTEXTUREBLEND\n"
1067 "uniform sampler2D Texture_SecondaryNormal;\n"
1068 "uniform sampler2D Texture_SecondaryColor;\n"
1069 "uniform sampler2D Texture_SecondaryGloss;\n"
1071 "uniform sampler2D Texture_SecondaryGlow;\n"
1074 "#ifdef USECOLORMAPPING\n"
1075 "uniform sampler2D Texture_Pants;\n"
1076 "uniform sampler2D Texture_Shirt;\n"
1079 "#ifdef USEFOGHEIGHTTEXTURE\n"
1080 "uniform sampler2D Texture_FogHeightTexture;\n"
1082 "uniform sampler2D Texture_FogMask;\n"
1084 "#ifdef USELIGHTMAP\n"
1085 "uniform sampler2D Texture_Lightmap;\n"
1087 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
1088 "uniform sampler2D Texture_Deluxemap;\n"
1090 "#ifdef USEREFLECTION\n"
1091 "uniform sampler2D Texture_Reflection;\n"
1094 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
1095 "uniform sampler2D Texture_ScreenDepth;\n"
1096 "uniform sampler2D Texture_ScreenNormalMap;\n"
1098 "#ifdef USEDEFERREDLIGHTMAP\n"
1099 "uniform sampler2D Texture_ScreenDiffuse;\n"
1100 "uniform sampler2D Texture_ScreenSpecular;\n"
1103 "uniform myhalf3 Color_Pants;\n"
1104 "uniform myhalf3 Color_Shirt;\n"
1105 "uniform myhalf3 FogColor;\n"
1108 "uniform float FogRangeRecip;\n"
1109 "uniform float FogPlaneViewDist;\n"
1110 "uniform float FogHeightFade;\n"
1111 "vec3 FogVertex(vec3 surfacecolor)\n"
1113 " vec3 EyeVectorModelSpace = EyeVectorModelSpaceFogPlaneVertexDist.xyz;\n"
1114 " float FogPlaneVertexDist = EyeVectorModelSpaceFogPlaneVertexDist.w;\n"
1116 "#ifdef USEFOGHEIGHTTEXTURE\n"
1117 " vec4 fogheightpixel = texture2D(Texture_FogHeightTexture, vec2(1,1) + vec2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n"
1118 " fogfrac = fogheightpixel.a;\n"
1119 " return mix(fogheightpixel.rgb * FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
1121 "# ifdef USEFOGOUTSIDE\n"
1122 " fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
1124 " fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
1126 " return mix(FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
1131 "#ifdef USEOFFSETMAPPING\n"
1132 "uniform float OffsetMapping_Scale;\n"
1133 "vec2 OffsetMapping(vec2 TexCoord)\n"
1135 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
1136 " // 14 sample relief mapping: linear search and then binary search\n"
1137 " // this basically steps forward a small amount repeatedly until it finds\n"
1138 " // itself inside solid, then jitters forward and back using decreasing\n"
1139 " // amounts to find the impact\n"
1140 " //vec3 OffsetVector = vec3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1), -1);\n"
1141 " //vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
1142 " vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
1143 " vec3 RT = vec3(TexCoord, 1);\n"
1144 " OffsetVector *= 0.1;\n"
1145 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1146 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1147 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1148 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1149 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1150 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1151 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1152 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1153 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
1154 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n"
1155 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n"
1156 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n"
1157 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n"
1158 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
1161 " // 2 sample offset mapping (only 2 samples because of ATI Radeon 9500-9800/X300 limits)\n"
1162 " // this basically moves forward the full distance, and then backs up based\n"
1163 " // on height of samples\n"
1164 " //vec2 OffsetVector = vec2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1));\n"
1165 " //vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1));\n"
1166 " vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1));\n"
1167 " TexCoord += OffsetVector;\n"
1168 " OffsetVector *= 0.5;\n"
1169 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1170 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
1171 " return TexCoord;\n"
1174 "#endif // USEOFFSETMAPPING\n"
1176 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
1177 "uniform sampler2D Texture_Attenuation;\n"
1178 "uniform samplerCube Texture_Cube;\n"
1181 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
1183 "#ifdef USESHADOWMAP2D\n"
1184 "# ifdef USESHADOWSAMPLER\n"
1185 "uniform sampler2DShadow Texture_ShadowMap2D;\n"
1187 "uniform sampler2D Texture_ShadowMap2D;\n"
1191 "#ifdef USESHADOWMAPVSDCT\n"
1192 "uniform samplerCube Texture_CubeProjection;\n"
1195 "#if defined(USESHADOWMAP2D)\n"
1196 "uniform vec2 ShadowMap_TextureScale;\n"
1197 "uniform vec4 ShadowMap_Parameters;\n"
1200 "#if defined(USESHADOWMAP2D)\n"
1201 "# ifdef USESHADOWMAPORTHO\n"
1202 "# define GetShadowMapTC2D(dir) (min(dir, ShadowMap_Parameters.xyz))\n"
1204 "# ifdef USESHADOWMAPVSDCT\n"
1205 "vec3 GetShadowMapTC2D(vec3 dir)\n"
1207 " vec3 adir = abs(dir);\n"
1208 " vec2 aparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n"
1209 " vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
1210 " return vec3(mix(dir.xy, dir.zz, proj.xy) * aparams.x + proj.zw * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
1213 "vec3 GetShadowMapTC2D(vec3 dir)\n"
1215 " vec3 adir = abs(dir);\n"
1216 " float ma = adir.z;\n"
1217 " vec4 proj = vec4(dir, 2.5);\n"
1218 " if (adir.x > ma) { ma = adir.x; proj = vec4(dir.zyx, 0.5); }\n"
1219 " if (adir.y > ma) { ma = adir.y; proj = vec4(dir.xzy, 1.5); }\n"
1220 " vec2 aparams = ShadowMap_Parameters.xy / ma;\n"
1221 " return vec3(proj.xy * aparams.x + vec2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
1225 "#endif // defined(USESHADOWMAP2D)\n"
1227 "# ifdef USESHADOWMAP2D\n"
1228 "float ShadowMapCompare(vec3 dir)\n"
1230 " vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
1233 "# ifdef USESHADOWSAMPLER\n"
1234 "# ifdef USESHADOWMAPPCF\n"
1235 "# define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r \n"
1236 " vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
1237 " f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
1239 " f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
1242 "# ifdef USESHADOWMAPPCF\n"
1243 "# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
1244 "# ifdef GL_ARB_texture_gather\n"
1245 "# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec2(x, y))\n"
1247 "# define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale)\n"
1249 " vec2 offset = fract(shadowmaptc.xy - 0.5), center = (shadowmaptc.xy - offset)*ShadowMap_TextureScale;\n"
1250 "# if USESHADOWMAPPCF > 1\n"
1251 " vec4 group1 = step(shadowmaptc.z, texval(-2.0, -2.0));\n"
1252 " vec4 group2 = step(shadowmaptc.z, texval( 0.0, -2.0));\n"
1253 " vec4 group3 = step(shadowmaptc.z, texval( 2.0, -2.0));\n"
1254 " vec4 group4 = step(shadowmaptc.z, texval(-2.0, 0.0));\n"
1255 " vec4 group5 = step(shadowmaptc.z, texval( 0.0, 0.0));\n"
1256 " vec4 group6 = step(shadowmaptc.z, texval( 2.0, 0.0));\n"
1257 " vec4 group7 = step(shadowmaptc.z, texval(-2.0, 2.0));\n"
1258 " vec4 group8 = step(shadowmaptc.z, texval( 0.0, 2.0));\n"
1259 " vec4 group9 = step(shadowmaptc.z, texval( 2.0, 2.0));\n"
1260 " vec4 locols = vec4(group1.ab, group3.ab);\n"
1261 " vec4 hicols = vec4(group7.rg, group9.rg);\n"
1262 " locols.yz += group2.ab;\n"
1263 " hicols.yz += group8.rg;\n"
1264 " vec4 midcols = vec4(group1.rg, group3.rg) + vec4(group7.ab, group9.ab) +\n"
1265 " vec4(group4.rg, group6.rg) + vec4(group4.ab, group6.ab) +\n"
1266 " mix(locols, hicols, offset.y);\n"
1267 " vec4 cols = group5 + vec4(group2.rg, group8.ab);\n"
1268 " cols.xyz += mix(midcols.xyz, midcols.yzw, offset.x);\n"
1269 " f = dot(cols, vec4(1.0/25.0));\n"
1271 " vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
1272 " vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
1273 " vec4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
1274 " vec4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
1275 " vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
1276 " mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
1277 " f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1280 "# ifdef GL_EXT_gpu_shader4\n"
1281 "# define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n"
1283 "# define texval(x, y) texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r \n"
1285 "# if USESHADOWMAPPCF > 1\n"
1286 " vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
1287 " center *= ShadowMap_TextureScale;\n"
1288 " vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
1289 " vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
1290 " vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
1291 " vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
1292 " vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
1293 " f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
1295 " vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
1296 " vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
1297 " vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
1298 " vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
1299 " vec3 cols = row2 + mix(row1, row3, offset.y);\n"
1300 " f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
1304 " f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
1307 "# ifdef USESHADOWMAPORTHO\n"
1308 " return mix(ShadowMap_Parameters.w, 1.0, f);\n"
1314 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
1315 "#endif // FRAGMENT_SHADER\n"
1320 "#ifdef MODE_DEFERREDGEOMETRY\n"
1321 "#ifdef VERTEX_SHADER\n"
1322 "uniform mat4 TexMatrix;\n"
1323 "#ifdef USEVERTEXTEXTUREBLEND\n"
1324 "uniform mat4 BackgroundTexMatrix;\n"
1326 "uniform mat4 ModelViewMatrix;\n"
1329 " TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
1330 "#ifdef USEVERTEXTEXTUREBLEND\n"
1331 " gl_FrontColor = gl_Color;\n"
1332 " TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
1335 " // transform unnormalized eye direction into tangent space\n"
1336 "#ifdef USEOFFSETMAPPING\n"
1337 " vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
1338 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
1339 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
1340 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
1343 " VectorS = (ModelViewMatrix * vec4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
1344 " VectorT = (ModelViewMatrix * vec4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
1345 " VectorR = (ModelViewMatrix * vec4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
1346 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
1348 "#endif // VERTEX_SHADER\n"
1350 "#ifdef FRAGMENT_SHADER\n"
1353 "#ifdef USEOFFSETMAPPING\n"
1354 " // apply offsetmapping\n"
1355 " vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1356 "#define TexCoord TexCoordOffset\n"
1359 "#ifdef USEALPHAKILL\n"
1360 " if (texture2D(Texture_Color, TexCoord).a < 0.5)\n"
1364 "#ifdef USEVERTEXTEXTUREBLEND\n"
1365 " float alpha = texture2D(Texture_Color, TexCoord).a;\n"
1366 " float terrainblend = clamp(float(gl_Color.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
1367 " //float terrainblend = min(float(gl_Color.a) * alpha * 2.0, float(1.0));\n"
1368 " //float terrainblend = float(gl_Color.a) * alpha > 0.5;\n"
1371 "#ifdef USEVERTEXTEXTUREBLEND\n"
1372 " vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(texture2D(Texture_Normal, TexCoord)), terrainblend) - vec3(0.5, 0.5, 0.5);\n"
1373 " float a = mix(texture2D(Texture_SecondaryGloss, TexCoord2).a, texture2D(Texture_Gloss, TexCoord).a, terrainblend);\n"
1375 " vec3 surfacenormal = vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5, 0.5, 0.5);\n"
1376 " float a = texture2D(Texture_Gloss, TexCoord).a;\n"
1379 " gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), a);\n"
1381 "#endif // FRAGMENT_SHADER\n"
1382 "#else // !MODE_DEFERREDGEOMETRY\n"
1387 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
1388 "#ifdef VERTEX_SHADER\n"
1389 "uniform mat4 ModelViewMatrix;\n"
1392 " ModelViewPosition = ModelViewMatrix * gl_Vertex;\n"
1393 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
1395 "#endif // VERTEX_SHADER\n"
1397 "#ifdef FRAGMENT_SHADER\n"
1398 "uniform mat4 ViewToLight;\n"
1399 "// ScreenToDepth = vec2(Far / (Far - Near), Far * Near / (Near - Far));\n"
1400 "uniform vec2 ScreenToDepth;\n"
1401 "uniform myhalf3 DeferredColor_Ambient;\n"
1402 "uniform myhalf3 DeferredColor_Diffuse;\n"
1403 "#ifdef USESPECULAR\n"
1404 "uniform myhalf3 DeferredColor_Specular;\n"
1405 "uniform myhalf SpecularPower;\n"
1407 "uniform myhalf2 PixelToScreenTexCoord;\n"
1410 " // calculate viewspace pixel position\n"
1411 " vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
1413 " position.z = ScreenToDepth.y / (texture2D(Texture_ScreenDepth, ScreenTexCoord).r + ScreenToDepth.x);\n"
1414 " position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
1415 " // decode viewspace pixel normal\n"
1416 " myhalf4 normalmap = texture2D(Texture_ScreenNormalMap, ScreenTexCoord);\n"
1417 " myhalf3 surfacenormal = normalize(normalmap.rgb - myhalf3(0.5,0.5,0.5));\n"
1418 " // surfacenormal = pixel normal in viewspace\n"
1419 " // LightVector = pixel to light in viewspace\n"
1420 " // CubeVector = position in lightspace\n"
1421 " // eyevector = pixel to view in viewspace\n"
1422 " vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n"
1423 " myhalf fade = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
1424 "#ifdef USEDIFFUSE\n"
1425 " // calculate diffuse shading\n"
1426 " myhalf3 lightnormal = myhalf3(normalize(LightPosition - position));\n"
1427 " myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1429 "#ifdef USESPECULAR\n"
1430 " // calculate directional shading\n"
1431 " vec3 eyevector = position * -1.0;\n"
1432 "# ifdef USEEXACTSPECULARMATH\n"
1433 " myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a);\n"
1435 " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(eyevector)));\n"
1436 " myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a);\n"
1440 "#if defined(USESHADOWMAP2D)\n"
1441 " fade *= ShadowMapCompare(CubeVector);\n"
1444 "#ifdef USEDIFFUSE\n"
1445 " gl_FragData[0] = vec4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
1447 " gl_FragData[0] = vec4(DeferredColor_Ambient * fade, 1.0);\n"
1449 "#ifdef USESPECULAR\n"
1450 " gl_FragData[1] = vec4(DeferredColor_Specular * (specular * fade), 1.0);\n"
1452 " gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0);\n"
1455 "# ifdef USECUBEFILTER\n"
1456 " vec3 cubecolor = textureCube(Texture_Cube, CubeVector).rgb;\n"
1457 " gl_FragData[0].rgb *= cubecolor;\n"
1458 " gl_FragData[1].rgb *= cubecolor;\n"
1461 "#endif // FRAGMENT_SHADER\n"
1462 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
1467 "#ifdef VERTEX_SHADER\n"
1468 "uniform mat4 TexMatrix;\n"
1469 "#ifdef USEVERTEXTEXTUREBLEND\n"
1470 "uniform mat4 BackgroundTexMatrix;\n"
1472 "#ifdef MODE_LIGHTSOURCE\n"
1473 "uniform mat4 ModelToLight;\n"
1475 "#ifdef USESHADOWMAPORTHO\n"
1476 "uniform mat4 ShadowMapMatrix;\n"
1480 "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
1481 " gl_FrontColor = gl_Color;\n"
1483 " // copy the surface texcoord\n"
1484 " TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
1485 "#ifdef USEVERTEXTEXTUREBLEND\n"
1486 " TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
1488 "#ifdef USELIGHTMAP\n"
1489 " TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
1492 "#ifdef MODE_LIGHTSOURCE\n"
1493 " // transform vertex position into light attenuation/cubemap space\n"
1494 " // (-1 to +1 across the light box)\n"
1495 " CubeVector = vec3(ModelToLight * gl_Vertex);\n"
1497 "# ifdef USEDIFFUSE\n"
1498 " // transform unnormalized light direction into tangent space\n"
1499 " // (we use unnormalized to ensure that it interpolates correctly and then\n"
1500 " // normalize it per pixel)\n"
1501 " vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
1502 " LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
1503 " LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
1504 " LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
1508 "#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
1509 " LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
1510 " LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
1511 " LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
1514 " // transform unnormalized eye direction into tangent space\n"
1515 "#ifdef USEEYEVECTOR\n"
1516 " vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
1517 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
1518 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
1519 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
1523 " EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
1524 " EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
1527 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(USEREFLECTCUBE)\n"
1528 " VectorS = gl_MultiTexCoord1.xyz;\n"
1529 " VectorT = gl_MultiTexCoord2.xyz;\n"
1530 " VectorR = gl_MultiTexCoord3.xyz;\n"
1533 " // transform vertex to camera space, using ftransform to match non-VS rendering\n"
1534 " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
1536 "#ifdef USESHADOWMAPORTHO\n"
1537 " ShadowMapTC = vec3(ShadowMapMatrix * gl_Position);\n"
1540 "#ifdef USEREFLECTION\n"
1541 " ModelViewProjectionPosition = gl_Position;\n"
1544 "#endif // VERTEX_SHADER\n"
1549 "#ifdef FRAGMENT_SHADER\n"
1550 "#ifdef USEDEFERREDLIGHTMAP\n"
1551 "uniform myhalf2 PixelToScreenTexCoord;\n"
1552 "uniform myhalf3 DeferredMod_Diffuse;\n"
1553 "uniform myhalf3 DeferredMod_Specular;\n"
1555 "uniform myhalf3 Color_Ambient;\n"
1556 "uniform myhalf3 Color_Diffuse;\n"
1557 "uniform myhalf3 Color_Specular;\n"
1558 "uniform myhalf SpecularPower;\n"
1560 "uniform myhalf3 Color_Glow;\n"
1562 "uniform myhalf Alpha;\n"
1563 "#ifdef USEREFLECTION\n"
1564 "uniform vec4 DistortScaleRefractReflect;\n"
1565 "uniform vec4 ScreenScaleRefractReflect;\n"
1566 "uniform vec4 ScreenCenterRefractReflect;\n"
1567 "uniform myhalf4 ReflectColor;\n"
1569 "#ifdef USEREFLECTCUBE\n"
1570 "uniform mat4 ModelToReflectCube;\n"
1571 "uniform sampler2D Texture_ReflectMask;\n"
1572 "uniform samplerCube Texture_ReflectCube;\n"
1574 "#ifdef MODE_LIGHTDIRECTION\n"
1575 "uniform myhalf3 LightColor;\n"
1577 "#ifdef MODE_LIGHTSOURCE\n"
1578 "uniform myhalf3 LightColor;\n"
1582 "#ifdef USEOFFSETMAPPING\n"
1583 " // apply offsetmapping\n"
1584 " vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
1585 "#define TexCoord TexCoordOffset\n"
1588 " // combine the diffuse textures (base, pants, shirt)\n"
1589 " myhalf4 color = myhalf4(texture2D(Texture_Color, TexCoord));\n"
1590 "#ifdef USEALPHAKILL\n"
1591 " if (color.a < 0.5)\n"
1594 " color.a *= Alpha;\n"
1595 "#ifdef USECOLORMAPPING\n"
1596 " color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
1598 "#ifdef USEVERTEXTEXTUREBLEND\n"
1599 " myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
1600 " //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n"
1601 " //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n"
1602 " color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord2)), color.rgb, terrainblend);\n"
1604 " //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
1607 " // get the surface normal\n"
1608 "#ifdef USEVERTEXTEXTUREBLEND\n"
1609 " myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n"
1611 " myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n"
1614 " // get the material colors\n"
1615 " myhalf3 diffusetex = color.rgb;\n"
1616 "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
1617 "# ifdef USEVERTEXTEXTUREBLEND\n"
1618 " myhalf4 glosstex = mix(myhalf4(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf4(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
1620 " myhalf4 glosstex = myhalf4(texture2D(Texture_Gloss, TexCoord));\n"
1624 "#ifdef USEREFLECTCUBE\n"
1625 " vec3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n"
1626 " vec3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n"
1627 " vec3 ReflectCubeTexCoord = vec3(ModelToReflectCube * vec4(ModelReflectVector, 0));\n"
1628 " diffusetex += myhalf3(texture2D(Texture_ReflectMask, TexCoord)) * myhalf3(textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n"
1634 "#ifdef MODE_LIGHTSOURCE\n"
1635 " // light source\n"
1636 "#ifdef USEDIFFUSE\n"
1637 " myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
1638 " myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1639 " color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
1640 "#ifdef USESPECULAR\n"
1641 "#ifdef USEEXACTSPECULARMATH\n"
1642 " myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
1644 " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
1645 " myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
1647 " color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
1650 " color.rgb = diffusetex * Color_Ambient;\n"
1652 " color.rgb *= LightColor;\n"
1653 " color.rgb *= myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
1654 "#if defined(USESHADOWMAP2D)\n"
1655 " color.rgb *= ShadowMapCompare(CubeVector);\n"
1657 "# ifdef USECUBEFILTER\n"
1658 " color.rgb *= myhalf3(textureCube(Texture_Cube, CubeVector));\n"
1660 "#endif // MODE_LIGHTSOURCE\n"
1665 "#ifdef MODE_LIGHTDIRECTION\n"
1667 "#ifdef USEDIFFUSE\n"
1668 " myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
1670 "#define lightcolor LightColor\n"
1671 "#endif // MODE_LIGHTDIRECTION\n"
1672 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1674 " // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
1675 " myhalf3 lightnormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1676 " myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1677 " // convert modelspace light vector to tangentspace\n"
1678 " myhalf3 lightnormal;\n"
1679 " lightnormal.x = dot(lightnormal_modelspace, myhalf3(VectorS));\n"
1680 " lightnormal.y = dot(lightnormal_modelspace, myhalf3(VectorT));\n"
1681 " lightnormal.z = dot(lightnormal_modelspace, myhalf3(VectorR));\n"
1682 " lightnormal = normalize(lightnormal); // VectorS/T/R are not always perfectly normalized, and EXACTSPECULARMATH is very picky about this\n"
1683 " // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
1684 " // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
1685 " // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
1686 " // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
1687 " // to map the luxels to coordinates on the draw surfaces), which also causes\n"
1688 " // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
1689 " // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
1690 " // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
1691 " // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
1692 " lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
1693 "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
1694 "#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
1696 " // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
1697 " myhalf3 lightnormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
1698 " myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
1704 "#ifdef MODE_FAKELIGHT\n"
1706 "myhalf3 lightnormal = myhalf3(normalize(EyeVector));\n"
1707 "myhalf3 lightcolor = myhalf3(1.0);\n"
1708 "#endif // MODE_FAKELIGHT\n"
1713 "#ifdef MODE_LIGHTMAP\n"
1714 " color.rgb = diffusetex * (Color_Ambient + myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
1715 "#endif // MODE_LIGHTMAP\n"
1716 "#ifdef MODE_VERTEXCOLOR\n"
1717 " color.rgb = diffusetex * (Color_Ambient + myhalf3(gl_Color.rgb) * Color_Diffuse);\n"
1718 "#endif // MODE_VERTEXCOLOR\n"
1719 "#ifdef MODE_FLATCOLOR\n"
1720 " color.rgb = diffusetex * Color_Ambient;\n"
1721 "#endif // MODE_FLATCOLOR\n"
1727 "# ifdef USEDIFFUSE\n"
1728 " myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
1729 "# ifdef USESPECULAR\n"
1730 "# ifdef USEEXACTSPECULARMATH\n"
1731 " myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
1733 " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
1734 " myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
1736 " color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
1738 " color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
1741 " color.rgb = diffusetex * Color_Ambient;\n"
1745 "#ifdef USESHADOWMAPORTHO\n"
1746 " color.rgb *= ShadowMapCompare(ShadowMapTC);\n"
1749 "#ifdef USEDEFERREDLIGHTMAP\n"
1750 " vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
1751 " color.rgb += diffusetex * myhalf3(texture2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n"
1752 " color.rgb += glosstex.rgb * myhalf3(texture2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n"
1756 "#ifdef USEVERTEXTEXTUREBLEND\n"
1757 " color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
1759 " color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
1764 " color.rgb = FogVertex(color.rgb);\n"
1767 " // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
1768 "#ifdef USEREFLECTION\n"
1769 " vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
1770 " //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
1771 " vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
1772 " vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
1773 " // FIXME temporary hack to detect the case that the reflection\n"
1774 " // gets blackened at edges due to leaving the area that contains actual\n"
1776 " // Remove this 'ack once we have a better way to stop this thing from\n"
1778 " float f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
1779 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
1780 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
1781 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
1782 " ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
1783 " color.rgb = mix(color.rgb, myhalf3(texture2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
1786 " gl_FragColor = vec4(color);\n"
1788 "#endif // FRAGMENT_SHADER\n"
1790 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
1791 "#endif // !MODE_DEFERREDGEOMETRY\n"
1792 "#endif // !MODE_WATER\n"
1793 "#endif // !MODE_REFRACTION\n"
1794 "#endif // !MODE_BLOOMBLUR\n"
1795 "#endif // !MODE_GENERIC\n"
1796 "#endif // !MODE_POSTPROCESS\n"
1797 "#endif // !MODE_SHOWDEPTH\n"
1798 "#endif // !MODE_DEPTH_OR_SHADOW\n"
1802 =========================================================================================================================================================
1806 =========================================================================================================================================================
1810 =========================================================================================================================================================
1814 =========================================================================================================================================================
1818 =========================================================================================================================================================
1822 =========================================================================================================================================================
1826 =========================================================================================================================================================
1829 const char *builtincgshaderstring =
1830 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
1831 "// written by Forest 'LordHavoc' Hale\n"
1832 "// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
1834 "// FIXME: we need to get rid of ModelViewProjectionPosition to make room for the texcoord for this\n"
1835 "#if defined(USEREFLECTION)\n"
1836 "#undef USESHADOWMAPORTHO\n"
1839 "#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE) || defined(USEFOGHEIGHTTEXTURE)\n"
1842 "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
1843 "#define USELIGHTMAP\n"
1845 "#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n"
1846 "#define USEEYEVECTOR\n"
1849 "#ifdef FRAGMENT_SHADER\n"
1851 "//#undef USESHADOWMAPPCF\n"
1852 "//#define texDepth2D(tex,texcoord) tex2D(tex,texcoord).r\n"
1853 "#define texDepth2D(tex,texcoord) dot(tex2D(tex,texcoord).rgb, float3(1.0, 255.0/65536.0, 255.0/16777216.0))\n"
1855 "#define texDepth2D(tex,texcoord) tex2D(tex,texcoord).r\n"
1859 "#ifdef MODE_DEPTH_OR_SHADOW\n"
1860 "#ifdef VERTEX_SHADER\n"
1863 "float4 gl_Vertex : POSITION,\n"
1864 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
1865 "out float4 gl_Position : POSITION,\n"
1866 "out float Depth : TEXCOORD0\n"
1869 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
1870 " Depth = gl_Position.z;\n"
1874 "#ifdef FRAGMENT_SHADER\n"
1877 "float Depth : TEXCOORD0,\n"
1878 "out float4 gl_FragColor : COLOR\n"
1881 "// float4 temp = float4(Depth,Depth*(65536.0/255.0),Depth*(16777216.0/255.0),0.0);\n"
1882 " float4 temp = float4(Depth,Depth*256.0,Depth*65536.0,0.0);\n"
1883 " temp.yz -= floor(temp.yz);\n"
1884 " gl_FragColor = temp;\n"
1885 "// gl_FragColor = float4(Depth,0,0,0);\n"
1888 "#else // !MODE_DEPTH_ORSHADOW\n"
1893 "#ifdef MODE_SHOWDEPTH\n"
1894 "#ifdef VERTEX_SHADER\n"
1897 "float4 gl_Vertex : POSITION,\n"
1898 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
1899 "out float4 gl_Position : POSITION,\n"
1900 "out float4 gl_FrontColor : COLOR0\n"
1903 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
1904 " gl_FrontColor = float4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
1908 "#ifdef FRAGMENT_SHADER\n"
1911 "float4 gl_FrontColor : COLOR0,\n"
1912 "out float4 gl_FragColor : COLOR\n"
1915 " gl_FragColor = gl_FrontColor;\n"
1918 "#else // !MODE_SHOWDEPTH\n"
1923 "#ifdef MODE_POSTPROCESS\n"
1925 "#ifdef VERTEX_SHADER\n"
1928 "float4 gl_Vertex : POSITION,\n"
1929 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
1930 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
1931 "float4 gl_MultiTexCoord4 : TEXCOORD4,\n"
1932 "out float4 gl_Position : POSITION,\n"
1933 "out float2 TexCoord1 : TEXCOORD0,\n"
1934 "out float2 TexCoord2 : TEXCOORD1\n"
1937 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
1938 " TexCoord1 = gl_MultiTexCoord0.xy;\n"
1940 " TexCoord2 = gl_MultiTexCoord4.xy;\n"
1945 "#ifdef FRAGMENT_SHADER\n"
1948 "float2 TexCoord1 : TEXCOORD0,\n"
1949 "float2 TexCoord2 : TEXCOORD1,\n"
1950 "uniform sampler Texture_First : register(s0),\n"
1952 "uniform sampler Texture_Second : register(s1),\n"
1954 "#ifdef USEGAMMARAMPS\n"
1955 "uniform sampler Texture_GammaRamps : register(s2),\n"
1957 "#ifdef USESATURATION\n"
1958 "uniform float Saturation : register(c30),\n"
1960 "#ifdef USEVIEWTINT\n"
1961 "uniform float4 ViewTintColor : register(c41),\n"
1963 "uniform float4 UserVec1 : register(c37),\n"
1964 "uniform float4 UserVec2 : register(c38),\n"
1965 "uniform float4 UserVec3 : register(c39),\n"
1966 "uniform float4 UserVec4 : register(c40),\n"
1967 "uniform float ClientTime : register(c2),\n"
1968 "uniform float2 PixelSize : register(c25),\n"
1969 "uniform float4 BloomColorSubtract : register(c43),\n"
1970 "out float4 gl_FragColor : COLOR\n"
1973 " gl_FragColor = tex2D(Texture_First, TexCoord1);\n"
1975 " gl_FragColor += max(float4(0,0,0,0), tex2D(Texture_Second, TexCoord2) - BloomColorSubtract);\n"
1977 "#ifdef USEVIEWTINT\n"
1978 " gl_FragColor = lerp(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
1981 "#ifdef USEPOSTPROCESSING\n"
1982 "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
1983 "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
1984 " float sobel = 1.0;\n"
1985 " // float2 ts = textureSize(Texture_First, 0);\n"
1986 " // float2 px = float2(1/ts.x, 1/ts.y);\n"
1987 " float2 px = PixelSize;\n"
1988 " float3 x1 = tex2D(Texture_First, TexCoord1 + float2(-px.x, px.y)).rgb;\n"
1989 " float3 x2 = tex2D(Texture_First, TexCoord1 + float2(-px.x, 0.0)).rgb;\n"
1990 " float3 x3 = tex2D(Texture_First, TexCoord1 + float2(-px.x,-px.y)).rgb;\n"
1991 " float3 x4 = tex2D(Texture_First, TexCoord1 + float2( px.x, px.y)).rgb;\n"
1992 " float3 x5 = tex2D(Texture_First, TexCoord1 + float2( px.x, 0.0)).rgb;\n"
1993 " float3 x6 = tex2D(Texture_First, TexCoord1 + float2( px.x,-px.y)).rgb;\n"
1994 " float3 y1 = tex2D(Texture_First, TexCoord1 + float2( px.x,-px.y)).rgb;\n"
1995 " float3 y2 = tex2D(Texture_First, TexCoord1 + float2( 0.0,-px.y)).rgb;\n"
1996 " float3 y3 = tex2D(Texture_First, TexCoord1 + float2(-px.x,-px.y)).rgb;\n"
1997 " float3 y4 = tex2D(Texture_First, TexCoord1 + float2( px.x, px.y)).rgb;\n"
1998 " float3 y5 = tex2D(Texture_First, TexCoord1 + float2( 0.0, px.y)).rgb;\n"
1999 " float3 y6 = tex2D(Texture_First, TexCoord1 + float2(-px.x, px.y)).rgb;\n"
2000 " float px1 = -1.0 * dot(float3(0.3, 0.59, 0.11), x1);\n"
2001 " float px2 = -2.0 * dot(float3(0.3, 0.59, 0.11), x2);\n"
2002 " float px3 = -1.0 * dot(float3(0.3, 0.59, 0.11), x3);\n"
2003 " float px4 = 1.0 * dot(float3(0.3, 0.59, 0.11), x4);\n"
2004 " float px5 = 2.0 * dot(float3(0.3, 0.59, 0.11), x5);\n"
2005 " float px6 = 1.0 * dot(float3(0.3, 0.59, 0.11), x6);\n"
2006 " float py1 = -1.0 * dot(float3(0.3, 0.59, 0.11), y1);\n"
2007 " float py2 = -2.0 * dot(float3(0.3, 0.59, 0.11), y2);\n"
2008 " float py3 = -1.0 * dot(float3(0.3, 0.59, 0.11), y3);\n"
2009 " float py4 = 1.0 * dot(float3(0.3, 0.59, 0.11), y4);\n"
2010 " float py5 = 2.0 * dot(float3(0.3, 0.59, 0.11), y5);\n"
2011 " float py6 = 1.0 * dot(float3(0.3, 0.59, 0.11), y6);\n"
2012 " sobel = 0.25 * abs(px1 + px2 + px3 + px4 + px5 + px6) + 0.25 * abs(py1 + py2 + py3 + py4 + py5 + py6);\n"
2013 " gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.987688, -0.156434)) * UserVec1.y;\n"
2014 " gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.156434, -0.891007)) * UserVec1.y;\n"
2015 " gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.891007, -0.453990)) * UserVec1.y;\n"
2016 " gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.707107, 0.707107)) * UserVec1.y;\n"
2017 " gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.453990, 0.891007)) * UserVec1.y;\n"
2018 " gl_FragColor /= (1.0 + 5.0 * UserVec1.y);\n"
2019 " gl_FragColor.rgb = gl_FragColor.rgb * (1.0 + UserVec2.x) + float3(1,1,1)*max(0.0, sobel - UserVec2.z)*UserVec2.y;\n"
2022 "#ifdef USESATURATION\n"
2023 " //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
2024 " float y = dot(gl_FragColor.rgb, float3(0.299, 0.587, 0.114));\n"
2025 " // 'vampire sight' effect, wheres red is compensated\n"
2026 " #ifdef SATURATION_REDCOMPENSATE\n"
2027 " float rboost = max(0.0, (gl_FragColor.r - max(gl_FragColor.g, gl_FragColor.b))*(1.0 - Saturation));\n"
2028 " gl_FragColor.rgb = mix(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
2029 " gl_FragColor.r += r;\n"
2031 " // normal desaturation\n"
2032 " //gl_FragColor = float3(y,y,y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
2033 " gl_FragColor.rgb = lerp(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
2037 "#ifdef USEGAMMARAMPS\n"
2038 " gl_FragColor.r = tex2D(Texture_GammaRamps, float2(gl_FragColor.r, 0)).r;\n"
2039 " gl_FragColor.g = tex2D(Texture_GammaRamps, float2(gl_FragColor.g, 0)).g;\n"
2040 " gl_FragColor.b = tex2D(Texture_GammaRamps, float2(gl_FragColor.b, 0)).b;\n"
2044 "#else // !MODE_POSTPROCESS\n"
2049 "#ifdef MODE_GENERIC\n"
2050 "#ifdef VERTEX_SHADER\n"
2053 "float4 gl_Vertex : POSITION,\n"
2054 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
2055 "float4 gl_Color : COLOR0,\n"
2056 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
2057 "float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
2058 "out float4 gl_Position : POSITION,\n"
2059 "#ifdef USEDIFFUSE\n"
2060 "out float2 TexCoord1 : TEXCOORD0,\n"
2062 "#ifdef USESPECULAR\n"
2063 "out float2 TexCoord2 : TEXCOORD1,\n"
2065 "out float4 gl_FrontColor : COLOR\n"
2069 " gl_FrontColor = gl_Color.bgra; // NOTE: D3DCOLOR is backwards\n"
2071 " gl_FrontColor = gl_Color; // Cg is forward\n"
2073 "#ifdef USEDIFFUSE\n"
2074 " TexCoord1 = gl_MultiTexCoord0.xy;\n"
2076 "#ifdef USESPECULAR\n"
2077 " TexCoord2 = gl_MultiTexCoord1.xy;\n"
2079 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
2083 "#ifdef FRAGMENT_SHADER\n"
2087 "float4 gl_FrontColor : COLOR0,\n"
2088 "float2 TexCoord1 : TEXCOORD0,\n"
2089 "float2 TexCoord2 : TEXCOORD1,\n"
2090 "#ifdef USEDIFFUSE\n"
2091 "uniform sampler Texture_First : register(s0),\n"
2093 "#ifdef USESPECULAR\n"
2094 "uniform sampler Texture_Second : register(s1),\n"
2096 "out float4 gl_FragColor : COLOR\n"
2099 "#ifdef USEVIEWTINT\n"
2100 " gl_FragColor = gl_FrontColor;\n"
2102 " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
2104 "#ifdef USEDIFFUSE\n"
2105 " gl_FragColor *= tex2D(Texture_First, TexCoord1);\n"
2108 "#ifdef USESPECULAR\n"
2109 " float4 tex2 = tex2D(Texture_Second, TexCoord2);\n"
2110 "# ifdef USECOLORMAPPING\n"
2111 " gl_FragColor *= tex2;\n"
2114 " gl_FragColor += tex2;\n"
2116 "# ifdef USEVERTEXTEXTUREBLEND\n"
2117 " gl_FragColor = lerp(gl_FragColor, tex2, tex2.a);\n"
2122 "#else // !MODE_GENERIC\n"
2127 "#ifdef MODE_BLOOMBLUR\n"
2128 "#ifdef VERTEX_SHADER\n"
2131 "float4 gl_Vertex : POSITION,\n"
2132 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
2133 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
2134 "out float4 gl_Position : POSITION,\n"
2135 "out float2 TexCoord : TEXCOORD0\n"
2138 " TexCoord = gl_MultiTexCoord0.xy;\n"
2139 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
2143 "#ifdef FRAGMENT_SHADER\n"
2147 "float2 TexCoord : TEXCOORD0,\n"
2148 "uniform sampler Texture_First : register(s0),\n"
2149 "uniform float4 BloomBlur_Parameters : register(c1),\n"
2150 "out float4 gl_FragColor : COLOR\n"
2154 " float2 tc = TexCoord;\n"
2155 " float3 color = tex2D(Texture_First, tc).rgb;\n"
2156 " tc += BloomBlur_Parameters.xy;\n"
2157 " for (i = 1;i < SAMPLES;i++)\n"
2159 " color += tex2D(Texture_First, tc).rgb;\n"
2160 " tc += BloomBlur_Parameters.xy;\n"
2162 " gl_FragColor = float4(color * BloomBlur_Parameters.z + float3(BloomBlur_Parameters.w), 1);\n"
2165 "#else // !MODE_BLOOMBLUR\n"
2166 "#ifdef MODE_REFRACTION\n"
2167 "#ifdef VERTEX_SHADER\n"
2170 "float4 gl_Vertex : POSITION,\n"
2171 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
2172 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
2173 "uniform float4x4 TexMatrix : register(c0),\n"
2174 "uniform float3 EyePosition : register(c24),\n"
2175 "out float4 gl_Position : POSITION,\n"
2176 "out float2 TexCoord : TEXCOORD0,\n"
2177 "out float3 EyeVector : TEXCOORD1,\n"
2178 "out float4 ModelViewProjectionPosition : TEXCOORD2\n"
2181 " TexCoord = mul(TexMatrix, gl_MultiTexCoord0).xy;\n"
2182 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
2183 " ModelViewProjectionPosition = gl_Position;\n"
2187 "#ifdef FRAGMENT_SHADER\n"
2190 "float2 TexCoord : TEXCOORD0,\n"
2191 "float3 EyeVector : TEXCOORD1,\n"
2192 "float4 ModelViewProjectionPosition : TEXCOORD2,\n"
2193 "uniform sampler Texture_Normal : register(s0),\n"
2194 "uniform sampler Texture_Refraction : register(s3),\n"
2195 "uniform sampler Texture_Reflection : register(s7),\n"
2196 "uniform float4 DistortScaleRefractReflect : register(c14),\n"
2197 "uniform float4 ScreenScaleRefractReflect : register(c32),\n"
2198 "uniform float4 ScreenCenterRefractReflect : register(c31),\n"
2199 "uniform float4 RefractColor : register(c29),\n"
2200 "out float4 gl_FragColor : COLOR\n"
2203 " float2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
2204 " //float2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(tex2D(Texture_Normal, TexCoord).rgb - float3(0.5,0.5,0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
2205 " float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
2206 " float2 ScreenTexCoord = SafeScreenTexCoord + normalize(tex2D(Texture_Normal, TexCoord).rgb - float3(0.5,0.5,0.5)).xy * DistortScaleRefractReflect.xy;\n"
2207 " // FIXME temporary hack to detect the case that the reflection\n"
2208 " // gets blackened at edges due to leaving the area that contains actual\n"
2210 " // Remove this 'ack once we have a better way to stop this thing from\n"
2212 " float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
2213 " f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
2214 " f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
2215 " f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
2216 " ScreenTexCoord = lerp(SafeScreenTexCoord, ScreenTexCoord, f);\n"
2217 " gl_FragColor = float4(tex2D(Texture_Refraction, ScreenTexCoord).rgb, 1) * RefractColor;\n"
2220 "#else // !MODE_REFRACTION\n"
2225 "#ifdef MODE_WATER\n"
2226 "#ifdef VERTEX_SHADER\n"
2230 "float4 gl_Vertex : POSITION,\n"
2231 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
2232 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
2233 "float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
2234 "float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
2235 "float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
2236 "uniform float4x4 TexMatrix : register(c0),\n"
2237 "uniform float3 EyePosition : register(c24),\n"
2238 "out float4 gl_Position : POSITION,\n"
2239 "out float2 TexCoord : TEXCOORD0,\n"
2240 "out float3 EyeVector : TEXCOORD1,\n"
2241 "out float4 ModelViewProjectionPosition : TEXCOORD2\n"
2244 " TexCoord = mul(TexMatrix, gl_MultiTexCoord0).xy;\n"
2245 " float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
2246 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
2247 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
2248 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
2249 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
2250 " ModelViewProjectionPosition = gl_Position;\n"
2254 "#ifdef FRAGMENT_SHADER\n"
2257 "float2 TexCoord : TEXCOORD0,\n"
2258 "float3 EyeVector : TEXCOORD1,\n"
2259 "float4 ModelViewProjectionPosition : TEXCOORD2,\n"
2260 "uniform sampler Texture_Normal : register(s0),\n"
2261 "uniform sampler Texture_Refraction : register(s3),\n"
2262 "uniform sampler Texture_Reflection : register(s7),\n"
2263 "uniform float4 DistortScaleRefractReflect : register(c14),\n"
2264 "uniform float4 ScreenScaleRefractReflect : register(c32),\n"
2265 "uniform float4 ScreenCenterRefractReflect : register(c31),\n"
2266 "uniform float4 RefractColor : register(c29),\n"
2267 "uniform float4 ReflectColor : register(c26),\n"
2268 "uniform float ReflectFactor : register(c27),\n"
2269 "uniform float ReflectOffset : register(c28),\n"
2270 "out float4 gl_FragColor : COLOR\n"
2273 " float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
2274 " //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(tex2D(Texture_Normal, TexCoord).rgb - float3(0.5,0.5,0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
2275 " float4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
2276 " //SafeScreenTexCoord = gl_FragCoord.xyxy * float4(1.0 / 1920.0, 1.0 / 1200.0, 1.0 / 1920.0, 1.0 / 1200.0);\n"
2277 " float4 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(tex2D(Texture_Normal, TexCoord).rgb - float3(0.5,0.5,0.5)).xy).xyxy * DistortScaleRefractReflect;\n"
2278 " // FIXME temporary hack to detect the case that the reflection\n"
2279 " // gets blackened at edges due to leaving the area that contains actual\n"
2281 " // Remove this 'ack once we have a better way to stop this thing from\n"
2283 " float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, 0.01)).rgb) / 0.05);\n"
2284 " f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, -0.01)).rgb) / 0.05);\n"
2285 " f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, 0.01)).rgb) / 0.05);\n"
2286 " f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, -0.01)).rgb) / 0.05);\n"
2287 " ScreenTexCoord.xy = lerp(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
2288 " f = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, 0.01)).rgb) / 0.05);\n"
2289 " f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, -0.01)).rgb) / 0.05);\n"
2290 " f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, 0.01)).rgb) / 0.05);\n"
2291 " f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, -0.01)).rgb) / 0.05);\n"
2292 " ScreenTexCoord.zw = lerp(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
2293 " float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
2294 " gl_FragColor = lerp(float4(tex2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, float4(tex2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
2297 "#else // !MODE_WATER\n"
2302 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
2304 "// fragment shader specific:\n"
2305 "#ifdef FRAGMENT_SHADER\n"
2308 "float3 FogVertex(float3 surfacecolor, float3 FogColor, float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler Texture_FogMask, sampler Texture_FogHeightTexture)\n"
2311 "#ifdef USEFOGHEIGHTTEXTURE\n"
2312 " float4 fogheightpixel = tex2D(Texture_FogHeightTexture, float2(1,1) + float2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n"
2313 " fogfrac = fogheightpixel.a;\n"
2314 " return lerp(fogheightpixel.rgb * FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
2316 "# ifdef USEFOGOUTSIDE\n"
2317 " fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
2319 " fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
2321 " return lerp(FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
2326 "#ifdef USEOFFSETMAPPING\n"
2327 "float2 OffsetMapping(float2 TexCoord, float OffsetMapping_Scale, float3 EyeVector, sampler Texture_Normal)\n"
2329 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
2330 " // 14 sample relief mapping: linear search and then binary search\n"
2331 " // this basically steps forward a small amount repeatedly until it finds\n"
2332 " // itself inside solid, then jitters forward and back using decreasing\n"
2333 " // amounts to find the impact\n"
2334 " //float3 OffsetVector = float3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1), -1);\n"
2335 " //float3 OffsetVector = float3(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1), -1);\n"
2336 " float3 OffsetVector = float3(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1), -1);\n"
2337 " float3 RT = float3(TexCoord, 1);\n"
2338 " OffsetVector *= 0.1;\n"
2339 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2340 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2341 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2342 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2343 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2344 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2345 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2346 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2347 " RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
2348 " RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n"
2349 " RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n"
2350 " RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n"
2351 " RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n"
2352 " RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
2355 " // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
2356 " // this basically moves forward the full distance, and then backs up based\n"
2357 " // on height of samples\n"
2358 " //float2 OffsetVector = float2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1));\n"
2359 " //float2 OffsetVector = float2(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1));\n"
2360 " float2 OffsetVector = float2(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1));\n"
2361 " TexCoord += OffsetVector;\n"
2362 " OffsetVector *= 0.333;\n"
2363 " TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
2364 " TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
2365 " TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
2366 " return TexCoord;\n"
2369 "#endif // USEOFFSETMAPPING\n"
2371 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
2372 "#if defined(USESHADOWMAP2D)\n"
2373 "# ifdef USESHADOWMAPORTHO\n"
2374 "# define GetShadowMapTC2D(dir, ShadowMap_Parameters) (min(dir, ShadowMap_Parameters.xyz))\n"
2376 "# ifdef USESHADOWMAPVSDCT\n"
2377 "float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
2379 " float3 adir = abs(dir);\n"
2380 " float2 aparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n"
2381 " float4 proj = texCUBE(Texture_CubeProjection, dir);\n"
2382 " return float3(lerp(dir.xy, dir.zz, proj.xy) * aparams.x + proj.zw * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
2385 "float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters)\n"
2387 " float3 adir = abs(dir);\n"
2388 " float ma = adir.z;\n"
2389 " float4 proj = float4(dir, 2.5);\n"
2390 " if (adir.x > ma) { ma = adir.x; proj = float4(dir.zyx, 0.5); }\n"
2391 " if (adir.y > ma) { ma = adir.y; proj = float4(dir.xzy, 1.5); }\n"
2393 " return float3(proj.xy * ShadowMap_Parameters.x / ma + float2(0.5,0.5) + float2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, ma + 64 * ShadowMap_Parameters.w);\n"
2395 " float2 aparams = ShadowMap_Parameters.xy / ma;\n"
2396 " return float3(proj.xy * aparams.x + float2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
2401 "#endif // defined(USESHADOWMAP2D)\n"
2403 "# ifdef USESHADOWMAP2D\n"
2404 "#ifdef USESHADOWMAPVSDCT\n"
2405 "float ShadowMapCompare(float3 dir, sampler Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale, samplerCUBE Texture_CubeProjection)\n"
2407 "float ShadowMapCompare(float3 dir, sampler Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale)\n"
2410 "#ifdef USESHADOWMAPVSDCT\n"
2411 " float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters, Texture_CubeProjection);\n"
2413 " float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters);\n"
2417 "# ifdef USESHADOWSAMPLER\n"
2418 "# ifdef USESHADOWMAPPCF\n"
2419 "# define texval(x, y) tex2Dproj(Texture_ShadowMap2D, float4(center + float2(x, y)*ShadowMap_TextureScale, shadowmaptc.z, 1.0)).r \n"
2420 " float2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
2421 " f = dot(float4(0.25,0.25,0.25,0.25), float4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
2423 " f = tex2Dproj(Texture_ShadowMap2D, float4(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z, 1.0)).r;\n"
2426 "# ifdef USESHADOWMAPPCF\n"
2427 "# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
2428 "# ifdef GL_ARB_texture_gather\n"
2429 "# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, int2(x, y))\n"
2431 "# define texval(x, y) texture4(Texture_ShadowMap2D, center + float2(x, y)*ShadowMap_TextureScale)\n"
2433 " float2 offset = frac(shadowmaptc.xy - 0.5), center = (shadowmaptc.xy - offset)*ShadowMap_TextureScale;\n"
2434 "# if USESHADOWMAPPCF > 1\n"
2435 " float4 group1 = step(shadowmaptc.z, texval(-2.0, -2.0));\n"
2436 " float4 group2 = step(shadowmaptc.z, texval( 0.0, -2.0));\n"
2437 " float4 group3 = step(shadowmaptc.z, texval( 2.0, -2.0));\n"
2438 " float4 group4 = step(shadowmaptc.z, texval(-2.0, 0.0));\n"
2439 " float4 group5 = step(shadowmaptc.z, texval( 0.0, 0.0));\n"
2440 " float4 group6 = step(shadowmaptc.z, texval( 2.0, 0.0));\n"
2441 " float4 group7 = step(shadowmaptc.z, texval(-2.0, 2.0));\n"
2442 " float4 group8 = step(shadowmaptc.z, texval( 0.0, 2.0));\n"
2443 " float4 group9 = step(shadowmaptc.z, texval( 2.0, 2.0));\n"
2444 " float4 locols = float4(group1.ab, group3.ab);\n"
2445 " float4 hicols = float4(group7.rg, group9.rg);\n"
2446 " locols.yz += group2.ab;\n"
2447 " hicols.yz += group8.rg;\n"
2448 " float4 midcols = float4(group1.rg, group3.rg) + float4(group7.ab, group9.ab) +\n"
2449 " float4(group4.rg, group6.rg) + float4(group4.ab, group6.ab) +\n"
2450 " lerp(locols, hicols, offset.y);\n"
2451 " float4 cols = group5 + float4(group2.rg, group8.ab);\n"
2452 " cols.xyz += lerp(midcols.xyz, midcols.yzw, offset.x);\n"
2453 " f = dot(cols, float4(1.0/25.0));\n"
2455 " float4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
2456 " float4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
2457 " float4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
2458 " float4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
2459 " float4 cols = float4(group1.rg, group2.rg) + float4(group3.ab, group4.ab) +\n"
2460 " lerp(float4(group1.ab, group2.ab), float4(group3.rg, group4.rg), offset.y);\n"
2461 " f = dot(lerp(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
2464 "# ifdef GL_EXT_gpu_shader4\n"
2465 "# define texval(x, y) tex2DOffset(Texture_ShadowMap2D, center, int2(x, y)).r\n"
2467 "# define texval(x, y) texDepth2D(Texture_ShadowMap2D, center + float2(x, y)*ShadowMap_TextureScale).r \n"
2469 "# if USESHADOWMAPPCF > 1\n"
2470 " float2 center = shadowmaptc.xy - 0.5, offset = frac(center);\n"
2471 " center *= ShadowMap_TextureScale;\n"
2472 " float4 row1 = step(shadowmaptc.z, float4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
2473 " float4 row2 = step(shadowmaptc.z, float4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
2474 " float4 row3 = step(shadowmaptc.z, float4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
2475 " float4 row4 = step(shadowmaptc.z, float4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
2476 " float4 cols = row2 + row3 + lerp(row1, row4, offset.y);\n"
2477 " f = dot(lerp(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
2479 " float2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = frac(shadowmaptc.xy);\n"
2480 " float3 row1 = step(shadowmaptc.z, float3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
2481 " float3 row2 = step(shadowmaptc.z, float3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
2482 " float3 row3 = step(shadowmaptc.z, float3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
2483 " float3 cols = row2 + lerp(row1, row3, offset.y);\n"
2484 " f = dot(lerp(cols.xy, cols.yz, offset.x), float2(0.25,0.25));\n"
2488 " f = step(shadowmaptc.z, tex2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
2491 "# ifdef USESHADOWMAPORTHO\n"
2492 " return lerp(ShadowMap_Parameters.w, 1.0, f);\n"
2498 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
2499 "#endif // FRAGMENT_SHADER\n"
2504 "#ifdef MODE_DEFERREDGEOMETRY\n"
2505 "#ifdef VERTEX_SHADER\n"
2508 "float4 gl_Vertex : POSITION,\n"
2509 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
2510 "#ifdef USEVERTEXTEXTUREBLEND\n"
2511 "float4 gl_Color : COLOR0,\n"
2513 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
2514 "float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
2515 "float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
2516 "float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
2517 "uniform float4x4 TexMatrix : register(c0),\n"
2518 "#ifdef USEVERTEXTEXTUREBLEND\n"
2519 "uniform float4x4 BackgroundTexMatrix : register(c4),\n"
2521 "uniform float4x4 ModelViewMatrix : register(c12),\n"
2522 "#ifdef USEOFFSETMAPPING\n"
2523 "uniform float3 EyePosition : register(c24),\n"
2525 "out float4 gl_Position : POSITION,\n"
2526 "#ifdef USEVERTEXTEXTUREBLEND\n"
2527 "out float4 gl_FrontColor : COLOR,\n"
2529 "out float4 TexCoordBoth : TEXCOORD0,\n"
2530 "#ifdef USEOFFSETMAPPING\n"
2531 "out float3 EyeVector : TEXCOORD2,\n"
2533 "out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
2534 "out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
2535 "out float4 VectorR : TEXCOORD7 // direction of R texcoord (surface normal), Depth value\n"
2538 " TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
2539 "#ifdef USEVERTEXTEXTUREBLEND\n"
2541 " gl_FrontColor = gl_Color.bgra; // NOTE: D3DCOLOR is backwards\n"
2543 " gl_FrontColor = gl_Color; // Cg is forward\n"
2545 " TexCoordBoth.zw = float2(Backgroundmul(TexMatrix, gl_MultiTexCoord0));\n"
2548 " // transform unnormalized eye direction into tangent space\n"
2549 "#ifdef USEOFFSETMAPPING\n"
2550 " float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
2551 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
2552 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
2553 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
2556 " VectorS = mul(ModelViewMatrix, float4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
2557 " VectorT = mul(ModelViewMatrix, float4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
2558 " VectorR.xyz = mul(ModelViewMatrix, float4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
2559 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
2560 " VectorR.w = gl_Position.z;\n"
2562 "#endif // VERTEX_SHADER\n"
2564 "#ifdef FRAGMENT_SHADER\n"
2567 "float4 TexCoordBoth : TEXCOORD0,\n"
2568 "float3 EyeVector : TEXCOORD2,\n"
2569 "float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
2570 "float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
2571 "float4 VectorR : TEXCOORD7, // direction of R texcoord (surface normal), Depth value\n"
2572 "uniform sampler Texture_Normal : register(s0),\n"
2573 "#ifdef USEALPHAKILL\n"
2574 "uniform sampler Texture_Color : register(s1),\n"
2576 "uniform sampler Texture_Gloss : register(s2),\n"
2577 "#ifdef USEVERTEXTEXTUREBLEND\n"
2578 "uniform sampler Texture_SecondaryNormal : register(s4),\n"
2579 "uniform sampler Texture_SecondaryGloss : register(s6),\n"
2581 "#ifdef USEOFFSETMAPPING\n"
2582 "uniform float OffsetMapping_Scale : register(c24),\n"
2584 "uniform half SpecularPower : register(c36),\n"
2586 "out float4 gl_FragData0 : COLOR0,\n"
2587 "out float4 gl_FragData1 : COLOR1\n"
2589 "out float4 gl_FragColor : COLOR\n"
2593 " float2 TexCoord = TexCoordBoth.xy;\n"
2594 "#ifdef USEOFFSETMAPPING\n"
2595 " // apply offsetmapping\n"
2596 " float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
2597 "#define TexCoord TexCoordOffset\n"
2600 "#ifdef USEALPHAKILL\n"
2601 " if (tex2D(Texture_Color, TexCoord).a < 0.5)\n"
2605 "#ifdef USEVERTEXTEXTUREBLEND\n"
2606 " float alpha = tex2D(Texture_Color, TexCoord).a;\n"
2607 " float terrainblend = clamp(float(gl_FrontColor.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
2608 " //float terrainblend = min(float(gl_FrontColor.a) * alpha * 2.0, float(1.0));\n"
2609 " //float terrainblend = float(gl_FrontColor.a) * alpha > 0.5;\n"
2612 "#ifdef USEVERTEXTEXTUREBLEND\n"
2613 " float3 surfacenormal = lerp(tex2D(Texture_SecondaryNormal, TexCoord2).rgb, tex2D(Texture_Normal, TexCoord).rgb, terrainblend) - float3(0.5, 0.5, 0.5);\n"
2614 " float a = lerp(tex2D(Texture_SecondaryGloss, TexCoord2).a, tex2D(Texture_Gloss, TexCoord).a, terrainblend);\n"
2616 " float3 surfacenormal = tex2D(Texture_Normal, TexCoord).rgb - float3(0.5, 0.5, 0.5);\n"
2617 " float a = tex2D(Texture_Gloss, TexCoord).a;\n"
2621 " gl_FragData0 = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR.xyz) * 0.5 + float3(0.5, 0.5, 0.5), a);\n"
2622 " float Depth = VectorR.w / 256.0;\n"
2623 " float4 depthcolor = float4(Depth,Depth*65536.0/255.0,Depth*16777216.0/255.0,0.0);\n"
2624 "// float4 depthcolor = float4(Depth,Depth*256.0,Depth*65536.0,0.0);\n"
2625 " depthcolor.yz -= floor(depthcolor.yz);\n"
2626 " gl_FragData1 = depthcolor;\n"
2628 " gl_FragColor = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + float3(0.5, 0.5, 0.5), a);\n"
2631 "#endif // FRAGMENT_SHADER\n"
2632 "#else // !MODE_DEFERREDGEOMETRY\n"
2637 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
2638 "#ifdef VERTEX_SHADER\n"
2641 "float4 gl_Vertex : POSITION,\n"
2642 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
2643 "uniform float4x4 ModelViewMatrix : register(c12),\n"
2644 "out float4 gl_Position : POSITION,\n"
2645 "out float4 ModelViewPosition : TEXCOORD0\n"
2648 " ModelViewPosition = mul(ModelViewMatrix, gl_Vertex);\n"
2649 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
2651 "#endif // VERTEX_SHADER\n"
2653 "#ifdef FRAGMENT_SHADER\n"
2657 "float2 Pixel : VPOS,\n"
2659 "float2 Pixel : WPOS,\n"
2661 "float4 ModelViewPosition : TEXCOORD0,\n"
2662 "uniform float4x4 ViewToLight : register(c44),\n"
2663 "uniform float2 ScreenToDepth : register(c33), // ScreenToDepth = float2(Far / (Far - Near), Far * Near / (Near - Far));\n"
2664 "uniform float3 LightPosition : register(c23),\n"
2665 "uniform half2 PixelToScreenTexCoord : register(c42),\n"
2666 "uniform half3 DeferredColor_Ambient : register(c9),\n"
2667 "uniform half3 DeferredColor_Diffuse : register(c10),\n"
2668 "#ifdef USESPECULAR\n"
2669 "uniform half3 DeferredColor_Specular : register(c11),\n"
2670 "uniform half SpecularPower : register(c36),\n"
2672 "uniform sampler Texture_Attenuation : register(s9),\n"
2673 "uniform sampler Texture_ScreenDepth : register(s13),\n"
2674 "uniform sampler Texture_ScreenNormalMap : register(s14),\n"
2676 "#ifdef USECUBEFILTER\n"
2677 "uniform samplerCUBE Texture_Cube : register(s10),\n"
2680 "#ifdef USESHADOWMAP2D\n"
2681 "# ifdef USESHADOWSAMPLER\n"
2682 "uniform sampler Texture_ShadowMap2D : register(s15),\n"
2684 "uniform sampler Texture_ShadowMap2D : register(s15),\n"
2688 "#ifdef USESHADOWMAPVSDCT\n"
2689 "uniform samplerCUBE Texture_CubeProjection : register(s12),\n"
2692 "#if defined(USESHADOWMAP2D)\n"
2693 "uniform float2 ShadowMap_TextureScale : register(c35),\n"
2694 "uniform float4 ShadowMap_Parameters : register(c34),\n"
2697 "out float4 gl_FragData0 : COLOR0,\n"
2698 "out float4 gl_FragData1 : COLOR1\n"
2701 " // calculate viewspace pixel position\n"
2702 " float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n"
2703 " //ScreenTexCoord.y = ScreenTexCoord.y * -1 + 1; // Cg is opposite?\n"
2704 " float3 position;\n"
2706 " position.z = texDepth2D(Texture_ScreenDepth, ScreenTexCoord) * 256.0;\n"
2708 " position.z = ScreenToDepth.y / (texDepth2D(Texture_ScreenDepth, ScreenTexCoord) + ScreenToDepth.x);\n"
2710 " position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
2711 " // decode viewspace pixel normal\n"
2712 " half4 normalmap = half4(tex2D(Texture_ScreenNormalMap, ScreenTexCoord));\n"
2713 " half3 surfacenormal = half3(normalize(normalmap.rgb - half3(0.5,0.5,0.5)));\n"
2714 " // surfacenormal = pixel normal in viewspace\n"
2715 " // LightVector = pixel to light in viewspace\n"
2716 " // CubeVector = position in lightspace\n"
2717 " // eyevector = pixel to view in viewspace\n"
2718 " float3 CubeVector = mul(ViewToLight, float4(position,1)).xyz;\n"
2719 " half fade = half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)).r);\n"
2720 "#ifdef USEDIFFUSE\n"
2721 " // calculate diffuse shading\n"
2722 " half3 lightnormal = half3(normalize(LightPosition - position));\n"
2723 " half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
2725 "#ifdef USESPECULAR\n"
2726 " // calculate directional shading\n"
2727 " float3 eyevector = position * -1.0;\n"
2728 "# ifdef USEEXACTSPECULARMATH\n"
2729 " half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a));\n"
2731 " half3 specularnormal = half3(normalize(lightnormal + half3(normalize(eyevector))));\n"
2732 " half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a));\n"
2736 "#if defined(USESHADOWMAP2D)\n"
2737 " fade *= half(ShadowMapCompare(CubeVector, Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
2738 "#ifdef USESHADOWMAPVSDCT\n"
2739 ", Texture_CubeProjection\n"
2744 "#ifdef USEDIFFUSE\n"
2745 " gl_FragData0 = float4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
2747 " gl_FragData0 = float4(DeferredColor_Ambient * fade, 1.0);\n"
2749 "#ifdef USESPECULAR\n"
2750 " gl_FragData1 = float4(DeferredColor_Specular * (specular * fade), 1.0);\n"
2752 " gl_FragData1 = float4(0.0, 0.0, 0.0, 1.0);\n"
2755 "# ifdef USECUBEFILTER\n"
2756 " float3 cubecolor = texCUBE(Texture_Cube, CubeVector).rgb;\n"
2757 " gl_FragData0.rgb *= cubecolor;\n"
2758 " gl_FragData1.rgb *= cubecolor;\n"
2761 "#endif // FRAGMENT_SHADER\n"
2762 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
2767 "#ifdef VERTEX_SHADER\n"
2770 "float4 gl_Vertex : POSITION,\n"
2771 "uniform float4x4 ModelViewProjectionMatrix : register(c8),\n"
2772 "#if defined(USEVERTEXTEXTUREBLEND) || defined(MODE_VERTEXCOLOR)\n"
2773 "float4 gl_Color : COLOR0,\n"
2775 "float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
2776 "float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
2777 "float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
2778 "float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
2779 "float4 gl_MultiTexCoord4 : TEXCOORD4,\n"
2781 "uniform float3 EyePosition : register(c24),\n"
2782 "uniform float4x4 TexMatrix : register(c0),\n"
2783 "#ifdef USEVERTEXTEXTUREBLEND\n"
2784 "uniform float4x4 BackgroundTexMatrix : register(c4),\n"
2786 "#ifdef MODE_LIGHTSOURCE\n"
2787 "uniform float4x4 ModelToLight : register(c20),\n"
2789 "#ifdef MODE_LIGHTSOURCE\n"
2790 "uniform float3 LightPosition : register(c27),\n"
2792 "#ifdef MODE_LIGHTDIRECTION\n"
2793 "uniform float3 LightDir : register(c26),\n"
2795 "uniform float4 FogPlane : register(c25),\n"
2796 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
2797 "uniform float3 LightPosition : register(c27),\n"
2799 "#ifdef USESHADOWMAPORTHO\n"
2800 "uniform float4x4 ShadowMapMatrix : register(c16),\n"
2802 "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
2803 "out float4 gl_FrontColor : COLOR,\n"
2805 "out float4 TexCoordBoth : TEXCOORD0,\n"
2806 "#ifdef USELIGHTMAP\n"
2807 "out float2 TexCoordLightmap : TEXCOORD1,\n"
2809 "#ifdef USEEYEVECTOR\n"
2810 "out float3 EyeVector : TEXCOORD2,\n"
2812 "#ifdef USEREFLECTION\n"
2813 "out float4 ModelViewProjectionPosition : TEXCOORD3,\n"
2816 "out float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
2818 "#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE) || defined(USEDIFFUSE)\n"
2819 "out float3 LightVector : TEXCOORD1,\n"
2821 "#ifdef MODE_LIGHTSOURCE\n"
2822 "out float3 CubeVector : TEXCOORD3,\n"
2824 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n"
2825 "out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
2826 "out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
2827 "out float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
2829 "#ifdef USESHADOWMAPORTHO\n"
2830 "out float3 ShadowMapTC : TEXCOORD3, // CONFLICTS WITH USEREFLECTION!\n"
2832 "out float4 gl_Position : POSITION\n"
2835 "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
2837 " gl_FrontColor = gl_Color.bgra; // NOTE: D3DCOLOR is backwards\n"
2839 " gl_FrontColor = gl_Color; // Cg is forward\n"
2842 " // copy the surface texcoord\n"
2843 " TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
2844 "#ifdef USEVERTEXTEXTUREBLEND\n"
2845 " TexCoordBoth.zw = mul(BackgroundTexMatrix, gl_MultiTexCoord0).xy;\n"
2847 "#ifdef USELIGHTMAP\n"
2848 " TexCoordLightmap = gl_MultiTexCoord4.xy;\n"
2851 "#ifdef MODE_LIGHTSOURCE\n"
2852 " // transform vertex position into light attenuation/cubemap space\n"
2853 " // (-1 to +1 across the light box)\n"
2854 " CubeVector = mul(ModelToLight, gl_Vertex).xyz;\n"
2856 "# ifdef USEDIFFUSE\n"
2857 " // transform unnormalized light direction into tangent space\n"
2858 " // (we use unnormalized to ensure that it interpolates correctly and then\n"
2859 " // normalize it per pixel)\n"
2860 " float3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
2861 " LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
2862 " LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
2863 " LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
2867 "#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
2868 " LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
2869 " LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
2870 " LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
2873 " // transform unnormalized eye direction into tangent space\n"
2874 "#ifdef USEEYEVECTOR\n"
2875 " float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
2876 " EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
2877 " EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
2878 " EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
2882 " EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
2883 " EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
2886 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
2887 " VectorS = gl_MultiTexCoord1.xyz;\n"
2888 " VectorT = gl_MultiTexCoord2.xyz;\n"
2889 " VectorR = gl_MultiTexCoord3.xyz;\n"
2892 " // transform vertex to camera space, using ftransform to match non-VS rendering\n"
2893 " gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
2895 "#ifdef USESHADOWMAPORTHO\n"
2896 " ShadowMapTC = mul(ShadowMapMatrix, gl_Position).xyz;\n"
2899 "#ifdef USEREFLECTION\n"
2900 " ModelViewProjectionPosition = gl_Position;\n"
2903 "#endif // VERTEX_SHADER\n"
2908 "#ifdef FRAGMENT_SHADER\n"
2911 "#ifdef USEDEFERREDLIGHTMAP\n"
2913 "float2 Pixel : VPOS,\n"
2915 "float2 Pixel : WPOS,\n"
2918 "float4 gl_FrontColor : COLOR,\n"
2919 "float4 TexCoordBoth : TEXCOORD0,\n"
2920 "#ifdef USELIGHTMAP\n"
2921 "float2 TexCoordLightmap : TEXCOORD1,\n"
2923 "#ifdef USEEYEVECTOR\n"
2924 "float3 EyeVector : TEXCOORD2,\n"
2926 "#ifdef USEREFLECTION\n"
2927 "float4 ModelViewProjectionPosition : TEXCOORD3,\n"
2930 "float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
2932 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
2933 "float3 LightVector : TEXCOORD1,\n"
2935 "#ifdef MODE_LIGHTSOURCE\n"
2936 "float3 CubeVector : TEXCOORD3,\n"
2938 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
2939 "float4 ModelViewPosition : TEXCOORD0,\n"
2941 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n"
2942 "float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
2943 "float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
2944 "float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
2946 "#ifdef USESHADOWMAPORTHO\n"
2947 "float3 ShadowMapTC : TEXCOORD3, // CONFLICTS WITH USEREFLECTION!\n"
2950 "uniform sampler Texture_Normal : register(s0),\n"
2951 "uniform sampler Texture_Color : register(s1),\n"
2952 "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
2953 "uniform sampler Texture_Gloss : register(s2),\n"
2956 "uniform sampler Texture_Glow : register(s3),\n"
2958 "#ifdef USEVERTEXTEXTUREBLEND\n"
2959 "uniform sampler Texture_SecondaryNormal : register(s4),\n"
2960 "uniform sampler Texture_SecondaryColor : register(s5),\n"
2961 "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
2962 "uniform sampler Texture_SecondaryGloss : register(s6),\n"
2965 "uniform sampler Texture_SecondaryGlow : register(s7),\n"
2968 "#ifdef USECOLORMAPPING\n"
2969 "uniform sampler Texture_Pants : register(s4),\n"
2970 "uniform sampler Texture_Shirt : register(s7),\n"
2973 "uniform sampler Texture_FogHeightTexture : register(s14),\n"
2974 "uniform sampler Texture_FogMask : register(s8),\n"
2976 "#ifdef USELIGHTMAP\n"
2977 "uniform sampler Texture_Lightmap : register(s9),\n"
2979 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
2980 "uniform sampler Texture_Deluxemap : register(s10),\n"
2982 "#ifdef USEREFLECTION\n"
2983 "uniform sampler Texture_Reflection : register(s7),\n"
2986 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
2987 "uniform sampler Texture_ScreenDepth : register(s13),\n"
2988 "uniform sampler Texture_ScreenNormalMap : register(s14),\n"
2990 "#ifdef USEDEFERREDLIGHTMAP\n"
2991 "uniform sampler Texture_ScreenDepth : register(s13),\n"
2992 "uniform sampler Texture_ScreenNormalMap : register(s14),\n"
2993 "uniform sampler Texture_ScreenDiffuse : register(s11),\n"
2994 "uniform sampler Texture_ScreenSpecular : register(s12),\n"
2997 "#ifdef USECOLORMAPPING\n"
2998 "uniform half3 Color_Pants : register(c7),\n"
2999 "uniform half3 Color_Shirt : register(c8),\n"
3002 "uniform float3 FogColor : register(c16),\n"
3003 "uniform float FogRangeRecip : register(c20),\n"
3004 "uniform float FogPlaneViewDist : register(c19),\n"
3005 "uniform float FogHeightFade : register(c17),\n"
3008 "#ifdef USEOFFSETMAPPING\n"
3009 "uniform float OffsetMapping_Scale : register(c24),\n"
3012 "#ifdef USEDEFERREDLIGHTMAP\n"
3013 "uniform half2 PixelToScreenTexCoord : register(c42),\n"
3014 "uniform half3 DeferredMod_Diffuse : register(c12),\n"
3015 "uniform half3 DeferredMod_Specular : register(c13),\n"
3017 "uniform half3 Color_Ambient : register(c3),\n"
3018 "uniform half3 Color_Diffuse : register(c4),\n"
3019 "uniform half3 Color_Specular : register(c5),\n"
3020 "uniform half SpecularPower : register(c36),\n"
3022 "uniform half3 Color_Glow : register(c6),\n"
3024 "uniform half Alpha : register(c0),\n"
3025 "#ifdef USEREFLECTION\n"
3026 "uniform float4 DistortScaleRefractReflect : register(c14),\n"
3027 "uniform float4 ScreenScaleRefractReflect : register(c32),\n"
3028 "uniform float4 ScreenCenterRefractReflect : register(c31),\n"
3029 "uniform half4 ReflectColor : register(c26),\n"
3031 "#ifdef USEREFLECTCUBE\n"
3032 "uniform float4x4 ModelToReflectCube : register(c48),\n"
3033 "uniform sampler Texture_ReflectMask : register(s5),\n"
3034 "uniform samplerCUBE Texture_ReflectCube : register(s6),\n"
3036 "#ifdef MODE_LIGHTDIRECTION\n"
3037 "uniform half3 LightColor : register(c21),\n"
3039 "#ifdef MODE_LIGHTSOURCE\n"
3040 "uniform half3 LightColor : register(c21),\n"
3043 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
3044 "uniform sampler Texture_Attenuation : register(s9),\n"
3045 "uniform samplerCUBE Texture_Cube : register(s10),\n"
3048 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
3050 "#ifdef USESHADOWMAP2D\n"
3051 "# ifdef USESHADOWSAMPLER\n"
3052 "uniform sampler Texture_ShadowMap2D : register(s15),\n"
3054 "uniform sampler Texture_ShadowMap2D : register(s15),\n"
3058 "#ifdef USESHADOWMAPVSDCT\n"
3059 "uniform samplerCUBE Texture_CubeProjection : register(s12),\n"
3062 "#if defined(USESHADOWMAP2D)\n"
3063 "uniform float2 ShadowMap_TextureScale : register(c35),\n"
3064 "uniform float4 ShadowMap_Parameters : register(c34),\n"
3066 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
3068 "out float4 gl_FragColor : COLOR\n"
3071 " float2 TexCoord = TexCoordBoth.xy;\n"
3072 "#ifdef USEVERTEXTEXTUREBLEND\n"
3073 " float2 TexCoord2 = TexCoordBoth.zw;\n"
3075 "#ifdef USEOFFSETMAPPING\n"
3076 " // apply offsetmapping\n"
3077 " float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
3078 "#define TexCoord TexCoordOffset\n"
3081 " // combine the diffuse textures (base, pants, shirt)\n"
3082 " half4 color = half4(tex2D(Texture_Color, TexCoord));\n"
3083 "#ifdef USEALPHAKILL\n"
3084 " if (color.a < 0.5)\n"
3087 " color.a *= Alpha;\n"
3088 "#ifdef USECOLORMAPPING\n"
3089 " color.rgb += half3(tex2D(Texture_Pants, TexCoord).rgb) * Color_Pants + half3(tex2D(Texture_Shirt, TexCoord).rgb) * Color_Shirt;\n"
3091 "#ifdef USEVERTEXTEXTUREBLEND\n"
3092 " half terrainblend = clamp(half(gl_FrontColor.a) * color.a * 2.0 - 0.5, half(0.0), half(1.0));\n"
3093 " //half terrainblend = min(half(gl_FrontColor.a) * color.a * 2.0, half(1.0));\n"
3094 " //half terrainblend = half(gl_FrontColor.a) * color.a > 0.5;\n"
3095 " color.rgb = half3(lerp(tex2D(Texture_SecondaryColor, TexCoord2).rgb, float3(color.rgb), terrainblend));\n"
3097 " //color = half4(lerp(float4(1, 0, 0, 1), color, terrainblend));\n"
3100 " // get the surface normal\n"
3101 "#ifdef USEVERTEXTEXTUREBLEND\n"
3102 " half3 surfacenormal = normalize(half3(lerp(tex2D(Texture_SecondaryNormal, TexCoord2).rgb, tex2D(Texture_Normal, TexCoord).rgb, terrainblend)) - half3(0.5, 0.5, 0.5));\n"
3104 " half3 surfacenormal = half3(normalize(half3(tex2D(Texture_Normal, TexCoord).rgb) - half3(0.5, 0.5, 0.5)));\n"
3107 " // get the material colors\n"
3108 " half3 diffusetex = color.rgb;\n"
3109 "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
3110 "# ifdef USEVERTEXTEXTUREBLEND\n"
3111 " half4 glosstex = half4(lerp(tex2D(Texture_SecondaryGloss, TexCoord2), tex2D(Texture_Gloss, TexCoord), terrainblend));\n"
3113 " half4 glosstex = half4(tex2D(Texture_Gloss, TexCoord));\n"
3117 "#ifdef USEREFLECTCUBE\n"
3118 " float3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n"
3119 " float3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n"
3120 " float3 ReflectCubeTexCoord = mul(ModelToReflectCube, float4(ModelReflectVector, 0)).xyz;\n"
3121 " diffusetex += half3(tex2D(Texture_ReflectMask, TexCoord).rgb) * half3(texCUBE(Texture_ReflectCube, ReflectCubeTexCoord).rgb);\n"
3127 "#ifdef MODE_LIGHTSOURCE\n"
3128 " // light source\n"
3129 "#ifdef USEDIFFUSE\n"
3130 " half3 lightnormal = half3(normalize(LightVector));\n"
3131 " half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
3132 " color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
3133 "#ifdef USESPECULAR\n"
3134 "#ifdef USEEXACTSPECULARMATH\n"
3135 " half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a));\n"
3137 " half3 specularnormal = half3(normalize(lightnormal + half3(normalize(EyeVector))));\n"
3138 " half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a));\n"
3140 " color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
3143 " color.rgb = diffusetex * Color_Ambient;\n"
3145 " color.rgb *= LightColor;\n"
3146 " color.rgb *= half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)).r);\n"
3147 "#if defined(USESHADOWMAP2D)\n"
3148 " color.rgb *= half(ShadowMapCompare(CubeVector, Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
3149 "#ifdef USESHADOWMAPVSDCT\n"
3150 ", Texture_CubeProjection\n"
3155 "# ifdef USECUBEFILTER\n"
3156 " color.rgb *= half3(texCUBE(Texture_Cube, CubeVector).rgb);\n"
3159 "#ifdef USESHADOWMAP2D\n"
3160 "#ifdef USESHADOWMAPVSDCT\n"
3161 "// float3 shadowmaptc = GetShadowMapTC2D(CubeVector, ShadowMap_Parameters, Texture_CubeProjection);\n"
3163 "// float3 shadowmaptc = GetShadowMapTC2D(CubeVector, ShadowMap_Parameters);\n"
3165 "// color.rgb = half3(tex2D(Texture_ShadowMap2D, float2(0.1,0.1)).rgb);\n"
3166 "// color.rgb = half3(tex2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale).rgb);\n"
3167 "// color.rgb = half3(shadowmaptc.xyz * float3(ShadowMap_TextureScale,1.0));\n"
3168 "// color.r = half(texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
3169 "// color.rgb = half3(tex2D(Texture_ShadowMap2D, float2(0.1,0.1)).rgb);\n"
3170 "// color.rgb = half3(tex2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale).rgb);\n"
3171 "// color.rgb = half3(shadowmaptc.xyz * float3(ShadowMap_TextureScale,1.0));\n"
3172 "// color.r = half(texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
3173 "// color.r = half(shadowmaptc.z - texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
3174 "// color.r = half(shadowmaptc.z);\n"
3175 "// color.r = half(texDepth2D(Texture_ShadowMap2D, shadowmaptc.xy * ShadowMap_TextureScale));\n"
3176 "// color.r = half(shadowmaptc.z);\n"
3178 "// color.rgb = abs(CubeVector);\n"
3180 "// color.rgb = half3(1,1,1);\n"
3181 "#endif // MODE_LIGHTSOURCE\n"
3186 "#ifdef MODE_LIGHTDIRECTION\n"
3188 "#ifdef USEDIFFUSE\n"
3189 " half3 lightnormal = half3(normalize(LightVector));\n"
3191 "#define lightcolor LightColor\n"
3192 "#endif // MODE_LIGHTDIRECTION\n"
3193 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
3195 " // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
3196 " half3 lightnormal_modelspace = half3(tex2D(Texture_Deluxemap, TexCoordLightmap).rgb) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
3197 " half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap).rgb);\n"
3198 " // convert modelspace light vector to tangentspace\n"
3199 " half3 lightnormal;\n"
3200 " lightnormal.x = dot(lightnormal_modelspace, half3(VectorS));\n"
3201 " lightnormal.y = dot(lightnormal_modelspace, half3(VectorT));\n"
3202 " lightnormal.z = dot(lightnormal_modelspace, half3(VectorR));\n"
3203 " // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
3204 " // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
3205 " // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
3206 " // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
3207 " // to map the luxels to coordinates on the draw surfaces), which also causes\n"
3208 " // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
3209 " // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
3210 " // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
3211 " // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
3212 " lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
3213 "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
3214 "#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
3216 " // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
3217 " half3 lightnormal = half3(tex2D(Texture_Deluxemap, TexCoordLightmap).rgb) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
3218 " half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap).rgb);\n"
3224 "#ifdef MODE_FAKELIGHT\n"
3226 "half3 lightnormal = half3(normalize(EyeVector));\n"
3227 "half3 lightcolor = half3(1.0,1.0,1.0);\n"
3228 "#endif // MODE_FAKELIGHT\n"
3233 "#ifdef MODE_LIGHTMAP\n"
3234 " color.rgb = diffusetex * (Color_Ambient + half3(tex2D(Texture_Lightmap, TexCoordLightmap).rgb) * Color_Diffuse);\n"
3235 "#endif // MODE_LIGHTMAP\n"
3236 "#ifdef MODE_VERTEXCOLOR\n"
3237 " color.rgb = diffusetex * (Color_Ambient + half3(gl_FrontColor.rgb) * Color_Diffuse);\n"
3238 "#endif // MODE_VERTEXCOLOR\n"
3239 "#ifdef MODE_FLATCOLOR\n"
3240 " color.rgb = diffusetex * Color_Ambient;\n"
3241 "#endif // MODE_FLATCOLOR\n"
3247 "# ifdef USEDIFFUSE\n"
3248 " half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
3249 "# ifdef USESPECULAR\n"
3250 "# ifdef USEEXACTSPECULARMATH\n"
3251 " half specular = half(pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a));\n"
3253 " half3 specularnormal = half3(normalize(lightnormal + half3(normalize(EyeVector))));\n"
3254 " half specular = half(pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a));\n"
3256 " color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
3258 " color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
3261 " color.rgb = diffusetex * Color_Ambient;\n"
3265 "#ifdef USESHADOWMAPORTHO\n"
3266 " color.rgb *= half(ShadowMapCompare(ShadowMapTC, Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale));\n"
3269 "#ifdef USEDEFERREDLIGHTMAP\n"
3270 " float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n"
3271 " color.rgb += diffusetex * half3(tex2D(Texture_ScreenDiffuse, ScreenTexCoord).rgb) * DeferredMod_Diffuse;\n"
3272 " color.rgb += glosstex.rgb * half3(tex2D(Texture_ScreenSpecular, ScreenTexCoord).rgb) * DeferredMod_Specular;\n"
3273 "// color.rgb = half3(tex2D(Texture_ScreenDepth, ScreenTexCoord).rgb);\n"
3274 "// color.r = half(texDepth2D(Texture_ScreenDepth, ScreenTexCoord)) * 1.0;\n"
3278 "#ifdef USEVERTEXTEXTUREBLEND\n"
3279 " color.rgb += half3(lerp(tex2D(Texture_SecondaryGlow, TexCoord2).rgb, tex2D(Texture_Glow, TexCoord).rgb, terrainblend)) * Color_Glow;\n"
3281 " color.rgb += half3(tex2D(Texture_Glow, TexCoord).rgb) * Color_Glow;\n"
3286 " color.rgb = FogVertex(color.rgb, FogColor, EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask, Texture_FogHeightTexture);\n"
3289 " // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
3290 "#ifdef USEREFLECTION\n"
3291 " float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
3292 " //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(half3(tex2D(Texture_Normal, TexCoord).rgb) - half3(0.5,0.5,0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
3293 " float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
3294 " float2 ScreenTexCoord = SafeScreenTexCoord + float3(normalize(half3(tex2D(Texture_Normal, TexCoord).rgb) - half3(0.5,0.5,0.5))).xy * DistortScaleRefractReflect.zw;\n"
3295 " // FIXME temporary hack to detect the case that the reflection\n"
3296 " // gets blackened at edges due to leaving the area that contains actual\n"
3298 " // Remove this 'ack once we have a better way to stop this thing from\n"
3300 " float f = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
3301 " f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
3302 " f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
3303 " f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
3304 " ScreenTexCoord = lerp(SafeScreenTexCoord, ScreenTexCoord, f);\n"
3305 " color.rgb = lerp(color.rgb, half3(tex2D(Texture_Reflection, ScreenTexCoord).rgb) * ReflectColor.rgb, ReflectColor.a);\n"
3308 " gl_FragColor = float4(color);\n"
3310 "#endif // FRAGMENT_SHADER\n"
3312 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
3313 "#endif // !MODE_DEFERREDGEOMETRY\n"
3314 "#endif // !MODE_WATER\n"
3315 "#endif // !MODE_REFRACTION\n"
3316 "#endif // !MODE_BLOOMBLUR\n"
3317 "#endif // !MODE_GENERIC\n"
3318 "#endif // !MODE_POSTPROCESS\n"
3319 "#endif // !MODE_SHOWDEPTH\n"
3320 "#endif // !MODE_DEPTH_OR_SHADOW\n"
3324 =========================================================================================================================================================
3328 =========================================================================================================================================================
3332 =========================================================================================================================================================
3336 =========================================================================================================================================================
3340 =========================================================================================================================================================
3344 =========================================================================================================================================================
3348 =========================================================================================================================================================
3351 const char *builtingles2shaderstring =
3352 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
3353 "// written by Forest 'LordHavoc' Hale\n"
3354 "// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
3356 "#ifdef VERTEX_SHADER\n"
3357 "attribute vec4 Attrib_Position;\n"
3358 "attribute vec4 Attrib_Color;\n"
3359 "attribute vec4 Attrib_TexCoord0;\n"
3360 "attribute vec3 Attrib_TexCoord1;\n"
3361 "attribute vec3 Attrib_TexCoord2;\n"
3362 "attribute vec3 Attrib_TexCoord3;\n"
3363 "attribute vec4 Attrib_TexCoord4;\n"
3365 "varying lowp vec4 VertexColor;\n"
3367 "#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE) || defined(USEFOGHEIGHTTEXTURE)\n"
3370 "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
3371 "#define USELIGHTMAP\n"
3373 "#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n"
3374 "#define USEEYEVECTOR\n"
3377 "#ifdef USESHADOWMAP2D\n"
3378 "# ifdef GL_EXT_gpu_shader4\n"
3379 "# extension GL_EXT_gpu_shader4 : enable\n"
3381 "# ifdef GL_ARB_texture_gather\n"
3382 "# extension GL_ARB_texture_gather : enable\n"
3384 "# ifdef GL_AMD_texture_texture4\n"
3385 "# extension GL_AMD_texture_texture4 : enable\n"
3390 "//#ifdef USESHADOWSAMPLER\n"
3391 "//# extension GL_ARB_shadow : enable\n"
3394 "//#ifdef __GLSL_CG_DATA_TYPES\n"
3395 "//# define myhalf half\n"
3396 "//# define myhalf2 half2\n"
3397 "//# define myhalf3 half3\n"
3398 "//# define myhalf4 half4\n"
3400 "# define myhalf mediump float\n"
3401 "# define myhalf2 mediump vec2\n"
3402 "# define myhalf3 mediump vec3\n"
3403 "# define myhalf4 mediump vec4\n"
3406 "#ifdef VERTEX_SHADER\n"
3407 "uniform highp mat4 ModelViewProjectionMatrix;\n"
3410 "#ifdef MODE_DEPTH_OR_SHADOW\n"
3411 "#ifdef VERTEX_SHADER\n"
3414 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
3417 "#else // !MODE_DEPTH_ORSHADOW\n"
3422 "#ifdef MODE_SHOWDEPTH\n"
3423 "#ifdef VERTEX_SHADER\n"
3426 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
3427 " VertexColor = vec4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
3431 "#ifdef FRAGMENT_SHADER\n"
3434 " gl_FragColor = VertexColor;\n"
3437 "#else // !MODE_SHOWDEPTH\n"
3442 "#ifdef MODE_POSTPROCESS\n"
3443 "varying mediump vec2 TexCoord1;\n"
3444 "varying mediump vec2 TexCoord2;\n"
3446 "#ifdef VERTEX_SHADER\n"
3449 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
3450 " TexCoord1 = Attrib_TexCoord0.xy;\n"
3452 " TexCoord2 = Attrib_TexCoord4.xy;\n"
3457 "#ifdef FRAGMENT_SHADER\n"
3458 "uniform sampler2D Texture_First;\n"
3460 "uniform sampler2D Texture_Second;\n"
3461 "uniform lowp vec4 BloomColorSubtract;\n"
3463 "#ifdef USEGAMMARAMPS\n"
3464 "uniform sampler2D Texture_GammaRamps;\n"
3466 "#ifdef USESATURATION\n"
3467 "uniform lowp float Saturation;\n"
3469 "#ifdef USEVIEWTINT\n"
3470 "uniform lowp vec4 ViewTintColor;\n"
3472 "//uncomment these if you want to use them:\n"
3473 "uniform mediump vec4 UserVec1;\n"
3474 "uniform mediump vec4 UserVec2;\n"
3475 "// uniform mediump vec4 UserVec3;\n"
3476 "// uniform mediump vec4 UserVec4;\n"
3477 "// uniform highp float ClientTime;\n"
3478 "uniform mediump vec2 PixelSize;\n"
3481 " gl_FragColor = texture2D(Texture_First, TexCoord1);\n"
3483 " gl_FragColor += max(vec4(0,0,0,0), texture2D(Texture_Second, TexCoord2) - BloomColorSubtract);\n"
3485 "#ifdef USEVIEWTINT\n"
3486 " gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
3489 "#ifdef USEPOSTPROCESSING\n"
3490 "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
3491 "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
3492 " float sobel = 1.0;\n"
3493 " // vec2 ts = textureSize(Texture_First, 0);\n"
3494 " // vec2 px = vec2(1/ts.x, 1/ts.y);\n"
3495 " vec2 px = PixelSize;\n"
3496 " vec3 x1 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n"
3497 " vec3 x2 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, 0.0)).rgb;\n"
3498 " vec3 x3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n"
3499 " vec3 x4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n"
3500 " vec3 x5 = texture2D(Texture_First, TexCoord1 + vec2( px.x, 0.0)).rgb;\n"
3501 " vec3 x6 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n"
3502 " vec3 y1 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n"
3503 " vec3 y2 = texture2D(Texture_First, TexCoord1 + vec2( 0.0,-px.y)).rgb;\n"
3504 " vec3 y3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n"
3505 " vec3 y4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n"
3506 " vec3 y5 = texture2D(Texture_First, TexCoord1 + vec2( 0.0, px.y)).rgb;\n"
3507 " vec3 y6 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n"
3508 " float px1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x1);\n"
3509 " float px2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), x2);\n"
3510 " float px3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x3);\n"
3511 " float px4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x4);\n"
3512 " float px5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), x5);\n"
3513 " float px6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x6);\n"
3514 " float py1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y1);\n"
3515 " float py2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), y2);\n"
3516 " float py3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y3);\n"
3517 " float py4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y4);\n"
3518 " float py5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), y5);\n"
3519 " float py6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y6);\n"
3520 " sobel = 0.25 * abs(px1 + px2 + px3 + px4 + px5 + px6) + 0.25 * abs(py1 + py2 + py3 + py4 + py5 + py6);\n"
3521 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
3522 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
3523 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
3524 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.707107, 0.707107)) * UserVec1.y;\n"
3525 " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.453990, 0.891007)) * UserVec1.y;\n"
3526 " gl_FragColor /= (1.0 + 5.0 * UserVec1.y);\n"
3527 " gl_FragColor.rgb = gl_FragColor.rgb * (1.0 + UserVec2.x) + vec3(max(0.0, sobel - UserVec2.z))*UserVec2.y;\n"
3530 "#ifdef USESATURATION\n"
3531 " //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
3532 " float y = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));\n"
3533 " // 'vampire sight' effect, wheres red is compensated\n"
3534 " #ifdef SATURATION_REDCOMPENSATE\n"
3535 " float rboost = max(0.0, (gl_FragColor.r - max(gl_FragColor.g, gl_FragColor.b))*(1.0 - Saturation));\n"
3536 " gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
3537 " gl_FragColor.r += rboost;\n"
3539 " // normal desaturation\n"
3540 " //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
3541 " gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
3545 "#ifdef USEGAMMARAMPS\n"
3546 " gl_FragColor.r = texture2D(Texture_GammaRamps, vec2(gl_FragColor.r, 0)).r;\n"
3547 " gl_FragColor.g = texture2D(Texture_GammaRamps, vec2(gl_FragColor.g, 0)).g;\n"
3548 " gl_FragColor.b = texture2D(Texture_GammaRamps, vec2(gl_FragColor.b, 0)).b;\n"
3552 "#else // !MODE_POSTPROCESS\n"
3557 "#ifdef MODE_GENERIC\n"
3558 "#ifdef USEDIFFUSE\n"
3559 "varying mediump vec2 TexCoord1;\n"
3561 "#ifdef USESPECULAR\n"
3562 "varying mediump vec2 TexCoord2;\n"
3564 "#ifdef VERTEX_SHADER\n"
3567 " VertexColor = Attrib_Color;\n"
3568 "#ifdef USEDIFFUSE\n"
3569 " TexCoord1 = Attrib_TexCoord0.xy;\n"
3571 "#ifdef USESPECULAR\n"
3572 " TexCoord2 = Attrib_TexCoord1.xy;\n"
3574 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
3578 "#ifdef FRAGMENT_SHADER\n"
3579 "#ifdef USEDIFFUSE\n"
3580 "uniform sampler2D Texture_First;\n"
3582 "#ifdef USESPECULAR\n"
3583 "uniform sampler2D Texture_Second;\n"
3588 "#ifdef USEVIEWTINT\n"
3589 " gl_FragColor = VertexColor;\n"
3591 " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
3593 "#ifdef USEDIFFUSE\n"
3594 " gl_FragColor *= texture2D(Texture_First, TexCoord1);\n"
3597 "#ifdef USESPECULAR\n"
3598 " vec4 tex2 = texture2D(Texture_Second, TexCoord2);\n"
3599 "# ifdef USECOLORMAPPING\n"
3600 " gl_FragColor *= tex2;\n"
3603 " gl_FragColor += tex2;\n"
3605 "# ifdef USEVERTEXTEXTUREBLEND\n"
3606 " gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
3611 "#else // !MODE_GENERIC\n"
3616 "#ifdef MODE_BLOOMBLUR\n"
3617 "varying mediump vec2 TexCoord;\n"
3618 "#ifdef VERTEX_SHADER\n"
3621 " VertexColor = Attrib_Color;\n"
3622 " TexCoord = Attrib_TexCoord0.xy;\n"
3623 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
3627 "#ifdef FRAGMENT_SHADER\n"
3628 "uniform sampler2D Texture_First;\n"
3629 "uniform mediump vec4 BloomBlur_Parameters;\n"
3634 " vec2 tc = TexCoord;\n"
3635 " vec3 color = texture2D(Texture_First, tc).rgb;\n"
3636 " tc += BloomBlur_Parameters.xy;\n"
3637 " for (i = 1;i < SAMPLES;i++)\n"
3639 " color += texture2D(Texture_First, tc).rgb;\n"
3640 " tc += BloomBlur_Parameters.xy;\n"
3642 " gl_FragColor = vec4(color * BloomBlur_Parameters.z + vec3(BloomBlur_Parameters.w), 1);\n"
3645 "#else // !MODE_BLOOMBLUR\n"
3646 "#ifdef MODE_REFRACTION\n"
3647 "varying mediump vec2 TexCoord;\n"
3648 "varying highp vec4 ModelViewProjectionPosition;\n"
3649 "uniform highp mat4 TexMatrix;\n"
3650 "#ifdef VERTEX_SHADER\n"
3654 " TexCoord = vec2(TexMatrix * Attrib_TexCoord0);\n"
3655 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
3656 " ModelViewProjectionPosition = gl_Position;\n"
3660 "#ifdef FRAGMENT_SHADER\n"
3661 "uniform sampler2D Texture_Normal;\n"
3662 "uniform sampler2D Texture_Refraction;\n"
3663 "uniform sampler2D Texture_Reflection;\n"
3665 "uniform mediump vec4 DistortScaleRefractReflect;\n"
3666 "uniform mediump vec4 ScreenScaleRefractReflect;\n"
3667 "uniform mediump vec4 ScreenCenterRefractReflect;\n"
3668 "uniform lowp vec4 RefractColor;\n"
3669 "uniform lowp vec4 ReflectColor;\n"
3670 "uniform mediump float ReflectFactor;\n"
3671 "uniform mediump float ReflectOffset;\n"
3675 " vec2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
3676 " //vec2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
3677 " vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
3678 " vec2 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
3679 " // FIXME temporary hack to detect the case that the reflection\n"
3680 " // gets blackened at edges due to leaving the area that contains actual\n"
3682 " // Remove this 'ack once we have a better way to stop this thing from\n"
3684 " float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
3685 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
3686 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
3687 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
3688 " ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
3689 " gl_FragColor = vec4(texture2D(Texture_Refraction, ScreenTexCoord).rgb, 1.0) * RefractColor;\n"
3692 "#else // !MODE_REFRACTION\n"
3697 "#ifdef MODE_WATER\n"
3698 "varying mediump vec2 TexCoord;\n"
3699 "varying highp vec3 EyeVector;\n"
3700 "varying highp vec4 ModelViewProjectionPosition;\n"
3701 "#ifdef VERTEX_SHADER\n"
3702 "uniform highp vec3 EyePosition;\n"
3703 "uniform highp mat4 TexMatrix;\n"
3707 " TexCoord = vec2(TexMatrix * Attrib_TexCoord0);\n"
3708 " vec3 EyeVectorModelSpace = EyePosition - Attrib_Position.xyz;\n"
3709 " EyeVector.x = dot(EyeVectorModelSpace, Attrib_TexCoord1.xyz);\n"
3710 " EyeVector.y = dot(EyeVectorModelSpace, Attrib_TexCoord2.xyz);\n"
3711 " EyeVector.z = dot(EyeVectorModelSpace, Attrib_TexCoord3.xyz);\n"
3712 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
3713 " ModelViewProjectionPosition = gl_Position;\n"
3717 "#ifdef FRAGMENT_SHADER\n"
3718 "uniform sampler2D Texture_Normal;\n"
3719 "uniform sampler2D Texture_Refraction;\n"
3720 "uniform sampler2D Texture_Reflection;\n"
3722 "uniform mediump vec4 DistortScaleRefractReflect;\n"
3723 "uniform mediump vec4 ScreenScaleRefractReflect;\n"
3724 "uniform mediump vec4 ScreenCenterRefractReflect;\n"
3725 "uniform lowp vec4 RefractColor;\n"
3726 "uniform lowp vec4 ReflectColor;\n"
3727 "uniform mediump float ReflectFactor;\n"
3728 "uniform mediump float ReflectOffset;\n"
3729 "uniform highp float ClientTime;\n"
3730 "#ifdef USENORMALMAPSCROLLBLEND\n"
3731 "uniform highp vec2 NormalmapScrollBlend;\n"
3736 " vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
3737 " //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
3738 " vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
3739 " //SafeScreenTexCoord = gl_FragCoord.xyxy * vec4(1.0 / 1920.0, 1.0 / 1200.0, 1.0 / 1920.0, 1.0 / 1200.0);\n"
3740 " // slight water animation via 2 layer scrolling (todo: tweak)\n"
3741 " #ifdef USENORMALMAPSCROLLBLEND\n"
3742 " vec3 normal = texture2D(Texture_Normal, (TexCoord + vec2(0.08, 0.08)*ClientTime*NormalmapScrollBlend.x*0.5)*NormalmapScrollBlend.y).rgb - vec3(1.0);\n"
3743 " normal += texture2D(Texture_Normal, (TexCoord + vec2(-0.06, -0.09)*ClientTime*NormalmapScrollBlend.x)*NormalmapScrollBlend.y*0.75).rgb;\n"
3744 " vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(normal) + vec3(0.15)).xyxy * DistortScaleRefractReflect;\n"
3746 " vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
3748 " // FIXME temporary hack to detect the case that the reflection\n"
3749 " // gets blackened at edges due to leaving the area that contains actual\n"
3751 " // Remove this 'ack once we have a better way to stop this thing from\n"
3753 " float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, 0.01)).rgb) / 0.002);\n"
3754 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, -0.01)).rgb) / 0.002);\n"
3755 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, 0.01)).rgb) / 0.002);\n"
3756 " f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, -0.01)).rgb) / 0.002);\n"
3757 " ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
3758 " f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, 0.005)).rgb) / 0.002);\n"
3759 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, -0.005)).rgb) / 0.002);\n"
3760 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, 0.005)).rgb) / 0.002);\n"
3761 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, -0.005)).rgb) / 0.002);\n"
3762 " ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
3763 " float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
3764 " gl_FragColor = mix(vec4(texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, vec4(texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
3767 "#else // !MODE_WATER\n"
3772 "// common definitions between vertex shader and fragment shader:\n"
3774 "varying mediump vec2 TexCoord;\n"
3775 "#ifdef USEVERTEXTEXTUREBLEND\n"
3776 "varying mediump vec2 TexCoord2;\n"
3778 "#ifdef USELIGHTMAP\n"
3779 "varying mediump vec2 TexCoordLightmap;\n"
3782 "#ifdef MODE_LIGHTSOURCE\n"
3783 "varying mediump vec3 CubeVector;\n"
3786 "#if (defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)) && defined(USEDIFFUSE)\n"
3787 "varying mediump vec3 LightVector;\n"
3790 "#ifdef USEEYEVECTOR\n"
3791 "varying highp vec3 EyeVector;\n"
3794 "varying highp vec4 EyeVectorModelSpaceFogPlaneVertexDist;\n"
3797 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n"
3798 "varying lowp vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
3799 "varying lowp vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
3800 "varying lowp vec3 VectorR; // direction of R texcoord (surface normal)\n"
3803 "#ifdef USEREFLECTION\n"
3804 "varying highp vec4 ModelViewProjectionPosition;\n"
3806 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
3807 "uniform highp vec3 LightPosition;\n"
3808 "varying highp vec4 ModelViewPosition;\n"
3811 "#ifdef MODE_LIGHTSOURCE\n"
3812 "uniform highp vec3 LightPosition;\n"
3814 "uniform highp vec3 EyePosition;\n"
3815 "#ifdef MODE_LIGHTDIRECTION\n"
3816 "uniform highp vec3 LightDir;\n"
3818 "uniform highp vec4 FogPlane;\n"
3820 "#ifdef USESHADOWMAPORTHO\n"
3821 "varying mediump vec3 ShadowMapTC;\n"
3828 "// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
3830 "// fragment shader specific:\n"
3831 "#ifdef FRAGMENT_SHADER\n"
3833 "uniform sampler2D Texture_Normal;\n"
3834 "uniform sampler2D Texture_Color;\n"
3835 "uniform sampler2D Texture_Gloss;\n"
3837 "uniform sampler2D Texture_Glow;\n"
3839 "#ifdef USEVERTEXTEXTUREBLEND\n"
3840 "uniform sampler2D Texture_SecondaryNormal;\n"
3841 "uniform sampler2D Texture_SecondaryColor;\n"
3842 "uniform sampler2D Texture_SecondaryGloss;\n"
3844 "uniform sampler2D Texture_SecondaryGlow;\n"
3847 "#ifdef USECOLORMAPPING\n"
3848 "uniform sampler2D Texture_Pants;\n"
3849 "uniform sampler2D Texture_Shirt;\n"
3852 "#ifdef USEFOGHEIGHTTEXTURE\n"
3853 "uniform sampler2D Texture_FogHeightTexture;\n"
3855 "uniform sampler2D Texture_FogMask;\n"
3857 "#ifdef USELIGHTMAP\n"
3858 "uniform sampler2D Texture_Lightmap;\n"
3860 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
3861 "uniform sampler2D Texture_Deluxemap;\n"
3863 "#ifdef USEREFLECTION\n"
3864 "uniform sampler2D Texture_Reflection;\n"
3867 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
3868 "uniform sampler2D Texture_ScreenDepth;\n"
3869 "uniform sampler2D Texture_ScreenNormalMap;\n"
3871 "#ifdef USEDEFERREDLIGHTMAP\n"
3872 "uniform sampler2D Texture_ScreenDiffuse;\n"
3873 "uniform sampler2D Texture_ScreenSpecular;\n"
3876 "uniform lowp vec3 Color_Pants;\n"
3877 "uniform lowp vec3 Color_Shirt;\n"
3878 "uniform lowp vec3 FogColor;\n"
3881 "uniform highp float FogRangeRecip;\n"
3882 "uniform highp float FogPlaneViewDist;\n"
3883 "uniform highp float FogHeightFade;\n"
3884 "vec3 FogVertex(vec3 surfacecolor)\n"
3886 " vec3 EyeVectorModelSpace = EyeVectorModelSpaceFogPlaneVertexDist.xyz;\n"
3887 " float FogPlaneVertexDist = EyeVectorModelSpaceFogPlaneVertexDist.w;\n"
3889 "#ifdef USEFOGHEIGHTTEXTURE\n"
3890 " vec4 fogheightpixel = texture2D(Texture_FogHeightTexture, vec2(1,1) + vec2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n"
3891 " fogfrac = fogheightpixel.a;\n"
3892 " return mix(fogheightpixel.rgb * FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
3894 "# ifdef USEFOGOUTSIDE\n"
3895 " fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
3897 " fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
3899 " return mix(FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
3904 "#ifdef USEOFFSETMAPPING\n"
3905 "uniform mediump float OffsetMapping_Scale;\n"
3906 "vec2 OffsetMapping(vec2 TexCoord)\n"
3908 "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
3909 " // 14 sample relief mapping: linear search and then binary search\n"
3910 " // this basically steps forward a small amount repeatedly until it finds\n"
3911 " // itself inside solid, then jitters forward and back using decreasing\n"
3912 " // amounts to find the impact\n"
3913 " //vec3 OffsetVector = vec3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1), -1);\n"
3914 " //vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
3915 " vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
3916 " vec3 RT = vec3(TexCoord, 1);\n"
3917 " OffsetVector *= 0.1;\n"
3918 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3919 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3920 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3921 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3922 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3923 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3924 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3925 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3926 " RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
3927 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n"
3928 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n"
3929 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n"
3930 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n"
3931 " RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
3934 " // 2 sample offset mapping (only 2 samples because of ATI Radeon 9500-9800/X300 limits)\n"
3935 " // this basically moves forward the full distance, and then backs up based\n"
3936 " // on height of samples\n"
3937 " //vec2 OffsetVector = vec2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1));\n"
3938 " //vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1));\n"
3939 " vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1));\n"
3940 " TexCoord += OffsetVector;\n"
3941 " OffsetVector *= 0.5;\n"
3942 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
3943 " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
3944 " return TexCoord;\n"
3947 "#endif // USEOFFSETMAPPING\n"
3949 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
3950 "uniform sampler2D Texture_Attenuation;\n"
3951 "uniform samplerCube Texture_Cube;\n"
3954 "#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
3956 "#ifdef USESHADOWMAP2D\n"
3957 "# ifdef USESHADOWSAMPLER\n"
3958 "uniform sampler2DShadow Texture_ShadowMap2D;\n"
3960 "uniform sampler2D Texture_ShadowMap2D;\n"
3964 "#ifdef USESHADOWMAPVSDCT\n"
3965 "uniform samplerCube Texture_CubeProjection;\n"
3968 "#if defined(USESHADOWMAP2D)\n"
3969 "uniform mediump vec2 ShadowMap_TextureScale;\n"
3970 "uniform mediump vec4 ShadowMap_Parameters;\n"
3973 "#if defined(USESHADOWMAP2D)\n"
3974 "# ifdef USESHADOWMAPORTHO\n"
3975 "# define GetShadowMapTC2D(dir) (min(dir, ShadowMap_Parameters.xyz))\n"
3977 "# ifdef USESHADOWMAPVSDCT\n"
3978 "vec3 GetShadowMapTC2D(vec3 dir)\n"
3980 " vec3 adir = abs(dir);\n"
3981 " vec2 aparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n"
3982 " vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
3983 " return vec3(mix(dir.xy, dir.zz, proj.xy) * aparams.x + proj.zw * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
3986 "vec3 GetShadowMapTC2D(vec3 dir)\n"
3988 " vec3 adir = abs(dir);\n"
3989 " float ma = adir.z;\n"
3990 " vec4 proj = vec4(dir, 2.5);\n"
3991 " if (adir.x > ma) { ma = adir.x; proj = vec4(dir.zyx, 0.5); }\n"
3992 " if (adir.y > ma) { ma = adir.y; proj = vec4(dir.xzy, 1.5); }\n"
3993 " vec2 aparams = ShadowMap_Parameters.xy / ma;\n"
3994 " return vec3(proj.xy * aparams.x + vec2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
3998 "#endif // defined(USESHADOWMAP2D)\n"
4000 "# ifdef USESHADOWMAP2D\n"
4001 "float ShadowMapCompare(vec3 dir)\n"
4003 " vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
4006 "# ifdef USESHADOWSAMPLER\n"
4007 "# ifdef USESHADOWMAPPCF\n"
4008 "# define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r \n"
4009 " vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
4010 " f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
4012 " f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
4015 "# ifdef USESHADOWMAPPCF\n"
4016 "# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
4017 "# ifdef GL_ARB_texture_gather\n"
4018 "# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec2(x, y))\n"
4020 "# define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale)\n"
4022 " vec2 offset = fract(shadowmaptc.xy - 0.5), center = (shadowmaptc.xy - offset)*ShadowMap_TextureScale;\n"
4023 "# if USESHADOWMAPPCF > 1\n"
4024 " vec4 group1 = step(shadowmaptc.z, texval(-2.0, -2.0));\n"
4025 " vec4 group2 = step(shadowmaptc.z, texval( 0.0, -2.0));\n"
4026 " vec4 group3 = step(shadowmaptc.z, texval( 2.0, -2.0));\n"
4027 " vec4 group4 = step(shadowmaptc.z, texval(-2.0, 0.0));\n"
4028 " vec4 group5 = step(shadowmaptc.z, texval( 0.0, 0.0));\n"
4029 " vec4 group6 = step(shadowmaptc.z, texval( 2.0, 0.0));\n"
4030 " vec4 group7 = step(shadowmaptc.z, texval(-2.0, 2.0));\n"
4031 " vec4 group8 = step(shadowmaptc.z, texval( 0.0, 2.0));\n"
4032 " vec4 group9 = step(shadowmaptc.z, texval( 2.0, 2.0));\n"
4033 " vec4 locols = vec4(group1.ab, group3.ab);\n"
4034 " vec4 hicols = vec4(group7.rg, group9.rg);\n"
4035 " locols.yz += group2.ab;\n"
4036 " hicols.yz += group8.rg;\n"
4037 " vec4 midcols = vec4(group1.rg, group3.rg) + vec4(group7.ab, group9.ab) +\n"
4038 " vec4(group4.rg, group6.rg) + vec4(group4.ab, group6.ab) +\n"
4039 " mix(locols, hicols, offset.y);\n"
4040 " vec4 cols = group5 + vec4(group2.rg, group8.ab);\n"
4041 " cols.xyz += mix(midcols.xyz, midcols.yzw, offset.x);\n"
4042 " f = dot(cols, vec4(1.0/25.0));\n"
4044 " vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
4045 " vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
4046 " vec4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
4047 " vec4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
4048 " vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
4049 " mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
4050 " f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
4053 "# ifdef GL_EXT_gpu_shader4\n"
4054 "# define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n"
4056 "# define texval(x, y) texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r \n"
4058 "# if USESHADOWMAPPCF > 1\n"
4059 " vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
4060 " center *= ShadowMap_TextureScale;\n"
4061 " vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
4062 " vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
4063 " vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
4064 " vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
4065 " vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
4066 " f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
4068 " vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
4069 " vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
4070 " vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
4071 " vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
4072 " vec3 cols = row2 + mix(row1, row3, offset.y);\n"
4073 " f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
4077 " f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
4080 "# ifdef USESHADOWMAPORTHO\n"
4081 " return mix(ShadowMap_Parameters.w, 1.0, f);\n"
4087 "#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
4088 "#endif // FRAGMENT_SHADER\n"
4093 "#ifdef MODE_DEFERREDGEOMETRY\n"
4094 "#ifdef VERTEX_SHADER\n"
4095 "uniform highp mat4 TexMatrix;\n"
4096 "#ifdef USEVERTEXTEXTUREBLEND\n"
4097 "uniform highp mat4 BackgroundTexMatrix;\n"
4099 "uniform highp mat4 ModelViewMatrix;\n"
4102 " TexCoord = vec2(TexMatrix * Attrib_TexCoord0);\n"
4103 "#ifdef USEVERTEXTEXTUREBLEND\n"
4104 " VertexColor = Attrib_Color;\n"
4105 " TexCoord2 = vec2(BackgroundTexMatrix * Attrib_TexCoord0);\n"
4108 " // transform unnormalized eye direction into tangent space\n"
4109 "#ifdef USEOFFSETMAPPING\n"
4110 " vec3 EyeVectorModelSpace = EyePosition - Attrib_Position.xyz;\n"
4111 " EyeVector.x = dot(EyeVectorModelSpace, Attrib_TexCoord1.xyz);\n"
4112 " EyeVector.y = dot(EyeVectorModelSpace, Attrib_TexCoord2.xyz);\n"
4113 " EyeVector.z = dot(EyeVectorModelSpace, Attrib_TexCoord3.xyz);\n"
4116 " VectorS = (ModelViewMatrix * vec4(Attrib_TexCoord1.xyz, 0)).xyz;\n"
4117 " VectorT = (ModelViewMatrix * vec4(Attrib_TexCoord2.xyz, 0)).xyz;\n"
4118 " VectorR = (ModelViewMatrix * vec4(Attrib_TexCoord3.xyz, 0)).xyz;\n"
4119 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
4121 "#endif // VERTEX_SHADER\n"
4123 "#ifdef FRAGMENT_SHADER\n"
4126 "#ifdef USEOFFSETMAPPING\n"
4127 " // apply offsetmapping\n"
4128 " vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
4129 "#define TexCoord TexCoordOffset\n"
4132 "#ifdef USEALPHAKILL\n"
4133 " if (texture2D(Texture_Color, TexCoord).a < 0.5)\n"
4137 "#ifdef USEVERTEXTEXTUREBLEND\n"
4138 " float alpha = texture2D(Texture_Color, TexCoord).a;\n"
4139 " float terrainblend = clamp(float(VertexColor.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
4140 " //float terrainblend = min(float(VertexColor.a) * alpha * 2.0, float(1.0));\n"
4141 " //float terrainblend = float(VertexColor.a) * alpha > 0.5;\n"
4144 "#ifdef USEVERTEXTEXTUREBLEND\n"
4145 " vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(texture2D(Texture_Normal, TexCoord)), terrainblend) - vec3(0.5, 0.5, 0.5);\n"
4146 " float a = mix(texture2D(Texture_SecondaryGloss, TexCoord2).a, texture2D(Texture_Gloss, TexCoord).a, terrainblend);\n"
4148 " vec3 surfacenormal = vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5, 0.5, 0.5);\n"
4149 " float a = texture2D(Texture_Gloss, TexCoord).a;\n"
4152 " gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), a);\n"
4154 "#endif // FRAGMENT_SHADER\n"
4155 "#else // !MODE_DEFERREDGEOMETRY\n"
4160 "#ifdef MODE_DEFERREDLIGHTSOURCE\n"
4161 "#ifdef VERTEX_SHADER\n"
4162 "uniform highp mat4 ModelViewMatrix;\n"
4165 " ModelViewPosition = ModelViewMatrix * Attrib_Position;\n"
4166 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
4168 "#endif // VERTEX_SHADER\n"
4170 "#ifdef FRAGMENT_SHADER\n"
4171 "uniform highp mat4 ViewToLight;\n"
4172 "// ScreenToDepth = vec2(Far / (Far - Near), Far * Near / (Near - Far));\n"
4173 "uniform highp vec2 ScreenToDepth;\n"
4174 "uniform myhalf3 DeferredColor_Ambient;\n"
4175 "uniform myhalf3 DeferredColor_Diffuse;\n"
4176 "#ifdef USESPECULAR\n"
4177 "uniform myhalf3 DeferredColor_Specular;\n"
4178 "uniform myhalf SpecularPower;\n"
4180 "uniform myhalf2 PixelToScreenTexCoord;\n"
4183 " // calculate viewspace pixel position\n"
4184 " vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
4186 " position.z = ScreenToDepth.y / (texture2D(Texture_ScreenDepth, ScreenTexCoord).r + ScreenToDepth.x);\n"
4187 " position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
4188 " // decode viewspace pixel normal\n"
4189 " myhalf4 normalmap = texture2D(Texture_ScreenNormalMap, ScreenTexCoord);\n"
4190 " myhalf3 surfacenormal = normalize(normalmap.rgb - myhalf3(0.5,0.5,0.5));\n"
4191 " // surfacenormal = pixel normal in viewspace\n"
4192 " // LightVector = pixel to light in viewspace\n"
4193 " // CubeVector = position in lightspace\n"
4194 " // eyevector = pixel to view in viewspace\n"
4195 " vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n"
4196 " myhalf fade = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
4197 "#ifdef USEDIFFUSE\n"
4198 " // calculate diffuse shading\n"
4199 " myhalf3 lightnormal = myhalf3(normalize(LightPosition - position));\n"
4200 " myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
4202 "#ifdef USESPECULAR\n"
4203 " // calculate directional shading\n"
4204 " vec3 eyevector = position * -1.0;\n"
4205 "# ifdef USEEXACTSPECULARMATH\n"
4206 " myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a);\n"
4208 " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(eyevector)));\n"
4209 " myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a);\n"
4213 "#if defined(USESHADOWMAP2D)\n"
4214 " fade *= ShadowMapCompare(CubeVector);\n"
4217 "#ifdef USEDIFFUSE\n"
4218 " gl_FragData[0] = vec4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
4220 " gl_FragData[0] = vec4(DeferredColor_Ambient * fade, 1.0);\n"
4222 "#ifdef USESPECULAR\n"
4223 " gl_FragData[1] = vec4(DeferredColor_Specular * (specular * fade), 1.0);\n"
4225 " gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0);\n"
4228 "# ifdef USECUBEFILTER\n"
4229 " vec3 cubecolor = textureCube(Texture_Cube, CubeVector).rgb;\n"
4230 " gl_FragData[0].rgb *= cubecolor;\n"
4231 " gl_FragData[1].rgb *= cubecolor;\n"
4234 "#endif // FRAGMENT_SHADER\n"
4235 "#else // !MODE_DEFERREDLIGHTSOURCE\n"
4240 "#ifdef VERTEX_SHADER\n"
4241 "uniform highp mat4 TexMatrix;\n"
4242 "#ifdef USEVERTEXTEXTUREBLEND\n"
4243 "uniform highp mat4 BackgroundTexMatrix;\n"
4245 "#ifdef MODE_LIGHTSOURCE\n"
4246 "uniform highp mat4 ModelToLight;\n"
4248 "#ifdef USESHADOWMAPORTHO\n"
4249 "uniform highp mat4 ShadowMapMatrix;\n"
4253 "#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
4254 " VertexColor = Attrib_Color;\n"
4256 " // copy the surface texcoord\n"
4257 " TexCoord = vec2(TexMatrix * Attrib_TexCoord0);\n"
4258 "#ifdef USEVERTEXTEXTUREBLEND\n"
4259 " TexCoord2 = vec2(BackgroundTexMatrix * Attrib_TexCoord0);\n"
4261 "#ifdef USELIGHTMAP\n"
4262 " TexCoordLightmap = vec2(Attrib_TexCoord4);\n"
4265 "#ifdef MODE_LIGHTSOURCE\n"
4266 " // transform vertex position into light attenuation/cubemap space\n"
4267 " // (-1 to +1 across the light box)\n"
4268 " CubeVector = vec3(ModelToLight * Attrib_Position);\n"
4270 "# ifdef USEDIFFUSE\n"
4271 " // transform unnormalized light direction into tangent space\n"
4272 " // (we use unnormalized to ensure that it interpolates correctly and then\n"
4273 " // normalize it per pixel)\n"
4274 " vec3 lightminusvertex = LightPosition - Attrib_Position.xyz;\n"
4275 " LightVector.x = dot(lightminusvertex, Attrib_TexCoord1.xyz);\n"
4276 " LightVector.y = dot(lightminusvertex, Attrib_TexCoord2.xyz);\n"
4277 " LightVector.z = dot(lightminusvertex, Attrib_TexCoord3.xyz);\n"
4281 "#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
4282 " LightVector.x = dot(LightDir, Attrib_TexCoord1.xyz);\n"
4283 " LightVector.y = dot(LightDir, Attrib_TexCoord2.xyz);\n"
4284 " LightVector.z = dot(LightDir, Attrib_TexCoord3.xyz);\n"
4287 " // transform unnormalized eye direction into tangent space\n"
4288 "#ifdef USEEYEVECTOR\n"
4289 " vec3 EyeVectorModelSpace = EyePosition - Attrib_Position.xyz;\n"
4290 " EyeVector.x = dot(EyeVectorModelSpace, Attrib_TexCoord1.xyz);\n"
4291 " EyeVector.y = dot(EyeVectorModelSpace, Attrib_TexCoord2.xyz);\n"
4292 " EyeVector.z = dot(EyeVectorModelSpace, Attrib_TexCoord3.xyz);\n"
4296 " EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - Attrib_Position.xyz;\n"
4297 " EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, Attrib_Position);\n"
4300 "#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(USEREFLECTCUBE)\n"
4301 " VectorS = Attrib_TexCoord1.xyz;\n"
4302 " VectorT = Attrib_TexCoord2.xyz;\n"
4303 " VectorR = Attrib_TexCoord3.xyz;\n"
4306 " // transform vertex to camera space, using ftransform to match non-VS rendering\n"
4307 " gl_Position = ModelViewProjectionMatrix * Attrib_Position;\n"
4309 "#ifdef USESHADOWMAPORTHO\n"
4310 " ShadowMapTC = vec3(ShadowMapMatrix * gl_Position);\n"
4313 "#ifdef USEREFLECTION\n"
4314 " ModelViewProjectionPosition = gl_Position;\n"
4317 "#endif // VERTEX_SHADER\n"
4322 "#ifdef FRAGMENT_SHADER\n"
4323 "#ifdef USEDEFERREDLIGHTMAP\n"
4324 "uniform myhalf2 PixelToScreenTexCoord;\n"
4325 "uniform myhalf3 DeferredMod_Diffuse;\n"
4326 "uniform myhalf3 DeferredMod_Specular;\n"
4328 "uniform myhalf3 Color_Ambient;\n"
4329 "uniform myhalf3 Color_Diffuse;\n"
4330 "uniform myhalf3 Color_Specular;\n"
4331 "uniform myhalf SpecularPower;\n"
4333 "uniform myhalf3 Color_Glow;\n"
4335 "uniform myhalf Alpha;\n"
4336 "#ifdef USEREFLECTION\n"
4337 "uniform mediump vec4 DistortScaleRefractReflect;\n"
4338 "uniform mediump vec4 ScreenScaleRefractReflect;\n"
4339 "uniform mediump vec4 ScreenCenterRefractReflect;\n"
4340 "uniform lowp vec4 ReflectColor;\n"
4342 "#ifdef USEREFLECTCUBE\n"
4343 "uniform highp mat4 ModelToReflectCube;\n"
4344 "uniform sampler2D Texture_ReflectMask;\n"
4345 "uniform samplerCube Texture_ReflectCube;\n"
4347 "#ifdef MODE_LIGHTDIRECTION\n"
4348 "uniform myhalf3 LightColor;\n"
4350 "#ifdef MODE_LIGHTSOURCE\n"
4351 "uniform myhalf3 LightColor;\n"
4355 "#ifdef USEOFFSETMAPPING\n"
4356 " // apply offsetmapping\n"
4357 " vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
4358 "#define TexCoord TexCoordOffset\n"
4361 " // combine the diffuse textures (base, pants, shirt)\n"
4362 " myhalf4 color = myhalf4(texture2D(Texture_Color, TexCoord));\n"
4363 "#ifdef USEALPHAKILL\n"
4364 " if (color.a < 0.5)\n"
4367 " color.a *= Alpha;\n"
4368 "#ifdef USECOLORMAPPING\n"
4369 " color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
4371 "#ifdef USEVERTEXTEXTUREBLEND\n"
4372 " myhalf terrainblend = clamp(myhalf(VertexColor.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
4373 " //myhalf terrainblend = min(myhalf(VertexColor.a) * color.a * 2.0, myhalf(1.0));\n"
4374 " //myhalf terrainblend = myhalf(VertexColor.a) * color.a > 0.5;\n"
4375 " color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord2)), color.rgb, terrainblend);\n"
4377 " //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
4380 " // get the surface normal\n"
4381 "#ifdef USEVERTEXTEXTUREBLEND\n"
4382 " myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n"
4384 " myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n"
4387 " // get the material colors\n"
4388 " myhalf3 diffusetex = color.rgb;\n"
4389 "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
4390 "# ifdef USEVERTEXTEXTUREBLEND\n"
4391 " myhalf4 glosstex = mix(myhalf4(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf4(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
4393 " myhalf4 glosstex = myhalf4(texture2D(Texture_Gloss, TexCoord));\n"
4397 "#ifdef USEREFLECTCUBE\n"
4398 " vec3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n"
4399 " vec3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n"
4400 " vec3 ReflectCubeTexCoord = vec3(ModelToReflectCube * vec4(ModelReflectVector, 0));\n"
4401 " diffusetex += myhalf3(texture2D(Texture_ReflectMask, TexCoord)) * myhalf3(textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n"
4407 "#ifdef MODE_LIGHTSOURCE\n"
4408 " // light source\n"
4409 "#ifdef USEDIFFUSE\n"
4410 " myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
4411 " myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
4412 " color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
4413 "#ifdef USESPECULAR\n"
4414 "#ifdef USEEXACTSPECULARMATH\n"
4415 " myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
4417 " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
4418 " myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
4420 " color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
4423 " color.rgb = diffusetex * Color_Ambient;\n"
4425 " color.rgb *= LightColor;\n"
4426 " color.rgb *= myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
4427 "#if defined(USESHADOWMAP2D)\n"
4428 " color.rgb *= ShadowMapCompare(CubeVector);\n"
4430 "# ifdef USECUBEFILTER\n"
4431 " color.rgb *= myhalf3(textureCube(Texture_Cube, CubeVector));\n"
4433 "#endif // MODE_LIGHTSOURCE\n"
4438 "#ifdef MODE_LIGHTDIRECTION\n"
4440 "#ifdef USEDIFFUSE\n"
4441 " myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
4443 "#define lightcolor LightColor\n"
4444 "#endif // MODE_LIGHTDIRECTION\n"
4445 "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
4447 " // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
4448 " myhalf3 lightnormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
4449 " myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
4450 " // convert modelspace light vector to tangentspace\n"
4451 " myhalf3 lightnormal;\n"
4452 " lightnormal.x = dot(lightnormal_modelspace, myhalf3(VectorS));\n"
4453 " lightnormal.y = dot(lightnormal_modelspace, myhalf3(VectorT));\n"
4454 " lightnormal.z = dot(lightnormal_modelspace, myhalf3(VectorR));\n"
4455 " lightnormal = normalize(lightnormal); // VectorS/T/R are not always perfectly normalized, and EXACTSPECULARMATH is very picky about this\n"
4456 " // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
4457 " // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
4458 " // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
4459 " // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
4460 " // to map the luxels to coordinates on the draw surfaces), which also causes\n"
4461 " // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
4462 " // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
4463 " // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
4464 " // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
4465 " lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
4466 "#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
4467 "#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
4469 " // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
4470 " myhalf3 lightnormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
4471 " myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
4477 "#ifdef MODE_FAKELIGHT\n"
4479 "myhalf3 lightnormal = myhalf3(normalize(EyeVector));\n"
4480 "myhalf3 lightcolor = myhalf3(1.0);\n"
4481 "#endif // MODE_FAKELIGHT\n"
4486 "#ifdef MODE_LIGHTMAP\n"
4487 " color.rgb = diffusetex * (Color_Ambient + myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
4488 "#endif // MODE_LIGHTMAP\n"
4489 "#ifdef MODE_VERTEXCOLOR\n"
4490 " color.rgb = diffusetex * (Color_Ambient + myhalf3(VertexColor.rgb) * Color_Diffuse);\n"
4491 "#endif // MODE_VERTEXCOLOR\n"
4492 "#ifdef MODE_FLATCOLOR\n"
4493 " color.rgb = diffusetex * Color_Ambient;\n"
4494 "#endif // MODE_FLATCOLOR\n"
4500 "# ifdef USEDIFFUSE\n"
4501 " myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
4502 "# ifdef USESPECULAR\n"
4503 "# ifdef USEEXACTSPECULARMATH\n"
4504 " myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
4506 " myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
4507 " myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
4509 " color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
4511 " color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
4514 " color.rgb = diffusetex * Color_Ambient;\n"
4518 "#ifdef USESHADOWMAPORTHO\n"
4519 " color.rgb *= ShadowMapCompare(ShadowMapTC);\n"
4522 "#ifdef USEDEFERREDLIGHTMAP\n"
4523 " vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
4524 " color.rgb += diffusetex * myhalf3(texture2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n"
4525 " color.rgb += glosstex.rgb * myhalf3(texture2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n"
4529 "#ifdef USEVERTEXTEXTUREBLEND\n"
4530 " color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
4532 " color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
4537 " color.rgb = FogVertex(color.rgb);\n"
4540 " // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
4541 "#ifdef USEREFLECTION\n"
4542 " vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
4543 " //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
4544 " vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
4545 " vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
4546 " // FIXME temporary hack to detect the case that the reflection\n"
4547 " // gets blackened at edges due to leaving the area that contains actual\n"
4549 " // Remove this 'ack once we have a better way to stop this thing from\n"
4551 " float f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
4552 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
4553 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
4554 " f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
4555 " ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
4556 " color.rgb = mix(color.rgb, myhalf3(texture2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
4559 " gl_FragColor = vec4(color);\n"
4561 "#endif // FRAGMENT_SHADER\n"
4563 "#endif // !MODE_DEFERREDLIGHTSOURCE\n"
4564 "#endif // !MODE_DEFERREDGEOMETRY\n"
4565 "#endif // !MODE_WATER\n"
4566 "#endif // !MODE_REFRACTION\n"
4567 "#endif // !MODE_BLOOMBLUR\n"
4568 "#endif // !MODE_GENERIC\n"
4569 "#endif // !MODE_POSTPROCESS\n"
4570 "#endif // !MODE_SHOWDEPTH\n"
4571 "#endif // !MODE_DEPTH_OR_SHADOW\n"
4574 char *glslshaderstring = NULL;
4575 char *cgshaderstring = NULL;
4576 char *hlslshaderstring = NULL;
4578 //=======================================================================================================================================================
4580 typedef struct shaderpermutationinfo_s
4582 const char *pretext;
4585 shaderpermutationinfo_t;
4587 typedef struct shadermodeinfo_s
4589 const char *vertexfilename;
4590 const char *geometryfilename;
4591 const char *fragmentfilename;
4592 const char *pretext;
4597 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
4598 shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
4600 {"#define USEDIFFUSE\n", " diffuse"},
4601 {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
4602 {"#define USEVIEWTINT\n", " viewtint"},
4603 {"#define USECOLORMAPPING\n", " colormapping"},
4604 {"#define USESATURATION\n", " saturation"},
4605 {"#define USEFOGINSIDE\n", " foginside"},
4606 {"#define USEFOGOUTSIDE\n", " fogoutside"},
4607 {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
4608 {"#define USEGAMMARAMPS\n", " gammaramps"},
4609 {"#define USECUBEFILTER\n", " cubefilter"},
4610 {"#define USEGLOW\n", " glow"},
4611 {"#define USEBLOOM\n", " bloom"},
4612 {"#define USESPECULAR\n", " specular"},
4613 {"#define USEPOSTPROCESSING\n", " postprocessing"},
4614 {"#define USEREFLECTION\n", " reflection"},
4615 {"#define USEOFFSETMAPPING\n", " offsetmapping"},
4616 {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
4617 {"#define USESHADOWMAP2D\n", " shadowmap2d"},
4618 {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"},
4619 {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"},
4620 {"#define USESHADOWSAMPLER\n", " shadowsampler"},
4621 {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"},
4622 {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
4623 {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
4624 {"#define USEALPHAKILL\n", " alphakill"},
4625 {"#define USEREFLECTCUBE\n", " reflectcube"},
4626 {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
4629 // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
4630 shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
4632 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_GENERIC\n", " generic"},
4633 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
4634 {"glsl/default.glsl", NULL, NULL , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
4635 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
4636 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
4637 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
4638 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
4639 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
4640 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
4641 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
4642 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
4643 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
4644 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_WATER\n", " water"},
4645 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
4646 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
4647 {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
4651 shadermodeinfo_t cgshadermodeinfo[SHADERMODE_COUNT] =
4653 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_GENERIC\n", " generic"},
4654 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_POSTPROCESS\n", " postprocess"},
4655 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
4656 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FLATCOLOR\n", " flatcolor"},
4657 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
4658 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTMAP\n", " lightmap"},
4659 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FAKELIGHT\n", " fakelight"},
4660 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
4661 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
4662 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
4663 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTSOURCE\n", " lightsource"},
4664 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_REFRACTION\n", " refraction"},
4665 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_WATER\n", " water"},
4666 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_SHOWDEPTH\n", " showdepth"},
4667 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
4668 {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
4672 shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
4674 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"},
4675 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"},
4676 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
4677 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
4678 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
4679 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"},
4680 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
4681 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
4682 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
4683 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
4684 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
4685 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
4686 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_WATER\n", " water"},
4687 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
4688 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
4689 {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
4692 shadermodeinfo_t gles2shadermodeinfo[SHADERMODE_COUNT] =
4694 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_GENERIC\n", " generic"},
4695 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_POSTPROCESS\n", " postprocess"},
4696 {"gles2/default.glsl", NULL, NULL , "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
4697 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
4698 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
4699 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
4700 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
4701 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
4702 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
4703 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
4704 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
4705 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_REFRACTION\n", " refraction"},
4706 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_WATER\n", " water"},
4707 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
4708 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
4709 {"gles2/default.glsl", NULL, "gles2/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
4712 struct r_glsl_permutation_s;
4713 typedef struct r_glsl_permutation_s
4715 /// hash lookup data
4716 struct r_glsl_permutation_s *hashnext;
4718 unsigned int permutation;
4720 /// indicates if we have tried compiling this permutation already
4722 /// 0 if compilation failed
4724 // texture units assigned to each detected uniform
4725 int tex_Texture_First;
4726 int tex_Texture_Second;
4727 int tex_Texture_GammaRamps;
4728 int tex_Texture_Normal;
4729 int tex_Texture_Color;
4730 int tex_Texture_Gloss;
4731 int tex_Texture_Glow;
4732 int tex_Texture_SecondaryNormal;
4733 int tex_Texture_SecondaryColor;
4734 int tex_Texture_SecondaryGloss;
4735 int tex_Texture_SecondaryGlow;
4736 int tex_Texture_Pants;
4737 int tex_Texture_Shirt;
4738 int tex_Texture_FogHeightTexture;
4739 int tex_Texture_FogMask;
4740 int tex_Texture_Lightmap;
4741 int tex_Texture_Deluxemap;
4742 int tex_Texture_Attenuation;
4743 int tex_Texture_Cube;
4744 int tex_Texture_Refraction;
4745 int tex_Texture_Reflection;
4746 int tex_Texture_ShadowMap2D;
4747 int tex_Texture_CubeProjection;
4748 int tex_Texture_ScreenDepth;
4749 int tex_Texture_ScreenNormalMap;
4750 int tex_Texture_ScreenDiffuse;
4751 int tex_Texture_ScreenSpecular;
4752 int tex_Texture_ReflectMask;
4753 int tex_Texture_ReflectCube;
4754 /// locations of detected uniforms in program object, or -1 if not found
4755 int loc_Texture_First;
4756 int loc_Texture_Second;
4757 int loc_Texture_GammaRamps;
4758 int loc_Texture_Normal;
4759 int loc_Texture_Color;
4760 int loc_Texture_Gloss;
4761 int loc_Texture_Glow;
4762 int loc_Texture_SecondaryNormal;
4763 int loc_Texture_SecondaryColor;
4764 int loc_Texture_SecondaryGloss;
4765 int loc_Texture_SecondaryGlow;
4766 int loc_Texture_Pants;
4767 int loc_Texture_Shirt;
4768 int loc_Texture_FogHeightTexture;
4769 int loc_Texture_FogMask;
4770 int loc_Texture_Lightmap;
4771 int loc_Texture_Deluxemap;
4772 int loc_Texture_Attenuation;
4773 int loc_Texture_Cube;
4774 int loc_Texture_Refraction;
4775 int loc_Texture_Reflection;
4776 int loc_Texture_ShadowMap2D;
4777 int loc_Texture_CubeProjection;
4778 int loc_Texture_ScreenDepth;
4779 int loc_Texture_ScreenNormalMap;
4780 int loc_Texture_ScreenDiffuse;
4781 int loc_Texture_ScreenSpecular;
4782 int loc_Texture_ReflectMask;
4783 int loc_Texture_ReflectCube;
4785 int loc_BloomBlur_Parameters;
4787 int loc_Color_Ambient;
4788 int loc_Color_Diffuse;
4789 int loc_Color_Specular;
4791 int loc_Color_Pants;
4792 int loc_Color_Shirt;
4793 int loc_DeferredColor_Ambient;
4794 int loc_DeferredColor_Diffuse;
4795 int loc_DeferredColor_Specular;
4796 int loc_DeferredMod_Diffuse;
4797 int loc_DeferredMod_Specular;
4798 int loc_DistortScaleRefractReflect;
4799 int loc_EyePosition;
4801 int loc_FogHeightFade;
4803 int loc_FogPlaneViewDist;
4804 int loc_FogRangeRecip;
4807 int loc_LightPosition;
4808 int loc_OffsetMapping_Scale;
4810 int loc_ReflectColor;
4811 int loc_ReflectFactor;
4812 int loc_ReflectOffset;
4813 int loc_RefractColor;
4815 int loc_ScreenCenterRefractReflect;
4816 int loc_ScreenScaleRefractReflect;
4817 int loc_ScreenToDepth;
4818 int loc_ShadowMap_Parameters;
4819 int loc_ShadowMap_TextureScale;
4820 int loc_SpecularPower;
4825 int loc_ViewTintColor;
4826 int loc_ViewToLight;
4827 int loc_ModelToLight;
4829 int loc_BackgroundTexMatrix;
4830 int loc_ModelViewProjectionMatrix;
4831 int loc_ModelViewMatrix;
4832 int loc_PixelToScreenTexCoord;
4833 int loc_ModelToReflectCube;
4834 int loc_ShadowMapMatrix;
4835 int loc_BloomColorSubtract;
4836 int loc_NormalmapScrollBlend;
4838 r_glsl_permutation_t;
4840 #define SHADERPERMUTATION_HASHSIZE 256
4843 // non-degradable "lightweight" shader parameters to keep the permutations simpler
4844 // these can NOT degrade! only use for simple stuff
4847 SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0, ///< red compensation filter for saturation
4848 SHADERSTATICPARM_EXACTSPECULARMATH = 1, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
4849 SHADERSTATICPARM_POSTPROCESS_USERVEC1 = 2, ///< postprocess uservec1 is enabled
4850 SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
4851 SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
4852 SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5 ///< postprocess uservec4 is enabled
4854 #define SHADERSTATICPARMS_COUNT 6
4856 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
4857 static int shaderstaticparms_count = 0;
4859 static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
4860 #define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
4861 qboolean R_CompileShader_CheckStaticParms(void)
4863 static int r_compileshader_staticparms_save[1];
4864 memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
4865 memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
4868 if (r_glsl_saturation_redcompensate.integer)
4869 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
4870 if (r_shadow_glossexact.integer)
4871 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_EXACTSPECULARMATH);
4872 if (r_glsl_postprocess.integer)
4874 if (r_glsl_postprocess_uservec1_enable.integer)
4875 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC1);
4876 if (r_glsl_postprocess_uservec2_enable.integer)
4877 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC2);
4878 if (r_glsl_postprocess_uservec3_enable.integer)
4879 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC3);
4880 if (r_glsl_postprocess_uservec4_enable.integer)
4881 R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
4883 return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
4886 #define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
4887 if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
4888 shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
4890 shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
4891 void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
4893 shaderstaticparms_count = 0;
4896 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
4897 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_EXACTSPECULARMATH, "USEEXACTSPECULARMATH");
4898 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC1, "USERVEC1");
4899 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC2, "USERVEC2");
4900 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
4901 R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
4904 /// information about each possible shader permutation
4905 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
4906 /// currently selected permutation
4907 r_glsl_permutation_t *r_glsl_permutation;
4908 /// storage for permutations linked in the hash table
4909 memexpandablearray_t r_glsl_permutationarray;
4911 static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, unsigned int permutation)
4913 //unsigned int hashdepth = 0;
4914 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
4915 r_glsl_permutation_t *p;
4916 for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
4918 if (p->mode == mode && p->permutation == permutation)
4920 //if (hashdepth > 10)
4921 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
4926 p = (r_glsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_glsl_permutationarray);
4928 p->permutation = permutation;
4929 p->hashnext = r_glsl_permutationhash[mode][hashindex];
4930 r_glsl_permutationhash[mode][hashindex] = p;
4931 //if (hashdepth > 10)
4932 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
4936 static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice)
4939 if (!filename || !filename[0])
4941 if (!strcmp(filename, "glsl/default.glsl"))
4943 if (!glslshaderstring)
4945 glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
4946 if (glslshaderstring)
4947 Con_DPrintf("Loading shaders from file %s...\n", filename);
4949 glslshaderstring = (char *)builtinshaderstring;
4951 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1);
4952 memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1);
4953 return shaderstring;
4955 if (!strcmp(filename, "gles2/default.glsl"))
4957 if (!glslshaderstring)
4959 glslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
4960 if (glslshaderstring)
4961 Con_DPrintf("Loading shaders from file %s...\n", filename);
4963 glslshaderstring = (char *)builtingles2shaderstring;
4965 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(glslshaderstring) + 1);
4966 memcpy(shaderstring, glslshaderstring, strlen(glslshaderstring) + 1);
4967 return shaderstring;
4969 shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
4972 if (printfromdisknotice)
4973 Con_DPrintf("from disk %s... ", filename);
4974 return shaderstring;
4976 return shaderstring;
4979 static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
4983 shadermodeinfo_t *modeinfo = vid.renderpath == RENDERPATH_GLES2 ? gles2shadermodeinfo + mode : glslshadermodeinfo + mode;
4984 char *vertexstring, *geometrystring, *fragmentstring;
4985 char permutationname[256];
4986 int vertstrings_count = 0;
4987 int geomstrings_count = 0;
4988 int fragstrings_count = 0;
4989 const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
4990 const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
4991 const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
4998 permutationname[0] = 0;
4999 vertexstring = R_GLSL_GetText(modeinfo->vertexfilename, true);
5000 geometrystring = R_GLSL_GetText(modeinfo->geometryfilename, false);
5001 fragmentstring = R_GLSL_GetText(modeinfo->fragmentfilename, false);
5003 strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
5005 // the first pretext is which type of shader to compile as
5006 // (later these will all be bound together as a program object)
5007 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
5008 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
5009 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
5011 // the second pretext is the mode (for example a light source)
5012 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
5013 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
5014 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
5015 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
5017 // now add all the permutation pretexts
5018 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
5020 if (permutation & (1<<i))
5022 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
5023 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
5024 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
5025 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
5029 // keep line numbers correct
5030 vertstrings_list[vertstrings_count++] = "\n";
5031 geomstrings_list[geomstrings_count++] = "\n";
5032 fragstrings_list[fragstrings_count++] = "\n";
5037 R_CompileShader_AddStaticParms(mode, permutation);
5038 memcpy((char *)(vertstrings_list + vertstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5039 vertstrings_count += shaderstaticparms_count;
5040 memcpy((char *)(geomstrings_list + geomstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5041 geomstrings_count += shaderstaticparms_count;
5042 memcpy((char *)(fragstrings_list + fragstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5043 fragstrings_count += shaderstaticparms_count;
5045 // now append the shader text itself
5046 vertstrings_list[vertstrings_count++] = vertexstring;
5047 geomstrings_list[geomstrings_count++] = geometrystring;
5048 fragstrings_list[fragstrings_count++] = fragmentstring;
5050 // if any sources were NULL, clear the respective list
5052 vertstrings_count = 0;
5053 if (!geometrystring)
5054 geomstrings_count = 0;
5055 if (!fragmentstring)
5056 fragstrings_count = 0;
5058 // compile the shader program
5059 if (vertstrings_count + geomstrings_count + fragstrings_count)
5060 p->program = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, geomstrings_count, geomstrings_list, fragstrings_count, fragstrings_list);
5064 qglUseProgram(p->program);CHECKGLERROR
5065 // look up all the uniform variable names we care about, so we don't
5066 // have to look them up every time we set them
5068 p->loc_Texture_First = qglGetUniformLocation(p->program, "Texture_First");
5069 p->loc_Texture_Second = qglGetUniformLocation(p->program, "Texture_Second");
5070 p->loc_Texture_GammaRamps = qglGetUniformLocation(p->program, "Texture_GammaRamps");
5071 p->loc_Texture_Normal = qglGetUniformLocation(p->program, "Texture_Normal");
5072 p->loc_Texture_Color = qglGetUniformLocation(p->program, "Texture_Color");
5073 p->loc_Texture_Gloss = qglGetUniformLocation(p->program, "Texture_Gloss");
5074 p->loc_Texture_Glow = qglGetUniformLocation(p->program, "Texture_Glow");
5075 p->loc_Texture_SecondaryNormal = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
5076 p->loc_Texture_SecondaryColor = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
5077 p->loc_Texture_SecondaryGloss = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
5078 p->loc_Texture_SecondaryGlow = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
5079 p->loc_Texture_Pants = qglGetUniformLocation(p->program, "Texture_Pants");
5080 p->loc_Texture_Shirt = qglGetUniformLocation(p->program, "Texture_Shirt");
5081 p->loc_Texture_FogHeightTexture = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
5082 p->loc_Texture_FogMask = qglGetUniformLocation(p->program, "Texture_FogMask");
5083 p->loc_Texture_Lightmap = qglGetUniformLocation(p->program, "Texture_Lightmap");
5084 p->loc_Texture_Deluxemap = qglGetUniformLocation(p->program, "Texture_Deluxemap");
5085 p->loc_Texture_Attenuation = qglGetUniformLocation(p->program, "Texture_Attenuation");
5086 p->loc_Texture_Cube = qglGetUniformLocation(p->program, "Texture_Cube");
5087 p->loc_Texture_Refraction = qglGetUniformLocation(p->program, "Texture_Refraction");
5088 p->loc_Texture_Reflection = qglGetUniformLocation(p->program, "Texture_Reflection");
5089 p->loc_Texture_ShadowMap2D = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
5090 p->loc_Texture_CubeProjection = qglGetUniformLocation(p->program, "Texture_CubeProjection");
5091 p->loc_Texture_ScreenDepth = qglGetUniformLocation(p->program, "Texture_ScreenDepth");
5092 p->loc_Texture_ScreenNormalMap = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
5093 p->loc_Texture_ScreenDiffuse = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
5094 p->loc_Texture_ScreenSpecular = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
5095 p->loc_Texture_ReflectMask = qglGetUniformLocation(p->program, "Texture_ReflectMask");
5096 p->loc_Texture_ReflectCube = qglGetUniformLocation(p->program, "Texture_ReflectCube");
5097 p->loc_Alpha = qglGetUniformLocation(p->program, "Alpha");
5098 p->loc_BloomBlur_Parameters = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
5099 p->loc_ClientTime = qglGetUniformLocation(p->program, "ClientTime");
5100 p->loc_Color_Ambient = qglGetUniformLocation(p->program, "Color_Ambient");
5101 p->loc_Color_Diffuse = qglGetUniformLocation(p->program, "Color_Diffuse");
5102 p->loc_Color_Specular = qglGetUniformLocation(p->program, "Color_Specular");
5103 p->loc_Color_Glow = qglGetUniformLocation(p->program, "Color_Glow");
5104 p->loc_Color_Pants = qglGetUniformLocation(p->program, "Color_Pants");
5105 p->loc_Color_Shirt = qglGetUniformLocation(p->program, "Color_Shirt");
5106 p->loc_DeferredColor_Ambient = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
5107 p->loc_DeferredColor_Diffuse = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
5108 p->loc_DeferredColor_Specular = qglGetUniformLocation(p->program, "DeferredColor_Specular");
5109 p->loc_DeferredMod_Diffuse = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
5110 p->loc_DeferredMod_Specular = qglGetUniformLocation(p->program, "DeferredMod_Specular");
5111 p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
5112 p->loc_EyePosition = qglGetUniformLocation(p->program, "EyePosition");
5113 p->loc_FogColor = qglGetUniformLocation(p->program, "FogColor");
5114 p->loc_FogHeightFade = qglGetUniformLocation(p->program, "FogHeightFade");
5115 p->loc_FogPlane = qglGetUniformLocation(p->program, "FogPlane");
5116 p->loc_FogPlaneViewDist = qglGetUniformLocation(p->program, "FogPlaneViewDist");
5117 p->loc_FogRangeRecip = qglGetUniformLocation(p->program, "FogRangeRecip");
5118 p->loc_LightColor = qglGetUniformLocation(p->program, "LightColor");
5119 p->loc_LightDir = qglGetUniformLocation(p->program, "LightDir");
5120 p->loc_LightPosition = qglGetUniformLocation(p->program, "LightPosition");
5121 p->loc_OffsetMapping_Scale = qglGetUniformLocation(p->program, "OffsetMapping_Scale");
5122 p->loc_PixelSize = qglGetUniformLocation(p->program, "PixelSize");
5123 p->loc_ReflectColor = qglGetUniformLocation(p->program, "ReflectColor");
5124 p->loc_ReflectFactor = qglGetUniformLocation(p->program, "ReflectFactor");
5125 p->loc_ReflectOffset = qglGetUniformLocation(p->program, "ReflectOffset");
5126 p->loc_RefractColor = qglGetUniformLocation(p->program, "RefractColor");
5127 p->loc_Saturation = qglGetUniformLocation(p->program, "Saturation");
5128 p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
5129 p->loc_ScreenScaleRefractReflect = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
5130 p->loc_ScreenToDepth = qglGetUniformLocation(p->program, "ScreenToDepth");
5131 p->loc_ShadowMap_Parameters = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
5132 p->loc_ShadowMap_TextureScale = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
5133 p->loc_SpecularPower = qglGetUniformLocation(p->program, "SpecularPower");
5134 p->loc_UserVec1 = qglGetUniformLocation(p->program, "UserVec1");
5135 p->loc_UserVec2 = qglGetUniformLocation(p->program, "UserVec2");
5136 p->loc_UserVec3 = qglGetUniformLocation(p->program, "UserVec3");
5137 p->loc_UserVec4 = qglGetUniformLocation(p->program, "UserVec4");
5138 p->loc_ViewTintColor = qglGetUniformLocation(p->program, "ViewTintColor");
5139 p->loc_ViewToLight = qglGetUniformLocation(p->program, "ViewToLight");
5140 p->loc_ModelToLight = qglGetUniformLocation(p->program, "ModelToLight");
5141 p->loc_TexMatrix = qglGetUniformLocation(p->program, "TexMatrix");
5142 p->loc_BackgroundTexMatrix = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
5143 p->loc_ModelViewMatrix = qglGetUniformLocation(p->program, "ModelViewMatrix");
5144 p->loc_ModelViewProjectionMatrix = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
5145 p->loc_PixelToScreenTexCoord = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
5146 p->loc_ModelToReflectCube = qglGetUniformLocation(p->program, "ModelToReflectCube");
5147 p->loc_ShadowMapMatrix = qglGetUniformLocation(p->program, "ShadowMapMatrix");
5148 p->loc_BloomColorSubtract = qglGetUniformLocation(p->program, "BloomColorSubtract");
5149 p->loc_NormalmapScrollBlend = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
5150 // initialize the samplers to refer to the texture units we use
5151 p->tex_Texture_First = -1;
5152 p->tex_Texture_Second = -1;
5153 p->tex_Texture_GammaRamps = -1;
5154 p->tex_Texture_Normal = -1;
5155 p->tex_Texture_Color = -1;
5156 p->tex_Texture_Gloss = -1;
5157 p->tex_Texture_Glow = -1;
5158 p->tex_Texture_SecondaryNormal = -1;
5159 p->tex_Texture_SecondaryColor = -1;
5160 p->tex_Texture_SecondaryGloss = -1;
5161 p->tex_Texture_SecondaryGlow = -1;
5162 p->tex_Texture_Pants = -1;
5163 p->tex_Texture_Shirt = -1;
5164 p->tex_Texture_FogHeightTexture = -1;
5165 p->tex_Texture_FogMask = -1;
5166 p->tex_Texture_Lightmap = -1;
5167 p->tex_Texture_Deluxemap = -1;
5168 p->tex_Texture_Attenuation = -1;
5169 p->tex_Texture_Cube = -1;
5170 p->tex_Texture_Refraction = -1;
5171 p->tex_Texture_Reflection = -1;
5172 p->tex_Texture_ShadowMap2D = -1;
5173 p->tex_Texture_CubeProjection = -1;
5174 p->tex_Texture_ScreenDepth = -1;
5175 p->tex_Texture_ScreenNormalMap = -1;
5176 p->tex_Texture_ScreenDiffuse = -1;
5177 p->tex_Texture_ScreenSpecular = -1;
5178 p->tex_Texture_ReflectMask = -1;
5179 p->tex_Texture_ReflectCube = -1;
5181 if (p->loc_Texture_First >= 0) {p->tex_Texture_First = sampler;qglUniform1i(p->loc_Texture_First , sampler);sampler++;}
5182 if (p->loc_Texture_Second >= 0) {p->tex_Texture_Second = sampler;qglUniform1i(p->loc_Texture_Second , sampler);sampler++;}
5183 if (p->loc_Texture_GammaRamps >= 0) {p->tex_Texture_GammaRamps = sampler;qglUniform1i(p->loc_Texture_GammaRamps , sampler);sampler++;}
5184 if (p->loc_Texture_Normal >= 0) {p->tex_Texture_Normal = sampler;qglUniform1i(p->loc_Texture_Normal , sampler);sampler++;}
5185 if (p->loc_Texture_Color >= 0) {p->tex_Texture_Color = sampler;qglUniform1i(p->loc_Texture_Color , sampler);sampler++;}
5186 if (p->loc_Texture_Gloss >= 0) {p->tex_Texture_Gloss = sampler;qglUniform1i(p->loc_Texture_Gloss , sampler);sampler++;}
5187 if (p->loc_Texture_Glow >= 0) {p->tex_Texture_Glow = sampler;qglUniform1i(p->loc_Texture_Glow , sampler);sampler++;}
5188 if (p->loc_Texture_SecondaryNormal >= 0) {p->tex_Texture_SecondaryNormal = sampler;qglUniform1i(p->loc_Texture_SecondaryNormal , sampler);sampler++;}
5189 if (p->loc_Texture_SecondaryColor >= 0) {p->tex_Texture_SecondaryColor = sampler;qglUniform1i(p->loc_Texture_SecondaryColor , sampler);sampler++;}
5190 if (p->loc_Texture_SecondaryGloss >= 0) {p->tex_Texture_SecondaryGloss = sampler;qglUniform1i(p->loc_Texture_SecondaryGloss , sampler);sampler++;}
5191 if (p->loc_Texture_SecondaryGlow >= 0) {p->tex_Texture_SecondaryGlow = sampler;qglUniform1i(p->loc_Texture_SecondaryGlow , sampler);sampler++;}
5192 if (p->loc_Texture_Pants >= 0) {p->tex_Texture_Pants = sampler;qglUniform1i(p->loc_Texture_Pants , sampler);sampler++;}
5193 if (p->loc_Texture_Shirt >= 0) {p->tex_Texture_Shirt = sampler;qglUniform1i(p->loc_Texture_Shirt , sampler);sampler++;}
5194 if (p->loc_Texture_FogHeightTexture>= 0) {p->tex_Texture_FogHeightTexture = sampler;qglUniform1i(p->loc_Texture_FogHeightTexture, sampler);sampler++;}
5195 if (p->loc_Texture_FogMask >= 0) {p->tex_Texture_FogMask = sampler;qglUniform1i(p->loc_Texture_FogMask , sampler);sampler++;}
5196 if (p->loc_Texture_Lightmap >= 0) {p->tex_Texture_Lightmap = sampler;qglUniform1i(p->loc_Texture_Lightmap , sampler);sampler++;}
5197 if (p->loc_Texture_Deluxemap >= 0) {p->tex_Texture_Deluxemap = sampler;qglUniform1i(p->loc_Texture_Deluxemap , sampler);sampler++;}
5198 if (p->loc_Texture_Attenuation >= 0) {p->tex_Texture_Attenuation = sampler;qglUniform1i(p->loc_Texture_Attenuation , sampler);sampler++;}
5199 if (p->loc_Texture_Cube >= 0) {p->tex_Texture_Cube = sampler;qglUniform1i(p->loc_Texture_Cube , sampler);sampler++;}
5200 if (p->loc_Texture_Refraction >= 0) {p->tex_Texture_Refraction = sampler;qglUniform1i(p->loc_Texture_Refraction , sampler);sampler++;}
5201 if (p->loc_Texture_Reflection >= 0) {p->tex_Texture_Reflection = sampler;qglUniform1i(p->loc_Texture_Reflection , sampler);sampler++;}
5202 if (p->loc_Texture_ShadowMap2D >= 0) {p->tex_Texture_ShadowMap2D = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D , sampler);sampler++;}
5203 if (p->loc_Texture_CubeProjection >= 0) {p->tex_Texture_CubeProjection = sampler;qglUniform1i(p->loc_Texture_CubeProjection , sampler);sampler++;}
5204 if (p->loc_Texture_ScreenDepth >= 0) {p->tex_Texture_ScreenDepth = sampler;qglUniform1i(p->loc_Texture_ScreenDepth , sampler);sampler++;}
5205 if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
5206 if (p->loc_Texture_ScreenDiffuse >= 0) {p->tex_Texture_ScreenDiffuse = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse , sampler);sampler++;}
5207 if (p->loc_Texture_ScreenSpecular >= 0) {p->tex_Texture_ScreenSpecular = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular , sampler);sampler++;}
5208 if (p->loc_Texture_ReflectMask >= 0) {p->tex_Texture_ReflectMask = sampler;qglUniform1i(p->loc_Texture_ReflectMask , sampler);sampler++;}
5209 if (p->loc_Texture_ReflectCube >= 0) {p->tex_Texture_ReflectCube = sampler;qglUniform1i(p->loc_Texture_ReflectCube , sampler);sampler++;}
5210 if (vid.renderpath == RENDERPATH_GLES2)
5212 qglBindAttribLocation(p->program, GLES2ATTRIB_POSITION , "Attrib_Position" );
5213 qglBindAttribLocation(p->program, GLES2ATTRIB_COLOR , "Attrib_Color" );
5214 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD0, "Attrib_TexCoord0");
5215 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD1, "Attrib_TexCoord1");
5216 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD2, "Attrib_TexCoord2");
5217 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD3, "Attrib_TexCoord3");
5218 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD4, "Attrib_TexCoord4");
5219 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD5, "Attrib_TexCoord5");
5220 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD6, "Attrib_TexCoord6");
5221 qglBindAttribLocation(p->program, GLES2ATTRIB_TEXCOORD7, "Attrib_TexCoord7");
5224 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
5227 Con_Printf("^1GLSL shader %s failed! some features may not work properly.\n", permutationname);
5231 Mem_Free(vertexstring);
5233 Mem_Free(geometrystring);
5235 Mem_Free(fragmentstring);
5238 void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
5240 r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
5241 if (r_glsl_permutation != perm)
5243 r_glsl_permutation = perm;
5244 if (!r_glsl_permutation->program)
5246 if (!r_glsl_permutation->compiled)
5247 R_GLSL_CompilePermutation(perm, mode, permutation);
5248 if (!r_glsl_permutation->program)
5250 // remove features until we find a valid permutation
5252 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
5254 // reduce i more quickly whenever it would not remove any bits
5255 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
5256 if (!(permutation & j))
5259 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
5260 if (!r_glsl_permutation->compiled)
5261 R_GLSL_CompilePermutation(perm, mode, permutation);
5262 if (r_glsl_permutation->program)
5265 if (i >= SHADERPERMUTATION_COUNT)
5267 //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
5268 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
5269 qglUseProgram(0);CHECKGLERROR
5270 return; // no bit left to clear, entire mode is broken
5275 qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
5277 if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
5278 if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
5279 if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
5283 #include <Cg/cgGL.h>
5284 struct r_cg_permutation_s;
5285 typedef struct r_cg_permutation_s
5287 /// hash lookup data
5288 struct r_cg_permutation_s *hashnext;
5290 unsigned int permutation;
5292 /// indicates if we have tried compiling this permutation already
5294 /// 0 if compilation failed
5297 /// locations of detected parameters in programs, or NULL if not found
5298 CGparameter vp_EyePosition;
5299 CGparameter vp_FogPlane;
5300 CGparameter vp_LightDir;
5301 CGparameter vp_LightPosition;
5302 CGparameter vp_ModelToLight;
5303 CGparameter vp_TexMatrix;
5304 CGparameter vp_BackgroundTexMatrix;
5305 CGparameter vp_ModelViewProjectionMatrix;
5306 CGparameter vp_ModelViewMatrix;
5307 CGparameter vp_ShadowMapMatrix;
5309 CGparameter fp_Texture_First;
5310 CGparameter fp_Texture_Second;
5311 CGparameter fp_Texture_GammaRamps;
5312 CGparameter fp_Texture_Normal;
5313 CGparameter fp_Texture_Color;
5314 CGparameter fp_Texture_Gloss;
5315 CGparameter fp_Texture_Glow;
5316 CGparameter fp_Texture_SecondaryNormal;
5317 CGparameter fp_Texture_SecondaryColor;
5318 CGparameter fp_Texture_SecondaryGloss;
5319 CGparameter fp_Texture_SecondaryGlow;
5320 CGparameter fp_Texture_Pants;
5321 CGparameter fp_Texture_Shirt;
5322 CGparameter fp_Texture_FogHeightTexture;
5323 CGparameter fp_Texture_FogMask;
5324 CGparameter fp_Texture_Lightmap;
5325 CGparameter fp_Texture_Deluxemap;
5326 CGparameter fp_Texture_Attenuation;
5327 CGparameter fp_Texture_Cube;
5328 CGparameter fp_Texture_Refraction;
5329 CGparameter fp_Texture_Reflection;
5330 CGparameter fp_Texture_ShadowMap2D;
5331 CGparameter fp_Texture_CubeProjection;
5332 CGparameter fp_Texture_ScreenDepth;
5333 CGparameter fp_Texture_ScreenNormalMap;
5334 CGparameter fp_Texture_ScreenDiffuse;
5335 CGparameter fp_Texture_ScreenSpecular;
5336 CGparameter fp_Texture_ReflectMask;
5337 CGparameter fp_Texture_ReflectCube;
5338 CGparameter fp_Alpha;
5339 CGparameter fp_BloomBlur_Parameters;
5340 CGparameter fp_ClientTime;
5341 CGparameter fp_Color_Ambient;
5342 CGparameter fp_Color_Diffuse;
5343 CGparameter fp_Color_Specular;
5344 CGparameter fp_Color_Glow;
5345 CGparameter fp_Color_Pants;
5346 CGparameter fp_Color_Shirt;
5347 CGparameter fp_DeferredColor_Ambient;
5348 CGparameter fp_DeferredColor_Diffuse;
5349 CGparameter fp_DeferredColor_Specular;
5350 CGparameter fp_DeferredMod_Diffuse;
5351 CGparameter fp_DeferredMod_Specular;
5352 CGparameter fp_DistortScaleRefractReflect;
5353 CGparameter fp_EyePosition;
5354 CGparameter fp_FogColor;
5355 CGparameter fp_FogHeightFade;
5356 CGparameter fp_FogPlane;
5357 CGparameter fp_FogPlaneViewDist;
5358 CGparameter fp_FogRangeRecip;
5359 CGparameter fp_LightColor;
5360 CGparameter fp_LightDir;
5361 CGparameter fp_LightPosition;
5362 CGparameter fp_OffsetMapping_Scale;
5363 CGparameter fp_PixelSize;
5364 CGparameter fp_ReflectColor;
5365 CGparameter fp_ReflectFactor;
5366 CGparameter fp_ReflectOffset;
5367 CGparameter fp_RefractColor;
5368 CGparameter fp_Saturation;
5369 CGparameter fp_ScreenCenterRefractReflect;
5370 CGparameter fp_ScreenScaleRefractReflect;
5371 CGparameter fp_ScreenToDepth;
5372 CGparameter fp_ShadowMap_Parameters;
5373 CGparameter fp_ShadowMap_TextureScale;
5374 CGparameter fp_SpecularPower;
5375 CGparameter fp_UserVec1;
5376 CGparameter fp_UserVec2;
5377 CGparameter fp_UserVec3;
5378 CGparameter fp_UserVec4;
5379 CGparameter fp_ViewTintColor;
5380 CGparameter fp_ViewToLight;
5381 CGparameter fp_PixelToScreenTexCoord;
5382 CGparameter fp_ModelToReflectCube;
5383 CGparameter fp_BloomColorSubtract;
5384 CGparameter fp_NormalmapScrollBlend;
5388 /// information about each possible shader permutation
5389 r_cg_permutation_t *r_cg_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
5390 /// currently selected permutation
5391 r_cg_permutation_t *r_cg_permutation;
5392 /// storage for permutations linked in the hash table
5393 memexpandablearray_t r_cg_permutationarray;
5395 #define CHECKCGERROR {CGerror err = cgGetError(), err2 = err;if (err){Con_Printf("%s:%i CG error %i: %s : %s\n", __FILE__, __LINE__, err, cgGetErrorString(err), cgGetLastErrorString(&err2));if (err == 1) Con_Printf("last listing:\n%s\n", cgGetLastListing(vid.cgcontext));}}
5397 static r_cg_permutation_t *R_CG_FindPermutation(unsigned int mode, unsigned int permutation)
5399 //unsigned int hashdepth = 0;
5400 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
5401 r_cg_permutation_t *p;
5402 for (p = r_cg_permutationhash[mode][hashindex];p;p = p->hashnext)
5404 if (p->mode == mode && p->permutation == permutation)
5406 //if (hashdepth > 10)
5407 // Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5412 p = (r_cg_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_cg_permutationarray);
5414 p->permutation = permutation;
5415 p->hashnext = r_cg_permutationhash[mode][hashindex];
5416 r_cg_permutationhash[mode][hashindex] = p;
5417 //if (hashdepth > 10)
5418 // Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5422 static char *R_CG_GetText(const char *filename, qboolean printfromdisknotice)
5425 if (!filename || !filename[0])
5427 if (!strcmp(filename, "cg/default.cg"))
5429 if (!cgshaderstring)
5431 cgshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5433 Con_DPrintf("Loading shaders from file %s...\n", filename);
5435 cgshaderstring = (char *)builtincgshaderstring;
5437 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(cgshaderstring) + 1);
5438 memcpy(shaderstring, cgshaderstring, strlen(cgshaderstring) + 1);
5439 return shaderstring;
5441 shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5444 if (printfromdisknotice)
5445 Con_DPrintf("from disk %s... ", filename);
5446 return shaderstring;
5448 return shaderstring;
5451 static void R_CG_CacheShader(r_cg_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
5453 // TODO: load or create .fp and .vp shader files
5456 static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, unsigned int permutation)
5459 shadermodeinfo_t *modeinfo = cgshadermodeinfo + mode;
5460 int vertstring_length = 0;
5461 int geomstring_length = 0;
5462 int fragstring_length = 0;
5464 char *vertexstring, *geometrystring, *fragmentstring;
5465 char *vertstring, *geomstring, *fragstring;
5466 char permutationname[256];
5467 char cachename[256];
5468 CGprofile vertexProfile;
5469 CGprofile fragmentProfile;
5470 int vertstrings_count = 0;
5471 int geomstrings_count = 0;
5472 int fragstrings_count = 0;
5473 const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
5474 const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
5475 const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
5483 permutationname[0] = 0;
5485 vertexstring = R_CG_GetText(modeinfo->vertexfilename, true);
5486 geometrystring = R_CG_GetText(modeinfo->geometryfilename, false);
5487 fragmentstring = R_CG_GetText(modeinfo->fragmentfilename, false);
5489 strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
5490 strlcat(cachename, "cg/", sizeof(cachename));
5492 // the first pretext is which type of shader to compile as
5493 // (later these will all be bound together as a program object)
5494 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
5495 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
5496 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
5498 // the second pretext is the mode (for example a light source)
5499 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
5500 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
5501 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
5502 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
5503 strlcat(cachename, modeinfo->name, sizeof(cachename));
5505 // now add all the permutation pretexts
5506 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
5508 if (permutation & (1<<i))
5510 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
5511 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
5512 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
5513 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
5514 strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
5518 // keep line numbers correct
5519 vertstrings_list[vertstrings_count++] = "\n";
5520 geomstrings_list[geomstrings_count++] = "\n";
5521 fragstrings_list[fragstrings_count++] = "\n";
5526 R_CompileShader_AddStaticParms(mode, permutation);
5527 memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5528 vertstrings_count += shaderstaticparms_count;
5529 memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5530 geomstrings_count += shaderstaticparms_count;
5531 memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5532 fragstrings_count += shaderstaticparms_count;
5534 // replace spaces in the cachename with _ characters
5535 for (i = 0;cachename[i];i++)
5536 if (cachename[i] == ' ')
5539 // now append the shader text itself
5540 vertstrings_list[vertstrings_count++] = vertexstring;
5541 geomstrings_list[geomstrings_count++] = geometrystring;
5542 fragstrings_list[fragstrings_count++] = fragmentstring;
5544 // if any sources were NULL, clear the respective list
5546 vertstrings_count = 0;
5547 if (!geometrystring)
5548 geomstrings_count = 0;
5549 if (!fragmentstring)
5550 fragstrings_count = 0;
5552 vertstring_length = 0;
5553 for (i = 0;i < vertstrings_count;i++)
5554 vertstring_length += strlen(vertstrings_list[i]);
5555 vertstring = t = Mem_Alloc(tempmempool, vertstring_length + 1);
5556 for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
5557 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
5559 geomstring_length = 0;
5560 for (i = 0;i < geomstrings_count;i++)
5561 geomstring_length += strlen(geomstrings_list[i]);
5562 geomstring = t = Mem_Alloc(tempmempool, geomstring_length + 1);
5563 for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
5564 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
5566 fragstring_length = 0;
5567 for (i = 0;i < fragstrings_count;i++)
5568 fragstring_length += strlen(fragstrings_list[i]);
5569 fragstring = t = Mem_Alloc(tempmempool, fragstring_length + 1);
5570 for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
5571 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
5575 //vertexProfile = CG_PROFILE_ARBVP1;
5576 //fragmentProfile = CG_PROFILE_ARBFP1;
5577 vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);CHECKCGERROR
5578 fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);CHECKCGERROR
5579 //cgGLSetOptimalOptions(vertexProfile);CHECKCGERROR
5580 //cgGLSetOptimalOptions(fragmentProfile);CHECKCGERROR
5581 //cgSetAutoCompile(vid.cgcontext, CG_COMPILE_MANUAL);CHECKCGERROR
5584 // try to load the cached shader, or generate one
5585 R_CG_CacheShader(p, cachename, vertstring, fragstring);
5587 // if caching failed, do a dynamic compile for now
5589 if (vertstring[0] && !p->vprogram)
5590 p->vprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, vertstring, vertexProfile, NULL, NULL);
5592 if (fragstring[0] && !p->fprogram)
5593 p->fprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, fragstring, fragmentProfile, NULL, NULL);
5596 // look up all the uniform variable names we care about, so we don't
5597 // have to look them up every time we set them
5601 cgGLLoadProgram(p->vprogram);CHECKCGERROR CHECKGLERROR
5602 cgGLEnableProfile(vertexProfile);CHECKCGERROR CHECKGLERROR
5603 p->vp_EyePosition = cgGetNamedParameter(p->vprogram, "EyePosition");
5604 p->vp_FogPlane = cgGetNamedParameter(p->vprogram, "FogPlane");
5605 p->vp_LightDir = cgGetNamedParameter(p->vprogram, "LightDir");
5606 p->vp_LightPosition = cgGetNamedParameter(p->vprogram, "LightPosition");
5607 p->vp_ModelToLight = cgGetNamedParameter(p->vprogram, "ModelToLight");
5608 p->vp_TexMatrix = cgGetNamedParameter(p->vprogram, "TexMatrix");
5609 p->vp_BackgroundTexMatrix = cgGetNamedParameter(p->vprogram, "BackgroundTexMatrix");
5610 p->vp_ModelViewProjectionMatrix = cgGetNamedParameter(p->vprogram, "ModelViewProjectionMatrix");
5611 p->vp_ModelViewMatrix = cgGetNamedParameter(p->vprogram, "ModelViewMatrix");
5612 p->vp_ShadowMapMatrix = cgGetNamedParameter(p->vprogram, "ShadowMapMatrix");
5618 cgGLLoadProgram(p->fprogram);CHECKCGERROR CHECKGLERROR
5619 cgGLEnableProfile(fragmentProfile);CHECKCGERROR CHECKGLERROR
5620 p->fp_Texture_First = cgGetNamedParameter(p->fprogram, "Texture_First");
5621 p->fp_Texture_Second = cgGetNamedParameter(p->fprogram, "Texture_Second");
5622 p->fp_Texture_GammaRamps = cgGetNamedParameter(p->fprogram, "Texture_GammaRamps");
5623 p->fp_Texture_Normal = cgGetNamedParameter(p->fprogram, "Texture_Normal");
5624 p->fp_Texture_Color = cgGetNamedParameter(p->fprogram, "Texture_Color");
5625 p->fp_Texture_Gloss = cgGetNamedParameter(p->fprogram, "Texture_Gloss");
5626 p->fp_Texture_Glow = cgGetNamedParameter(p->fprogram, "Texture_Glow");
5627 p->fp_Texture_SecondaryNormal = cgGetNamedParameter(p->fprogram, "Texture_SecondaryNormal");
5628 p->fp_Texture_SecondaryColor = cgGetNamedParameter(p->fprogram, "Texture_SecondaryColor");
5629 p->fp_Texture_SecondaryGloss = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGloss");
5630 p->fp_Texture_SecondaryGlow = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGlow");
5631 p->fp_Texture_Pants = cgGetNamedParameter(p->fprogram, "Texture_Pants");
5632 p->fp_Texture_Shirt = cgGetNamedParameter(p->fprogram, "Texture_Shirt");
5633 p->fp_Texture_FogHeightTexture = cgGetNamedParameter(p->fprogram, "Texture_FogHeightTexture");
5634 p->fp_Texture_FogMask = cgGetNamedParameter(p->fprogram, "Texture_FogMask");
5635 p->fp_Texture_Lightmap = cgGetNamedParameter(p->fprogram, "Texture_Lightmap");
5636 p->fp_Texture_Deluxemap = cgGetNamedParameter(p->fprogram, "Texture_Deluxemap");
5637 p->fp_Texture_Attenuation = cgGetNamedParameter(p->fprogram, "Texture_Attenuation");
5638 p->fp_Texture_Cube = cgGetNamedParameter(p->fprogram, "Texture_Cube");
5639 p->fp_Texture_Refraction = cgGetNamedParameter(p->fprogram, "Texture_Refraction");
5640 p->fp_Texture_Reflection = cgGetNamedParameter(p->fprogram, "Texture_Reflection");
5641 p->fp_Texture_ShadowMap2D = cgGetNamedParameter(p->fprogram, "Texture_ShadowMap2D");
5642 p->fp_Texture_CubeProjection = cgGetNamedParameter(p->fprogram, "Texture_CubeProjection");
5643 p->fp_Texture_ScreenDepth = cgGetNamedParameter(p->fprogram, "Texture_ScreenDepth");
5644 p->fp_Texture_ScreenNormalMap = cgGetNamedParameter(p->fprogram, "Texture_ScreenNormalMap");
5645 p->fp_Texture_ScreenDiffuse = cgGetNamedParameter(p->fprogram, "Texture_ScreenDiffuse");
5646 p->fp_Texture_ScreenSpecular = cgGetNamedParameter(p->fprogram, "Texture_ScreenSpecular");
5647 p->fp_Texture_ReflectMask = cgGetNamedParameter(p->fprogram, "Texture_ReflectMask");
5648 p->fp_Texture_ReflectCube = cgGetNamedParameter(p->fprogram, "Texture_ReflectCube");
5649 p->fp_Alpha = cgGetNamedParameter(p->fprogram, "Alpha");
5650 p->fp_BloomBlur_Parameters = cgGetNamedParameter(p->fprogram, "BloomBlur_Parameters");
5651 p->fp_ClientTime = cgGetNamedParameter(p->fprogram, "ClientTime");
5652 p->fp_Color_Ambient = cgGetNamedParameter(p->fprogram, "Color_Ambient");
5653 p->fp_Color_Diffuse = cgGetNamedParameter(p->fprogram, "Color_Diffuse");
5654 p->fp_Color_Specular = cgGetNamedParameter(p->fprogram, "Color_Specular");
5655 p->fp_Color_Glow = cgGetNamedParameter(p->fprogram, "Color_Glow");
5656 p->fp_Color_Pants = cgGetNamedParameter(p->fprogram, "Color_Pants");
5657 p->fp_Color_Shirt = cgGetNamedParameter(p->fprogram, "Color_Shirt");
5658 p->fp_DeferredColor_Ambient = cgGetNamedParameter(p->fprogram, "DeferredColor_Ambient");
5659 p->fp_DeferredColor_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredColor_Diffuse");
5660 p->fp_DeferredColor_Specular = cgGetNamedParameter(p->fprogram, "DeferredColor_Specular");
5661 p->fp_DeferredMod_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredMod_Diffuse");
5662 p->fp_DeferredMod_Specular = cgGetNamedParameter(p->fprogram, "DeferredMod_Specular");
5663 p->fp_DistortScaleRefractReflect = cgGetNamedParameter(p->fprogram, "DistortScaleRefractReflect");
5664 p->fp_EyePosition = cgGetNamedParameter(p->fprogram, "EyePosition");
5665 p->fp_FogColor = cgGetNamedParameter(p->fprogram, "FogColor");
5666 p->fp_FogHeightFade = cgGetNamedParameter(p->fprogram, "FogHeightFade");
5667 p->fp_FogPlane = cgGetNamedParameter(p->fprogram, "FogPlane");
5668 p->fp_FogPlaneViewDist = cgGetNamedParameter(p->fprogram, "FogPlaneViewDist");
5669 p->fp_FogRangeRecip = cgGetNamedParameter(p->fprogram, "FogRangeRecip");
5670 p->fp_LightColor = cgGetNamedParameter(p->fprogram, "LightColor");
5671 p->fp_LightDir = cgGetNamedParameter(p->fprogram, "LightDir");
5672 p->fp_LightPosition = cgGetNamedParameter(p->fprogram, "LightPosition");
5673 p->fp_OffsetMapping_Scale = cgGetNamedParameter(p->fprogram, "OffsetMapping_Scale");
5674 p->fp_PixelSize = cgGetNamedParameter(p->fprogram, "PixelSize");
5675 p->fp_ReflectColor = cgGetNamedParameter(p->fprogram, "ReflectColor");
5676 p->fp_ReflectFactor = cgGetNamedParameter(p->fprogram, "ReflectFactor");
5677 p->fp_ReflectOffset = cgGetNamedParameter(p->fprogram, "ReflectOffset");
5678 p->fp_RefractColor = cgGetNamedParameter(p->fprogram, "RefractColor");
5679 p->fp_Saturation = cgGetNamedParameter(p->fprogram, "Saturation");
5680 p->fp_ScreenCenterRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenCenterRefractReflect");
5681 p->fp_ScreenScaleRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenScaleRefractReflect");
5682 p->fp_ScreenToDepth = cgGetNamedParameter(p->fprogram, "ScreenToDepth");
5683 p->fp_ShadowMap_Parameters = cgGetNamedParameter(p->fprogram, "ShadowMap_Parameters");
5684 p->fp_ShadowMap_TextureScale = cgGetNamedParameter(p->fprogram, "ShadowMap_TextureScale");
5685 p->fp_SpecularPower = cgGetNamedParameter(p->fprogram, "SpecularPower");
5686 p->fp_UserVec1 = cgGetNamedParameter(p->fprogram, "UserVec1");
5687 p->fp_UserVec2 = cgGetNamedParameter(p->fprogram, "UserVec2");
5688 p->fp_UserVec3 = cgGetNamedParameter(p->fprogram, "UserVec3");
5689 p->fp_UserVec4 = cgGetNamedParameter(p->fprogram, "UserVec4");
5690 p->fp_ViewTintColor = cgGetNamedParameter(p->fprogram, "ViewTintColor");
5691 p->fp_ViewToLight = cgGetNamedParameter(p->fprogram, "ViewToLight");
5692 p->fp_PixelToScreenTexCoord = cgGetNamedParameter(p->fprogram, "PixelToScreenTexCoord");
5693 p->fp_ModelToReflectCube = cgGetNamedParameter(p->fprogram, "ModelToReflectCube");
5694 p->fp_BloomColorSubtract = cgGetNamedParameter(p->fprogram, "BloomColorSubtract");
5695 p->fp_NormalmapScrollBlend = cgGetNamedParameter(p->fprogram, "NormalmapScrollBlend");
5699 if ((p->vprogram || !vertstring[0]) && (p->fprogram || !fragstring[0]))
5700 Con_DPrintf("^5CG shader %s compiled.\n", permutationname);
5702 Con_Printf("^1CG shader %s failed! some features may not work properly.\n", permutationname);
5706 Mem_Free(vertstring);
5708 Mem_Free(geomstring);
5710 Mem_Free(fragstring);
5712 Mem_Free(vertexstring);
5714 Mem_Free(geometrystring);
5716 Mem_Free(fragmentstring);
5719 void R_SetupShader_SetPermutationCG(unsigned int mode, unsigned int permutation)
5721 r_cg_permutation_t *perm = R_CG_FindPermutation(mode, permutation);
5724 if (r_cg_permutation != perm)
5726 r_cg_permutation = perm;
5727 if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
5729 if (!r_cg_permutation->compiled)
5730 R_CG_CompilePermutation(perm, mode, permutation);
5731 if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
5733 // remove features until we find a valid permutation
5735 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
5737 // reduce i more quickly whenever it would not remove any bits
5738 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
5739 if (!(permutation & j))
5742 r_cg_permutation = R_CG_FindPermutation(mode, permutation);
5743 if (!r_cg_permutation->compiled)
5744 R_CG_CompilePermutation(perm, mode, permutation);
5745 if (r_cg_permutation->vprogram || r_cg_permutation->fprogram)
5748 if (i >= SHADERPERMUTATION_COUNT)
5750 //Con_Printf("Could not find a working Cg shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
5751 r_cg_permutation = R_CG_FindPermutation(mode, permutation);
5752 return; // no bit left to clear, entire mode is broken
5758 if (r_cg_permutation->vprogram)
5760 cgGLLoadProgram(r_cg_permutation->vprogram);CHECKCGERROR CHECKGLERROR
5761 cgGLBindProgram(r_cg_permutation->vprogram);CHECKCGERROR CHECKGLERROR
5762 cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
5766 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
5767 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
5769 if (r_cg_permutation->fprogram)
5771 cgGLLoadProgram(r_cg_permutation->fprogram);CHECKCGERROR CHECKGLERROR
5772 cgGLBindProgram(r_cg_permutation->fprogram);CHECKCGERROR CHECKGLERROR
5773 cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
5777 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
5778 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
5782 if (r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR
5783 if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR
5784 if (r_cg_permutation->fp_ClientTime) cgGLSetParameter1f(r_cg_permutation->fp_ClientTime, cl.time);CHECKCGERROR
5787 void CG_BindTexture(CGparameter param, rtexture_t *tex)
5789 cgGLSetTextureParameter(param, R_GetTexture(tex));
5790 cgGLEnableTextureParameter(param);
5798 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
5799 extern D3DCAPS9 vid_d3d9caps;
5802 struct r_hlsl_permutation_s;
5803 typedef struct r_hlsl_permutation_s
5805 /// hash lookup data
5806 struct r_hlsl_permutation_s *hashnext;
5808 unsigned int permutation;
5810 /// indicates if we have tried compiling this permutation already
5812 /// NULL if compilation failed
5813 IDirect3DVertexShader9 *vertexshader;
5814 IDirect3DPixelShader9 *pixelshader;
5816 r_hlsl_permutation_t;
5818 typedef enum D3DVSREGISTER_e
5820 D3DVSREGISTER_TexMatrix = 0, // float4x4
5821 D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
5822 D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
5823 D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
5824 D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
5825 D3DVSREGISTER_ModelToLight = 20, // float4x4
5826 D3DVSREGISTER_EyePosition = 24,
5827 D3DVSREGISTER_FogPlane = 25,
5828 D3DVSREGISTER_LightDir = 26,
5829 D3DVSREGISTER_LightPosition = 27,
5833 typedef enum D3DPSREGISTER_e
5835 D3DPSREGISTER_Alpha = 0,
5836 D3DPSREGISTER_BloomBlur_Parameters = 1,
5837 D3DPSREGISTER_ClientTime = 2,
5838 D3DPSREGISTER_Color_Ambient = 3,
5839 D3DPSREGISTER_Color_Diffuse = 4,
5840 D3DPSREGISTER_Color_Specular = 5,
5841 D3DPSREGISTER_Color_Glow = 6,
5842 D3DPSREGISTER_Color_Pants = 7,
5843 D3DPSREGISTER_Color_Shirt = 8,
5844 D3DPSREGISTER_DeferredColor_Ambient = 9,
5845 D3DPSREGISTER_DeferredColor_Diffuse = 10,
5846 D3DPSREGISTER_DeferredColor_Specular = 11,
5847 D3DPSREGISTER_DeferredMod_Diffuse = 12,
5848 D3DPSREGISTER_DeferredMod_Specular = 13,
5849 D3DPSREGISTER_DistortScaleRefractReflect = 14,
5850 D3DPSREGISTER_EyePosition = 15, // unused
5851 D3DPSREGISTER_FogColor = 16,
5852 D3DPSREGISTER_FogHeightFade = 17,
5853 D3DPSREGISTER_FogPlane = 18,
5854 D3DPSREGISTER_FogPlaneViewDist = 19,
5855 D3DPSREGISTER_FogRangeRecip = 20,
5856 D3DPSREGISTER_LightColor = 21,
5857 D3DPSREGISTER_LightDir = 22, // unused
5858 D3DPSREGISTER_LightPosition = 23,
5859 D3DPSREGISTER_OffsetMapping_Scale = 24,
5860 D3DPSREGISTER_PixelSize = 25,
5861 D3DPSREGISTER_ReflectColor = 26,
5862 D3DPSREGISTER_ReflectFactor = 27,
5863 D3DPSREGISTER_ReflectOffset = 28,
5864 D3DPSREGISTER_RefractColor = 29,
5865 D3DPSREGISTER_Saturation = 30,
5866 D3DPSREGISTER_ScreenCenterRefractReflect = 31,
5867 D3DPSREGISTER_ScreenScaleRefractReflect = 32,
5868 D3DPSREGISTER_ScreenToDepth = 33,
5869 D3DPSREGISTER_ShadowMap_Parameters = 34,
5870 D3DPSREGISTER_ShadowMap_TextureScale = 35,
5871 D3DPSREGISTER_SpecularPower = 36,
5872 D3DPSREGISTER_UserVec1 = 37,
5873 D3DPSREGISTER_UserVec2 = 38,
5874 D3DPSREGISTER_UserVec3 = 39,
5875 D3DPSREGISTER_UserVec4 = 40,
5876 D3DPSREGISTER_ViewTintColor = 41,
5877 D3DPSREGISTER_PixelToScreenTexCoord = 42,
5878 D3DPSREGISTER_BloomColorSubtract = 43,
5879 D3DPSREGISTER_ViewToLight = 44, // float4x4
5880 D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
5881 D3DPSREGISTER_NormalmapScrollBlend = 52,
5886 /// information about each possible shader permutation
5887 r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
5888 /// currently selected permutation
5889 r_hlsl_permutation_t *r_hlsl_permutation;
5890 /// storage for permutations linked in the hash table
5891 memexpandablearray_t r_hlsl_permutationarray;
5893 static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, unsigned int permutation)
5895 //unsigned int hashdepth = 0;
5896 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
5897 r_hlsl_permutation_t *p;
5898 for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
5900 if (p->mode == mode && p->permutation == permutation)
5902 //if (hashdepth > 10)
5903 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5908 p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
5910 p->permutation = permutation;
5911 p->hashnext = r_hlsl_permutationhash[mode][hashindex];
5912 r_hlsl_permutationhash[mode][hashindex] = p;
5913 //if (hashdepth > 10)
5914 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5918 static char *R_HLSL_GetText(const char *filename, qboolean printfromdisknotice)
5921 if (!filename || !filename[0])
5923 if (!strcmp(filename, "hlsl/default.hlsl"))
5925 if (!hlslshaderstring)
5927 hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5928 if (hlslshaderstring)
5929 Con_DPrintf("Loading shaders from file %s...\n", filename);
5931 hlslshaderstring = (char *)builtincgshaderstring;
5933 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
5934 memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
5935 return shaderstring;
5937 shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5940 if (printfromdisknotice)
5941 Con_DPrintf("from disk %s... ", filename);
5942 return shaderstring;
5944 return shaderstring;
5948 //#include <d3dx9shader.h>
5949 //#include <d3dx9mesh.h>
5951 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
5953 DWORD *vsbin = NULL;
5954 DWORD *psbin = NULL;
5955 fs_offset_t vsbinsize;
5956 fs_offset_t psbinsize;
5957 // IDirect3DVertexShader9 *vs = NULL;
5958 // IDirect3DPixelShader9 *ps = NULL;
5959 ID3DXBuffer *vslog = NULL;
5960 ID3DXBuffer *vsbuffer = NULL;
5961 ID3DXConstantTable *vsconstanttable = NULL;
5962 ID3DXBuffer *pslog = NULL;
5963 ID3DXBuffer *psbuffer = NULL;
5964 ID3DXConstantTable *psconstanttable = NULL;
5967 char temp[MAX_INPUTLINE];
5968 const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
5969 qboolean debugshader = gl_paranoid.integer != 0;
5970 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
5971 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
5974 vsbin = (DWORD *)FS_LoadFile(va("%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
5975 psbin = (DWORD *)FS_LoadFile(va("%s.psbin", cachename), r_main_mempool, true, &psbinsize);
5977 if ((!vsbin && vertstring) || (!psbin && fragstring))
5979 const char* dllnames_d3dx9 [] =
6003 dllhandle_t d3dx9_dll = NULL;
6004 HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
6005 HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
6006 HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
6007 dllfunction_t d3dx9_dllfuncs[] =
6009 {"D3DXCompileShaderFromFileA", (void **) &qD3DXCompileShaderFromFileA},
6010 {"D3DXPreprocessShader", (void **) &qD3DXPreprocessShader},
6011 {"D3DXCompileShader", (void **) &qD3DXCompileShader},
6014 if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
6016 DWORD shaderflags = 0;
6018 shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
6019 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
6020 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
6021 if (vertstring && vertstring[0])
6025 // vsresult = qD3DXPreprocessShader(vertstring, strlen(vertstring), NULL, NULL, &vsbuffer, &vslog);
6026 // FS_WriteFile(va("%s_vs.fx", cachename), vsbuffer->GetBufferPointer(), vsbuffer->GetBufferSize());
6027 FS_WriteFile(va("%s_vs.fx", cachename), vertstring, strlen(vertstring));
6028 vsresult = qD3DXCompileShaderFromFileA(va("%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
6031 vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
6034 vsbinsize = vsbuffer->GetBufferSize();
6035 vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
6036 memcpy(vsbin, vsbuffer->GetBufferPointer(), vsbinsize);
6037 vsbuffer->Release();
6041 strlcpy(temp, (const char *)vslog->GetBufferPointer(), min(sizeof(temp), vslog->GetBufferSize()));
6042 Con_Printf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
6046 if (fragstring && fragstring[0])
6050 // psresult = qD3DXPreprocessShader(fragstring, strlen(fragstring), NULL, NULL, &psbuffer, &pslog);
6051 // FS_WriteFile(va("%s_ps.fx", cachename), psbuffer->GetBufferPointer(), psbuffer->GetBufferSize());
6052 FS_WriteFile(va("%s_ps.fx", cachename), fragstring, strlen(fragstring));
6053 psresult = qD3DXCompileShaderFromFileA(va("%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
6056 psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
6059 psbinsize = psbuffer->GetBufferSize();
6060 psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
6061 memcpy(psbin, psbuffer->GetBufferPointer(), psbinsize);
6062 psbuffer->Release();
6066 strlcpy(temp, (const char *)pslog->GetBufferPointer(), min(sizeof(temp), pslog->GetBufferSize()));
6067 Con_Printf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
6071 Sys_UnloadLibrary(&d3dx9_dll);
6074 Con_Printf("Unable to compile shader - D3DXCompileShader function not found\n");
6078 vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
6079 if (FAILED(vsresult))
6080 Con_Printf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
6081 psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
6082 if (FAILED(psresult))
6083 Con_Printf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
6085 // free the shader data
6086 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
6087 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
6090 static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
6093 shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
6094 int vertstring_length = 0;
6095 int geomstring_length = 0;
6096 int fragstring_length = 0;
6098 char *vertexstring, *geometrystring, *fragmentstring;
6099 char *vertstring, *geomstring, *fragstring;
6100 char permutationname[256];
6101 char cachename[256];
6102 int vertstrings_count = 0;
6103 int geomstrings_count = 0;
6104 int fragstrings_count = 0;
6105 const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
6106 const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
6107 const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
6112 p->vertexshader = NULL;
6113 p->pixelshader = NULL;
6115 permutationname[0] = 0;
6117 vertexstring = R_HLSL_GetText(modeinfo->vertexfilename, true);
6118 geometrystring = R_HLSL_GetText(modeinfo->geometryfilename, false);
6119 fragmentstring = R_HLSL_GetText(modeinfo->fragmentfilename, false);
6121 strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
6122 strlcat(cachename, "hlsl/", sizeof(cachename));
6124 // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
6125 vertstrings_count = 0;
6126 geomstrings_count = 0;
6127 fragstrings_count = 0;
6128 vertstrings_list[vertstrings_count++] = "#define HLSL\n";
6129 geomstrings_list[geomstrings_count++] = "#define HLSL\n";
6130 fragstrings_list[fragstrings_count++] = "#define HLSL\n";
6132 // the first pretext is which type of shader to compile as
6133 // (later these will all be bound together as a program object)
6134 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
6135 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
6136 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
6138 // the second pretext is the mode (for example a light source)
6139 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
6140 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
6141 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
6142 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
6143 strlcat(cachename, modeinfo->name, sizeof(cachename));
6145 // now add all the permutation pretexts
6146 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6148 if (permutation & (1<<i))
6150 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
6151 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
6152 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
6153 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
6154 strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
6158 // keep line numbers correct
6159 vertstrings_list[vertstrings_count++] = "\n";
6160 geomstrings_list[geomstrings_count++] = "\n";
6161 fragstrings_list[fragstrings_count++] = "\n";
6166 R_CompileShader_AddStaticParms(mode, permutation);
6167 memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
6168 vertstrings_count += shaderstaticparms_count;
6169 memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
6170 geomstrings_count += shaderstaticparms_count;
6171 memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
6172 fragstrings_count += shaderstaticparms_count;
6174 // replace spaces in the cachename with _ characters
6175 for (i = 0;cachename[i];i++)
6176 if (cachename[i] == ' ')
6179 // now append the shader text itself
6180 vertstrings_list[vertstrings_count++] = vertexstring;
6181 geomstrings_list[geomstrings_count++] = geometrystring;
6182 fragstrings_list[fragstrings_count++] = fragmentstring;
6184 // if any sources were NULL, clear the respective list
6186 vertstrings_count = 0;
6187 if (!geometrystring)
6188 geomstrings_count = 0;
6189 if (!fragmentstring)
6190 fragstrings_count = 0;
6192 vertstring_length = 0;
6193 for (i = 0;i < vertstrings_count;i++)
6194 vertstring_length += strlen(vertstrings_list[i]);
6195 vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
6196 for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
6197 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
6199 geomstring_length = 0;
6200 for (i = 0;i < geomstrings_count;i++)
6201 geomstring_length += strlen(geomstrings_list[i]);
6202 geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
6203 for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
6204 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
6206 fragstring_length = 0;
6207 for (i = 0;i < fragstrings_count;i++)
6208 fragstring_length += strlen(fragstrings_list[i]);
6209 fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
6210 for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
6211 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
6213 // try to load the cached shader, or generate one
6214 R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
6216 if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
6217 Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
6219 Con_Printf("^1HLSL shader %s failed! some features may not work properly.\n", permutationname);
6223 Mem_Free(vertstring);
6225 Mem_Free(geomstring);
6227 Mem_Free(fragstring);
6229 Mem_Free(vertexstring);
6231 Mem_Free(geometrystring);
6233 Mem_Free(fragmentstring);
6236 static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
6237 static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
6238 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);}
6239 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);}
6240 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);}
6241 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);}
6243 static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
6244 static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
6245 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);}
6246 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);}
6247 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);}
6248 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);}
6250 void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
6252 r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
6253 if (r_hlsl_permutation != perm)
6255 r_hlsl_permutation = perm;
6256 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
6258 if (!r_hlsl_permutation->compiled)
6259 R_HLSL_CompilePermutation(perm, mode, permutation);
6260 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
6262 // remove features until we find a valid permutation
6264 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6266 // reduce i more quickly whenever it would not remove any bits
6267 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
6268 if (!(permutation & j))
6271 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
6272 if (!r_hlsl_permutation->compiled)
6273 R_HLSL_CompilePermutation(perm, mode, permutation);
6274 if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
6277 if (i >= SHADERPERMUTATION_COUNT)
6279 //Con_Printf("Could not find a working Cg shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
6280 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
6281 return; // no bit left to clear, entire mode is broken
6285 IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
6286 IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
6288 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
6289 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
6290 hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
6294 void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
6296 DPSOFTRAST_SetShader(mode, permutation);
6297 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
6298 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
6299 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
6302 void R_GLSL_Restart_f(void)
6304 unsigned int i, limit;
6305 if (glslshaderstring && glslshaderstring != builtinshaderstring && glslshaderstring != builtingles2shaderstring)
6306 Mem_Free(glslshaderstring);
6307 glslshaderstring = NULL;
6308 if (cgshaderstring && cgshaderstring != builtincgshaderstring)
6309 Mem_Free(cgshaderstring);
6310 cgshaderstring = NULL;
6311 if (hlslshaderstring && hlslshaderstring != builtincgshaderstring)
6312 Mem_Free(hlslshaderstring);
6313 hlslshaderstring = NULL;
6314 switch(vid.renderpath)
6316 case RENDERPATH_D3D9:
6319 r_hlsl_permutation_t *p;
6320 r_hlsl_permutation = NULL;
6321 // cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6322 // cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6323 // cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6324 // cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6325 limit = Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
6326 for (i = 0;i < limit;i++)
6328 if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
6330 if (p->vertexshader)
6331 IDirect3DVertexShader9_Release(p->vertexshader);
6333 IDirect3DPixelShader9_Release(p->pixelshader);
6334 Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
6337 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
6341 case RENDERPATH_D3D10:
6342 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6344 case RENDERPATH_D3D11:
6345 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6347 case RENDERPATH_GL20:
6348 case RENDERPATH_GLES2:
6350 r_glsl_permutation_t *p;
6351 r_glsl_permutation = NULL;
6352 limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
6353 for (i = 0;i < limit;i++)
6355 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
6357 GL_Backend_FreeProgram(p->program);
6358 Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
6361 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
6364 case RENDERPATH_CGGL:
6367 r_cg_permutation_t *p;
6368 r_cg_permutation = NULL;
6369 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6370 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6371 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6372 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6373 limit = Mem_ExpandableArray_IndexRange(&r_cg_permutationarray);
6374 for (i = 0;i < limit;i++)
6376 if ((p = (r_cg_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_cg_permutationarray, i)))
6379 cgDestroyProgram(p->vprogram);
6381 cgDestroyProgram(p->fprogram);
6382 Mem_ExpandableArray_FreeRecord(&r_cg_permutationarray, (void*)p);
6385 memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
6389 case RENDERPATH_GL13:
6390 case RENDERPATH_GL11:
6392 case RENDERPATH_SOFT:
6397 void R_GLSL_DumpShader_f(void)
6402 file = FS_OpenRealFile("glsl/default.glsl", "w", false);
6405 FS_Print(file, "/* The engine may define the following macros:\n");
6406 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6407 for (i = 0;i < SHADERMODE_COUNT;i++)
6408 FS_Print(file, glslshadermodeinfo[i].pretext);
6409 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6410 FS_Print(file, shaderpermutationinfo[i].pretext);
6411 FS_Print(file, "*/\n");
6412 FS_Print(file, builtinshaderstring);
6414 Con_Printf("glsl/default.glsl written\n");
6417 Con_Printf("failed to write to glsl/default.glsl\n");
6419 file = FS_OpenRealFile("gles2/default.glsl", "w", false);
6422 FS_Print(file, "/* The engine may define the following macros:\n");
6423 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6424 for (i = 0;i < SHADERMODE_COUNT;i++)
6425 FS_Print(file, glslshadermodeinfo[i].pretext);
6426 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6427 FS_Print(file, shaderpermutationinfo[i].pretext);
6428 FS_Print(file, "*/\n");
6429 FS_Print(file, builtingles2shaderstring);
6431 Con_Printf("gles2/default.glsl written\n");
6434 Con_Printf("failed to write to glsl/default.glsl\n");
6437 file = FS_OpenRealFile("cg/default.cg", "w", false);
6440 FS_Print(file, "/* The engine may define the following macros:\n");
6441 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6442 for (i = 0;i < SHADERMODE_COUNT;i++)
6443 FS_Print(file, cgshadermodeinfo[i].pretext);
6444 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6445 FS_Print(file, shaderpermutationinfo[i].pretext);
6446 FS_Print(file, "*/\n");
6447 FS_Print(file, builtincgshaderstring);
6449 Con_Printf("cg/default.cg written\n");
6452 Con_Printf("failed to write to cg/default.cg\n");
6455 file = FS_OpenRealFile("hlsl/default.hlsl", "w", false);
6458 FS_Print(file, "/* The engine may define the following macros:\n");
6459 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6460 for (i = 0;i < SHADERMODE_COUNT;i++)
6461 FS_Print(file, hlslshadermodeinfo[i].pretext);
6462 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6463 FS_Print(file, shaderpermutationinfo[i].pretext);
6464 FS_Print(file, "*/\n");
6465 FS_Print(file, builtincgshaderstring);
6467 Con_Printf("hlsl/default.hlsl written\n");
6470 Con_Printf("failed to write to hlsl/default.hlsl\n");
6473 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale)
6476 texturemode = GL_MODULATE;
6477 switch (vid.renderpath)
6479 case RENDERPATH_D3D9:
6481 R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
6482 R_Mesh_TexBind(GL20TU_FIRST , first );
6483 R_Mesh_TexBind(GL20TU_SECOND, second);
6486 case RENDERPATH_D3D10:
6487 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6489 case RENDERPATH_D3D11:
6490 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6492 case RENDERPATH_GL20:
6493 case RENDERPATH_GLES2:
6494 R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
6495 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
6496 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
6498 case RENDERPATH_CGGL:
6501 R_SetupShader_SetPermutationCG(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
6502 if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , first );CHECKCGERROR
6503 if (r_cg_permutation->fp_Texture_Second) CG_BindTexture(r_cg_permutation->fp_Texture_Second, second);CHECKCGERROR
6506 case RENDERPATH_GL13:
6507 R_Mesh_TexBind(0, first );
6508 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
6509 R_Mesh_TexBind(1, second);
6511 R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
6513 case RENDERPATH_GL11:
6514 R_Mesh_TexBind(0, first );
6516 case RENDERPATH_SOFT:
6517 R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
6518 R_Mesh_TexBind(GL20TU_FIRST , first );
6519 R_Mesh_TexBind(GL20TU_SECOND, second);
6524 void R_SetupShader_DepthOrShadow(void)
6526 switch (vid.renderpath)
6528 case RENDERPATH_D3D9:
6530 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, 0);
6533 case RENDERPATH_D3D10:
6534 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6536 case RENDERPATH_D3D11:
6537 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6539 case RENDERPATH_GL20:
6540 case RENDERPATH_GLES2:
6541 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, 0);
6543 case RENDERPATH_CGGL:
6545 R_SetupShader_SetPermutationCG(SHADERMODE_DEPTH_OR_SHADOW, 0);
6548 case RENDERPATH_GL13:
6549 R_Mesh_TexBind(0, 0);
6550 R_Mesh_TexBind(1, 0);
6552 case RENDERPATH_GL11:
6553 R_Mesh_TexBind(0, 0);
6555 case RENDERPATH_SOFT:
6556 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, 0);
6561 void R_SetupShader_ShowDepth(void)
6563 switch (vid.renderpath)
6565 case RENDERPATH_D3D9:
6567 R_SetupShader_SetPermutationHLSL(SHADERMODE_SHOWDEPTH, 0);
6570 case RENDERPATH_D3D10:
6571 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6573 case RENDERPATH_D3D11:
6574 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6576 case RENDERPATH_GL20:
6577 case RENDERPATH_GLES2:
6578 R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, 0);
6580 case RENDERPATH_CGGL:
6582 R_SetupShader_SetPermutationCG(SHADERMODE_SHOWDEPTH, 0);
6585 case RENDERPATH_GL13:
6587 case RENDERPATH_GL11:
6589 case RENDERPATH_SOFT:
6590 R_SetupShader_SetPermutationSoft(SHADERMODE_SHOWDEPTH, 0);
6595 extern qboolean r_shadow_usingdeferredprepass;
6596 extern cvar_t r_shadow_deferred_8bitrange;
6597 extern rtexture_t *r_shadow_attenuationgradienttexture;
6598 extern rtexture_t *r_shadow_attenuation2dtexture;
6599 extern rtexture_t *r_shadow_attenuation3dtexture;
6600 extern qboolean r_shadow_usingshadowmap2d;
6601 extern qboolean r_shadow_usingshadowmaportho;
6602 extern float r_shadow_shadowmap_texturescale[2];
6603 extern float r_shadow_shadowmap_parameters[4];
6604 extern qboolean r_shadow_shadowmapvsdct;
6605 extern qboolean r_shadow_shadowmapsampler;
6606 extern int r_shadow_shadowmappcf;
6607 extern rtexture_t *r_shadow_shadowmap2dtexture;
6608 extern rtexture_t *r_shadow_shadowmap2dcolortexture;
6609 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
6610 extern matrix4x4_t r_shadow_shadowmapmatrix;
6611 extern int r_shadow_shadowmaplod; // changes for each light based on distance
6612 extern int r_shadow_prepass_width;
6613 extern int r_shadow_prepass_height;
6614 extern rtexture_t *r_shadow_prepassgeometrydepthtexture;
6615 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
6616 extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
6617 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
6618 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
6619 static qboolean R_BlendFuncAllowsColormod(int src, int dst)
6621 // a blendfunc allows colormod if:
6622 // a) it can never keep the destination pixel invariant, or
6623 // b) it can keep the destination pixel invariant, and still can do so if colormodded
6624 // this is to prevent unintended side effects from colormod
6627 // IF there is a (s, sa) for which for all (d, da),
6628 // s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
6629 // THEN, for this (s, sa) and all (colormod, d, da):
6630 // s*colormod * src(s*colormod, d, sa, da) + d * dst(s*colormod, d, sa, da) == d
6631 // OBVIOUSLY, this means that
6632 // s*colormod * src(s*colormod, d, sa, da) = 0
6633 // dst(s*colormod, d, sa, da) = 1
6635 // note: not caring about GL_SRC_ALPHA_SATURATE and following here, these are unused in DP code
6637 // main condition to leave dst color invariant:
6638 // s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
6640 // s * 0 + d * dst(s, d, sa, da) == d
6641 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6642 // => colormod is a problem for GL_SRC_COLOR only
6644 // s + d * dst(s, d, sa, da) == d
6646 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6647 // => colormod is never problematic for these
6648 // src == GL_SRC_COLOR:
6649 // s*s + d * dst(s, d, sa, da) == d
6651 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6652 // => colormod is never problematic for these
6653 // src == GL_ONE_MINUS_SRC_COLOR:
6654 // s*(1-s) + d * dst(s, d, sa, da) == d
6655 // => s == 0 or s == 1
6656 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6657 // => colormod is a problem for GL_SRC_COLOR only
6658 // src == GL_DST_COLOR
6659 // s*d + d * dst(s, d, sa, da) == d
6661 // => dst == GL_ZERO/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6662 // => colormod is always a problem
6665 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6666 // => colormod is never problematic for these
6667 // => BUT, we do not know s! We must assume it is problematic
6668 // then... except in GL_ONE case, where we know all invariant
6670 // src == GL_ONE_MINUS_DST_COLOR
6671 // s*(1-d) + d * dst(s, d, sa, da) == d
6672 // => s == 0 (1-d is impossible to handle for our desired result)
6673 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6674 // => colormod is never problematic for these
6675 // src == GL_SRC_ALPHA
6676 // s*sa + d * dst(s, d, sa, da) == d
6677 // => s == 0, or sa == 0
6678 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6679 // => colormod breaks in the case GL_SRC_COLOR only
6680 // src == GL_ONE_MINUS_SRC_ALPHA
6681 // s*(1-sa) + d * dst(s, d, sa, da) == d
6682 // => s == 0, or sa == 1
6683 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6684 // => colormod breaks in the case GL_SRC_COLOR only
6685 // src == GL_DST_ALPHA
6686 // s*da + d * dst(s, d, sa, da) == d
6688 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6689 // => colormod is never problematic for these
6694 case GL_ONE_MINUS_SRC_COLOR:
6696 case GL_ONE_MINUS_SRC_ALPHA:
6697 if(dst == GL_SRC_COLOR)
6702 case GL_ONE_MINUS_DST_COLOR:
6704 case GL_ONE_MINUS_DST_ALPHA:
6714 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)
6716 // select a permutation of the lighting shader appropriate to this
6717 // combination of texture, entity, light source, and fogging, only use the
6718 // minimum features necessary to avoid wasting rendering time in the
6719 // fragment shader on features that are not being used
6720 unsigned int permutation = 0;
6721 unsigned int mode = 0;
6722 qboolean allow_colormod;
6723 static float dummy_colormod[3] = {1, 1, 1};
6724 float *colormod = rsurface.colormod;
6726 r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
6727 if (rsurfacepass == RSURFPASS_BACKGROUND)
6729 // distorted background
6730 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
6732 mode = SHADERMODE_WATER;
6733 if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
6734 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND;
6735 if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
6737 // this is the right thing to do for wateralpha
6738 GL_BlendFunc(GL_ONE, GL_ZERO);
6739 allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
6743 // this is the right thing to do for entity alpha
6744 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6745 allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6748 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
6750 mode = SHADERMODE_REFRACTION;
6751 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6752 allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6756 mode = SHADERMODE_GENERIC;
6757 permutation |= SHADERPERMUTATION_DIFFUSE;
6758 GL_BlendFunc(GL_ONE, GL_ZERO);
6759 allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
6761 GL_AlphaTest(false);
6763 else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
6765 if (r_glsl_offsetmapping.integer)
6767 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6768 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6769 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6770 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6771 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6773 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6774 if (r_glsl_offsetmapping_reliefmapping.integer)
6775 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6778 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6779 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6780 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
6781 permutation |= SHADERPERMUTATION_ALPHAKILL;
6782 // normalmap (deferred prepass), may use alpha test on diffuse
6783 mode = SHADERMODE_DEFERREDGEOMETRY;
6784 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6785 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6786 GL_AlphaTest(false);
6787 GL_BlendFunc(GL_ONE, GL_ZERO);
6788 allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
6790 else if (rsurfacepass == RSURFPASS_RTLIGHT)
6792 if (r_glsl_offsetmapping.integer)
6794 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6795 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6796 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6797 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6798 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6800 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6801 if (r_glsl_offsetmapping_reliefmapping.integer)
6802 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6805 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6806 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6808 mode = SHADERMODE_LIGHTSOURCE;
6809 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6810 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6811 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
6812 permutation |= SHADERPERMUTATION_CUBEFILTER;
6813 if (diffusescale > 0)
6814 permutation |= SHADERPERMUTATION_DIFFUSE;
6815 if (specularscale > 0)
6816 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
6817 if (r_refdef.fogenabled)
6818 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6819 if (rsurface.texture->colormapping)
6820 permutation |= SHADERPERMUTATION_COLORMAPPING;
6821 if (r_shadow_usingshadowmap2d)
6823 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6824 if(r_shadow_shadowmapvsdct)
6825 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
6827 if (r_shadow_shadowmapsampler)
6828 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6829 if (r_shadow_shadowmappcf > 1)
6830 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6831 else if (r_shadow_shadowmappcf)
6832 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6834 if (rsurface.texture->reflectmasktexture)
6835 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6836 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6837 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
6838 allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE);
6840 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
6842 if (r_glsl_offsetmapping.integer)
6844 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6845 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6846 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6847 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6848 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6850 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6851 if (r_glsl_offsetmapping_reliefmapping.integer)
6852 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6855 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6856 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6857 // unshaded geometry (fullbright or ambient model lighting)
6858 mode = SHADERMODE_FLATCOLOR;
6859 ambientscale = diffusescale = specularscale = 0;
6860 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
6861 permutation |= SHADERPERMUTATION_GLOW;
6862 if (r_refdef.fogenabled)
6863 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6864 if (rsurface.texture->colormapping)
6865 permutation |= SHADERPERMUTATION_COLORMAPPING;
6866 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
6868 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
6869 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6871 if (r_shadow_shadowmapsampler)
6872 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6873 if (r_shadow_shadowmappcf > 1)
6874 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6875 else if (r_shadow_shadowmappcf)
6876 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6878 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
6879 permutation |= SHADERPERMUTATION_REFLECTION;
6880 if (rsurface.texture->reflectmasktexture)
6881 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6882 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6883 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6884 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6886 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
6888 if (r_glsl_offsetmapping.integer)
6890 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6891 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6892 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6893 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6894 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6896 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6897 if (r_glsl_offsetmapping_reliefmapping.integer)
6898 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6901 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6902 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6903 // directional model lighting
6904 mode = SHADERMODE_LIGHTDIRECTION;
6905 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
6906 permutation |= SHADERPERMUTATION_GLOW;
6907 permutation |= SHADERPERMUTATION_DIFFUSE;
6908 if (specularscale > 0)
6909 permutation |= SHADERPERMUTATION_SPECULAR;
6910 if (r_refdef.fogenabled)
6911 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6912 if (rsurface.texture->colormapping)
6913 permutation |= SHADERPERMUTATION_COLORMAPPING;
6914 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
6916 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
6917 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6919 if (r_shadow_shadowmapsampler)
6920 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6921 if (r_shadow_shadowmappcf > 1)
6922 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6923 else if (r_shadow_shadowmappcf)
6924 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6926 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
6927 permutation |= SHADERPERMUTATION_REFLECTION;
6928 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
6929 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
6930 if (rsurface.texture->reflectmasktexture)
6931 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6932 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6933 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6934 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6936 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
6938 if (r_glsl_offsetmapping.integer)
6940 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6941 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6942 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6943 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6944 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6946 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6947 if (r_glsl_offsetmapping_reliefmapping.integer)
6948 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6951 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6952 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6953 // ambient model lighting
6954 mode = SHADERMODE_LIGHTDIRECTION;
6955 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
6956 permutation |= SHADERPERMUTATION_GLOW;
6957 if (r_refdef.fogenabled)
6958 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6959 if (rsurface.texture->colormapping)
6960 permutation |= SHADERPERMUTATION_COLORMAPPING;
6961 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
6963 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
6964 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6966 if (r_shadow_shadowmapsampler)
6967 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6968 if (r_shadow_shadowmappcf > 1)
6969 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6970 else if (r_shadow_shadowmappcf)
6971 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6973 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
6974 permutation |= SHADERPERMUTATION_REFLECTION;
6975 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
6976 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
6977 if (rsurface.texture->reflectmasktexture)
6978 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6979 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6980 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6981 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6985 if (r_glsl_offsetmapping.integer)
6987 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6988 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6989 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6990 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6991 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6993 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6994 if (r_glsl_offsetmapping_reliefmapping.integer)
6995 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6998 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6999 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
7001 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
7002 permutation |= SHADERPERMUTATION_GLOW;
7003 if (r_refdef.fogenabled)
7004 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
7005 if (rsurface.texture->colormapping)
7006 permutation |= SHADERPERMUTATION_COLORMAPPING;
7007 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
7009 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
7010 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
7012 if (r_shadow_shadowmapsampler)
7013 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
7014 if (r_shadow_shadowmappcf > 1)
7015 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
7016 else if (r_shadow_shadowmappcf)
7017 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
7019 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
7020 permutation |= SHADERPERMUTATION_REFLECTION;
7021 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
7022 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
7023 if (rsurface.texture->reflectmasktexture)
7024 permutation |= SHADERPERMUTATION_REFLECTCUBE;
7025 if (FAKELIGHT_ENABLED)
7027 // fake lightmapping (q1bsp, q3bsp, fullbright map)
7028 mode = SHADERMODE_FAKELIGHT;
7029 permutation |= SHADERPERMUTATION_DIFFUSE;
7030 if (specularscale > 0)
7031 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7033 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
7035 // deluxemapping (light direction texture)
7036 if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
7037 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
7039 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
7040 permutation |= SHADERPERMUTATION_DIFFUSE;
7041 if (specularscale > 0)
7042 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7044 else if (r_glsl_deluxemapping.integer >= 2 && rsurface.uselightmaptexture)
7046 // fake deluxemapping (uniform light direction in tangentspace)
7047 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
7048 permutation |= SHADERPERMUTATION_DIFFUSE;
7049 if (specularscale > 0)
7050 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7052 else if (rsurface.uselightmaptexture)
7054 // ordinary lightmapping (q1bsp, q3bsp)
7055 mode = SHADERMODE_LIGHTMAP;
7059 // ordinary vertex coloring (q3bsp)
7060 mode = SHADERMODE_VERTEXCOLOR;
7062 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
7063 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
7064 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
7067 colormod = dummy_colormod;
7068 switch(vid.renderpath)
7070 case RENDERPATH_D3D9:
7072 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), texturenumsurfaces, texturesurfacelist);
7073 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
7074 R_SetupShader_SetPermutationHLSL(mode, permutation);
7075 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
7076 if (mode == SHADERMODE_LIGHTSOURCE)
7078 Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
7079 hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7083 if (mode == SHADERMODE_LIGHTDIRECTION)
7085 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
7088 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
7089 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
7090 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
7091 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7092 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
7094 if (mode == SHADERMODE_LIGHTSOURCE)
7096 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7097 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
7098 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
7099 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
7100 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
7102 // additive passes are only darkened by fog, not tinted
7103 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
7104 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7108 if (mode == SHADERMODE_FLATCOLOR)
7110 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
7112 else if (mode == SHADERMODE_LIGHTDIRECTION)
7114 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]);
7115 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
7116 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);
7117 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
7118 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7119 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
7120 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
7124 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
7125 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
7126 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);
7127 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
7128 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7130 // additive passes are only darkened by fog, not tinted
7131 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7132 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
7134 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7135 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);
7136 hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
7137 hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
7138 hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
7139 hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
7140 hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
7141 hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
7142 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7143 if (mode == SHADERMODE_WATER)
7144 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
7146 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7147 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7148 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
7149 hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
7150 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7151 if (rsurface.texture->pantstexture)
7152 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7154 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
7155 if (rsurface.texture->shirttexture)
7156 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7158 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
7159 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
7160 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
7161 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
7162 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
7163 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
7164 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7165 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
7167 R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
7168 R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
7169 R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
7170 R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
7171 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
7172 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
7173 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
7174 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
7175 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
7176 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
7177 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
7178 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
7179 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
7180 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
7181 R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
7182 R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
7183 if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7184 if (rsurfacepass == RSURFPASS_BACKGROUND)
7186 R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
7187 if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
7188 R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7192 if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7194 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
7195 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7196 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
7197 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
7198 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7200 R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
7201 if (rsurface.rtlight)
7203 if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7204 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7209 case RENDERPATH_D3D10:
7210 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7212 case RENDERPATH_D3D11:
7213 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7215 case RENDERPATH_GL20:
7216 case RENDERPATH_GLES2:
7217 if (!vid.useinterleavedarrays)
7219 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), texturenumsurfaces, texturesurfacelist);
7220 R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
7221 R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
7222 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
7223 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
7224 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
7225 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
7226 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
7230 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), texturenumsurfaces, texturesurfacelist);
7231 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
7233 R_SetupShader_SetPermutationGLSL(mode, permutation);
7234 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
7235 if (mode == SHADERMODE_LIGHTSOURCE)
7237 if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
7238 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7239 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
7240 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
7241 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
7242 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);
7244 // additive passes are only darkened by fog, not tinted
7245 if (r_glsl_permutation->loc_FogColor >= 0)
7246 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
7247 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7251 if (mode == SHADERMODE_FLATCOLOR)
7253 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
7255 else if (mode == SHADERMODE_LIGHTDIRECTION)
7257 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]);
7258 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]);
7259 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);
7260 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
7261 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7262 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]);
7263 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]);
7267 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]);
7268 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]);
7269 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);
7270 if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
7271 if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7273 // additive passes are only darkened by fog, not tinted
7274 if (r_glsl_permutation->loc_FogColor >= 0)
7276 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7277 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
7279 qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7281 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);
7282 if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
7283 if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
7284 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]);
7285 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]);
7286 if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
7287 if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
7288 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7289 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]);
7291 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
7292 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
7293 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
7294 if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7295 if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7297 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
7298 if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
7299 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7300 if (r_glsl_permutation->loc_Color_Pants >= 0)
7302 if (rsurface.texture->pantstexture)
7303 qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7305 qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
7307 if (r_glsl_permutation->loc_Color_Shirt >= 0)
7309 if (rsurface.texture->shirttexture)
7310 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7312 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
7314 if (r_glsl_permutation->loc_FogPlane >= 0) qglUniform4f(r_glsl_permutation->loc_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
7315 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
7316 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
7317 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
7318 if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale);
7319 if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7320 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
7322 if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white );
7323 if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white );
7324 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps , r_texture_gammaramps );
7325 if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , rsurface.texture->nmaptexture );
7326 if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , rsurface.texture->basetexture );
7327 if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , rsurface.texture->glosstexture );
7328 if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , rsurface.texture->glowtexture );
7329 if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , rsurface.texture->backgroundnmaptexture );
7330 if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );
7331 if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );
7332 if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );
7333 if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , rsurface.texture->pantstexture );
7334 if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , rsurface.texture->shirttexture );
7335 if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , rsurface.texture->reflectmasktexture );
7336 if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
7337 if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture );
7338 if (r_glsl_permutation->tex_Texture_FogMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask , r_texture_fogattenuation );
7339 if (r_glsl_permutation->tex_Texture_Lightmap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
7340 if (r_glsl_permutation->tex_Texture_Deluxemap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
7341 if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
7342 if (rsurfacepass == RSURFPASS_BACKGROUND)
7344 if (r_glsl_permutation->tex_Texture_Refraction >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Refraction , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
7345 if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
7346 if (r_glsl_permutation->tex_Texture_Reflection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7350 if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7352 if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );
7353 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
7354 if (r_glsl_permutation->tex_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );
7355 if (r_glsl_permutation->tex_Texture_ScreenSpecular >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );
7356 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7358 if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2dtexture );
7359 if (rsurface.rtlight)
7361 if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
7362 if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
7367 case RENDERPATH_CGGL:
7369 if (!vid.useinterleavedarrays)
7371 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), texturenumsurfaces, texturesurfacelist);
7372 R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
7373 R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
7374 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
7375 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
7376 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
7377 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
7378 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
7382 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), texturenumsurfaces, texturesurfacelist);
7383 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
7385 R_SetupShader_SetPermutationCG(mode, permutation);
7386 if (r_cg_permutation->fp_ModelToReflectCube) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->fp_ModelToReflectCube, m16f);}CHECKCGERROR
7387 if (mode == SHADERMODE_LIGHTSOURCE)
7389 if (r_cg_permutation->vp_ModelToLight) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelToLight, m16f);}CHECKCGERROR
7390 if (r_cg_permutation->vp_LightPosition) cgGLSetParameter3f(r_cg_permutation->vp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);CHECKCGERROR
7394 if (mode == SHADERMODE_LIGHTDIRECTION)
7396 if (r_cg_permutation->vp_LightDir) cgGLSetParameter3f(r_cg_permutation->vp_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);CHECKCGERROR
7399 if (r_cg_permutation->vp_TexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_TexMatrix, m16f);}CHECKCGERROR
7400 if (r_cg_permutation->vp_BackgroundTexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_BackgroundTexMatrix, m16f);}CHECKCGERROR
7401 if (r_cg_permutation->vp_ShadowMapMatrix) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ShadowMapMatrix, m16f);}CHECKGLERROR
7402 if (r_cg_permutation->vp_EyePosition) cgGLSetParameter3f(r_cg_permutation->vp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
7403 if (r_cg_permutation->vp_FogPlane) cgGLSetParameter4f(r_cg_permutation->vp_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);CHECKCGERROR
7406 if (mode == SHADERMODE_LIGHTSOURCE)
7408 if (r_cg_permutation->fp_LightPosition) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);CHECKCGERROR
7409 if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKCGERROR
7410 if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);CHECKCGERROR
7411 if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);CHECKCGERROR
7412 if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);CHECKCGERROR
7414 // additive passes are only darkened by fog, not tinted
7415 if (r_cg_permutation->fp_FogColor) cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);CHECKCGERROR
7416 if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
7420 if (mode == SHADERMODE_FLATCOLOR)
7422 if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, colormod[0], colormod[1], colormod[2]);CHECKCGERROR
7424 else if (mode == SHADERMODE_LIGHTDIRECTION)
7426 if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_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]);CHECKCGERROR
7427 if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);CHECKCGERROR
7428 if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_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);CHECKCGERROR
7429 if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);CHECKCGERROR
7430 if (r_cg_permutation->fp_DeferredMod_Specular) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
7431 if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);CHECKCGERROR
7432 if (r_cg_permutation->fp_LightDir) cgGLSetParameter3f(r_cg_permutation->fp_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);CHECKCGERROR
7436 if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);CHECKCGERROR
7437 if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);CHECKCGERROR
7438 if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_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);CHECKCGERROR
7439 if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
7440 if (r_cg_permutation->fp_DeferredMod_Specular) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
7442 // additive passes are only darkened by fog, not tinted
7443 if (r_cg_permutation->fp_FogColor)
7445 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7446 cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);
7448 cgGLSetParameter3f(r_cg_permutation->fp_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7451 if (r_cg_permutation->fp_DistortScaleRefractReflect) cgGLSetParameter4f(r_cg_permutation->fp_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);CHECKCGERROR
7452 if (r_cg_permutation->fp_ScreenScaleRefractReflect) cgGLSetParameter4f(r_cg_permutation->fp_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);CHECKCGERROR
7453 if (r_cg_permutation->fp_ScreenCenterRefractReflect) cgGLSetParameter4f(r_cg_permutation->fp_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);CHECKCGERROR
7454 if (r_cg_permutation->fp_RefractColor) cgGLSetParameter4f(r_cg_permutation->fp_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);CHECKCGERROR
7455 if (r_cg_permutation->fp_ReflectColor) cgGLSetParameter4f(r_cg_permutation->fp_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);CHECKCGERROR
7456 if (r_cg_permutation->fp_ReflectFactor) cgGLSetParameter1f(r_cg_permutation->fp_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);CHECKCGERROR
7457 if (r_cg_permutation->fp_ReflectOffset) cgGLSetParameter1f(r_cg_permutation->fp_ReflectOffset, rsurface.texture->reflectmin);CHECKCGERROR
7458 if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
7459 if (r_cg_permutation->fp_NormalmapScrollBlend) cgGLSetParameter2f(r_cg_permutation->fp_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
7461 if (r_cg_permutation->fp_ShadowMap_TextureScale) cgGLSetParameter2f(r_cg_permutation->fp_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);CHECKCGERROR
7462 if (r_cg_permutation->fp_ShadowMap_Parameters) cgGLSetParameter4f(r_cg_permutation->fp_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);CHECKCGERROR
7463 if (r_cg_permutation->fp_Color_Glow) cgGLSetParameter3f(r_cg_permutation->fp_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);CHECKCGERROR
7464 if (r_cg_permutation->fp_Alpha) cgGLSetParameter1f(r_cg_permutation->fp_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));CHECKCGERROR
7465 if (r_cg_permutation->fp_EyePosition) cgGLSetParameter3f(r_cg_permutation->fp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
7466 if (r_cg_permutation->fp_Color_Pants)
7468 if (rsurface.texture->pantstexture)
7469 cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7471 cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, 0, 0, 0);
7474 if (r_cg_permutation->fp_Color_Shirt)
7476 if (rsurface.texture->shirttexture)
7477 cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7479 cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, 0, 0, 0);
7482 if (r_cg_permutation->fp_FogPlane) cgGLSetParameter4f(r_cg_permutation->fp_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);CHECKCGERROR
7483 if (r_cg_permutation->fp_FogPlaneViewDist) cgGLSetParameter1f(r_cg_permutation->fp_FogPlaneViewDist, rsurface.fogplaneviewdist);CHECKCGERROR
7484 if (r_cg_permutation->fp_FogRangeRecip) cgGLSetParameter1f(r_cg_permutation->fp_FogRangeRecip, rsurface.fograngerecip);CHECKCGERROR
7485 if (r_cg_permutation->fp_FogHeightFade) cgGLSetParameter1f(r_cg_permutation->fp_FogHeightFade, rsurface.fogheightfade);CHECKCGERROR
7486 if (r_cg_permutation->fp_OffsetMapping_Scale) cgGLSetParameter1f(r_cg_permutation->fp_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);CHECKCGERROR
7487 if (r_cg_permutation->fp_ScreenToDepth) cgGLSetParameter2f(r_cg_permutation->fp_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);CHECKCGERROR
7488 if (r_cg_permutation->fp_PixelToScreenTexCoord) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
7490 // if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , r_texture_white );CHECKCGERROR
7491 // if (r_cg_permutation->fp_Texture_Second ) CG_BindTexture(r_cg_permutation->fp_Texture_Second , r_texture_white );CHECKCGERROR
7492 // if (r_cg_permutation->fp_Texture_GammaRamps ) CG_BindTexture(r_cg_permutation->fp_Texture_GammaRamps , r_texture_gammaramps );CHECKCGERROR
7493 if (r_cg_permutation->fp_Texture_Normal ) CG_BindTexture(r_cg_permutation->fp_Texture_Normal , rsurface.texture->nmaptexture );CHECKCGERROR
7494 if (r_cg_permutation->fp_Texture_Color ) CG_BindTexture(r_cg_permutation->fp_Texture_Color , rsurface.texture->basetexture );CHECKCGERROR
7495 if (r_cg_permutation->fp_Texture_Gloss ) CG_BindTexture(r_cg_permutation->fp_Texture_Gloss , rsurface.texture->glosstexture );CHECKCGERROR
7496 if (r_cg_permutation->fp_Texture_Glow ) CG_BindTexture(r_cg_permutation->fp_Texture_Glow , rsurface.texture->glowtexture );CHECKCGERROR
7497 if (r_cg_permutation->fp_Texture_SecondaryNormal) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryNormal, rsurface.texture->backgroundnmaptexture );CHECKCGERROR
7498 if (r_cg_permutation->fp_Texture_SecondaryColor ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );CHECKCGERROR
7499 if (r_cg_permutation->fp_Texture_SecondaryGloss ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );CHECKCGERROR
7500 if (r_cg_permutation->fp_Texture_SecondaryGlow ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );CHECKCGERROR
7501 if (r_cg_permutation->fp_Texture_Pants ) CG_BindTexture(r_cg_permutation->fp_Texture_Pants , rsurface.texture->pantstexture );CHECKCGERROR
7502 if (r_cg_permutation->fp_Texture_Shirt ) CG_BindTexture(r_cg_permutation->fp_Texture_Shirt , rsurface.texture->shirttexture );CHECKCGERROR
7503 if (r_cg_permutation->fp_Texture_ReflectMask ) CG_BindTexture(r_cg_permutation->fp_Texture_ReflectMask , rsurface.texture->reflectmasktexture );CHECKCGERROR
7504 if (r_cg_permutation->fp_Texture_ReflectCube ) CG_BindTexture(r_cg_permutation->fp_Texture_ReflectCube , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);CHECKCGERROR
7505 if (r_cg_permutation->fp_Texture_FogHeightTexture) CG_BindTexture(r_cg_permutation->fp_Texture_FogHeightTexture, r_texture_fogheighttexture );CHECKCGERROR
7506 if (r_cg_permutation->fp_Texture_FogMask ) CG_BindTexture(r_cg_permutation->fp_Texture_FogMask , r_texture_fogattenuation );CHECKCGERROR
7507 if (r_cg_permutation->fp_Texture_Lightmap ) CG_BindTexture(r_cg_permutation->fp_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);CHECKCGERROR
7508 if (r_cg_permutation->fp_Texture_Deluxemap ) CG_BindTexture(r_cg_permutation->fp_Texture_Deluxemap , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);CHECKCGERROR
7509 if (r_cg_permutation->fp_Texture_Attenuation ) CG_BindTexture(r_cg_permutation->fp_Texture_Attenuation , r_shadow_attenuationgradienttexture );CHECKCGERROR
7510 if (rsurfacepass == RSURFPASS_BACKGROUND)
7512 if (r_cg_permutation->fp_Texture_Refraction ) CG_BindTexture(r_cg_permutation->fp_Texture_Refraction , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);CHECKCGERROR
7513 else if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);CHECKCGERROR
7514 if (r_cg_permutation->fp_Texture_Reflection ) CG_BindTexture(r_cg_permutation->fp_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);CHECKCGERROR
7518 if (r_cg_permutation->fp_Texture_Reflection ) CG_BindTexture(r_cg_permutation->fp_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);CHECKCGERROR
7520 if (r_cg_permutation->fp_Texture_ScreenDepth ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );CHECKCGERROR
7521 if (r_cg_permutation->fp_Texture_ScreenNormalMap) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture );CHECKCGERROR
7522 if (r_cg_permutation->fp_Texture_ScreenDiffuse ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );CHECKCGERROR
7523 if (r_cg_permutation->fp_Texture_ScreenSpecular ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );CHECKCGERROR
7524 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7526 if (r_cg_permutation->fp_Texture_ShadowMap2D ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );CHECKCGERROR
7527 if (rsurface.rtlight)
7529 if (r_cg_permutation->fp_Texture_Cube ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube , rsurface.rtlight->currentcubemap );CHECKCGERROR
7530 if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );CHECKCGERROR
7537 case RENDERPATH_GL13:
7538 case RENDERPATH_GL11:
7540 case RENDERPATH_SOFT:
7541 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), texturenumsurfaces, texturesurfacelist);
7542 R_Mesh_PrepareVertices_Mesh_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchsvector3f, rsurface.batchtvector3f, rsurface.batchnormal3f, rsurface.batchlightmapcolor4f, rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f);
7543 R_SetupShader_SetPermutationSoft(mode, permutation);
7544 {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
7545 if (mode == SHADERMODE_LIGHTSOURCE)
7547 {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
7548 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7549 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
7550 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
7551 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
7552 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
7554 // additive passes are only darkened by fog, not tinted
7555 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
7556 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7560 if (mode == SHADERMODE_FLATCOLOR)
7562 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
7564 else if (mode == SHADERMODE_LIGHTDIRECTION)
7566 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
7567 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
7568 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
7569 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
7570 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7571 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
7572 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
7576 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
7577 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
7578 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
7579 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
7580 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7582 // additive passes are only darkened by fog, not tinted
7583 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7584 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
7586 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7587 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
7588 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
7589 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
7590 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
7591 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
7592 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
7593 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
7594 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7595 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
7597 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
7598 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
7599 {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
7600 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7601 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7603 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
7604 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
7605 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7606 if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
7608 if (rsurface.texture->pantstexture)
7609 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7611 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
7613 if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
7615 if (rsurface.texture->shirttexture)
7616 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7618 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
7620 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
7621 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist);
7622 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
7623 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
7624 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale);
7625 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7626 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
7628 R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
7629 R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
7630 R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
7631 R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
7632 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
7633 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
7634 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
7635 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
7636 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
7637 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
7638 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
7639 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
7640 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
7641 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
7642 R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
7643 R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
7644 if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7645 if (rsurfacepass == RSURFPASS_BACKGROUND)
7647 R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
7648 if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
7649 R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7653 if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7655 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
7656 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7657 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
7658 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
7659 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7661 R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
7662 if (rsurface.rtlight)
7664 if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7665 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7672 void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
7674 // select a permutation of the lighting shader appropriate to this
7675 // combination of texture, entity, light source, and fogging, only use the
7676 // minimum features necessary to avoid wasting rendering time in the
7677 // fragment shader on features that are not being used
7678 unsigned int permutation = 0;
7679 unsigned int mode = 0;
7680 const float *lightcolorbase = rtlight->currentcolor;
7681 float ambientscale = rtlight->ambientscale;
7682 float diffusescale = rtlight->diffusescale;
7683 float specularscale = rtlight->specularscale;
7684 // this is the location of the light in view space
7685 vec3_t viewlightorigin;
7686 // this transforms from view space (camera) to light space (cubemap)
7687 matrix4x4_t viewtolight;
7688 matrix4x4_t lighttoview;
7689 float viewtolight16f[16];
7690 float range = 1.0f / r_shadow_deferred_8bitrange.value;
7692 mode = SHADERMODE_DEFERREDLIGHTSOURCE;
7693 if (rtlight->currentcubemap != r_texture_whitecube)
7694 permutation |= SHADERPERMUTATION_CUBEFILTER;
7695 if (diffusescale > 0)
7696 permutation |= SHADERPERMUTATION_DIFFUSE;
7697 if (specularscale > 0)
7698 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7699 if (r_shadow_usingshadowmap2d)
7701 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
7702 if (r_shadow_shadowmapvsdct)
7703 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
7705 if (r_shadow_shadowmapsampler)
7706 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
7707 if (r_shadow_shadowmappcf > 1)
7708 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
7709 else if (r_shadow_shadowmappcf)
7710 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
7712 Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
7713 Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
7714 Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
7715 Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
7716 switch(vid.renderpath)
7718 case RENDERPATH_D3D9:
7720 R_SetupShader_SetPermutationHLSL(mode, permutation);
7721 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
7722 hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f);
7723 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
7724 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
7725 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
7726 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7727 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7728 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7729 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7730 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
7732 R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7733 R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthcolortexture );
7734 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7735 R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7736 R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dcolortexture );
7737 R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7740 case RENDERPATH_D3D10:
7741 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7743 case RENDERPATH_D3D11:
7744 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7746 case RENDERPATH_GL20:
7747 case RENDERPATH_GLES2:
7748 R_SetupShader_SetPermutationGLSL(mode, permutation);
7749 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f( r_glsl_permutation->loc_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
7750 if (r_glsl_permutation->loc_ViewToLight >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ViewToLight , 1, false, viewtolight16f);
7751 if (r_glsl_permutation->loc_DeferredColor_Ambient >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
7752 if (r_glsl_permutation->loc_DeferredColor_Diffuse >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
7753 if (r_glsl_permutation->loc_DeferredColor_Specular >= 0) qglUniform3f( r_glsl_permutation->loc_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
7754 if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7755 if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7756 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f( r_glsl_permutation->loc_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7757 if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f( r_glsl_permutation->loc_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7758 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height);
7760 if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
7761 if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );
7762 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
7763 if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
7764 if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );
7765 if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
7767 case RENDERPATH_CGGL:
7769 R_SetupShader_SetPermutationCG(mode, permutation);
7770 if (r_cg_permutation->fp_LightPosition ) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);CHECKCGERROR
7771 if (r_cg_permutation->fp_ViewToLight ) cgGLSetMatrixParameterfc(r_cg_permutation->fp_ViewToLight, viewtolight16f);CHECKCGERROR
7772 if (r_cg_permutation->fp_DeferredColor_Ambient ) cgGLSetParameter3f(r_cg_permutation->fp_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);CHECKCGERROR
7773 if (r_cg_permutation->fp_DeferredColor_Diffuse ) cgGLSetParameter3f(r_cg_permutation->fp_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);CHECKCGERROR
7774 if (r_cg_permutation->fp_DeferredColor_Specular ) cgGLSetParameter3f(r_cg_permutation->fp_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);CHECKCGERROR
7775 if (r_cg_permutation->fp_ShadowMap_TextureScale ) cgGLSetParameter2f(r_cg_permutation->fp_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);CHECKCGERROR
7776 if (r_cg_permutation->fp_ShadowMap_Parameters ) cgGLSetParameter4f(r_cg_permutation->fp_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);CHECKCGERROR
7777 if (r_cg_permutation->fp_SpecularPower ) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
7778 if (r_cg_permutation->fp_ScreenToDepth ) cgGLSetParameter2f(r_cg_permutation->fp_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);CHECKCGERROR
7779 if (r_cg_permutation->fp_PixelToScreenTexCoord ) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
7781 if (r_cg_permutation->fp_Texture_Attenuation ) CG_BindTexture(r_cg_permutation->fp_Texture_Attenuation , r_shadow_attenuationgradienttexture );CHECKCGERROR
7782 if (r_cg_permutation->fp_Texture_ScreenDepth ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );CHECKCGERROR
7783 if (r_cg_permutation->fp_Texture_ScreenNormalMap ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture );CHECKCGERROR
7784 if (r_cg_permutation->fp_Texture_Cube ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube , rsurface.rtlight->currentcubemap );CHECKCGERROR
7785 if (r_cg_permutation->fp_Texture_ShadowMap2D ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );CHECKCGERROR
7786 if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );CHECKCGERROR
7789 case RENDERPATH_GL13:
7790 case RENDERPATH_GL11:
7792 case RENDERPATH_SOFT:
7793 R_SetupShader_SetPermutationGLSL(mode, permutation);
7794 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
7795 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ViewToLightM1 , 1, false, viewtolight16f);
7796 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
7797 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
7798 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
7799 DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7800 DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7801 DPSOFTRAST_Uniform1f( DPSOFTRAST_UNIFORM_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7802 DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7803 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
7805 R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7806 R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
7807 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7808 R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7809 R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dtexture );
7810 R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7815 #define SKINFRAME_HASH 1024
7819 int loadsequence; // incremented each level change
7820 memexpandablearray_t array;
7821 skinframe_t *hash[SKINFRAME_HASH];
7824 r_skinframe_t r_skinframe;
7826 void R_SkinFrame_PrepareForPurge(void)
7828 r_skinframe.loadsequence++;
7829 // wrap it without hitting zero
7830 if (r_skinframe.loadsequence >= 200)
7831 r_skinframe.loadsequence = 1;
7834 void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
7838 // mark the skinframe as used for the purging code
7839 skinframe->loadsequence = r_skinframe.loadsequence;
7842 void R_SkinFrame_Purge(void)
7846 for (i = 0;i < SKINFRAME_HASH;i++)
7848 for (s = r_skinframe.hash[i];s;s = s->next)
7850 if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
7852 if (s->merged == s->base)
7854 // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
7855 R_PurgeTexture(s->stain );s->stain = NULL;
7856 R_PurgeTexture(s->merged);s->merged = NULL;
7857 R_PurgeTexture(s->base );s->base = NULL;
7858 R_PurgeTexture(s->pants );s->pants = NULL;
7859 R_PurgeTexture(s->shirt );s->shirt = NULL;
7860 R_PurgeTexture(s->nmap );s->nmap = NULL;
7861 R_PurgeTexture(s->gloss );s->gloss = NULL;
7862 R_PurgeTexture(s->glow );s->glow = NULL;
7863 R_PurgeTexture(s->fog );s->fog = NULL;
7864 R_PurgeTexture(s->reflect);s->reflect = NULL;
7865 s->loadsequence = 0;
7871 skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
7873 char basename[MAX_QPATH];
7875 Image_StripImageExtension(name, basename, sizeof(basename));
7877 if( last == NULL ) {
7879 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
7880 item = r_skinframe.hash[hashindex];
7885 // linearly search through the hash bucket
7886 for( ; item ; item = item->next ) {
7887 if( !strcmp( item->basename, basename ) ) {
7894 skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
7898 char basename[MAX_QPATH];
7900 Image_StripImageExtension(name, basename, sizeof(basename));
7902 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
7903 for (item = r_skinframe.hash[hashindex];item;item = item->next)
7904 if (!strcmp(item->basename, basename) && item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)
7908 rtexture_t *dyntexture;
7909 // check whether its a dynamic texture
7910 dyntexture = CL_GetDynTexture( basename );
7911 if (!add && !dyntexture)
7913 item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
7914 memset(item, 0, sizeof(*item));
7915 strlcpy(item->basename, basename, sizeof(item->basename));
7916 item->base = dyntexture; // either NULL or dyntexture handle
7917 item->textureflags = textureflags;
7918 item->comparewidth = comparewidth;
7919 item->compareheight = compareheight;
7920 item->comparecrc = comparecrc;
7921 item->next = r_skinframe.hash[hashindex];
7922 r_skinframe.hash[hashindex] = item;
7924 else if( item->base == NULL )
7926 rtexture_t *dyntexture;
7927 // check whether its a dynamic texture
7928 // this only needs to be done because Purge doesnt delete skinframes - only sets the texture pointers to NULL and we need to restore it before returing.. [11/29/2007 Black]
7929 dyntexture = CL_GetDynTexture( basename );
7930 item->base = dyntexture; // either NULL or dyntexture handle
7933 R_SkinFrame_MarkUsed(item);
7937 #define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \
7939 unsigned long long avgcolor[5], wsum; \
7947 for(pix = 0; pix < cnt; ++pix) \
7950 for(comp = 0; comp < 3; ++comp) \
7952 if(w) /* ignore perfectly black pixels because that is better for model skins */ \
7955 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
7957 for(comp = 0; comp < 3; ++comp) \
7958 avgcolor[comp] += getpixel * w; \
7961 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
7962 avgcolor[4] += getpixel; \
7964 if(avgcolor[3] == 0) /* no pixels seen? even worse */ \
7966 skinframe->avgcolor[0] = avgcolor[2] / (255.0 * avgcolor[3]); \
7967 skinframe->avgcolor[1] = avgcolor[1] / (255.0 * avgcolor[3]); \
7968 skinframe->avgcolor[2] = avgcolor[0] / (255.0 * avgcolor[3]); \
7969 skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \
7972 extern cvar_t gl_picmip;
7973 skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain)
7976 unsigned char *pixels;
7977 unsigned char *bumppixels;
7978 unsigned char *basepixels = NULL;
7979 int basepixels_width = 0;
7980 int basepixels_height = 0;
7981 skinframe_t *skinframe;
7982 rtexture_t *ddsbase = NULL;
7983 qboolean ddshasalpha = false;
7984 float ddsavgcolor[4];
7985 char basename[MAX_QPATH];
7986 int miplevel = R_PicmipForFlags(textureflags);
7987 int savemiplevel = miplevel;
7990 if (cls.state == ca_dedicated)
7993 // return an existing skinframe if already loaded
7994 // if loading of the first image fails, don't make a new skinframe as it
7995 // would cause all future lookups of this to be missing
7996 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
7997 if (skinframe && skinframe->base)
8000 Image_StripImageExtension(name, basename, sizeof(basename));
8002 // check for DDS texture file first
8003 if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
8005 basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer != 0, &miplevel);
8006 if (basepixels == NULL)
8010 // FIXME handle miplevel
8012 if (developer_loading.integer)
8013 Con_Printf("loading skin \"%s\"\n", name);
8015 // we've got some pixels to store, so really allocate this new texture now
8017 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, true);
8018 skinframe->stain = NULL;
8019 skinframe->merged = NULL;
8020 skinframe->base = NULL;
8021 skinframe->pants = NULL;
8022 skinframe->shirt = NULL;
8023 skinframe->nmap = NULL;
8024 skinframe->gloss = NULL;
8025 skinframe->glow = NULL;
8026 skinframe->fog = NULL;
8027 skinframe->reflect = NULL;
8028 skinframe->hasalpha = false;
8032 skinframe->base = ddsbase;
8033 skinframe->hasalpha = ddshasalpha;
8034 VectorCopy(ddsavgcolor, skinframe->avgcolor);
8035 if (r_loadfog && skinframe->hasalpha)
8036 skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
8037 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
8041 basepixels_width = image_width;
8042 basepixels_height = image_height;
8043 skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
8044 if (textureflags & TEXF_ALPHA)
8046 for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
8048 if (basepixels[j] < 255)
8050 skinframe->hasalpha = true;
8054 if (r_loadfog && skinframe->hasalpha)
8056 // has transparent pixels
8057 pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
8058 for (j = 0;j < image_width * image_height * 4;j += 4)
8063 pixels[j+3] = basepixels[j+3];
8065 skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
8069 R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
8070 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
8071 if (r_savedds && qglGetCompressedTexImageARB && skinframe->base)
8072 R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true, skinframe->hasalpha);
8073 if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog)
8074 R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true, true);
8079 mymiplevel = savemiplevel;
8080 if (r_loadnormalmap)
8081 skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), NULL, NULL, mymiplevel);
8082 skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8084 skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8085 skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8086 skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8087 skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8090 // _norm is the name used by tenebrae and has been adopted as standard
8091 if (r_loadnormalmap && skinframe->nmap == NULL)
8093 mymiplevel = savemiplevel;
8094 if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
8096 skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8100 else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
8102 pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
8103 Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value);
8104 skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8106 Mem_Free(bumppixels);
8108 else if (r_shadow_bumpscale_basetexture.value > 0)
8110 pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4);
8111 Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value);
8112 skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8115 if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap)
8116 R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true, true);
8119 // _luma is supported only for tenebrae compatibility
8120 // _glow is the preferred name
8121 mymiplevel = savemiplevel;
8122 if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel))))
8124 skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8125 if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
8126 R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true, true);
8127 Mem_Free(pixels);pixels = NULL;
8130 mymiplevel = savemiplevel;
8131 if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8133 skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8134 if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
8135 R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true, true);
8140 mymiplevel = savemiplevel;
8141 if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8143 skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8144 if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
8145 R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true, false);
8150 mymiplevel = savemiplevel;
8151 if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8153 skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8154 if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
8155 R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true, false);
8160 mymiplevel = savemiplevel;
8161 if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8163 skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
8164 if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
8165 R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true, true);
8171 Mem_Free(basepixels);
8176 // this is only used by .spr32 sprites, HL .spr files, HL .bsp files
8177 skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height)
8180 unsigned char *temp1, *temp2;
8181 skinframe_t *skinframe;
8183 if (cls.state == ca_dedicated)
8186 // if already loaded just return it, otherwise make a new skinframe
8187 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height*4) : 0, true);
8188 if (skinframe && skinframe->base)
8191 skinframe->stain = NULL;
8192 skinframe->merged = NULL;
8193 skinframe->base = NULL;
8194 skinframe->pants = NULL;
8195 skinframe->shirt = NULL;
8196 skinframe->nmap = NULL;
8197 skinframe->gloss = NULL;
8198 skinframe->glow = NULL;
8199 skinframe->fog = NULL;
8200 skinframe->reflect = NULL;
8201 skinframe->hasalpha = false;
8203 // if no data was provided, then clearly the caller wanted to get a blank skinframe
8207 if (developer_loading.integer)
8208 Con_Printf("loading 32bit skin \"%s\"\n", name);
8210 if (r_loadnormalmap && r_shadow_bumpscale_basetexture.value > 0)
8212 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
8213 temp2 = temp1 + width * height * 4;
8214 Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
8215 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
8218 skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, textureflags, -1, NULL);
8219 if (textureflags & TEXF_ALPHA)
8221 for (i = 3;i < width * height * 4;i += 4)
8223 if (skindata[i] < 255)
8225 skinframe->hasalpha = true;
8229 if (r_loadfog && skinframe->hasalpha)
8231 unsigned char *fogpixels = (unsigned char *)Mem_Alloc(tempmempool, width * height * 4);
8232 memcpy(fogpixels, skindata, width * height * 4);
8233 for (i = 0;i < width * height * 4;i += 4)
8234 fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
8235 skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, textureflags, -1, NULL);
8236 Mem_Free(fogpixels);
8240 R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, skindata[4 * pix + comp]);
8241 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
8246 skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height)
8250 skinframe_t *skinframe;
8252 if (cls.state == ca_dedicated)
8255 // if already loaded just return it, otherwise make a new skinframe
8256 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
8257 if (skinframe && skinframe->base)
8260 skinframe->stain = NULL;
8261 skinframe->merged = NULL;
8262 skinframe->base = NULL;
8263 skinframe->pants = NULL;
8264 skinframe->shirt = NULL;
8265 skinframe->nmap = NULL;
8266 skinframe->gloss = NULL;
8267 skinframe->glow = NULL;
8268 skinframe->fog = NULL;
8269 skinframe->reflect = NULL;
8270 skinframe->hasalpha = false;
8272 // if no data was provided, then clearly the caller wanted to get a blank skinframe
8276 if (developer_loading.integer)
8277 Con_Printf("loading quake skin \"%s\"\n", name);
8279 // we actually don't upload anything until the first use, because mdl skins frequently go unused, and are almost never used in both modes (colormapped and non-colormapped)
8280 skinframe->qpixels = (unsigned char *)Mem_Alloc(r_main_mempool, width*height); // FIXME LEAK
8281 memcpy(skinframe->qpixels, skindata, width*height);
8282 skinframe->qwidth = width;
8283 skinframe->qheight = height;
8286 for (i = 0;i < width * height;i++)
8287 featuresmask |= palette_featureflags[skindata[i]];
8289 skinframe->hasalpha = false;
8290 skinframe->qhascolormapping = loadpantsandshirt && (featuresmask & (PALETTEFEATURE_PANTS | PALETTEFEATURE_SHIRT));
8291 skinframe->qgeneratenmap = r_shadow_bumpscale_basetexture.value > 0;
8292 skinframe->qgeneratemerged = true;
8293 skinframe->qgeneratebase = skinframe->qhascolormapping;
8294 skinframe->qgenerateglow = loadglowtexture && (featuresmask & PALETTEFEATURE_GLOW);
8296 R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette_bgra_complete)[skindata[pix]*4 + comp]);
8297 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
8302 static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboolean colormapped)
8306 unsigned char *skindata;
8308 if (!skinframe->qpixels)
8311 if (!skinframe->qhascolormapping)
8312 colormapped = false;
8316 if (!skinframe->qgeneratebase)
8321 if (!skinframe->qgeneratemerged)
8325 width = skinframe->qwidth;
8326 height = skinframe->qheight;
8327 skindata = skinframe->qpixels;
8329 if (skinframe->qgeneratenmap)
8331 unsigned char *temp1, *temp2;
8332 skinframe->qgeneratenmap = false;
8333 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
8334 temp2 = temp1 + width * height * 4;
8335 // use either a custom palette or the quake palette
8336 Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
8337 Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
8338 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
8342 if (skinframe->qgenerateglow)
8344 skinframe->qgenerateglow = false;
8345 skinframe->glow = R_LoadTexture2D(r_main_texturepool, va("%s_glow", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow
8350 skinframe->qgeneratebase = false;
8351 skinframe->base = R_LoadTexture2D(r_main_texturepool, va("%s_nospecial", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap);
8352 skinframe->pants = R_LoadTexture2D(r_main_texturepool, va("%s_pants", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_pantsaswhite);
8353 skinframe->shirt = R_LoadTexture2D(r_main_texturepool, va("%s_shirt", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_shirtaswhite);
8357 skinframe->qgeneratemerged = false;
8358 skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete);
8361 if (!skinframe->qgeneratemerged && !skinframe->qgeneratebase)
8363 Mem_Free(skinframe->qpixels);
8364 skinframe->qpixels = NULL;
8368 skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, const unsigned char *skindata, int width, int height, const unsigned int *palette, const unsigned int *alphapalette)
8371 skinframe_t *skinframe;
8373 if (cls.state == ca_dedicated)
8376 // if already loaded just return it, otherwise make a new skinframe
8377 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
8378 if (skinframe && skinframe->base)
8381 skinframe->stain = NULL;
8382 skinframe->merged = NULL;
8383 skinframe->base = NULL;
8384 skinframe->pants = NULL;
8385 skinframe->shirt = NULL;
8386 skinframe->nmap = NULL;
8387 skinframe->gloss = NULL;
8388 skinframe->glow = NULL;
8389 skinframe->fog = NULL;
8390 skinframe->reflect = NULL;
8391 skinframe->hasalpha = false;
8393 // if no data was provided, then clearly the caller wanted to get a blank skinframe
8397 if (developer_loading.integer)
8398 Con_Printf("loading embedded 8bit image \"%s\"\n", name);
8400 skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, palette);
8401 if (textureflags & TEXF_ALPHA)
8403 for (i = 0;i < width * height;i++)
8405 if (((unsigned char *)palette)[skindata[i]*4+3] < 255)
8407 skinframe->hasalpha = true;
8411 if (r_loadfog && skinframe->hasalpha)
8412 skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, alphapalette);
8415 R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
8416 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
8421 skinframe_t *R_SkinFrame_LoadMissing(void)
8423 skinframe_t *skinframe;
8425 if (cls.state == ca_dedicated)
8428 skinframe = R_SkinFrame_Find("missing", TEXF_FORCENEAREST, 0, 0, 0, true);
8429 skinframe->stain = NULL;
8430 skinframe->merged = NULL;
8431 skinframe->base = NULL;
8432 skinframe->pants = NULL;
8433 skinframe->shirt = NULL;
8434 skinframe->nmap = NULL;
8435 skinframe->gloss = NULL;
8436 skinframe->glow = NULL;
8437 skinframe->fog = NULL;
8438 skinframe->reflect = NULL;
8439 skinframe->hasalpha = false;
8441 skinframe->avgcolor[0] = rand() / RAND_MAX;
8442 skinframe->avgcolor[1] = rand() / RAND_MAX;
8443 skinframe->avgcolor[2] = rand() / RAND_MAX;
8444 skinframe->avgcolor[3] = 1;
8449 //static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
8450 typedef struct suffixinfo_s
8453 qboolean flipx, flipy, flipdiagonal;
8456 static suffixinfo_t suffix[3][6] =
8459 {"px", false, false, false},
8460 {"nx", false, false, false},
8461 {"py", false, false, false},
8462 {"ny", false, false, false},
8463 {"pz", false, false, false},
8464 {"nz", false, false, false}
8467 {"posx", false, false, false},
8468 {"negx", false, false, false},
8469 {"posy", false, false, false},
8470 {"negy", false, false, false},
8471 {"posz", false, false, false},
8472 {"negz", false, false, false}
8475 {"rt", true, false, true},
8476 {"lf", false, true, true},
8477 {"ft", true, true, false},
8478 {"bk", false, false, false},
8479 {"up", true, false, true},
8480 {"dn", true, false, true}
8484 static int componentorder[4] = {0, 1, 2, 3};
8486 rtexture_t *R_LoadCubemap(const char *basename)
8488 int i, j, cubemapsize;
8489 unsigned char *cubemappixels, *image_buffer;
8490 rtexture_t *cubemaptexture;
8492 // must start 0 so the first loadimagepixels has no requested width/height
8494 cubemappixels = NULL;
8495 cubemaptexture = NULL;
8496 // keep trying different suffix groups (posx, px, rt) until one loads
8497 for (j = 0;j < 3 && !cubemappixels;j++)
8499 // load the 6 images in the suffix group
8500 for (i = 0;i < 6;i++)
8502 // generate an image name based on the base and and suffix
8503 dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix);
8505 if ((image_buffer = loadimagepixelsbgra(name, false, false, r_texture_convertsRGB_cubemap.integer != 0, NULL)))
8507 // an image loaded, make sure width and height are equal
8508 if (image_width == image_height && (!cubemappixels || image_width == cubemapsize))
8510 // if this is the first image to load successfully, allocate the cubemap memory
8511 if (!cubemappixels && image_width >= 1)
8513 cubemapsize = image_width;
8514 // note this clears to black, so unavailable sides are black
8515 cubemappixels = (unsigned char *)Mem_Alloc(tempmempool, 6*cubemapsize*cubemapsize*4);
8517 // copy the image with any flipping needed by the suffix (px and posx types don't need flipping)
8519 Image_CopyMux(cubemappixels+i*cubemapsize*cubemapsize*4, image_buffer, cubemapsize, cubemapsize, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, componentorder);
8522 Con_Printf("Cubemap image \"%s\" (%ix%i) is not square, OpenGL requires square cubemaps.\n", name, image_width, image_height);
8524 Mem_Free(image_buffer);
8528 // if a cubemap loaded, upload it
8531 if (developer_loading.integer)
8532 Con_Printf("loading cubemap \"%s\"\n", basename);
8534 cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
8535 Mem_Free(cubemappixels);
8539 Con_DPrintf("failed to load cubemap \"%s\"\n", basename);
8540 if (developer_loading.integer)
8542 Con_Printf("(tried tried images ");
8543 for (j = 0;j < 3;j++)
8544 for (i = 0;i < 6;i++)
8545 Con_Printf("%s\"%s%s.tga\"", j + i > 0 ? ", " : "", basename, suffix[j][i].suffix);
8546 Con_Print(" and was unable to find any of them).\n");
8549 return cubemaptexture;
8552 rtexture_t *R_GetCubemap(const char *basename)
8555 for (i = 0;i < r_texture_numcubemaps;i++)
8556 if (!strcasecmp(r_texture_cubemaps[i].basename, basename))
8557 return r_texture_cubemaps[i].texture ? r_texture_cubemaps[i].texture : r_texture_whitecube;
8558 if (i >= MAX_CUBEMAPS)
8559 return r_texture_whitecube;
8560 r_texture_numcubemaps++;
8561 strlcpy(r_texture_cubemaps[i].basename, basename, sizeof(r_texture_cubemaps[i].basename));
8562 r_texture_cubemaps[i].texture = R_LoadCubemap(r_texture_cubemaps[i].basename);
8563 return r_texture_cubemaps[i].texture;
8566 void R_FreeCubemaps(void)
8569 for (i = 0;i < r_texture_numcubemaps;i++)
8571 if (developer_loading.integer)
8572 Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i].basename);
8573 if (r_texture_cubemaps[i].texture)
8574 R_FreeTexture(r_texture_cubemaps[i].texture);
8576 r_texture_numcubemaps = 0;
8579 void R_Main_FreeViewCache(void)
8581 if (r_refdef.viewcache.entityvisible)
8582 Mem_Free(r_refdef.viewcache.entityvisible);
8583 if (r_refdef.viewcache.world_pvsbits)
8584 Mem_Free(r_refdef.viewcache.world_pvsbits);
8585 if (r_refdef.viewcache.world_leafvisible)
8586 Mem_Free(r_refdef.viewcache.world_leafvisible);
8587 if (r_refdef.viewcache.world_surfacevisible)
8588 Mem_Free(r_refdef.viewcache.world_surfacevisible);
8589 memset(&r_refdef.viewcache, 0, sizeof(r_refdef.viewcache));
8592 void R_Main_ResizeViewCache(void)
8594 int numentities = r_refdef.scene.numentities;
8595 int numclusters = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusters : 1;
8596 int numclusterbytes = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusterbytes : 1;
8597 int numleafs = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_leafs : 1;
8598 int numsurfaces = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->num_surfaces : 1;
8599 if (r_refdef.viewcache.maxentities < numentities)
8601 r_refdef.viewcache.maxentities = numentities;
8602 if (r_refdef.viewcache.entityvisible)
8603 Mem_Free(r_refdef.viewcache.entityvisible);
8604 r_refdef.viewcache.entityvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
8606 if (r_refdef.viewcache.world_numclusters != numclusters)
8608 r_refdef.viewcache.world_numclusters = numclusters;
8609 r_refdef.viewcache.world_numclusterbytes = numclusterbytes;
8610 if (r_refdef.viewcache.world_pvsbits)
8611 Mem_Free(r_refdef.viewcache.world_pvsbits);
8612 r_refdef.viewcache.world_pvsbits = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
8614 if (r_refdef.viewcache.world_numleafs != numleafs)
8616 r_refdef.viewcache.world_numleafs = numleafs;
8617 if (r_refdef.viewcache.world_leafvisible)
8618 Mem_Free(r_refdef.viewcache.world_leafvisible);
8619 r_refdef.viewcache.world_leafvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
8621 if (r_refdef.viewcache.world_numsurfaces != numsurfaces)
8623 r_refdef.viewcache.world_numsurfaces = numsurfaces;
8624 if (r_refdef.viewcache.world_surfacevisible)
8625 Mem_Free(r_refdef.viewcache.world_surfacevisible);
8626 r_refdef.viewcache.world_surfacevisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
8630 extern rtexture_t *loadingscreentexture;
8631 void gl_main_start(void)
8633 loadingscreentexture = NULL;
8634 r_texture_blanknormalmap = NULL;
8635 r_texture_white = NULL;
8636 r_texture_grey128 = NULL;
8637 r_texture_black = NULL;
8638 r_texture_whitecube = NULL;
8639 r_texture_normalizationcube = NULL;
8640 r_texture_fogattenuation = NULL;
8641 r_texture_fogheighttexture = NULL;
8642 r_texture_gammaramps = NULL;
8643 r_texture_numcubemaps = 0;
8645 r_loaddds = r_texture_dds_load.integer != 0;
8646 r_savedds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_save.integer;
8648 switch(vid.renderpath)
8650 case RENDERPATH_GL20:
8651 case RENDERPATH_CGGL:
8652 case RENDERPATH_D3D9:
8653 case RENDERPATH_D3D10:
8654 case RENDERPATH_D3D11:
8655 case RENDERPATH_SOFT:
8656 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
8657 Cvar_SetValueQuick(&gl_combine, 1);
8658 Cvar_SetValueQuick(&r_glsl, 1);
8659 r_loadnormalmap = true;
8663 case RENDERPATH_GL13:
8664 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
8665 Cvar_SetValueQuick(&gl_combine, 1);
8666 Cvar_SetValueQuick(&r_glsl, 0);
8667 r_loadnormalmap = false;
8668 r_loadgloss = false;
8671 case RENDERPATH_GL11:
8672 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
8673 Cvar_SetValueQuick(&gl_combine, 0);
8674 Cvar_SetValueQuick(&r_glsl, 0);
8675 r_loadnormalmap = false;
8676 r_loadgloss = false;
8679 case RENDERPATH_GLES2:
8680 Cvar_SetValueQuick(&r_textureunits, 1);
8681 Cvar_SetValueQuick(&gl_combine, 1);
8682 Cvar_SetValueQuick(&r_glsl, 1);
8683 r_loadnormalmap = true;
8684 r_loadgloss = false;
8690 R_FrameData_Reset();
8694 memset(r_queries, 0, sizeof(r_queries));
8696 r_qwskincache = NULL;
8697 r_qwskincache_size = 0;
8699 // set up r_skinframe loading system for textures
8700 memset(&r_skinframe, 0, sizeof(r_skinframe));
8701 r_skinframe.loadsequence = 1;
8702 Mem_ExpandableArray_NewArray(&r_skinframe.array, r_main_mempool, sizeof(skinframe_t), 256);
8704 r_main_texturepool = R_AllocTexturePool();
8705 R_BuildBlankTextures();
8707 if (vid.support.arb_texture_cube_map)
8710 R_BuildNormalizationCube();
8712 r_texture_fogattenuation = NULL;
8713 r_texture_fogheighttexture = NULL;
8714 r_texture_gammaramps = NULL;
8715 //r_texture_fogintensity = NULL;
8716 memset(&r_bloomstate, 0, sizeof(r_bloomstate));
8717 memset(&r_waterstate, 0, sizeof(r_waterstate));
8718 r_glsl_permutation = NULL;
8719 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
8720 Mem_ExpandableArray_NewArray(&r_glsl_permutationarray, r_main_mempool, sizeof(r_glsl_permutation_t), 256);
8721 glslshaderstring = NULL;
8723 r_cg_permutation = NULL;
8724 memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
8725 Mem_ExpandableArray_NewArray(&r_cg_permutationarray, r_main_mempool, sizeof(r_cg_permutation_t), 256);
8726 cgshaderstring = NULL;
8729 r_hlsl_permutation = NULL;
8730 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
8731 Mem_ExpandableArray_NewArray(&r_hlsl_permutationarray, r_main_mempool, sizeof(r_hlsl_permutation_t), 256);
8732 hlslshaderstring = NULL;
8734 memset(&r_svbsp, 0, sizeof (r_svbsp));
8736 r_refdef.fogmasktable_density = 0;
8739 void gl_main_shutdown(void)
8742 R_FrameData_Reset();
8744 R_Main_FreeViewCache();
8746 switch(vid.renderpath)
8748 case RENDERPATH_GL11:
8749 case RENDERPATH_GL13:
8750 case RENDERPATH_GL20:
8751 case RENDERPATH_CGGL:
8753 qglDeleteQueriesARB(r_maxqueries, r_queries);
8755 case RENDERPATH_D3D9:
8756 //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8758 case RENDERPATH_D3D10:
8759 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8761 case RENDERPATH_D3D11:
8762 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8764 case RENDERPATH_SOFT:
8766 case RENDERPATH_GLES2:
8767 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8773 memset(r_queries, 0, sizeof(r_queries));
8775 r_qwskincache = NULL;
8776 r_qwskincache_size = 0;
8778 // clear out the r_skinframe state
8779 Mem_ExpandableArray_FreeArray(&r_skinframe.array);
8780 memset(&r_skinframe, 0, sizeof(r_skinframe));
8783 Mem_Free(r_svbsp.nodes);
8784 memset(&r_svbsp, 0, sizeof (r_svbsp));
8785 R_FreeTexturePool(&r_main_texturepool);
8786 loadingscreentexture = NULL;
8787 r_texture_blanknormalmap = NULL;
8788 r_texture_white = NULL;
8789 r_texture_grey128 = NULL;
8790 r_texture_black = NULL;
8791 r_texture_whitecube = NULL;
8792 r_texture_normalizationcube = NULL;
8793 r_texture_fogattenuation = NULL;
8794 r_texture_fogheighttexture = NULL;
8795 r_texture_gammaramps = NULL;
8796 r_texture_numcubemaps = 0;
8797 //r_texture_fogintensity = NULL;
8798 memset(&r_bloomstate, 0, sizeof(r_bloomstate));
8799 memset(&r_waterstate, 0, sizeof(r_waterstate));
8802 r_glsl_permutation = NULL;
8803 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
8804 Mem_ExpandableArray_FreeArray(&r_glsl_permutationarray);
8805 glslshaderstring = NULL;
8807 r_cg_permutation = NULL;
8808 memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
8809 Mem_ExpandableArray_FreeArray(&r_cg_permutationarray);
8810 cgshaderstring = NULL;
8813 r_hlsl_permutation = NULL;
8814 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
8815 Mem_ExpandableArray_FreeArray(&r_hlsl_permutationarray);
8816 hlslshaderstring = NULL;
8820 extern void CL_ParseEntityLump(char *entitystring);
8821 void gl_main_newmap(void)
8823 // FIXME: move this code to client
8824 char *entities, entname[MAX_QPATH];
8826 Mem_Free(r_qwskincache);
8827 r_qwskincache = NULL;
8828 r_qwskincache_size = 0;
8831 dpsnprintf(entname, sizeof(entname), "%s.ent", cl.worldnamenoextension);
8832 if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
8834 CL_ParseEntityLump(entities);
8838 if (cl.worldmodel->brush.entities)
8839 CL_ParseEntityLump(cl.worldmodel->brush.entities);
8841 R_Main_FreeViewCache();
8843 R_FrameData_Reset();
8846 void GL_Main_Init(void)
8848 r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
8850 Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed");
8851 Cmd_AddCommand("r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl");
8852 // FIXME: the client should set up r_refdef.fog stuff including the fogmasktable
8853 if (gamemode == GAME_NEHAHRA)
8855 Cvar_RegisterVariable (&gl_fogenable);
8856 Cvar_RegisterVariable (&gl_fogdensity);
8857 Cvar_RegisterVariable (&gl_fogred);
8858 Cvar_RegisterVariable (&gl_foggreen);
8859 Cvar_RegisterVariable (&gl_fogblue);
8860 Cvar_RegisterVariable (&gl_fogstart);
8861 Cvar_RegisterVariable (&gl_fogend);
8862 Cvar_RegisterVariable (&gl_skyclip);
8864 Cvar_RegisterVariable(&r_motionblur);
8865 Cvar_RegisterVariable(&r_motionblur_maxblur);
8866 Cvar_RegisterVariable(&r_motionblur_bmin);
8867 Cvar_RegisterVariable(&r_motionblur_vmin);
8868 Cvar_RegisterVariable(&r_motionblur_vmax);
8869 Cvar_RegisterVariable(&r_motionblur_vcoeff);
8870 Cvar_RegisterVariable(&r_motionblur_randomize);
8871 Cvar_RegisterVariable(&r_damageblur);
8872 Cvar_RegisterVariable(&r_equalize_entities_fullbright);
8873 Cvar_RegisterVariable(&r_equalize_entities_minambient);
8874 Cvar_RegisterVariable(&r_equalize_entities_by);
8875 Cvar_RegisterVariable(&r_equalize_entities_to);
8876 Cvar_RegisterVariable(&r_depthfirst);
8877 Cvar_RegisterVariable(&r_useinfinitefarclip);
8878 Cvar_RegisterVariable(&r_farclip_base);
8879 Cvar_RegisterVariable(&r_farclip_world);
8880 Cvar_RegisterVariable(&r_nearclip);
8881 Cvar_RegisterVariable(&r_showbboxes);
8882 Cvar_RegisterVariable(&r_showsurfaces);
8883 Cvar_RegisterVariable(&r_showtris);
8884 Cvar_RegisterVariable(&r_shownormals);
8885 Cvar_RegisterVariable(&r_showlighting);
8886 Cvar_RegisterVariable(&r_showshadowvolumes);
8887 Cvar_RegisterVariable(&r_showcollisionbrushes);
8888 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
8889 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
8890 Cvar_RegisterVariable(&r_showdisabledepthtest);
8891 Cvar_RegisterVariable(&r_drawportals);
8892 Cvar_RegisterVariable(&r_drawentities);
8893 Cvar_RegisterVariable(&r_draw2d);
8894 Cvar_RegisterVariable(&r_drawworld);
8895 Cvar_RegisterVariable(&r_cullentities_trace);
8896 Cvar_RegisterVariable(&r_cullentities_trace_samples);
8897 Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
8898 Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
8899 Cvar_RegisterVariable(&r_cullentities_trace_delay);
8900 Cvar_RegisterVariable(&r_drawviewmodel);
8901 Cvar_RegisterVariable(&r_drawexteriormodel);
8902 Cvar_RegisterVariable(&r_speeds);
8903 Cvar_RegisterVariable(&r_fullbrights);
8904 Cvar_RegisterVariable(&r_wateralpha);
8905 Cvar_RegisterVariable(&r_dynamic);
8906 Cvar_RegisterVariable(&r_fakelight);
8907 Cvar_RegisterVariable(&r_fakelight_intensity);
8908 Cvar_RegisterVariable(&r_fullbright);
8909 Cvar_RegisterVariable(&r_shadows);
8910 Cvar_RegisterVariable(&r_shadows_darken);
8911 Cvar_RegisterVariable(&r_shadows_drawafterrtlighting);
8912 Cvar_RegisterVariable(&r_shadows_castfrombmodels);
8913 Cvar_RegisterVariable(&r_shadows_throwdistance);
8914 Cvar_RegisterVariable(&r_shadows_throwdirection);
8915 Cvar_RegisterVariable(&r_shadows_focus);
8916 Cvar_RegisterVariable(&r_shadows_shadowmapscale);
8917 Cvar_RegisterVariable(&r_q1bsp_skymasking);
8918 Cvar_RegisterVariable(&r_polygonoffset_submodel_factor);
8919 Cvar_RegisterVariable(&r_polygonoffset_submodel_offset);
8920 Cvar_RegisterVariable(&r_polygonoffset_decals_factor);
8921 Cvar_RegisterVariable(&r_polygonoffset_decals_offset);
8922 Cvar_RegisterVariable(&r_fog_exp2);
8923 Cvar_RegisterVariable(&r_drawfog);
8924 Cvar_RegisterVariable(&r_transparentdepthmasking);
8925 Cvar_RegisterVariable(&r_texture_dds_load);
8926 Cvar_RegisterVariable(&r_texture_dds_save);
8927 Cvar_RegisterVariable(&r_texture_convertsRGB_2d);
8928 Cvar_RegisterVariable(&r_texture_convertsRGB_skin);
8929 Cvar_RegisterVariable(&r_texture_convertsRGB_cubemap);
8930 Cvar_RegisterVariable(&r_texture_convertsRGB_skybox);
8931 Cvar_RegisterVariable(&r_texture_convertsRGB_particles);
8932 Cvar_RegisterVariable(&r_textureunits);
8933 Cvar_RegisterVariable(&gl_combine);
8934 Cvar_RegisterVariable(&r_glsl);
8935 Cvar_RegisterVariable(&r_glsl_deluxemapping);
8936 Cvar_RegisterVariable(&r_glsl_offsetmapping);
8937 Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
8938 Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
8939 Cvar_RegisterVariable(&r_glsl_postprocess);
8940 Cvar_RegisterVariable(&r_glsl_postprocess_uservec1);
8941 Cvar_RegisterVariable(&r_glsl_postprocess_uservec2);
8942 Cvar_RegisterVariable(&r_glsl_postprocess_uservec3);
8943 Cvar_RegisterVariable(&r_glsl_postprocess_uservec4);
8944 Cvar_RegisterVariable(&r_glsl_postprocess_uservec1_enable);
8945 Cvar_RegisterVariable(&r_glsl_postprocess_uservec2_enable);
8946 Cvar_RegisterVariable(&r_glsl_postprocess_uservec3_enable);
8947 Cvar_RegisterVariable(&r_glsl_postprocess_uservec4_enable);
8949 Cvar_RegisterVariable(&r_water);
8950 Cvar_RegisterVariable(&r_water_resolutionmultiplier);
8951 Cvar_RegisterVariable(&r_water_clippingplanebias);
8952 Cvar_RegisterVariable(&r_water_refractdistort);
8953 Cvar_RegisterVariable(&r_water_reflectdistort);
8954 Cvar_RegisterVariable(&r_water_scissormode);
8955 Cvar_RegisterVariable(&r_lerpsprites);
8956 Cvar_RegisterVariable(&r_lerpmodels);
8957 Cvar_RegisterVariable(&r_lerplightstyles);
8958 Cvar_RegisterVariable(&r_waterscroll);
8959 Cvar_RegisterVariable(&r_bloom);
8960 Cvar_RegisterVariable(&r_bloom_colorscale);
8961 Cvar_RegisterVariable(&r_bloom_brighten);
8962 Cvar_RegisterVariable(&r_bloom_blur);
8963 Cvar_RegisterVariable(&r_bloom_resolution);
8964 Cvar_RegisterVariable(&r_bloom_colorexponent);
8965 Cvar_RegisterVariable(&r_bloom_colorsubtract);
8966 Cvar_RegisterVariable(&r_hdr);
8967 Cvar_RegisterVariable(&r_hdr_scenebrightness);
8968 Cvar_RegisterVariable(&r_hdr_glowintensity);
8969 Cvar_RegisterVariable(&r_hdr_range);
8970 Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
8971 Cvar_RegisterVariable(&developer_texturelogging);
8972 Cvar_RegisterVariable(&gl_lightmaps);
8973 Cvar_RegisterVariable(&r_test);
8974 Cvar_RegisterVariable(&r_glsl_saturation);
8975 Cvar_RegisterVariable(&r_glsl_saturation_redcompensate);
8976 Cvar_RegisterVariable(&r_framedatasize);
8977 if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
8978 Cvar_SetValue("r_fullbrights", 0);
8979 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap, NULL, NULL);
8981 Cvar_RegisterVariable(&r_track_sprites);
8982 Cvar_RegisterVariable(&r_track_sprites_flags);
8983 Cvar_RegisterVariable(&r_track_sprites_scalew);
8984 Cvar_RegisterVariable(&r_track_sprites_scaleh);
8985 Cvar_RegisterVariable(&r_overheadsprites_perspective);
8986 Cvar_RegisterVariable(&r_overheadsprites_pushback);
8987 Cvar_RegisterVariable(&r_overheadsprites_scalex);
8988 Cvar_RegisterVariable(&r_overheadsprites_scaley);
8991 extern void R_Textures_Init(void);
8992 extern void GL_Draw_Init(void);
8993 extern void GL_Main_Init(void);
8994 extern void R_Shadow_Init(void);
8995 extern void R_Sky_Init(void);
8996 extern void GL_Surf_Init(void);
8997 extern void R_Particles_Init(void);
8998 extern void R_Explosion_Init(void);
8999 extern void gl_backend_init(void);
9000 extern void Sbar_Init(void);
9001 extern void R_LightningBeams_Init(void);
9002 extern void Mod_RenderInit(void);
9003 extern void Font_Init(void);
9005 void Render_Init(void)
9018 R_LightningBeams_Init();
9027 extern char *ENGINE_EXTENSIONS;
9030 gl_renderer = (const char *)qglGetString(GL_RENDERER);
9031 gl_vendor = (const char *)qglGetString(GL_VENDOR);
9032 gl_version = (const char *)qglGetString(GL_VERSION);
9033 gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
9037 if (!gl_platformextensions)
9038 gl_platformextensions = "";
9040 Con_Printf("GL_VENDOR: %s\n", gl_vendor);
9041 Con_Printf("GL_RENDERER: %s\n", gl_renderer);
9042 Con_Printf("GL_VERSION: %s\n", gl_version);
9043 Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
9044 Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
9046 VID_CheckExtensions();
9048 // LordHavoc: report supported extensions
9049 Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
9051 // clear to black (loading plaque will be seen over this)
9052 GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
9055 int R_CullBox(const vec3_t mins, const vec3_t maxs)
9059 for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
9061 // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
9064 p = r_refdef.view.frustum + i;
9069 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9073 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9077 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9081 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9085 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9089 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9093 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9097 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9105 int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
9109 for (i = 0;i < numplanes;i++)
9116 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9120 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9124 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9128 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9132 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9136 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9140 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9144 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9152 //==================================================================================
9154 // LordHavoc: this stores temporary data used within the same frame
9156 typedef struct r_framedata_mem_s
9158 struct r_framedata_mem_s *purge; // older mem block to free on next frame
9159 size_t size; // how much usable space
9160 size_t current; // how much space in use
9161 size_t mark; // last "mark" location, temporary memory can be freed by returning to this
9162 size_t wantedsize; // how much space was allocated
9163 unsigned char *data; // start of real data (16byte aligned)
9167 static r_framedata_mem_t *r_framedata_mem;
9169 void R_FrameData_Reset(void)
9171 while (r_framedata_mem)
9173 r_framedata_mem_t *next = r_framedata_mem->purge;
9174 Mem_Free(r_framedata_mem);
9175 r_framedata_mem = next;
9179 void R_FrameData_Resize(void)
9182 wantedsize = (size_t)(r_framedatasize.value * 1024*1024);
9183 wantedsize = bound(65536, wantedsize, 1000*1024*1024);
9184 if (!r_framedata_mem || r_framedata_mem->wantedsize != wantedsize)
9186 r_framedata_mem_t *newmem = (r_framedata_mem_t *)Mem_Alloc(r_main_mempool, wantedsize);
9187 newmem->wantedsize = wantedsize;
9188 newmem->data = (unsigned char *)(((size_t)(newmem+1) + 15) & ~15);
9189 newmem->size = (unsigned char *)newmem + wantedsize - newmem->data;
9190 newmem->current = 0;
9192 newmem->purge = r_framedata_mem;
9193 r_framedata_mem = newmem;
9197 void R_FrameData_NewFrame(void)
9199 R_FrameData_Resize();
9200 if (!r_framedata_mem)
9202 // if we ran out of space on the last frame, free the old memory now
9203 while (r_framedata_mem->purge)
9205 // repeatedly remove the second item in the list, leaving only head
9206 r_framedata_mem_t *next = r_framedata_mem->purge->purge;
9207 Mem_Free(r_framedata_mem->purge);
9208 r_framedata_mem->purge = next;
9210 // reset the current mem pointer
9211 r_framedata_mem->current = 0;
9212 r_framedata_mem->mark = 0;
9215 void *R_FrameData_Alloc(size_t size)
9219 // align to 16 byte boundary - the data pointer is already aligned, so we
9220 // only need to ensure the size of every allocation is also aligned
9221 size = (size + 15) & ~15;
9223 while (!r_framedata_mem || r_framedata_mem->current + size > r_framedata_mem->size)
9225 // emergency - we ran out of space, allocate more memory
9226 Cvar_SetValueQuick(&r_framedatasize, bound(0.25f, r_framedatasize.value * 2.0f, 128.0f));
9227 R_FrameData_Resize();
9230 data = r_framedata_mem->data + r_framedata_mem->current;
9231 r_framedata_mem->current += size;
9233 // count the usage for stats
9234 r_refdef.stats.framedatacurrent = max(r_refdef.stats.framedatacurrent, (int)r_framedata_mem->current);
9235 r_refdef.stats.framedatasize = max(r_refdef.stats.framedatasize, (int)r_framedata_mem->size);
9237 return (void *)data;
9240 void *R_FrameData_Store(size_t size, void *data)
9242 void *d = R_FrameData_Alloc(size);
9244 memcpy(d, data, size);
9248 void R_FrameData_SetMark(void)
9250 if (!r_framedata_mem)
9252 r_framedata_mem->mark = r_framedata_mem->current;
9255 void R_FrameData_ReturnToMark(void)
9257 if (!r_framedata_mem)
9259 r_framedata_mem->current = r_framedata_mem->mark;
9262 //==================================================================================
9264 // LordHavoc: animcache originally written by Echon, rewritten since then
9267 * Animation cache prevents re-generating mesh data for an animated model
9268 * multiple times in one frame for lighting, shadowing, reflections, etc.
9271 void R_AnimCache_Free(void)
9275 void R_AnimCache_ClearCache(void)
9278 entity_render_t *ent;
9280 for (i = 0;i < r_refdef.scene.numentities;i++)
9282 ent = r_refdef.scene.entities[i];
9283 ent->animcache_vertex3f = NULL;
9284 ent->animcache_normal3f = NULL;
9285 ent->animcache_svector3f = NULL;
9286 ent->animcache_tvector3f = NULL;
9287 ent->animcache_vertexmesh = NULL;
9288 ent->animcache_vertex3fbuffer = NULL;
9289 ent->animcache_vertexmeshbuffer = NULL;
9293 void R_AnimCache_UpdateEntityMeshBuffers(entity_render_t *ent, int numvertices)
9297 // check if we need the meshbuffers
9298 if (!vid.useinterleavedarrays)
9301 if (!ent->animcache_vertexmesh && ent->animcache_normal3f)
9302 ent->animcache_vertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
9303 // TODO: upload vertex3f buffer?
9304 if (ent->animcache_vertexmesh)
9306 memcpy(ent->animcache_vertexmesh, ent->model->surfmesh.vertexmesh, sizeof(r_vertexmesh_t)*numvertices);
9307 for (i = 0;i < numvertices;i++)
9308 memcpy(ent->animcache_vertexmesh[i].vertex3f, ent->animcache_vertex3f + 3*i, sizeof(float[3]));
9309 if (ent->animcache_svector3f)
9310 for (i = 0;i < numvertices;i++)
9311 memcpy(ent->animcache_vertexmesh[i].svector3f, ent->animcache_svector3f + 3*i, sizeof(float[3]));
9312 if (ent->animcache_tvector3f)
9313 for (i = 0;i < numvertices;i++)
9314 memcpy(ent->animcache_vertexmesh[i].tvector3f, ent->animcache_tvector3f + 3*i, sizeof(float[3]));
9315 if (ent->animcache_normal3f)
9316 for (i = 0;i < numvertices;i++)
9317 memcpy(ent->animcache_vertexmesh[i].normal3f, ent->animcache_normal3f + 3*i, sizeof(float[3]));
9318 // TODO: upload vertexmeshbuffer?
9322 qboolean R_AnimCache_GetEntity(entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
9324 dp_model_t *model = ent->model;
9326 // see if it's already cached this frame
9327 if (ent->animcache_vertex3f)
9329 // add normals/tangents if needed (this only happens with multiple views, reflections, cameras, etc)
9330 if (wantnormals || wanttangents)
9332 if (ent->animcache_normal3f)
9333 wantnormals = false;
9334 if (ent->animcache_svector3f)
9335 wanttangents = false;
9336 if (wantnormals || wanttangents)
9338 numvertices = model->surfmesh.num_vertices;
9340 ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9343 ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9344 ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9346 model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? ent->animcache_normal3f : NULL, wanttangents ? ent->animcache_svector3f : NULL, wanttangents ? ent->animcache_tvector3f : NULL);
9347 R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
9353 // see if this ent is worth caching
9354 if (!model || !model->Draw || !model->surfmesh.isanimated || !model->AnimateVertices || (ent->frameblend[0].lerp == 1 && ent->frameblend[0].subframe == 0 && !ent->skeleton))
9356 // get some memory for this entity and generate mesh data
9357 numvertices = model->surfmesh.num_vertices;
9358 ent->animcache_vertex3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9360 ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9363 ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9364 ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9366 model->AnimateVertices(model, ent->frameblend, ent->skeleton, ent->animcache_vertex3f, ent->animcache_normal3f, ent->animcache_svector3f, ent->animcache_tvector3f);
9367 R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
9372 void R_AnimCache_CacheVisibleEntities(void)
9375 qboolean wantnormals = true;
9376 qboolean wanttangents = !r_showsurfaces.integer;
9378 switch(vid.renderpath)
9380 case RENDERPATH_GL20:
9381 case RENDERPATH_CGGL:
9382 case RENDERPATH_D3D9:
9383 case RENDERPATH_D3D10:
9384 case RENDERPATH_D3D11:
9385 case RENDERPATH_GLES2:
9387 case RENDERPATH_GL13:
9388 case RENDERPATH_GL11:
9389 wanttangents = false;
9391 case RENDERPATH_SOFT:
9395 if (r_shownormals.integer)
9396 wanttangents = wantnormals = true;
9398 // TODO: thread this
9399 // NOTE: R_PrepareRTLights() also caches entities
9401 for (i = 0;i < r_refdef.scene.numentities;i++)
9402 if (r_refdef.viewcache.entityvisible[i])
9403 R_AnimCache_GetEntity(r_refdef.scene.entities[i], wantnormals, wanttangents);
9406 //==================================================================================
9408 static void R_View_UpdateEntityLighting (void)
9411 entity_render_t *ent;
9412 vec3_t tempdiffusenormal, avg;
9413 vec_t f, fa, fd, fdd;
9414 qboolean skipunseen = r_shadows.integer != 1; //|| R_Shadow_ShadowMappingEnabled();
9416 for (i = 0;i < r_refdef.scene.numentities;i++)
9418 ent = r_refdef.scene.entities[i];
9420 // skip unseen models
9421 if (!r_refdef.viewcache.entityvisible[i] && skipunseen)
9425 if (ent->model && ent->model->brush.num_leafs)
9427 // TODO: use modellight for r_ambient settings on world?
9428 VectorSet(ent->modellight_ambient, 0, 0, 0);
9429 VectorSet(ent->modellight_diffuse, 0, 0, 0);
9430 VectorSet(ent->modellight_lightdir, 0, 0, 1);
9434 // fetch the lighting from the worldmodel data
9435 VectorClear(ent->modellight_ambient);
9436 VectorClear(ent->modellight_diffuse);
9437 VectorClear(tempdiffusenormal);
9438 if ((ent->flags & RENDER_LIGHT) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
9441 Matrix4x4_OriginFromMatrix(&ent->matrix, org);
9443 // complete lightning for lit sprites
9444 // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
9445 if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
9447 if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
9448 org[2] = org[2] + r_overheadsprites_pushback.value;
9449 R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, ent->modellight_lightdir, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
9452 r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
9454 if(ent->flags & RENDER_EQUALIZE)
9456 // first fix up ambient lighting...
9457 if(r_equalize_entities_minambient.value > 0)
9459 fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
9462 fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]);
9463 if(fa < r_equalize_entities_minambient.value * fd)
9466 // fa'/fd' = minambient
9467 // fa'+0.25*fd' = fa+0.25*fd
9469 // fa' = fd' * minambient
9470 // fd'*(0.25+minambient) = fa+0.25*fd
9472 // fd' = (fa+0.25*fd) * 1 / (0.25+minambient)
9473 // fa' = (fa+0.25*fd) * minambient / (0.25+minambient)
9475 fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value);
9476 f = fdd / fd; // f>0 because all this is additive; f<1 because fdd<fd because this follows from fa < r_equalize_entities_minambient.value * fd
9477 VectorMA(ent->modellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient);
9478 VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
9483 if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
9485 fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
9486 fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
9490 // adjust brightness and saturation to target
9491 avg[0] = avg[1] = avg[2] = fa / f;
9492 VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
9493 avg[0] = avg[1] = avg[2] = fd / f;
9494 VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
9500 VectorSet(ent->modellight_ambient, 1, 1, 1);
9502 // move the light direction into modelspace coordinates for lighting code
9503 Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
9504 if(VectorLength2(ent->modellight_lightdir) == 0)
9505 VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
9506 VectorNormalize(ent->modellight_lightdir);
9510 #define MAX_LINEOFSIGHTTRACES 64
9512 static qboolean R_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
9515 vec3_t boxmins, boxmaxs;
9518 dp_model_t *model = r_refdef.scene.worldmodel;
9520 if (!model || !model->brush.TraceLineOfSight)
9523 // expand the box a little
9524 boxmins[0] = (enlarge+1) * entboxmins[0] - enlarge * entboxmaxs[0];
9525 boxmaxs[0] = (enlarge+1) * entboxmaxs[0] - enlarge * entboxmins[0];
9526 boxmins[1] = (enlarge+1) * entboxmins[1] - enlarge * entboxmaxs[1];
9527 boxmaxs[1] = (enlarge+1) * entboxmaxs[1] - enlarge * entboxmins[1];
9528 boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2];
9529 boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2];
9531 // return true if eye is inside enlarged box
9532 if (BoxesOverlap(boxmins, boxmaxs, eye, eye))
9536 VectorCopy(eye, start);
9537 VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, end);
9538 if (model->brush.TraceLineOfSight(model, start, end))
9541 // try various random positions
9542 for (i = 0;i < numsamples;i++)
9544 VectorSet(end, lhrandom(boxmins[0], boxmaxs[0]), lhrandom(boxmins[1], boxmaxs[1]), lhrandom(boxmins[2], boxmaxs[2]));
9545 if (model->brush.TraceLineOfSight(model, start, end))
9553 static void R_View_UpdateEntityVisible (void)
9558 entity_render_t *ent;
9560 renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL)
9561 : r_waterstate.renderingrefraction ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL)
9562 : (chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL
9563 : RENDER_EXTERIORMODEL;
9564 if (!r_drawviewmodel.integer)
9565 renderimask |= RENDER_VIEWMODEL;
9566 if (!r_drawexteriormodel.integer)
9567 renderimask |= RENDER_EXTERIORMODEL;
9568 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs)
9570 // worldmodel can check visibility
9571 memset(r_refdef.viewcache.entityvisible, 0, r_refdef.scene.numentities);
9572 for (i = 0;i < r_refdef.scene.numentities;i++)
9574 ent = r_refdef.scene.entities[i];
9575 if (!(ent->flags & renderimask))
9576 if (!R_CullBox(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
9577 if ((ent->flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL)) || r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, ent->mins, ent->maxs))
9578 r_refdef.viewcache.entityvisible[i] = true;
9580 if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane)
9581 // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling
9583 for (i = 0;i < r_refdef.scene.numentities;i++)
9585 ent = r_refdef.scene.entities[i];
9586 if(r_refdef.viewcache.entityvisible[i] && !(ent->flags & (RENDER_VIEWMODEL | RENDER_NOCULL | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
9588 samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer;
9590 continue; // temp entities do pvs only
9591 if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
9592 ent->last_trace_visibility = realtime;
9593 if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
9594 r_refdef.viewcache.entityvisible[i] = 0;
9601 // no worldmodel or it can't check visibility
9602 for (i = 0;i < r_refdef.scene.numentities;i++)
9604 ent = r_refdef.scene.entities[i];
9605 r_refdef.viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs));
9610 /// only used if skyrendermasked, and normally returns false
9611 int R_DrawBrushModelsSky (void)
9614 entity_render_t *ent;
9617 for (i = 0;i < r_refdef.scene.numentities;i++)
9619 if (!r_refdef.viewcache.entityvisible[i])
9621 ent = r_refdef.scene.entities[i];
9622 if (!ent->model || !ent->model->DrawSky)
9624 ent->model->DrawSky(ent);
9630 static void R_DrawNoModel(entity_render_t *ent);
9631 static void R_DrawModels(void)
9634 entity_render_t *ent;
9636 for (i = 0;i < r_refdef.scene.numentities;i++)
9638 if (!r_refdef.viewcache.entityvisible[i])
9640 ent = r_refdef.scene.entities[i];
9641 r_refdef.stats.entities++;
9642 if (ent->model && ent->model->Draw != NULL)
9643 ent->model->Draw(ent);
9649 static void R_DrawModelsDepth(void)
9652 entity_render_t *ent;
9654 for (i = 0;i < r_refdef.scene.numentities;i++)
9656 if (!r_refdef.viewcache.entityvisible[i])
9658 ent = r_refdef.scene.entities[i];
9659 if (ent->model && ent->model->DrawDepth != NULL)
9660 ent->model->DrawDepth(ent);
9664 static void R_DrawModelsDebug(void)
9667 entity_render_t *ent;
9669 for (i = 0;i < r_refdef.scene.numentities;i++)
9671 if (!r_refdef.viewcache.entityvisible[i])
9673 ent = r_refdef.scene.entities[i];
9674 if (ent->model && ent->model->DrawDebug != NULL)
9675 ent->model->DrawDebug(ent);
9679 static void R_DrawModelsAddWaterPlanes(void)
9682 entity_render_t *ent;
9684 for (i = 0;i < r_refdef.scene.numentities;i++)
9686 if (!r_refdef.viewcache.entityvisible[i])
9688 ent = r_refdef.scene.entities[i];
9689 if (ent->model && ent->model->DrawAddWaterPlanes != NULL)
9690 ent->model->DrawAddWaterPlanes(ent);
9694 static void R_View_SetFrustum(const int *scissor)
9697 double fpx = +1, fnx = -1, fpy = +1, fny = -1;
9698 vec3_t forward, left, up, origin, v;
9702 // flipped x coordinates (because x points left here)
9703 fpx = 1.0 - 2.0 * (scissor[0] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
9704 fnx = 1.0 - 2.0 * (scissor[0] + scissor[2] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
9706 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
9707 switch(vid.renderpath)
9709 case RENDERPATH_D3D9:
9710 case RENDERPATH_D3D10:
9711 case RENDERPATH_D3D11:
9712 case RENDERPATH_SOFT:
9713 // non-flipped y coordinates
9714 fny = -1.0 + 2.0 * (vid.height - scissor[1] - scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9715 fpy = -1.0 + 2.0 * (vid.height - scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9717 case RENDERPATH_GL11:
9718 case RENDERPATH_GL13:
9719 case RENDERPATH_GL20:
9720 case RENDERPATH_CGGL:
9721 case RENDERPATH_GLES2:
9722 // non-flipped y coordinates
9723 fny = -1.0 + 2.0 * (scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9724 fpy = -1.0 + 2.0 * (scissor[1] + scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9729 // we can't trust r_refdef.view.forward and friends in reflected scenes
9730 Matrix4x4_ToVectors(&r_refdef.view.matrix, forward, left, up, origin);
9733 r_refdef.view.frustum[0].normal[0] = 0 - 1.0 / r_refdef.view.frustum_x;
9734 r_refdef.view.frustum[0].normal[1] = 0 - 0;
9735 r_refdef.view.frustum[0].normal[2] = -1 - 0;
9736 r_refdef.view.frustum[1].normal[0] = 0 + 1.0 / r_refdef.view.frustum_x;
9737 r_refdef.view.frustum[1].normal[1] = 0 + 0;
9738 r_refdef.view.frustum[1].normal[2] = -1 + 0;
9739 r_refdef.view.frustum[2].normal[0] = 0 - 0;
9740 r_refdef.view.frustum[2].normal[1] = 0 - 1.0 / r_refdef.view.frustum_y;
9741 r_refdef.view.frustum[2].normal[2] = -1 - 0;
9742 r_refdef.view.frustum[3].normal[0] = 0 + 0;
9743 r_refdef.view.frustum[3].normal[1] = 0 + 1.0 / r_refdef.view.frustum_y;
9744 r_refdef.view.frustum[3].normal[2] = -1 + 0;
9748 zNear = r_refdef.nearclip;
9749 nudge = 1.0 - 1.0 / (1<<23);
9750 r_refdef.view.frustum[4].normal[0] = 0 - 0;
9751 r_refdef.view.frustum[4].normal[1] = 0 - 0;
9752 r_refdef.view.frustum[4].normal[2] = -1 - -nudge;
9753 r_refdef.view.frustum[4].dist = 0 - -2 * zNear * nudge;
9754 r_refdef.view.frustum[5].normal[0] = 0 + 0;
9755 r_refdef.view.frustum[5].normal[1] = 0 + 0;
9756 r_refdef.view.frustum[5].normal[2] = -1 + -nudge;
9757 r_refdef.view.frustum[5].dist = 0 + -2 * zNear * nudge;
9763 r_refdef.view.frustum[0].normal[0] = m[3] - m[0];
9764 r_refdef.view.frustum[0].normal[1] = m[7] - m[4];
9765 r_refdef.view.frustum[0].normal[2] = m[11] - m[8];
9766 r_refdef.view.frustum[0].dist = m[15] - m[12];
9768 r_refdef.view.frustum[1].normal[0] = m[3] + m[0];
9769 r_refdef.view.frustum[1].normal[1] = m[7] + m[4];
9770 r_refdef.view.frustum[1].normal[2] = m[11] + m[8];
9771 r_refdef.view.frustum[1].dist = m[15] + m[12];
9773 r_refdef.view.frustum[2].normal[0] = m[3] - m[1];
9774 r_refdef.view.frustum[2].normal[1] = m[7] - m[5];
9775 r_refdef.view.frustum[2].normal[2] = m[11] - m[9];
9776 r_refdef.view.frustum[2].dist = m[15] - m[13];
9778 r_refdef.view.frustum[3].normal[0] = m[3] + m[1];
9779 r_refdef.view.frustum[3].normal[1] = m[7] + m[5];
9780 r_refdef.view.frustum[3].normal[2] = m[11] + m[9];
9781 r_refdef.view.frustum[3].dist = m[15] + m[13];
9783 r_refdef.view.frustum[4].normal[0] = m[3] - m[2];
9784 r_refdef.view.frustum[4].normal[1] = m[7] - m[6];
9785 r_refdef.view.frustum[4].normal[2] = m[11] - m[10];
9786 r_refdef.view.frustum[4].dist = m[15] - m[14];
9788 r_refdef.view.frustum[5].normal[0] = m[3] + m[2];
9789 r_refdef.view.frustum[5].normal[1] = m[7] + m[6];
9790 r_refdef.view.frustum[5].normal[2] = m[11] + m[10];
9791 r_refdef.view.frustum[5].dist = m[15] + m[14];
9794 if (r_refdef.view.useperspective)
9796 // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
9797 VectorMAMAM(1024, forward, fnx * 1024.0 * r_refdef.view.frustum_x, left, fny * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[0]);
9798 VectorMAMAM(1024, forward, fpx * 1024.0 * r_refdef.view.frustum_x, left, fny * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[1]);
9799 VectorMAMAM(1024, forward, fnx * 1024.0 * r_refdef.view.frustum_x, left, fpy * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[2]);
9800 VectorMAMAM(1024, forward, fpx * 1024.0 * r_refdef.view.frustum_x, left, fpy * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[3]);
9802 // then the normals from the corners relative to origin
9803 CrossProduct(r_refdef.view.frustumcorner[2], r_refdef.view.frustumcorner[0], r_refdef.view.frustum[0].normal);
9804 CrossProduct(r_refdef.view.frustumcorner[1], r_refdef.view.frustumcorner[3], r_refdef.view.frustum[1].normal);
9805 CrossProduct(r_refdef.view.frustumcorner[0], r_refdef.view.frustumcorner[1], r_refdef.view.frustum[2].normal);
9806 CrossProduct(r_refdef.view.frustumcorner[3], r_refdef.view.frustumcorner[2], r_refdef.view.frustum[3].normal);
9808 // in a NORMAL view, forward cross left == up
9809 // in a REFLECTED view, forward cross left == down
9810 // so our cross products above need to be adjusted for a left handed coordinate system
9811 CrossProduct(forward, left, v);
9812 if(DotProduct(v, up) < 0)
9814 VectorNegate(r_refdef.view.frustum[0].normal, r_refdef.view.frustum[0].normal);
9815 VectorNegate(r_refdef.view.frustum[1].normal, r_refdef.view.frustum[1].normal);
9816 VectorNegate(r_refdef.view.frustum[2].normal, r_refdef.view.frustum[2].normal);
9817 VectorNegate(r_refdef.view.frustum[3].normal, r_refdef.view.frustum[3].normal);
9820 // Leaving those out was a mistake, those were in the old code, and they
9821 // fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix
9822 // I couldn't reproduce it after adding those normalizations. --blub
9823 VectorNormalize(r_refdef.view.frustum[0].normal);
9824 VectorNormalize(r_refdef.view.frustum[1].normal);
9825 VectorNormalize(r_refdef.view.frustum[2].normal);
9826 VectorNormalize(r_refdef.view.frustum[3].normal);
9828 // make the corners absolute
9829 VectorAdd(r_refdef.view.frustumcorner[0], r_refdef.view.origin, r_refdef.view.frustumcorner[0]);
9830 VectorAdd(r_refdef.view.frustumcorner[1], r_refdef.view.origin, r_refdef.view.frustumcorner[1]);
9831 VectorAdd(r_refdef.view.frustumcorner[2], r_refdef.view.origin, r_refdef.view.frustumcorner[2]);
9832 VectorAdd(r_refdef.view.frustumcorner[3], r_refdef.view.origin, r_refdef.view.frustumcorner[3]);
9835 VectorCopy(forward, r_refdef.view.frustum[4].normal);
9837 r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal);
9838 r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal);
9839 r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[2].normal);
9840 r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[3].normal);
9841 r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[4].normal) + r_refdef.nearclip;
9845 VectorScale(left, -r_refdef.view.ortho_x, r_refdef.view.frustum[0].normal);
9846 VectorScale(left, r_refdef.view.ortho_x, r_refdef.view.frustum[1].normal);
9847 VectorScale(up, -r_refdef.view.ortho_y, r_refdef.view.frustum[2].normal);
9848 VectorScale(up, r_refdef.view.ortho_y, r_refdef.view.frustum[3].normal);
9849 VectorCopy(forward, r_refdef.view.frustum[4].normal);
9850 r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal) + r_refdef.view.ortho_x;
9851 r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal) + r_refdef.view.ortho_x;
9852 r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[2].normal) + r_refdef.view.ortho_y;
9853 r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[3].normal) + r_refdef.view.ortho_y;
9854 r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[4].normal) + r_refdef.nearclip;
9856 r_refdef.view.numfrustumplanes = 5;
9858 if (r_refdef.view.useclipplane)
9860 r_refdef.view.numfrustumplanes = 6;
9861 r_refdef.view.frustum[5] = r_refdef.view.clipplane;
9864 for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
9865 PlaneClassify(r_refdef.view.frustum + i);
9867 // LordHavoc: note to all quake engine coders, Quake had a special case
9868 // for 90 degrees which assumed a square view (wrong), so I removed it,
9869 // Quake2 has it disabled as well.
9871 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
9872 //RotatePointAroundVector( r_refdef.view.frustum[0].normal, up, forward, -(90 - r_refdef.fov_x / 2));
9873 //r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, frustum[0].normal);
9874 //PlaneClassify(&frustum[0]);
9876 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
9877 //RotatePointAroundVector( r_refdef.view.frustum[1].normal, up, forward, (90 - r_refdef.fov_x / 2));
9878 //r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, frustum[1].normal);
9879 //PlaneClassify(&frustum[1]);
9881 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
9882 //RotatePointAroundVector( r_refdef.view.frustum[2].normal, left, forward, -(90 - r_refdef.fov_y / 2));
9883 //r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, frustum[2].normal);
9884 //PlaneClassify(&frustum[2]);
9886 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
9887 //RotatePointAroundVector( r_refdef.view.frustum[3].normal, left, forward, (90 - r_refdef.fov_y / 2));
9888 //r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, frustum[3].normal);
9889 //PlaneClassify(&frustum[3]);
9892 //VectorCopy(forward, r_refdef.view.frustum[4].normal);
9893 //r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, frustum[4].normal) + r_nearclip.value;
9894 //PlaneClassify(&frustum[4]);
9897 void R_View_UpdateWithScissor(const int *myscissor)
9899 R_Main_ResizeViewCache();
9900 R_View_SetFrustum(myscissor);
9901 R_View_WorldVisibility(r_refdef.view.useclipplane);
9902 R_View_UpdateEntityVisible();
9903 R_View_UpdateEntityLighting();
9906 void R_View_Update(void)
9908 R_Main_ResizeViewCache();
9909 R_View_SetFrustum(NULL);
9910 R_View_WorldVisibility(r_refdef.view.useclipplane);
9911 R_View_UpdateEntityVisible();
9912 R_View_UpdateEntityLighting();
9915 void R_SetupView(qboolean allowwaterclippingplane)
9917 const float *customclipplane = NULL;
9919 if (r_refdef.view.useclipplane && allowwaterclippingplane)
9921 // LordHavoc: couldn't figure out how to make this approach the
9922 vec_t dist = r_refdef.view.clipplane.dist - r_water_clippingplanebias.value;
9923 vec_t viewdist = DotProduct(r_refdef.view.origin, r_refdef.view.clipplane.normal);
9924 if (viewdist < r_refdef.view.clipplane.dist + r_water_clippingplanebias.value)
9925 dist = r_refdef.view.clipplane.dist;
9926 plane[0] = r_refdef.view.clipplane.normal[0];
9927 plane[1] = r_refdef.view.clipplane.normal[1];
9928 plane[2] = r_refdef.view.clipplane.normal[2];
9930 customclipplane = plane;
9933 if (!r_refdef.view.useperspective)
9934 R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, -r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip, customclipplane);
9935 else if (vid.stencil && r_useinfinitefarclip.integer)
9936 R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane);
9938 R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane);
9939 R_SetViewport(&r_refdef.view.viewport);
9942 void R_EntityMatrix(const matrix4x4_t *matrix)
9944 if (gl_modelmatrixchanged || memcmp(matrix, &gl_modelmatrix, sizeof(matrix4x4_t)))
9946 gl_modelmatrixchanged = false;
9947 gl_modelmatrix = *matrix;
9948 Matrix4x4_Concat(&gl_modelviewmatrix, &gl_viewmatrix, &gl_modelmatrix);
9949 Matrix4x4_Concat(&gl_modelviewprojectionmatrix, &gl_projectionmatrix, &gl_modelviewmatrix);
9950 Matrix4x4_ToArrayFloatGL(&gl_modelviewmatrix, gl_modelview16f);
9951 Matrix4x4_ToArrayFloatGL(&gl_modelviewprojectionmatrix, gl_modelviewprojection16f);
9953 switch(vid.renderpath)
9955 case RENDERPATH_D3D9:
9957 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
9958 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
9961 case RENDERPATH_D3D10:
9962 Con_DPrintf("FIXME D3D10 shader %s:%i\n", __FILE__, __LINE__);
9964 case RENDERPATH_D3D11:
9965 Con_DPrintf("FIXME D3D11 shader %s:%i\n", __FILE__, __LINE__);
9967 case RENDERPATH_GL20:
9968 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
9969 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
9970 qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
9972 case RENDERPATH_CGGL:
9975 if (r_cg_permutation && r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR
9976 if (r_cg_permutation && r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR
9977 qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
9980 case RENDERPATH_GL13:
9981 case RENDERPATH_GL11:
9982 qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
9984 case RENDERPATH_SOFT:
9985 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
9986 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
9988 case RENDERPATH_GLES2:
9989 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
9990 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
9996 void R_ResetViewRendering2D(void)
9998 r_viewport_t viewport;
10001 // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom
10002 R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, 1, 1, -10, 100, NULL);
10003 R_SetViewport(&viewport);
10004 GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
10005 GL_Color(1, 1, 1, 1);
10006 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
10007 GL_BlendFunc(GL_ONE, GL_ZERO);
10008 GL_AlphaTest(false);
10009 GL_ScissorTest(false);
10010 GL_DepthMask(false);
10011 GL_DepthRange(0, 1);
10012 GL_DepthTest(false);
10013 GL_DepthFunc(GL_LEQUAL);
10014 R_EntityMatrix(&identitymatrix);
10015 R_Mesh_ResetTextureState();
10016 GL_PolygonOffset(0, 0);
10017 R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
10018 switch(vid.renderpath)
10020 case RENDERPATH_GL11:
10021 case RENDERPATH_GL13:
10022 case RENDERPATH_GL20:
10023 case RENDERPATH_CGGL:
10024 case RENDERPATH_GLES2:
10025 qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
10027 case RENDERPATH_D3D9:
10028 case RENDERPATH_D3D10:
10029 case RENDERPATH_D3D11:
10030 case RENDERPATH_SOFT:
10033 GL_CullFace(GL_NONE);
10036 void R_ResetViewRendering3D(void)
10041 GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
10042 GL_Color(1, 1, 1, 1);
10043 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
10044 GL_BlendFunc(GL_ONE, GL_ZERO);
10045 GL_AlphaTest(false);
10046 GL_ScissorTest(true);
10047 GL_DepthMask(true);
10048 GL_DepthRange(0, 1);
10049 GL_DepthTest(true);
10050 GL_DepthFunc(GL_LEQUAL);
10051 R_EntityMatrix(&identitymatrix);
10052 R_Mesh_ResetTextureState();
10053 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
10054 R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
10055 switch(vid.renderpath)
10057 case RENDERPATH_GL11:
10058 case RENDERPATH_GL13:
10059 case RENDERPATH_GL20:
10060 case RENDERPATH_CGGL:
10061 case RENDERPATH_GLES2:
10062 qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
10064 case RENDERPATH_D3D9:
10065 case RENDERPATH_D3D10:
10066 case RENDERPATH_D3D11:
10067 case RENDERPATH_SOFT:
10070 GL_CullFace(r_refdef.view.cullface_back);
10075 R_RenderView_UpdateViewVectors
10078 static void R_RenderView_UpdateViewVectors(void)
10080 // break apart the view matrix into vectors for various purposes
10081 // it is important that this occurs outside the RenderScene function because that can be called from reflection renders, where the vectors come out wrong
10082 // however the r_refdef.view.origin IS updated in RenderScene intentionally - otherwise the sky renders at the wrong origin, etc
10083 Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin);
10084 VectorNegate(r_refdef.view.left, r_refdef.view.right);
10085 // make an inverted copy of the view matrix for tracking sprites
10086 Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix);
10089 void R_RenderScene(void);
10090 void R_RenderWaterPlanes(void);
10092 static void R_Water_StartFrame(void)
10095 int waterwidth, waterheight, texturewidth, textureheight, camerawidth, cameraheight;
10096 r_waterstate_waterplane_t *p;
10098 if (vid.width > (int)vid.maxtexturesize_2d || vid.height > (int)vid.maxtexturesize_2d)
10101 switch(vid.renderpath)
10103 case RENDERPATH_GL20:
10104 case RENDERPATH_CGGL:
10105 case RENDERPATH_D3D9:
10106 case RENDERPATH_D3D10:
10107 case RENDERPATH_D3D11:
10108 case RENDERPATH_SOFT:
10110 case RENDERPATH_GL13:
10111 case RENDERPATH_GL11:
10112 case RENDERPATH_GLES2:
10116 // set waterwidth and waterheight to the water resolution that will be
10117 // used (often less than the screen resolution for faster rendering)
10118 waterwidth = (int)bound(1, vid.width * r_water_resolutionmultiplier.value, vid.width);
10119 waterheight = (int)bound(1, vid.height * r_water_resolutionmultiplier.value, vid.height);
10121 // calculate desired texture sizes
10122 // can't use water if the card does not support the texture size
10123 if (!r_water.integer || r_showsurfaces.integer)
10124 texturewidth = textureheight = waterwidth = waterheight = camerawidth = cameraheight = 0;
10125 else if (vid.support.arb_texture_non_power_of_two)
10127 texturewidth = waterwidth;
10128 textureheight = waterheight;
10129 camerawidth = waterwidth;
10130 cameraheight = waterheight;
10134 for (texturewidth = 1;texturewidth < waterwidth ;texturewidth *= 2);
10135 for (textureheight = 1;textureheight < waterheight;textureheight *= 2);
10136 for (camerawidth = 1;camerawidth <= waterwidth; camerawidth *= 2); camerawidth /= 2;
10137 for (cameraheight = 1;cameraheight <= waterheight;cameraheight *= 2); cameraheight /= 2;
10140 // allocate textures as needed
10141 if (r_waterstate.texturewidth != texturewidth || r_waterstate.textureheight != textureheight || r_waterstate.camerawidth != camerawidth || r_waterstate.cameraheight != cameraheight)
10143 r_waterstate.maxwaterplanes = MAX_WATERPLANES;
10144 for (i = 0, p = r_waterstate.waterplanes;i < r_waterstate.maxwaterplanes;i++, p++)
10146 if (p->texture_refraction)
10147 R_FreeTexture(p->texture_refraction);
10148 p->texture_refraction = NULL;
10149 if (p->texture_reflection)
10150 R_FreeTexture(p->texture_reflection);
10151 p->texture_reflection = NULL;
10152 if (p->texture_camera)
10153 R_FreeTexture(p->texture_camera);
10154 p->texture_camera = NULL;
10156 memset(&r_waterstate, 0, sizeof(r_waterstate));
10157 r_waterstate.texturewidth = texturewidth;
10158 r_waterstate.textureheight = textureheight;
10159 r_waterstate.camerawidth = camerawidth;
10160 r_waterstate.cameraheight = cameraheight;
10163 if (r_waterstate.texturewidth)
10165 r_waterstate.enabled = true;
10167 // when doing a reduced render (HDR) we want to use a smaller area
10168 r_waterstate.waterwidth = (int)bound(1, r_refdef.view.width * r_water_resolutionmultiplier.value, r_refdef.view.width);
10169 r_waterstate.waterheight = (int)bound(1, r_refdef.view.height * r_water_resolutionmultiplier.value, r_refdef.view.height);
10171 // set up variables that will be used in shader setup
10172 r_waterstate.screenscale[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
10173 r_waterstate.screenscale[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
10174 r_waterstate.screencenter[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
10175 r_waterstate.screencenter[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
10178 r_waterstate.maxwaterplanes = MAX_WATERPLANES;
10179 r_waterstate.numwaterplanes = 0;
10182 void R_Water_AddWaterPlane(msurface_t *surface, int entno)
10184 int triangleindex, planeindex;
10190 r_waterstate_waterplane_t *p;
10191 texture_t *t = R_GetCurrentTexture(surface->texture);
10193 // just use the first triangle with a valid normal for any decisions
10194 VectorClear(normal);
10195 for (triangleindex = 0, e = rsurface.modelelement3i + surface->num_firsttriangle * 3;triangleindex < surface->num_triangles;triangleindex++, e += 3)
10197 Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[0]*3, vert[0]);
10198 Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[1]*3, vert[1]);
10199 Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[2]*3, vert[2]);
10200 TriangleNormal(vert[0], vert[1], vert[2], normal);
10201 if (VectorLength2(normal) >= 0.001)
10205 VectorCopy(normal, plane.normal);
10206 VectorNormalize(plane.normal);
10207 plane.dist = DotProduct(vert[0], plane.normal);
10208 PlaneClassify(&plane);
10209 if (PlaneDiff(r_refdef.view.origin, &plane) < 0)
10211 // skip backfaces (except if nocullface is set)
10212 if (!(t->currentmaterialflags & MATERIALFLAG_NOCULLFACE))
10214 VectorNegate(plane.normal, plane.normal);
10216 PlaneClassify(&plane);
10220 // find a matching plane if there is one
10221 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
10222 if(p->camera_entity == t->camera_entity)
10223 if (fabs(PlaneDiff(vert[0], &p->plane)) < 1 && fabs(PlaneDiff(vert[1], &p->plane)) < 1 && fabs(PlaneDiff(vert[2], &p->plane)) < 1)
10225 if (planeindex >= r_waterstate.maxwaterplanes)
10226 return; // nothing we can do, out of planes
10228 // if this triangle does not fit any known plane rendered this frame, add one
10229 if (planeindex >= r_waterstate.numwaterplanes)
10231 // store the new plane
10232 r_waterstate.numwaterplanes++;
10234 // clear materialflags and pvs
10235 p->materialflags = 0;
10236 p->pvsvalid = false;
10237 p->camera_entity = t->camera_entity;
10238 VectorCopy(surface->mins, p->mins);
10239 VectorCopy(surface->maxs, p->maxs);
10244 p->mins[0] = min(p->mins[0], surface->mins[0]);
10245 p->mins[1] = min(p->mins[1], surface->mins[1]);
10246 p->mins[2] = min(p->mins[2], surface->mins[2]);
10247 p->maxs[0] = max(p->maxs[0], surface->maxs[0]);
10248 p->maxs[1] = max(p->maxs[1], surface->maxs[1]);
10249 p->maxs[2] = max(p->maxs[2], surface->maxs[2]);
10251 // merge this surface's materialflags into the waterplane
10252 p->materialflags |= t->currentmaterialflags;
10253 if(!(p->materialflags & MATERIALFLAG_CAMERA))
10255 // merge this surface's PVS into the waterplane
10256 VectorMAM(0.5f, surface->mins, 0.5f, surface->maxs, center);
10257 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS
10258 && r_refdef.scene.worldmodel->brush.PointInLeaf && r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, center)->clusterindex >= 0)
10260 r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, center, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid);
10261 p->pvsvalid = true;
10266 static void R_Water_ProcessPlanes(void)
10269 r_refdef_view_t originalview;
10270 r_refdef_view_t myview;
10272 r_waterstate_waterplane_t *p;
10275 originalview = r_refdef.view;
10277 // make sure enough textures are allocated
10278 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
10280 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
10282 if (!p->texture_refraction)
10283 p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_refraction", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
10284 if (!p->texture_refraction)
10287 else if (p->materialflags & MATERIALFLAG_CAMERA)
10289 if (!p->texture_camera)
10290 p->texture_camera = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_camera", planeindex), r_waterstate.camerawidth, r_waterstate.cameraheight, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCELINEAR, -1, NULL);
10291 if (!p->texture_camera)
10295 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
10297 if (!p->texture_reflection)
10298 p->texture_reflection = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_reflection", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
10299 if (!p->texture_reflection)
10305 r_refdef.view = originalview;
10306 r_refdef.view.showdebug = false;
10307 r_refdef.view.width = r_waterstate.waterwidth;
10308 r_refdef.view.height = r_waterstate.waterheight;
10309 r_refdef.view.useclipplane = true;
10310 myview = r_refdef.view;
10311 r_waterstate.renderingscene = true;
10312 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
10314 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
10316 r_refdef.view = myview;
10317 if(r_water_scissormode.integer)
10320 if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
10321 continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
10324 // render reflected scene and copy into texture
10325 Matrix4x4_Reflect(&r_refdef.view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
10326 // update the r_refdef.view.origin because otherwise the sky renders at the wrong location (amongst other problems)
10327 Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin);
10328 r_refdef.view.clipplane = p->plane;
10330 // reverse the cullface settings for this render
10331 r_refdef.view.cullface_front = GL_FRONT;
10332 r_refdef.view.cullface_back = GL_BACK;
10333 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.num_pvsclusterbytes)
10335 r_refdef.view.usecustompvs = true;
10337 memcpy(r_refdef.viewcache.world_pvsbits, p->pvsbits, r_refdef.scene.worldmodel->brush.num_pvsclusterbytes);
10339 memset(r_refdef.viewcache.world_pvsbits, 0xFF, r_refdef.scene.worldmodel->brush.num_pvsclusterbytes);
10342 R_ResetViewRendering3D();
10343 R_ClearScreen(r_refdef.fogenabled);
10344 if(r_water_scissormode.integer & 2)
10345 R_View_UpdateWithScissor(myscissor);
10348 if(r_water_scissormode.integer & 1)
10349 GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
10352 R_Mesh_CopyToTexture(p->texture_reflection, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
10355 // render the normal view scene and copy into texture
10356 // (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted)
10357 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
10359 r_refdef.view = myview;
10360 if(r_water_scissormode.integer)
10363 if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
10364 continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
10367 r_waterstate.renderingrefraction = true;
10369 r_refdef.view.clipplane = p->plane;
10370 VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal);
10371 r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist;
10373 if((p->materialflags & MATERIALFLAG_CAMERA) && p->camera_entity)
10375 // we need to perform a matrix transform to render the view... so let's get the transformation matrix
10376 r_waterstate.renderingrefraction = false; // we don't want to hide the player model from these ones
10377 CL_VM_TransformView(p->camera_entity - MAX_EDICTS, &r_refdef.view.matrix, &r_refdef.view.clipplane, visorigin);
10378 R_RenderView_UpdateViewVectors();
10379 if(r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
10381 r_refdef.view.usecustompvs = true;
10382 r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, visorigin, 2, r_refdef.viewcache.world_pvsbits, (r_refdef.viewcache.world_numclusters+7)>>3, false);
10386 PlaneClassify(&r_refdef.view.clipplane);
10388 R_ResetViewRendering3D();
10389 R_ClearScreen(r_refdef.fogenabled);
10390 if(r_water_scissormode.integer & 2)
10391 R_View_UpdateWithScissor(myscissor);
10394 if(r_water_scissormode.integer & 1)
10395 GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
10398 R_Mesh_CopyToTexture(p->texture_refraction, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
10399 r_waterstate.renderingrefraction = false;
10401 else if (p->materialflags & MATERIALFLAG_CAMERA)
10403 r_refdef.view = myview;
10405 r_refdef.view.clipplane = p->plane;
10406 VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal);
10407 r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist;
10409 r_refdef.view.width = r_waterstate.camerawidth;
10410 r_refdef.view.height = r_waterstate.cameraheight;
10411 r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
10412 r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
10414 if(p->camera_entity)
10416 // we need to perform a matrix transform to render the view... so let's get the transformation matrix
10417 CL_VM_TransformView(p->camera_entity - MAX_EDICTS, &r_refdef.view.matrix, &r_refdef.view.clipplane, visorigin);
10420 // note: all of the view is used for displaying... so
10421 // there is no use in scissoring
10423 // reverse the cullface settings for this render
10424 r_refdef.view.cullface_front = GL_FRONT;
10425 r_refdef.view.cullface_back = GL_BACK;
10426 // also reverse the view matrix
10427 Matrix4x4_ConcatScale3(&r_refdef.view.matrix, 1, 1, -1); // this serves to invert texcoords in the result, as the copied texture is mapped the wrong way round
10428 R_RenderView_UpdateViewVectors();
10429 if(p->camera_entity && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
10431 r_refdef.view.usecustompvs = true;
10432 r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, visorigin, 2, r_refdef.viewcache.world_pvsbits, (r_refdef.viewcache.world_numclusters+7)>>3, false);
10435 // camera needs no clipplane
10436 r_refdef.view.useclipplane = false;
10438 PlaneClassify(&r_refdef.view.clipplane);
10440 R_ResetViewRendering3D();
10441 R_ClearScreen(r_refdef.fogenabled);
10445 R_Mesh_CopyToTexture(p->texture_camera, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
10446 r_waterstate.renderingrefraction = false;
10450 r_waterstate.renderingscene = false;
10451 r_refdef.view = originalview;
10452 R_ResetViewRendering3D();
10453 R_ClearScreen(r_refdef.fogenabled);
10457 r_refdef.view = originalview;
10458 r_waterstate.renderingscene = false;
10459 Cvar_SetValueQuick(&r_water, 0);
10460 Con_Printf("R_Water_ProcessPlanes: Error: texture creation failed! Turned off r_water.\n");
10464 void R_Bloom_StartFrame(void)
10466 int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight;
10468 switch(vid.renderpath)
10470 case RENDERPATH_GL20:
10471 case RENDERPATH_CGGL:
10472 case RENDERPATH_D3D9:
10473 case RENDERPATH_D3D10:
10474 case RENDERPATH_D3D11:
10475 case RENDERPATH_SOFT:
10477 case RENDERPATH_GL13:
10478 case RENDERPATH_GL11:
10479 case RENDERPATH_GLES2:
10483 // set bloomwidth and bloomheight to the bloom resolution that will be
10484 // used (often less than the screen resolution for faster rendering)
10485 r_bloomstate.bloomwidth = bound(1, r_bloom_resolution.integer, vid.height);
10486 r_bloomstate.bloomheight = r_bloomstate.bloomwidth * vid.height / vid.width;
10487 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, vid.height);
10488 r_bloomstate.bloomwidth = bound(1, r_bloomstate.bloomwidth, (int)vid.maxtexturesize_2d);
10489 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, (int)vid.maxtexturesize_2d);
10491 // calculate desired texture sizes
10492 if (vid.support.arb_texture_non_power_of_two)
10494 screentexturewidth = r_refdef.view.width;
10495 screentextureheight = r_refdef.view.height;
10496 bloomtexturewidth = r_bloomstate.bloomwidth;
10497 bloomtextureheight = r_bloomstate.bloomheight;
10501 for (screentexturewidth = 1;screentexturewidth < vid.width ;screentexturewidth *= 2);
10502 for (screentextureheight = 1;screentextureheight < vid.height ;screentextureheight *= 2);
10503 for (bloomtexturewidth = 1;bloomtexturewidth < r_bloomstate.bloomwidth ;bloomtexturewidth *= 2);
10504 for (bloomtextureheight = 1;bloomtextureheight < r_bloomstate.bloomheight;bloomtextureheight *= 2);
10507 if ((r_hdr.integer || r_bloom.integer || (!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0))) && ((r_bloom_resolution.integer < 4 || r_bloom_blur.value < 1 || r_bloom_blur.value >= 512) || r_refdef.view.width > (int)vid.maxtexturesize_2d || r_refdef.view.height > (int)vid.maxtexturesize_2d))
10509 Cvar_SetValueQuick(&r_hdr, 0);
10510 Cvar_SetValueQuick(&r_bloom, 0);
10511 Cvar_SetValueQuick(&r_motionblur, 0);
10512 Cvar_SetValueQuick(&r_damageblur, 0);
10515 if (!(r_glsl_postprocess.integer || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial)) && !r_bloom.integer && !r_hdr.integer && (R_Stereo_Active() || (r_motionblur.value <= 0 && r_damageblur.value <= 0)))
10516 screentexturewidth = screentextureheight = 0;
10517 if (!r_hdr.integer && !r_bloom.integer)
10518 bloomtexturewidth = bloomtextureheight = 0;
10520 // allocate textures as needed
10521 if (r_bloomstate.screentexturewidth != screentexturewidth || r_bloomstate.screentextureheight != screentextureheight)
10523 if (r_bloomstate.texture_screen)
10524 R_FreeTexture(r_bloomstate.texture_screen);
10525 r_bloomstate.texture_screen = NULL;
10526 r_bloomstate.screentexturewidth = screentexturewidth;
10527 r_bloomstate.screentextureheight = screentextureheight;
10528 if (r_bloomstate.screentexturewidth && r_bloomstate.screentextureheight)
10529 r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP, -1, NULL);
10531 if (r_bloomstate.bloomtexturewidth != bloomtexturewidth || r_bloomstate.bloomtextureheight != bloomtextureheight)
10533 if (r_bloomstate.texture_bloom)
10534 R_FreeTexture(r_bloomstate.texture_bloom);
10535 r_bloomstate.texture_bloom = NULL;
10536 r_bloomstate.bloomtexturewidth = bloomtexturewidth;
10537 r_bloomstate.bloomtextureheight = bloomtextureheight;
10538 if (r_bloomstate.bloomtexturewidth && r_bloomstate.bloomtextureheight)
10539 r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
10542 // when doing a reduced render (HDR) we want to use a smaller area
10543 r_bloomstate.bloomwidth = bound(1, r_bloom_resolution.integer, r_refdef.view.height);
10544 r_bloomstate.bloomheight = r_bloomstate.bloomwidth * r_refdef.view.height / r_refdef.view.width;
10545 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, r_refdef.view.height);
10546 r_bloomstate.bloomwidth = bound(1, r_bloomstate.bloomwidth, r_bloomstate.bloomtexturewidth);
10547 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, r_bloomstate.bloomtextureheight);
10549 // set up a texcoord array for the full resolution screen image
10550 // (we have to keep this around to copy back during final render)
10551 r_bloomstate.screentexcoord2f[0] = 0;
10552 r_bloomstate.screentexcoord2f[1] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight;
10553 r_bloomstate.screentexcoord2f[2] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth;
10554 r_bloomstate.screentexcoord2f[3] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight;
10555 r_bloomstate.screentexcoord2f[4] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth;
10556 r_bloomstate.screentexcoord2f[5] = 0;
10557 r_bloomstate.screentexcoord2f[6] = 0;
10558 r_bloomstate.screentexcoord2f[7] = 0;
10560 // set up a texcoord array for the reduced resolution bloom image
10561 // (which will be additive blended over the screen image)
10562 r_bloomstate.bloomtexcoord2f[0] = 0;
10563 r_bloomstate.bloomtexcoord2f[1] = (float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10564 r_bloomstate.bloomtexcoord2f[2] = (float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10565 r_bloomstate.bloomtexcoord2f[3] = (float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10566 r_bloomstate.bloomtexcoord2f[4] = (float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10567 r_bloomstate.bloomtexcoord2f[5] = 0;
10568 r_bloomstate.bloomtexcoord2f[6] = 0;
10569 r_bloomstate.bloomtexcoord2f[7] = 0;
10571 switch(vid.renderpath)
10573 case RENDERPATH_GL11:
10574 case RENDERPATH_GL13:
10575 case RENDERPATH_GL20:
10576 case RENDERPATH_CGGL:
10577 case RENDERPATH_SOFT:
10578 case RENDERPATH_GLES2:
10580 case RENDERPATH_D3D9:
10581 case RENDERPATH_D3D10:
10582 case RENDERPATH_D3D11:
10585 for (i = 0;i < 4;i++)
10587 r_bloomstate.screentexcoord2f[i*2+0] += 0.5f / (float)r_bloomstate.screentexturewidth;
10588 r_bloomstate.screentexcoord2f[i*2+1] += 0.5f / (float)r_bloomstate.screentextureheight;
10589 r_bloomstate.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_bloomstate.bloomtexturewidth;
10590 r_bloomstate.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_bloomstate.bloomtextureheight;
10596 if (r_hdr.integer || r_bloom.integer)
10598 r_bloomstate.enabled = true;
10599 r_bloomstate.hdr = r_hdr.integer != 0;
10602 R_Viewport_InitOrtho(&r_bloomstate.viewport, &identitymatrix, r_refdef.view.x, vid.height - r_bloomstate.bloomheight - r_refdef.view.y, r_bloomstate.bloomwidth, r_bloomstate.bloomheight, 0, 0, 1, 1, -10, 100, NULL);
10605 void R_Bloom_CopyBloomTexture(float colorscale)
10607 r_refdef.stats.bloom++;
10609 // scale down screen texture to the bloom texture size
10611 R_SetViewport(&r_bloomstate.viewport);
10612 GL_BlendFunc(GL_ONE, GL_ZERO);
10613 GL_Color(colorscale, colorscale, colorscale, 1);
10614 // D3D has upside down Y coords, the easiest way to flip this is to flip the screen vertices rather than the texcoords, so we just use a different array for that...
10615 switch(vid.renderpath)
10617 case RENDERPATH_GL11:
10618 case RENDERPATH_GL13:
10619 case RENDERPATH_GL20:
10620 case RENDERPATH_CGGL:
10621 case RENDERPATH_SOFT:
10622 case RENDERPATH_GLES2:
10623 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10625 case RENDERPATH_D3D9:
10626 case RENDERPATH_D3D10:
10627 case RENDERPATH_D3D11:
10628 R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10631 // TODO: do boxfilter scale-down in shader?
10632 R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1);
10633 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10634 r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
10636 // we now have a bloom image in the framebuffer
10637 // copy it into the bloom image texture for later processing
10638 R_Mesh_CopyToTexture(r_bloomstate.texture_bloom, 0, 0, r_bloomstate.viewport.x, r_bloomstate.viewport.y, r_bloomstate.viewport.width, r_bloomstate.viewport.height);
10639 r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
10642 void R_Bloom_CopyHDRTexture(void)
10644 R_Mesh_CopyToTexture(r_bloomstate.texture_bloom, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
10645 r_refdef.stats.bloom_copypixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
10648 void R_Bloom_MakeTexture(void)
10651 float xoffset, yoffset, r, brighten;
10653 r_refdef.stats.bloom++;
10655 R_ResetViewRendering2D();
10657 // we have a bloom image in the framebuffer
10659 R_SetViewport(&r_bloomstate.viewport);
10661 for (x = 1;x < min(r_bloom_colorexponent.value, 32);)
10664 r = bound(0, r_bloom_colorexponent.value / x, 1);
10665 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
10667 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.bloomtexcoord2f);
10668 R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1);
10669 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10670 r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
10672 // copy the vertically blurred bloom view to a texture
10673 R_Mesh_CopyToTexture(r_bloomstate.texture_bloom, 0, 0, r_bloomstate.viewport.x, r_bloomstate.viewport.y, r_bloomstate.viewport.width, r_bloomstate.viewport.height);
10674 r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
10677 range = r_bloom_blur.integer * r_bloomstate.bloomwidth / 320;
10678 brighten = r_bloom_brighten.value;
10680 brighten *= r_hdr_range.value;
10681 brighten = sqrt(brighten);
10683 brighten *= (3 * range) / (2 * range - 1); // compensate for the "dot particle"
10684 R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1);
10686 for (dir = 0;dir < 2;dir++)
10688 // blend on at multiple vertical offsets to achieve a vertical blur
10689 // TODO: do offset blends using GLSL
10690 // TODO instead of changing the texcoords, change the target positions to prevent artifacts at edges
10691 GL_BlendFunc(GL_ONE, GL_ZERO);
10692 for (x = -range;x <= range;x++)
10694 if (!dir){xoffset = 0;yoffset = x;}
10695 else {xoffset = x;yoffset = 0;}
10696 xoffset /= (float)r_bloomstate.bloomtexturewidth;
10697 yoffset /= (float)r_bloomstate.bloomtextureheight;
10698 // compute a texcoord array with the specified x and y offset
10699 r_bloomstate.offsettexcoord2f[0] = xoffset+0;
10700 r_bloomstate.offsettexcoord2f[1] = yoffset+(float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10701 r_bloomstate.offsettexcoord2f[2] = xoffset+(float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10702 r_bloomstate.offsettexcoord2f[3] = yoffset+(float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10703 r_bloomstate.offsettexcoord2f[4] = xoffset+(float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10704 r_bloomstate.offsettexcoord2f[5] = yoffset+0;
10705 r_bloomstate.offsettexcoord2f[6] = xoffset+0;
10706 r_bloomstate.offsettexcoord2f[7] = yoffset+0;
10707 // this r value looks like a 'dot' particle, fading sharply to
10708 // black at the edges
10709 // (probably not realistic but looks good enough)
10710 //r = ((range*range+1)/((float)(x*x+1)))/(range*2+1);
10711 //r = brighten/(range*2+1);
10712 r = brighten / (range * 2 + 1);
10714 r *= (1 - x*x/(float)(range*range));
10715 GL_Color(r, r, r, 1);
10716 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.offsettexcoord2f);
10717 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10718 r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
10719 GL_BlendFunc(GL_ONE, GL_ONE);
10722 // copy the vertically blurred bloom view to a texture
10723 R_Mesh_CopyToTexture(r_bloomstate.texture_bloom, 0, 0, r_bloomstate.viewport.x, r_bloomstate.viewport.y, r_bloomstate.viewport.width, r_bloomstate.viewport.height);
10724 r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
10728 void R_HDR_RenderBloomTexture(void)
10730 int oldwidth, oldheight;
10731 float oldcolorscale;
10732 qboolean oldwaterstate;
10734 oldwaterstate = r_waterstate.enabled;
10735 oldcolorscale = r_refdef.view.colorscale;
10736 oldwidth = r_refdef.view.width;
10737 oldheight = r_refdef.view.height;
10738 r_refdef.view.width = r_bloomstate.bloomwidth;
10739 r_refdef.view.height = r_bloomstate.bloomheight;
10741 if(r_hdr.integer < 2)
10742 r_waterstate.enabled = false;
10744 // TODO: support GL_EXT_framebuffer_object rather than reusing the framebuffer? it might improve SLI performance.
10745 // TODO: add exposure compensation features
10746 // TODO: add fp16 framebuffer support (using GL_EXT_framebuffer_object)
10748 r_refdef.view.showdebug = false;
10749 r_refdef.view.colorscale *= r_bloom_colorscale.value / bound(1, r_hdr_range.value, 16);
10751 R_ResetViewRendering3D();
10753 R_ClearScreen(r_refdef.fogenabled);
10754 if (r_timereport_active)
10755 R_TimeReport("HDRclear");
10758 if (r_timereport_active)
10759 R_TimeReport("visibility");
10761 // only do secondary renders with HDR if r_hdr is 2 or higher
10762 r_waterstate.numwaterplanes = 0;
10763 if (r_waterstate.enabled)
10764 R_RenderWaterPlanes();
10766 r_refdef.view.showdebug = true;
10768 r_waterstate.numwaterplanes = 0;
10770 R_ResetViewRendering2D();
10772 R_Bloom_CopyHDRTexture();
10773 R_Bloom_MakeTexture();
10775 // restore the view settings
10776 r_waterstate.enabled = oldwaterstate;
10777 r_refdef.view.width = oldwidth;
10778 r_refdef.view.height = oldheight;
10779 r_refdef.view.colorscale = oldcolorscale;
10781 R_ResetViewRendering3D();
10783 R_ClearScreen(r_refdef.fogenabled);
10784 if (r_timereport_active)
10785 R_TimeReport("viewclear");
10788 static void R_BlendView(void)
10790 unsigned int permutation;
10791 float uservecs[4][4];
10793 switch (vid.renderpath)
10795 case RENDERPATH_GL20:
10796 case RENDERPATH_CGGL:
10797 case RENDERPATH_D3D9:
10798 case RENDERPATH_D3D10:
10799 case RENDERPATH_D3D11:
10800 case RENDERPATH_SOFT:
10801 case RENDERPATH_GLES2:
10803 (r_bloomstate.texture_bloom ? SHADERPERMUTATION_BLOOM : 0)
10804 | (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VIEWTINT : 0)
10805 | ((v_glslgamma.value && !vid_gammatables_trivial) ? SHADERPERMUTATION_GAMMARAMPS : 0)
10806 | (r_glsl_postprocess.integer ? SHADERPERMUTATION_POSTPROCESSING : 0)
10807 | ((!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) ? SHADERPERMUTATION_SATURATION : 0);
10809 if (r_bloomstate.texture_screen)
10811 // make sure the buffer is available
10812 if (r_bloom_blur.value < 1) { Cvar_SetValueQuick(&r_bloom_blur, 1); }
10814 R_ResetViewRendering2D();
10816 if(!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0))
10818 // declare variables
10820 static float avgspeed;
10822 speed = VectorLength(cl.movement_velocity);
10824 cl.motionbluralpha = bound(0, (cl.time - cl.oldtime) / max(0.001, r_motionblur_vcoeff.value), 1);
10825 avgspeed = avgspeed * (1 - cl.motionbluralpha) + speed * cl.motionbluralpha;
10827 speed = (avgspeed - r_motionblur_vmin.value) / max(1, r_motionblur_vmax.value - r_motionblur_vmin.value);
10828 speed = bound(0, speed, 1);
10829 speed = speed * (1 - r_motionblur_bmin.value) + r_motionblur_bmin.value;
10831 // calculate values into a standard alpha
10832 cl.motionbluralpha = 1 - exp(-
10834 (r_motionblur.value * speed / 80)
10836 (r_damageblur.value * (cl.cshifts[CSHIFT_DAMAGE].percent / 1600))
10839 max(0.0001, cl.time - cl.oldtime) // fps independent
10842 cl.motionbluralpha *= lhrandom(1 - r_motionblur_randomize.value, 1 + r_motionblur_randomize.value);
10843 cl.motionbluralpha = bound(0, cl.motionbluralpha, r_motionblur_maxblur.value);
10845 if (cl.motionbluralpha > 0 && !r_refdef.envmap)
10847 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
10848 GL_Color(1, 1, 1, cl.motionbluralpha);
10849 switch(vid.renderpath)
10851 case RENDERPATH_GL11:
10852 case RENDERPATH_GL13:
10853 case RENDERPATH_GL20:
10854 case RENDERPATH_CGGL:
10855 case RENDERPATH_SOFT:
10856 case RENDERPATH_GLES2:
10857 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10859 case RENDERPATH_D3D9:
10860 case RENDERPATH_D3D10:
10861 case RENDERPATH_D3D11:
10862 R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10865 R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1);
10866 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10867 r_refdef.stats.bloom_drawpixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
10871 // copy view into the screen texture
10872 R_Mesh_CopyToTexture(r_bloomstate.texture_screen, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
10873 r_refdef.stats.bloom_copypixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
10875 else if (!r_bloomstate.texture_bloom)
10877 // we may still have to do view tint...
10878 if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
10880 // apply a color tint to the whole view
10881 R_ResetViewRendering2D();
10882 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10883 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
10884 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
10885 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
10886 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10888 break; // no screen processing, no bloom, skip it
10891 if (r_bloomstate.texture_bloom && !r_bloomstate.hdr)
10893 // render simple bloom effect
10894 // copy the screen and shrink it and darken it for the bloom process
10895 R_Bloom_CopyBloomTexture(r_bloom_colorscale.value);
10896 // make the bloom texture
10897 R_Bloom_MakeTexture();
10900 #if _MSC_VER >= 1400
10901 #define sscanf sscanf_s
10903 memset(uservecs, 0, sizeof(uservecs));
10904 if (r_glsl_postprocess_uservec1_enable.integer)
10905 sscanf(r_glsl_postprocess_uservec1.string, "%f %f %f %f", &uservecs[0][0], &uservecs[0][1], &uservecs[0][2], &uservecs[0][3]);
10906 if (r_glsl_postprocess_uservec2_enable.integer)
10907 sscanf(r_glsl_postprocess_uservec2.string, "%f %f %f %f", &uservecs[1][0], &uservecs[1][1], &uservecs[1][2], &uservecs[1][3]);
10908 if (r_glsl_postprocess_uservec3_enable.integer)
10909 sscanf(r_glsl_postprocess_uservec3.string, "%f %f %f %f", &uservecs[2][0], &uservecs[2][1], &uservecs[2][2], &uservecs[2][3]);
10910 if (r_glsl_postprocess_uservec4_enable.integer)
10911 sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &uservecs[3][0], &uservecs[3][1], &uservecs[3][2], &uservecs[3][3]);
10913 R_ResetViewRendering2D();
10914 GL_Color(1, 1, 1, 1);
10915 GL_BlendFunc(GL_ONE, GL_ZERO);
10917 switch(vid.renderpath)
10919 case RENDERPATH_GL20:
10920 case RENDERPATH_GLES2:
10921 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10922 R_SetupShader_SetPermutationGLSL(SHADERMODE_POSTPROCESS, permutation);
10923 if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_bloomstate.texture_screen);
10924 if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_bloomstate.texture_bloom );
10925 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps );
10926 if (r_glsl_permutation->loc_ViewTintColor >= 0) qglUniform4f(r_glsl_permutation->loc_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10927 if (r_glsl_permutation->loc_PixelSize >= 0) qglUniform2f(r_glsl_permutation->loc_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
10928 if (r_glsl_permutation->loc_UserVec1 >= 0) qglUniform4f(r_glsl_permutation->loc_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
10929 if (r_glsl_permutation->loc_UserVec2 >= 0) qglUniform4f(r_glsl_permutation->loc_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
10930 if (r_glsl_permutation->loc_UserVec3 >= 0) qglUniform4f(r_glsl_permutation->loc_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
10931 if (r_glsl_permutation->loc_UserVec4 >= 0) qglUniform4f(r_glsl_permutation->loc_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
10932 if (r_glsl_permutation->loc_Saturation >= 0) qglUniform1f(r_glsl_permutation->loc_Saturation , r_glsl_saturation.value);
10933 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
10934 if (r_glsl_permutation->loc_BloomColorSubtract >= 0) qglUniform4f(r_glsl_permutation->loc_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
10936 case RENDERPATH_CGGL:
10938 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10939 R_SetupShader_SetPermutationCG(SHADERMODE_POSTPROCESS, permutation);
10940 if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , r_bloomstate.texture_screen);CHECKCGERROR
10941 if (r_cg_permutation->fp_Texture_Second ) CG_BindTexture(r_cg_permutation->fp_Texture_Second , r_bloomstate.texture_bloom );CHECKCGERROR
10942 if (r_cg_permutation->fp_Texture_GammaRamps) CG_BindTexture(r_cg_permutation->fp_Texture_GammaRamps, r_texture_gammaramps );CHECKCGERROR
10943 if (r_cg_permutation->fp_ViewTintColor ) cgGLSetParameter4f( r_cg_permutation->fp_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);CHECKCGERROR
10944 if (r_cg_permutation->fp_PixelSize ) cgGLSetParameter2f( r_cg_permutation->fp_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);CHECKCGERROR
10945 if (r_cg_permutation->fp_UserVec1 ) cgGLSetParameter4f( r_cg_permutation->fp_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);CHECKCGERROR
10946 if (r_cg_permutation->fp_UserVec2 ) cgGLSetParameter4f( r_cg_permutation->fp_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);CHECKCGERROR
10947 if (r_cg_permutation->fp_UserVec3 ) cgGLSetParameter4f( r_cg_permutation->fp_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);CHECKCGERROR
10948 if (r_cg_permutation->fp_UserVec4 ) cgGLSetParameter4f( r_cg_permutation->fp_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);CHECKCGERROR
10949 if (r_cg_permutation->fp_Saturation ) cgGLSetParameter1f( r_cg_permutation->fp_Saturation , r_glsl_saturation.value);CHECKCGERROR
10950 if (r_cg_permutation->fp_PixelToScreenTexCoord) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
10951 if (r_cg_permutation->fp_BloomColorSubtract ) cgGLSetParameter4f(r_cg_permutation->fp_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
10954 case RENDERPATH_D3D9:
10956 // D3D has upside down Y coords, the easiest way to flip this is to flip the screen vertices rather than the texcoords, so we just use a different array for that...
10957 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_d3dscreenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10958 R_SetupShader_SetPermutationHLSL(SHADERMODE_POSTPROCESS, permutation);
10959 R_Mesh_TexBind(GL20TU_FIRST , r_bloomstate.texture_screen);
10960 R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom );
10961 R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
10962 hlslPSSetParameter4f(D3DPSREGISTER_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10963 hlslPSSetParameter2f(D3DPSREGISTER_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
10964 hlslPSSetParameter4f(D3DPSREGISTER_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
10965 hlslPSSetParameter4f(D3DPSREGISTER_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
10966 hlslPSSetParameter4f(D3DPSREGISTER_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
10967 hlslPSSetParameter4f(D3DPSREGISTER_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
10968 hlslPSSetParameter1f(D3DPSREGISTER_Saturation , r_glsl_saturation.value);
10969 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
10970 hlslPSSetParameter4f(D3DPSREGISTER_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
10973 case RENDERPATH_D3D10:
10974 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
10976 case RENDERPATH_D3D11:
10977 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
10979 case RENDERPATH_SOFT:
10980 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10981 R_SetupShader_SetPermutationSoft(SHADERMODE_POSTPROCESS, permutation);
10982 R_Mesh_TexBind(GL20TU_FIRST , r_bloomstate.texture_screen);
10983 R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom );
10984 R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
10985 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10986 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
10987 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
10988 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
10989 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
10990 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
10991 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Saturation , r_glsl_saturation.value);
10992 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
10993 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
10998 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10999 r_refdef.stats.bloom_drawpixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
11001 case RENDERPATH_GL13:
11002 case RENDERPATH_GL11:
11003 if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
11005 // apply a color tint to the whole view
11006 R_ResetViewRendering2D();
11007 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
11008 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
11009 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
11010 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
11011 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
11017 matrix4x4_t r_waterscrollmatrix;
11019 void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as that changes colorscale!
11021 if (r_refdef.fog_density)
11023 r_refdef.fogcolor[0] = r_refdef.fog_red;
11024 r_refdef.fogcolor[1] = r_refdef.fog_green;
11025 r_refdef.fogcolor[2] = r_refdef.fog_blue;
11027 Vector4Set(r_refdef.fogplane, 0, 0, 1, -r_refdef.fog_height);
11028 r_refdef.fogplaneviewdist = DotProduct(r_refdef.fogplane, r_refdef.view.origin) + r_refdef.fogplane[3];
11029 r_refdef.fogplaneviewabove = r_refdef.fogplaneviewdist >= 0;
11030 r_refdef.fogheightfade = -0.5f/max(0.125f, r_refdef.fog_fadedepth);
11034 VectorCopy(r_refdef.fogcolor, fogvec);
11035 // color.rgb *= ContrastBoost * SceneBrightness;
11036 VectorScale(fogvec, r_refdef.view.colorscale, fogvec);
11037 r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
11038 r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
11039 r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
11044 void R_UpdateVariables(void)
11046 R_Textures_Frame();
11048 r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f);
11050 r_refdef.farclip = r_farclip_base.value;
11051 if (r_refdef.scene.worldmodel)
11052 r_refdef.farclip += r_refdef.scene.worldmodel->radius * r_farclip_world.value * 2;
11053 r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
11055 if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1)
11056 Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1);
11057 r_refdef.polygonfactor = 0;
11058 r_refdef.polygonoffset = 0;
11059 r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
11060 r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
11062 r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0;
11063 r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
11064 r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
11065 r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
11066 r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
11067 if (FAKELIGHT_ENABLED)
11069 r_refdef.lightmapintensity *= r_fakelight_intensity.value;
11071 if (r_showsurfaces.integer)
11073 r_refdef.scene.rtworld = false;
11074 r_refdef.scene.rtworldshadows = false;
11075 r_refdef.scene.rtdlight = false;
11076 r_refdef.scene.rtdlightshadows = false;
11077 r_refdef.lightmapintensity = 0;
11080 if (gamemode == GAME_NEHAHRA)
11082 if (gl_fogenable.integer)
11084 r_refdef.oldgl_fogenable = true;
11085 r_refdef.fog_density = gl_fogdensity.value;
11086 r_refdef.fog_red = gl_fogred.value;
11087 r_refdef.fog_green = gl_foggreen.value;
11088 r_refdef.fog_blue = gl_fogblue.value;
11089 r_refdef.fog_alpha = 1;
11090 r_refdef.fog_start = 0;
11091 r_refdef.fog_end = gl_skyclip.value;
11092 r_refdef.fog_height = 1<<30;
11093 r_refdef.fog_fadedepth = 128;
11095 else if (r_refdef.oldgl_fogenable)
11097 r_refdef.oldgl_fogenable = false;
11098 r_refdef.fog_density = 0;
11099 r_refdef.fog_red = 0;
11100 r_refdef.fog_green = 0;
11101 r_refdef.fog_blue = 0;
11102 r_refdef.fog_alpha = 0;
11103 r_refdef.fog_start = 0;
11104 r_refdef.fog_end = 0;
11105 r_refdef.fog_height = 1<<30;
11106 r_refdef.fog_fadedepth = 128;
11110 r_refdef.fog_alpha = bound(0, r_refdef.fog_alpha, 1);
11111 r_refdef.fog_start = max(0, r_refdef.fog_start);
11112 r_refdef.fog_end = max(r_refdef.fog_start + 0.01, r_refdef.fog_end);
11114 // R_UpdateFogColor(); // why? R_RenderScene does it anyway
11116 if (r_refdef.fog_density && r_drawfog.integer)
11118 r_refdef.fogenabled = true;
11119 // this is the point where the fog reaches 0.9986 alpha, which we
11120 // consider a good enough cutoff point for the texture
11121 // (0.9986 * 256 == 255.6)
11122 if (r_fog_exp2.integer)
11123 r_refdef.fogrange = 32 / (r_refdef.fog_density * r_refdef.fog_density) + r_refdef.fog_start;
11125 r_refdef.fogrange = 2048 / r_refdef.fog_density + r_refdef.fog_start;
11126 r_refdef.fogrange = bound(r_refdef.fog_start, r_refdef.fogrange, r_refdef.fog_end);
11127 r_refdef.fograngerecip = 1.0f / r_refdef.fogrange;
11128 r_refdef.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * r_refdef.fograngerecip;
11129 if (strcmp(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename))
11130 R_BuildFogHeightTexture();
11131 // fog color was already set
11132 // update the fog texture
11133 if (r_refdef.fogmasktable_start != r_refdef.fog_start || r_refdef.fogmasktable_alpha != r_refdef.fog_alpha || r_refdef.fogmasktable_density != r_refdef.fog_density || r_refdef.fogmasktable_range != r_refdef.fogrange)
11134 R_BuildFogTexture();
11135 r_refdef.fog_height_texcoordscale = 1.0f / max(0.125f, r_refdef.fog_fadedepth);
11136 r_refdef.fog_height_tablescale = r_refdef.fog_height_tablesize * r_refdef.fog_height_texcoordscale;
11139 r_refdef.fogenabled = false;
11141 switch(vid.renderpath)
11143 case RENDERPATH_GL20:
11144 case RENDERPATH_CGGL:
11145 case RENDERPATH_D3D9:
11146 case RENDERPATH_D3D10:
11147 case RENDERPATH_D3D11:
11148 case RENDERPATH_SOFT:
11149 case RENDERPATH_GLES2:
11150 if(v_glslgamma.integer && !vid_gammatables_trivial)
11152 if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial)
11154 // build GLSL gamma texture
11155 #define RAMPWIDTH 256
11156 unsigned short ramp[RAMPWIDTH * 3];
11157 unsigned char rampbgr[RAMPWIDTH][4];
11160 r_texture_gammaramps_serial = vid_gammatables_serial;
11162 VID_BuildGammaTables(&ramp[0], RAMPWIDTH);
11163 for(i = 0; i < RAMPWIDTH; ++i)
11165 rampbgr[i][0] = (unsigned char) (ramp[i + 2 * RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
11166 rampbgr[i][1] = (unsigned char) (ramp[i + RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
11167 rampbgr[i][2] = (unsigned char) (ramp[i] * 255.0 / 65535.0 + 0.5);
11170 if (r_texture_gammaramps)
11172 R_UpdateTexture(r_texture_gammaramps, &rampbgr[0][0], 0, 0, RAMPWIDTH, 1);
11176 r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &rampbgr[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
11182 // remove GLSL gamma texture
11185 case RENDERPATH_GL13:
11186 case RENDERPATH_GL11:
11191 static r_refdef_scene_type_t r_currentscenetype = RST_CLIENT;
11192 static r_refdef_scene_t r_scenes_store[ RST_COUNT ];
11198 void R_SelectScene( r_refdef_scene_type_t scenetype ) {
11199 if( scenetype != r_currentscenetype ) {
11200 // store the old scenetype
11201 r_scenes_store[ r_currentscenetype ] = r_refdef.scene;
11202 r_currentscenetype = scenetype;
11203 // move in the new scene
11204 r_refdef.scene = r_scenes_store[ r_currentscenetype ];
11213 r_refdef_scene_t * R_GetScenePointer( r_refdef_scene_type_t scenetype )
11215 // of course, we could also add a qboolean that provides a lock state and a ReleaseScenePointer function..
11216 if( scenetype == r_currentscenetype ) {
11217 return &r_refdef.scene;
11219 return &r_scenes_store[ scenetype ];
11228 int dpsoftrast_test;
11229 void R_RenderView(void)
11231 matrix4x4_t originalmatrix = r_refdef.view.matrix, offsetmatrix;
11233 dpsoftrast_test = r_test.integer;
11235 if (r_timereport_active)
11236 R_TimeReport("start");
11237 r_textureframe++; // used only by R_GetCurrentTexture
11238 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
11240 if(R_CompileShader_CheckStaticParms())
11241 R_GLSL_Restart_f();
11243 if (!r_drawentities.integer)
11244 r_refdef.scene.numentities = 0;
11246 R_AnimCache_ClearCache();
11247 R_FrameData_NewFrame();
11249 /* adjust for stereo display */
11250 if(R_Stereo_Active())
11252 Matrix4x4_CreateFromQuakeEntity(&offsetmatrix, 0, r_stereo_separation.value * (0.5f - r_stereo_side), 0, 0, r_stereo_angle.value * (0.5f - r_stereo_side), 0, 1);
11253 Matrix4x4_Concat(&r_refdef.view.matrix, &originalmatrix, &offsetmatrix);
11256 if (r_refdef.view.isoverlay)
11258 // TODO: FIXME: move this into its own backend function maybe? [2/5/2008 Andreas]
11259 GL_Clear(GL_DEPTH_BUFFER_BIT, NULL, 1.0f, 0);
11260 R_TimeReport("depthclear");
11262 r_refdef.view.showdebug = false;
11264 r_waterstate.enabled = false;
11265 r_waterstate.numwaterplanes = 0;
11269 r_refdef.view.matrix = originalmatrix;
11275 if (!r_refdef.scene.entities || r_refdef.view.width * r_refdef.view.height == 0 || !r_renderview.integer || cl_videoplaying/* || !r_refdef.scene.worldmodel*/)
11277 r_refdef.view.matrix = originalmatrix;
11278 return; //Host_Error ("R_RenderView: NULL worldmodel");
11281 r_refdef.view.colorscale = r_hdr_scenebrightness.value;
11283 R_RenderView_UpdateViewVectors();
11285 R_Shadow_UpdateWorldLightSelection();
11287 R_Bloom_StartFrame();
11288 R_Water_StartFrame();
11291 if (r_timereport_active)
11292 R_TimeReport("viewsetup");
11294 R_ResetViewRendering3D();
11296 if (r_refdef.view.clear || r_refdef.fogenabled)
11298 R_ClearScreen(r_refdef.fogenabled);
11299 if (r_timereport_active)
11300 R_TimeReport("viewclear");
11302 r_refdef.view.clear = true;
11304 // this produces a bloom texture to be used in R_BlendView() later
11305 if (r_hdr.integer && r_bloomstate.bloomwidth)
11307 R_HDR_RenderBloomTexture();
11308 // we have to bump the texture frame again because r_refdef.view.colorscale is cached in the textures
11309 r_textureframe++; // used only by R_GetCurrentTexture
11312 r_refdef.view.showdebug = true;
11315 if (r_timereport_active)
11316 R_TimeReport("visibility");
11318 r_waterstate.numwaterplanes = 0;
11319 if (r_waterstate.enabled)
11320 R_RenderWaterPlanes();
11323 r_waterstate.numwaterplanes = 0;
11326 if (r_timereport_active)
11327 R_TimeReport("blendview");
11329 GL_Scissor(0, 0, vid.width, vid.height);
11330 GL_ScissorTest(false);
11332 r_refdef.view.matrix = originalmatrix;
11337 void R_RenderWaterPlanes(void)
11339 if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawAddWaterPlanes)
11341 r_refdef.scene.worldmodel->DrawAddWaterPlanes(r_refdef.scene.worldentity);
11342 if (r_timereport_active)
11343 R_TimeReport("waterworld");
11346 // don't let sound skip if going slow
11347 if (r_refdef.scene.extraupdate)
11350 R_DrawModelsAddWaterPlanes();
11351 if (r_timereport_active)
11352 R_TimeReport("watermodels");
11354 if (r_waterstate.numwaterplanes)
11356 R_Water_ProcessPlanes();
11357 if (r_timereport_active)
11358 R_TimeReport("waterscenes");
11362 extern void R_DrawLightningBeams (void);
11363 extern void VM_CL_AddPolygonsToMeshQueue (void);
11364 extern void R_DrawPortals (void);
11365 extern cvar_t cl_locs_show;
11366 static void R_DrawLocs(void);
11367 static void R_DrawEntityBBoxes(void);
11368 static void R_DrawModelDecals(void);
11369 extern void R_DrawModelShadows(void);
11370 extern void R_DrawModelShadowMaps(void);
11371 extern cvar_t cl_decals_newsystem;
11372 extern qboolean r_shadow_usingdeferredprepass;
11373 void R_RenderScene(void)
11375 qboolean shadowmapping = false;
11377 if (r_timereport_active)
11378 R_TimeReport("beginscene");
11380 r_refdef.stats.renders++;
11382 R_UpdateFogColor();
11384 // don't let sound skip if going slow
11385 if (r_refdef.scene.extraupdate)
11388 R_MeshQueue_BeginScene();
11392 Matrix4x4_CreateTranslate(&r_waterscrollmatrix, sin(r_refdef.scene.time) * 0.025 * r_waterscroll.value, sin(r_refdef.scene.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
11394 if (r_timereport_active)
11395 R_TimeReport("skystartframe");
11397 if (cl.csqc_vidvars.drawworld)
11399 // don't let sound skip if going slow
11400 if (r_refdef.scene.extraupdate)
11403 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawSky)
11405 r_refdef.scene.worldmodel->DrawSky(r_refdef.scene.worldentity);
11406 if (r_timereport_active)
11407 R_TimeReport("worldsky");
11410 if (R_DrawBrushModelsSky() && r_timereport_active)
11411 R_TimeReport("bmodelsky");
11413 if (skyrendermasked && skyrenderlater)
11415 // we have to force off the water clipping plane while rendering sky
11416 R_SetupView(false);
11419 if (r_timereport_active)
11420 R_TimeReport("sky");
11424 R_AnimCache_CacheVisibleEntities();
11425 if (r_timereport_active)
11426 R_TimeReport("animation");
11428 R_Shadow_PrepareLights();
11429 if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0)
11430 R_Shadow_PrepareModelShadows();
11431 if (r_timereport_active)
11432 R_TimeReport("preparelights");
11434 if (R_Shadow_ShadowMappingEnabled())
11435 shadowmapping = true;
11437 if (r_shadow_usingdeferredprepass)
11438 R_Shadow_DrawPrepass();
11440 if (r_depthfirst.integer >= 1 && cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDepth)
11442 r_refdef.scene.worldmodel->DrawDepth(r_refdef.scene.worldentity);
11443 if (r_timereport_active)
11444 R_TimeReport("worlddepth");
11446 if (r_depthfirst.integer >= 2)
11448 R_DrawModelsDepth();
11449 if (r_timereport_active)
11450 R_TimeReport("modeldepth");
11453 if (r_shadows.integer >= 2 && shadowmapping && r_refdef.lightmapintensity > 0)
11455 R_DrawModelShadowMaps();
11456 R_ResetViewRendering3D();
11457 // don't let sound skip if going slow
11458 if (r_refdef.scene.extraupdate)
11462 if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->Draw)
11464 r_refdef.scene.worldmodel->Draw(r_refdef.scene.worldentity);
11465 if (r_timereport_active)
11466 R_TimeReport("world");
11469 // don't let sound skip if going slow
11470 if (r_refdef.scene.extraupdate)
11474 if (r_timereport_active)
11475 R_TimeReport("models");
11477 // don't let sound skip if going slow
11478 if (r_refdef.scene.extraupdate)
11481 if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
11483 R_DrawModelShadows();
11484 R_ResetViewRendering3D();
11485 // don't let sound skip if going slow
11486 if (r_refdef.scene.extraupdate)
11490 if (!r_shadow_usingdeferredprepass)
11492 R_Shadow_DrawLights();
11493 if (r_timereport_active)
11494 R_TimeReport("rtlights");
11497 // don't let sound skip if going slow
11498 if (r_refdef.scene.extraupdate)
11501 if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
11503 R_DrawModelShadows();
11504 R_ResetViewRendering3D();
11505 // don't let sound skip if going slow
11506 if (r_refdef.scene.extraupdate)
11510 if (cl.csqc_vidvars.drawworld)
11512 if (cl_decals_newsystem.integer)
11514 R_DrawModelDecals();
11515 if (r_timereport_active)
11516 R_TimeReport("modeldecals");
11521 if (r_timereport_active)
11522 R_TimeReport("decals");
11526 if (r_timereport_active)
11527 R_TimeReport("particles");
11529 R_DrawExplosions();
11530 if (r_timereport_active)
11531 R_TimeReport("explosions");
11533 R_DrawLightningBeams();
11534 if (r_timereport_active)
11535 R_TimeReport("lightning");
11538 VM_CL_AddPolygonsToMeshQueue();
11540 if (r_refdef.view.showdebug)
11542 if (cl_locs_show.integer)
11545 if (r_timereport_active)
11546 R_TimeReport("showlocs");
11549 if (r_drawportals.integer)
11552 if (r_timereport_active)
11553 R_TimeReport("portals");
11556 if (r_showbboxes.value > 0)
11558 R_DrawEntityBBoxes();
11559 if (r_timereport_active)
11560 R_TimeReport("bboxes");
11564 R_MeshQueue_RenderTransparent();
11565 if (r_timereport_active)
11566 R_TimeReport("drawtrans");
11568 if (r_refdef.view.showdebug && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDebug && (r_showtris.value > 0 || r_shownormals.value != 0 || r_showcollisionbrushes.value > 0))
11570 r_refdef.scene.worldmodel->DrawDebug(r_refdef.scene.worldentity);
11571 if (r_timereport_active)
11572 R_TimeReport("worlddebug");
11573 R_DrawModelsDebug();
11574 if (r_timereport_active)
11575 R_TimeReport("modeldebug");
11578 if (cl.csqc_vidvars.drawworld)
11580 R_Shadow_DrawCoronas();
11581 if (r_timereport_active)
11582 R_TimeReport("coronas");
11587 GL_DepthTest(false);
11588 qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
11589 GL_Color(1, 1, 1, 1);
11590 qglBegin(GL_POLYGON);
11591 qglVertex3f(r_refdef.view.frustumcorner[0][0], r_refdef.view.frustumcorner[0][1], r_refdef.view.frustumcorner[0][2]);
11592 qglVertex3f(r_refdef.view.frustumcorner[1][0], r_refdef.view.frustumcorner[1][1], r_refdef.view.frustumcorner[1][2]);
11593 qglVertex3f(r_refdef.view.frustumcorner[3][0], r_refdef.view.frustumcorner[3][1], r_refdef.view.frustumcorner[3][2]);
11594 qglVertex3f(r_refdef.view.frustumcorner[2][0], r_refdef.view.frustumcorner[2][1], r_refdef.view.frustumcorner[2][2]);
11596 qglBegin(GL_POLYGON);
11597 qglVertex3f(r_refdef.view.frustumcorner[0][0] + 1000 * r_refdef.view.forward[0], r_refdef.view.frustumcorner[0][1] + 1000 * r_refdef.view.forward[1], r_refdef.view.frustumcorner[0][2] + 1000 * r_refdef.view.forward[2]);
11598 qglVertex3f(r_refdef.view.frustumcorner[1][0] + 1000 * r_refdef.view.forward[0], r_refdef.view.frustumcorner[1][1] + 1000 * r_refdef.view.forward[1], r_refdef.view.frustumcorner[1][2] + 1000 * r_refdef.view.forward[2]);
11599 qglVertex3f(r_refdef.view.frustumcorner[3][0] + 1000 * r_refdef.view.forward[0], r_refdef.view.frustumcorner[3][1] + 1000 * r_refdef.view.forward[1], r_refdef.view.frustumcorner[3][2] + 1000 * r_refdef.view.forward[2]);
11600 qglVertex3f(r_refdef.view.frustumcorner[2][0] + 1000 * r_refdef.view.forward[0], r_refdef.view.frustumcorner[2][1] + 1000 * r_refdef.view.forward[1], r_refdef.view.frustumcorner[2][2] + 1000 * r_refdef.view.forward[2]);
11602 qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
11606 // don't let sound skip if going slow
11607 if (r_refdef.scene.extraupdate)
11610 R_ResetViewRendering2D();
11613 static const unsigned short bboxelements[36] =
11623 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
11626 float *v, *c, f1, f2, vertex3f[8*3], color4f[8*4];
11628 RSurf_ActiveWorldEntity();
11630 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
11631 GL_DepthMask(false);
11632 GL_DepthRange(0, 1);
11633 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
11634 // R_Mesh_ResetTextureState();
11636 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2]; //
11637 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
11638 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
11639 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
11640 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
11641 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
11642 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
11643 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
11644 R_FillColors(color4f, 8, cr, cg, cb, ca);
11645 if (r_refdef.fogenabled)
11647 for (i = 0, v = vertex3f, c = color4f;i < 8;i++, v += 3, c += 4)
11649 f1 = RSurf_FogVertex(v);
11651 c[0] = c[0] * f1 + r_refdef.fogcolor[0] * f2;
11652 c[1] = c[1] * f1 + r_refdef.fogcolor[1] * f2;
11653 c[2] = c[2] * f1 + r_refdef.fogcolor[2] * f2;
11656 R_Mesh_PrepareVertices_Generic_Arrays(8, vertex3f, color4f, NULL);
11657 R_Mesh_ResetTextureState();
11658 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
11659 R_Mesh_Draw(0, 8, 0, 12, NULL, NULL, 0, bboxelements, NULL, 0);
11662 static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
11666 prvm_edict_t *edict;
11667 prvm_prog_t *prog_save = prog;
11669 // this function draws bounding boxes of server entities
11673 GL_CullFace(GL_NONE);
11674 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
11678 for (i = 0;i < numsurfaces;i++)
11680 edict = PRVM_EDICT_NUM(surfacelist[i]);
11681 switch ((int)edict->fields.server->solid)
11683 case SOLID_NOT: Vector4Set(color, 1, 1, 1, 0.05);break;
11684 case SOLID_TRIGGER: Vector4Set(color, 1, 0, 1, 0.10);break;
11685 case SOLID_BBOX: Vector4Set(color, 0, 1, 0, 0.10);break;
11686 case SOLID_SLIDEBOX: Vector4Set(color, 1, 0, 0, 0.10);break;
11687 case SOLID_BSP: Vector4Set(color, 0, 0, 1, 0.05);break;
11688 default: Vector4Set(color, 0, 0, 0, 0.50);break;
11690 color[3] *= r_showbboxes.value;
11691 color[3] = bound(0, color[3], 1);
11692 GL_DepthTest(!r_showdisabledepthtest.integer);
11693 GL_CullFace(r_refdef.view.cullface_front);
11694 R_DrawBBoxMesh(edict->priv.server->areamins, edict->priv.server->areamaxs, color[0], color[1], color[2], color[3]);
11700 static void R_DrawEntityBBoxes(void)
11703 prvm_edict_t *edict;
11705 prvm_prog_t *prog_save = prog;
11707 // this function draws bounding boxes of server entities
11713 for (i = 0;i < prog->num_edicts;i++)
11715 edict = PRVM_EDICT_NUM(i);
11716 if (edict->priv.server->free)
11718 // exclude the following for now, as they don't live in world coordinate space and can't be solid:
11719 if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.tag_entity)->edict != 0)
11721 if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.viewmodelforclient)->edict != 0)
11723 VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
11724 R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL);
11730 static const int nomodelelement3i[24] =
11742 static const unsigned short nomodelelement3s[24] =
11754 static const float nomodelvertex3f[6*3] =
11764 static const float nomodelcolor4f[6*4] =
11766 0.0f, 0.0f, 0.5f, 1.0f,
11767 0.0f, 0.0f, 0.5f, 1.0f,
11768 0.0f, 0.5f, 0.0f, 1.0f,
11769 0.0f, 0.5f, 0.0f, 1.0f,
11770 0.5f, 0.0f, 0.0f, 1.0f,
11771 0.5f, 0.0f, 0.0f, 1.0f
11774 void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
11778 float color4f[6*4];
11780 RSurf_ActiveCustomEntity(&ent->matrix, &ent->inversematrix, ent->flags, ent->shadertime, ent->colormod[0], ent->colormod[1], ent->colormod[2], ent->alpha, 6, nomodelvertex3f, NULL, NULL, NULL, NULL, nomodelcolor4f, 8, nomodelelement3i, nomodelelement3s, false, false);
11782 // this is only called once per entity so numsurfaces is always 1, and
11783 // surfacelist is always {0}, so this code does not handle batches
11785 if (rsurface.ent_flags & RENDER_ADDITIVE)
11787 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
11788 GL_DepthMask(false);
11790 else if (rsurface.colormod[3] < 1)
11792 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
11793 GL_DepthMask(false);
11797 GL_BlendFunc(GL_ONE, GL_ZERO);
11798 GL_DepthMask(true);
11800 GL_DepthRange(0, (rsurface.ent_flags & RENDER_VIEWMODEL) ? 0.0625 : 1);
11801 GL_PolygonOffset(rsurface.basepolygonfactor, rsurface.basepolygonoffset);
11802 GL_DepthTest(!(rsurface.ent_flags & RENDER_NODEPTHTEST));
11803 GL_CullFace((rsurface.ent_flags & RENDER_DOUBLESIDED) ? GL_NONE : r_refdef.view.cullface_back);
11804 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
11805 for (i = 0, c = color4f;i < 6;i++, c += 4)
11807 c[0] *= rsurface.colormod[0];
11808 c[1] *= rsurface.colormod[1];
11809 c[2] *= rsurface.colormod[2];
11810 c[3] *= rsurface.colormod[3];
11812 if (r_refdef.fogenabled)
11814 for (i = 0, c = color4f;i < 6;i++, c += 4)
11816 f1 = RSurf_FogVertex(nomodelvertex3f + 3*i);
11818 c[0] = (c[0] * f1 + r_refdef.fogcolor[0] * f2);
11819 c[1] = (c[1] * f1 + r_refdef.fogcolor[1] * f2);
11820 c[2] = (c[2] * f1 + r_refdef.fogcolor[2] * f2);
11823 // R_Mesh_ResetTextureState();
11824 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
11825 R_Mesh_PrepareVertices_Generic_Arrays(6, nomodelvertex3f, color4f, NULL);
11826 R_Mesh_Draw(0, 6, 0, 8, nomodelelement3i, NULL, 0, nomodelelement3s, NULL, 0);
11829 void R_DrawNoModel(entity_render_t *ent)
11832 Matrix4x4_OriginFromMatrix(&ent->matrix, org);
11833 if ((ent->flags & RENDER_ADDITIVE) || (ent->alpha < 1))
11834 R_MeshQueue_AddTransparent(ent->flags & RENDER_NODEPTHTEST ? r_refdef.view.origin : org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight);
11836 R_DrawNoModel_TransparentCallback(ent, rsurface.rtlight, 0, NULL);
11839 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
11841 vec3_t right1, right2, diff, normal;
11843 VectorSubtract (org2, org1, normal);
11845 // calculate 'right' vector for start
11846 VectorSubtract (r_refdef.view.origin, org1, diff);
11847 CrossProduct (normal, diff, right1);
11848 VectorNormalize (right1);
11850 // calculate 'right' vector for end
11851 VectorSubtract (r_refdef.view.origin, org2, diff);
11852 CrossProduct (normal, diff, right2);
11853 VectorNormalize (right2);
11855 vert[ 0] = org1[0] + width * right1[0];
11856 vert[ 1] = org1[1] + width * right1[1];
11857 vert[ 2] = org1[2] + width * right1[2];
11858 vert[ 3] = org1[0] - width * right1[0];
11859 vert[ 4] = org1[1] - width * right1[1];
11860 vert[ 5] = org1[2] - width * right1[2];
11861 vert[ 6] = org2[0] - width * right2[0];
11862 vert[ 7] = org2[1] - width * right2[1];
11863 vert[ 8] = org2[2] - width * right2[2];
11864 vert[ 9] = org2[0] + width * right2[0];
11865 vert[10] = org2[1] + width * right2[1];
11866 vert[11] = org2[2] + width * right2[2];
11869 void R_CalcSprite_Vertex3f(float *vertex3f, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2)
11871 vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
11872 vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
11873 vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
11874 vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
11875 vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
11876 vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
11877 vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
11878 vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
11879 vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
11880 vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
11881 vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
11882 vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
11885 int R_Mesh_AddVertex(rmesh_t *mesh, float x, float y, float z)
11890 VectorSet(v, x, y, z);
11891 for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
11892 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
11894 if (i == mesh->numvertices)
11896 if (mesh->numvertices < mesh->maxvertices)
11898 VectorCopy(v, vertex3f);
11899 mesh->numvertices++;
11901 return mesh->numvertices;
11907 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
11910 int *e, element[3];
11911 element[0] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);vertex3f += 3;
11912 element[1] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);vertex3f += 3;
11913 e = mesh->element3i + mesh->numtriangles * 3;
11914 for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
11916 element[2] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);
11917 if (mesh->numtriangles < mesh->maxtriangles)
11922 mesh->numtriangles++;
11924 element[1] = element[2];
11928 void R_Mesh_AddPolygon3d(rmesh_t *mesh, int numvertices, double *vertex3d)
11931 int *e, element[3];
11932 element[0] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);vertex3d += 3;
11933 element[1] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);vertex3d += 3;
11934 e = mesh->element3i + mesh->numtriangles * 3;
11935 for (i = 0;i < numvertices - 2;i++, vertex3d += 3)
11937 element[2] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);
11938 if (mesh->numtriangles < mesh->maxtriangles)
11943 mesh->numtriangles++;
11945 element[1] = element[2];
11949 #define R_MESH_PLANE_DIST_EPSILON (1.0 / 32.0)
11950 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
11952 int planenum, planenum2;
11955 mplane_t *plane, *plane2;
11957 double temppoints[2][256*3];
11958 // figure out how large a bounding box we need to properly compute this brush
11960 for (w = 0;w < numplanes;w++)
11961 maxdist = max(maxdist, fabs(planes[w].dist));
11962 // now make it large enough to enclose the entire brush, and round it off to a reasonable multiple of 1024
11963 maxdist = floor(maxdist * (4.0 / 1024.0) + 1) * 1024.0;
11964 for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
11968 PolygonD_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->dist, maxdist);
11969 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
11971 if (planenum2 == planenum)
11973 PolygonD_Divide(tempnumpoints, temppoints[w], plane2->normal[0], plane2->normal[1], plane2->normal[2], plane2->dist, R_MESH_PLANE_DIST_EPSILON, 0, NULL, NULL, 256, temppoints[!w], &tempnumpoints, NULL);
11976 if (tempnumpoints < 3)
11978 // generate elements forming a triangle fan for this polygon
11979 R_Mesh_AddPolygon3d(mesh, tempnumpoints, temppoints[w]);
11983 static void R_Texture_AddLayer(texture_t *t, qboolean depthmask, int blendfunc1, int blendfunc2, texturelayertype_t type, rtexture_t *texture, const matrix4x4_t *matrix, float r, float g, float b, float a)
11985 texturelayer_t *layer;
11986 layer = t->currentlayers + t->currentnumlayers++;
11987 layer->type = type;
11988 layer->depthmask = depthmask;
11989 layer->blendfunc1 = blendfunc1;
11990 layer->blendfunc2 = blendfunc2;
11991 layer->texture = texture;
11992 layer->texmatrix = *matrix;
11993 layer->color[0] = r;
11994 layer->color[1] = g;
11995 layer->color[2] = b;
11996 layer->color[3] = a;
11999 static qboolean R_TestQ3WaveFunc(q3wavefunc_t func, const float *parms)
12001 if(parms[0] == 0 && parms[1] == 0)
12003 if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
12004 if(rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)] == 0)
12009 static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms)
12012 index = parms[2] + r_refdef.scene.time * parms[3];
12013 index -= floor(index);
12014 switch (func & ((1 << Q3WAVEFUNC_USER_SHIFT) - 1))
12017 case Q3WAVEFUNC_NONE:
12018 case Q3WAVEFUNC_NOISE:
12019 case Q3WAVEFUNC_COUNT:
12022 case Q3WAVEFUNC_SIN: f = sin(index * M_PI * 2);break;
12023 case Q3WAVEFUNC_SQUARE: f = index < 0.5 ? 1 : -1;break;
12024 case Q3WAVEFUNC_SAWTOOTH: f = index;break;
12025 case Q3WAVEFUNC_INVERSESAWTOOTH: f = 1 - index;break;
12026 case Q3WAVEFUNC_TRIANGLE:
12028 f = index - floor(index);
12031 else if (index < 2)
12033 else if (index < 3)
12039 f = parms[0] + parms[1] * f;
12040 if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
12041 f *= rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)];
12045 void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags)
12050 matrix4x4_t matrix, temp;
12051 switch(tcmod->tcmod)
12053 case Q3TCMOD_COUNT:
12055 if (currentmaterialflags & MATERIALFLAG_WATERSCROLL)
12056 matrix = r_waterscrollmatrix;
12058 matrix = identitymatrix;
12060 case Q3TCMOD_ENTITYTRANSLATE:
12061 // this is used in Q3 to allow the gamecode to control texcoord
12062 // scrolling on the entity, which is not supported in darkplaces yet.
12063 Matrix4x4_CreateTranslate(&matrix, 0, 0, 0);
12065 case Q3TCMOD_ROTATE:
12066 Matrix4x4_CreateTranslate(&matrix, 0.5, 0.5, 0);
12067 Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * r_refdef.scene.time, 0, 0, 1);
12068 Matrix4x4_ConcatTranslate(&matrix, -0.5, -0.5, 0);
12070 case Q3TCMOD_SCALE:
12071 Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1);
12073 case Q3TCMOD_SCROLL:
12074 Matrix4x4_CreateTranslate(&matrix, tcmod->parms[0] * r_refdef.scene.time, tcmod->parms[1] * r_refdef.scene.time, 0);
12076 case Q3TCMOD_PAGE: // poor man's animmap (to store animations into a single file, useful for HTTP downloaded textures)
12077 w = (int) tcmod->parms[0];
12078 h = (int) tcmod->parms[1];
12079 f = r_refdef.scene.time / (tcmod->parms[2] * w * h);
12081 idx = (int) floor(f * w * h);
12082 Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0);
12084 case Q3TCMOD_STRETCH:
12085 f = 1.0f / R_EvaluateQ3WaveFunc(tcmod->wavefunc, tcmod->waveparms);
12086 Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f);
12088 case Q3TCMOD_TRANSFORM:
12089 VectorSet(tcmat + 0, tcmod->parms[0], tcmod->parms[1], 0);
12090 VectorSet(tcmat + 3, tcmod->parms[2], tcmod->parms[3], 0);
12091 VectorSet(tcmat + 6, 0 , 0 , 1);
12092 VectorSet(tcmat + 9, tcmod->parms[4], tcmod->parms[5], 0);
12093 Matrix4x4_FromArray12FloatGL(&matrix, tcmat);
12095 case Q3TCMOD_TURBULENT:
12096 // this is handled in the RSurf_PrepareVertices function
12097 matrix = identitymatrix;
12101 Matrix4x4_Concat(texmatrix, &matrix, &temp);
12104 void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
12106 int textureflags = (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP | TEXF_COMPRESS;
12107 char name[MAX_QPATH];
12108 skinframe_t *skinframe;
12109 unsigned char pixels[296*194];
12110 strlcpy(cache->name, skinname, sizeof(cache->name));
12111 dpsnprintf(name, sizeof(name), "skins/%s.pcx", cache->name);
12112 if (developer_loading.integer)
12113 Con_Printf("loading %s\n", name);
12114 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
12115 if (!skinframe || !skinframe->base)
12118 fs_offset_t filesize;
12120 f = FS_LoadFile(name, tempmempool, true, &filesize);
12123 if (LoadPCX_QWSkin(f, (int)filesize, pixels, 296, 194))
12124 skinframe = R_SkinFrame_LoadInternalQuake(name, textureflags, true, r_fullbrights.integer, pixels, image_width, image_height);
12128 cache->skinframe = skinframe;
12131 texture_t *R_GetCurrentTexture(texture_t *t)
12134 const entity_render_t *ent = rsurface.entity;
12135 dp_model_t *model = ent->model;
12136 q3shaderinfo_layer_tcmod_t *tcmod;
12138 if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent)
12139 return t->currentframe;
12140 t->update_lastrenderframe = r_textureframe;
12141 t->update_lastrenderentity = (void *)ent;
12143 if(ent && ent->entitynumber >= MAX_EDICTS && ent->entitynumber < 2 * MAX_EDICTS)
12144 t->camera_entity = ent->entitynumber;
12146 t->camera_entity = 0;
12148 // switch to an alternate material if this is a q1bsp animated material
12150 texture_t *texture = t;
12151 int s = rsurface.ent_skinnum;
12152 if ((unsigned int)s >= (unsigned int)model->numskins)
12154 if (model->skinscenes)
12156 if (model->skinscenes[s].framecount > 1)
12157 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.scene.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
12159 s = model->skinscenes[s].firstframe;
12162 t = t + s * model->num_surfaces;
12165 // use an alternate animation if the entity's frame is not 0,
12166 // and only if the texture has an alternate animation
12167 if (rsurface.ent_alttextures && t->anim_total[1])
12168 t = t->anim_frames[1][(t->anim_total[1] >= 2) ? ((int)(r_refdef.scene.time * 5.0f) % t->anim_total[1]) : 0];
12170 t = t->anim_frames[0][(t->anim_total[0] >= 2) ? ((int)(r_refdef.scene.time * 5.0f) % t->anim_total[0]) : 0];
12172 texture->currentframe = t;
12175 // update currentskinframe to be a qw skin or animation frame
12176 if (rsurface.ent_qwskin >= 0)
12178 i = rsurface.ent_qwskin;
12179 if (!r_qwskincache || r_qwskincache_size != cl.maxclients)
12181 r_qwskincache_size = cl.maxclients;
12183 Mem_Free(r_qwskincache);
12184 r_qwskincache = (r_qwskincache_t *)Mem_Alloc(r_main_mempool, sizeof(*r_qwskincache) * r_qwskincache_size);
12186 if (strcmp(r_qwskincache[i].name, cl.scores[i].qw_skin))
12187 R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin);
12188 t->currentskinframe = r_qwskincache[i].skinframe;
12189 if (t->currentskinframe == NULL)
12190 t->currentskinframe = t->skinframes[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
12192 else if (t->numskinframes >= 2)
12193 t->currentskinframe = t->skinframes[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
12194 if (t->backgroundnumskinframes >= 2)
12195 t->backgroundcurrentskinframe = t->backgroundskinframes[(unsigned int)(t->backgroundskinframerate * (cl.time - rsurface.ent_shadertime)) % t->backgroundnumskinframes];
12197 t->currentmaterialflags = t->basematerialflags;
12198 t->currentalpha = rsurface.colormod[3];
12199 if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer))
12200 t->currentalpha *= r_wateralpha.value;
12201 if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay)
12202 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // we apply wateralpha later
12203 if(!r_waterstate.enabled || r_refdef.view.isoverlay)
12204 t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA);
12205 if (!(rsurface.ent_flags & RENDER_LIGHT))
12206 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
12207 else if (FAKELIGHT_ENABLED)
12209 // no modellight if using fakelight for the map
12211 else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
12213 // pick a model lighting mode
12214 if (VectorLength2(rsurface.modellight_diffuse) >= (1.0f / 256.0f))
12215 t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL;
12217 t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT;
12219 if (rsurface.ent_flags & RENDER_ADDITIVE)
12220 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
12221 else if (t->currentalpha < 1)
12222 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
12223 if (rsurface.ent_flags & RENDER_DOUBLESIDED)
12224 t->currentmaterialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
12225 if (rsurface.ent_flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL))
12226 t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
12227 if (t->backgroundnumskinframes)
12228 t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
12229 if (t->currentmaterialflags & MATERIALFLAG_BLENDED)
12231 if (t->currentmaterialflags & (MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER | MATERIALFLAG_CAMERA))
12232 t->currentmaterialflags &= ~MATERIALFLAG_BLENDED;
12235 t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER | MATERIALFLAG_CAMERA);
12236 if ((t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)) == MATERIALFLAG_BLENDED && r_transparentdepthmasking.integer && !(t->basematerialflags & MATERIALFLAG_BLENDED))
12237 t->currentmaterialflags |= MATERIALFLAG_TRANSDEPTH;
12239 // there is no tcmod
12240 if (t->currentmaterialflags & MATERIALFLAG_WATERSCROLL)
12242 t->currenttexmatrix = r_waterscrollmatrix;
12243 t->currentbackgroundtexmatrix = r_waterscrollmatrix;
12245 else if (!(t->currentmaterialflags & MATERIALFLAG_CUSTOMSURFACE))
12247 Matrix4x4_CreateIdentity(&t->currenttexmatrix);
12248 Matrix4x4_CreateIdentity(&t->currentbackgroundtexmatrix);
12251 for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
12252 R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags);
12253 for (i = 0, tcmod = t->backgroundtcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
12254 R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags);
12256 t->colormapping = VectorLength2(rsurface.colormap_pantscolor) + VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f);
12257 if (t->currentskinframe->qpixels)
12258 R_SkinFrame_GenerateTexturesFromQPixels(t->currentskinframe, t->colormapping);
12259 t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base;
12260 if (!t->basetexture)
12261 t->basetexture = r_texture_notexture;
12262 t->pantstexture = t->colormapping ? t->currentskinframe->pants : NULL;
12263 t->shirttexture = t->colormapping ? t->currentskinframe->shirt : NULL;
12264 t->nmaptexture = t->currentskinframe->nmap;
12265 if (!t->nmaptexture)
12266 t->nmaptexture = r_texture_blanknormalmap;
12267 t->glosstexture = r_texture_black;
12268 t->glowtexture = t->currentskinframe->glow;
12269 t->fogtexture = t->currentskinframe->fog;
12270 t->reflectmasktexture = t->currentskinframe->reflect;
12271 if (t->backgroundnumskinframes)
12273 t->backgroundbasetexture = (!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base;
12274 t->backgroundnmaptexture = t->backgroundcurrentskinframe->nmap;
12275 t->backgroundglosstexture = r_texture_black;
12276 t->backgroundglowtexture = t->backgroundcurrentskinframe->glow;
12277 if (!t->backgroundnmaptexture)
12278 t->backgroundnmaptexture = r_texture_blanknormalmap;
12282 t->backgroundbasetexture = r_texture_white;
12283 t->backgroundnmaptexture = r_texture_blanknormalmap;
12284 t->backgroundglosstexture = r_texture_black;
12285 t->backgroundglowtexture = NULL;
12287 t->specularpower = r_shadow_glossexponent.value;
12288 // TODO: store reference values for these in the texture?
12289 t->specularscale = 0;
12290 if (r_shadow_gloss.integer > 0)
12292 if (t->currentskinframe->gloss || (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss))
12294 if (r_shadow_glossintensity.value > 0)
12296 t->glosstexture = t->currentskinframe->gloss ? t->currentskinframe->gloss : r_texture_white;
12297 t->backgroundglosstexture = (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss) ? t->backgroundcurrentskinframe->gloss : r_texture_white;
12298 t->specularscale = r_shadow_glossintensity.value;
12301 else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
12303 t->glosstexture = r_texture_white;
12304 t->backgroundglosstexture = r_texture_white;
12305 t->specularscale = r_shadow_gloss2intensity.value;
12306 t->specularpower = r_shadow_gloss2exponent.value;
12309 t->specularscale *= t->specularscalemod;
12310 t->specularpower *= t->specularpowermod;
12312 // lightmaps mode looks bad with dlights using actual texturing, so turn
12313 // off the colormap and glossmap, but leave the normalmap on as it still
12314 // accurately represents the shading involved
12315 if (gl_lightmaps.integer)
12317 t->basetexture = r_texture_grey128;
12318 t->pantstexture = r_texture_black;
12319 t->shirttexture = r_texture_black;
12320 t->nmaptexture = r_texture_blanknormalmap;
12321 t->glosstexture = r_texture_black;
12322 t->glowtexture = NULL;
12323 t->fogtexture = NULL;
12324 t->reflectmasktexture = NULL;
12325 t->backgroundbasetexture = NULL;
12326 t->backgroundnmaptexture = r_texture_blanknormalmap;
12327 t->backgroundglosstexture = r_texture_black;
12328 t->backgroundglowtexture = NULL;
12329 t->specularscale = 0;
12330 t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE));
12333 Vector4Set(t->lightmapcolor, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2], t->currentalpha);
12334 VectorClear(t->dlightcolor);
12335 t->currentnumlayers = 0;
12336 if (t->currentmaterialflags & MATERIALFLAG_WALL)
12338 int blendfunc1, blendfunc2;
12339 qboolean depthmask;
12340 if (t->currentmaterialflags & MATERIALFLAG_ADD)
12342 blendfunc1 = GL_SRC_ALPHA;
12343 blendfunc2 = GL_ONE;
12345 else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
12347 blendfunc1 = GL_SRC_ALPHA;
12348 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
12350 else if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
12352 blendfunc1 = t->customblendfunc[0];
12353 blendfunc2 = t->customblendfunc[1];
12357 blendfunc1 = GL_ONE;
12358 blendfunc2 = GL_ZERO;
12360 // don't colormod evilblend textures
12361 if(!R_BlendFuncAllowsColormod(blendfunc1, blendfunc2))
12362 VectorSet(t->lightmapcolor, 1, 1, 1);
12363 depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
12364 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
12366 // fullbright is not affected by r_refdef.lightmapintensity
12367 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]);
12368 if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
12369 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
12370 if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
12371 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
12375 vec3_t ambientcolor;
12377 // set the color tint used for lights affecting this surface
12378 VectorSet(t->dlightcolor, t->lightmapcolor[0] * t->lightmapcolor[3], t->lightmapcolor[1] * t->lightmapcolor[3], t->lightmapcolor[2] * t->lightmapcolor[3]);
12380 // q3bsp has no lightmap updates, so the lightstylevalue that
12381 // would normally be baked into the lightmap must be
12382 // applied to the color
12383 // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright)
12384 if (model->type == mod_brushq3)
12385 colorscale *= r_refdef.scene.rtlightstylevalue[0];
12386 colorscale *= r_refdef.lightmapintensity;
12387 VectorScale(t->lightmapcolor, r_refdef.scene.ambient, ambientcolor);
12388 VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor);
12389 // basic lit geometry
12390 R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]);
12391 // add pants/shirt if needed
12392 if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
12393 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * t->lightmapcolor[0], rsurface.colormap_pantscolor[1] * t->lightmapcolor[1], rsurface.colormap_pantscolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
12394 if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
12395 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * t->lightmapcolor[0], rsurface.colormap_shirtcolor[1] * t->lightmapcolor[1], rsurface.colormap_shirtcolor[2] * t->lightmapcolor[2], t->lightmapcolor[3]);
12396 // now add ambient passes if needed
12397 if (VectorLength2(ambientcolor) >= (1.0f/1048576.0f))
12399 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->basetexture, &t->currenttexmatrix, ambientcolor[0], ambientcolor[1], ambientcolor[2], t->lightmapcolor[3]);
12400 if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
12401 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->pantstexture, &t->currenttexmatrix, rsurface.colormap_pantscolor[0] * ambientcolor[0], rsurface.colormap_pantscolor[1] * ambientcolor[1], rsurface.colormap_pantscolor[2] * ambientcolor[2], t->lightmapcolor[3]);
12402 if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
12403 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->shirttexture, &t->currenttexmatrix, rsurface.colormap_shirtcolor[0] * ambientcolor[0], rsurface.colormap_shirtcolor[1] * ambientcolor[1], rsurface.colormap_shirtcolor[2] * ambientcolor[2], t->lightmapcolor[3]);
12406 if (t->glowtexture != NULL && !gl_lightmaps.integer)
12407 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->glowtexture, &t->currenttexmatrix, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2], t->lightmapcolor[3]);
12408 if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
12410 // if this is opaque use alpha blend which will darken the earlier
12413 // if this is an alpha blended material, all the earlier passes
12414 // were darkened by fog already, so we only need to add the fog
12415 // color ontop through the fog mask texture
12417 // if this is an additive blended material, all the earlier passes
12418 // were darkened by fog already, and we should not add fog color
12419 // (because the background was not darkened, there is no fog color
12420 // that was lost behind it).
12421 R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_BLENDED) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->fogtexture, &t->currenttexmatrix, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], t->lightmapcolor[3]);
12425 return t->currentframe;
12428 rsurfacestate_t rsurface;
12430 void RSurf_ActiveWorldEntity(void)
12432 dp_model_t *model = r_refdef.scene.worldmodel;
12433 //if (rsurface.entity == r_refdef.scene.worldentity)
12435 rsurface.entity = r_refdef.scene.worldentity;
12436 rsurface.skeleton = NULL;
12437 memset(rsurface.userwavefunc_param, 0, sizeof(rsurface.userwavefunc_param));
12438 rsurface.ent_skinnum = 0;
12439 rsurface.ent_qwskin = -1;
12440 rsurface.ent_shadertime = 0;
12441 rsurface.ent_flags = r_refdef.scene.worldentity->flags;
12442 rsurface.matrix = identitymatrix;
12443 rsurface.inversematrix = identitymatrix;
12444 rsurface.matrixscale = 1;
12445 rsurface.inversematrixscale = 1;
12446 R_EntityMatrix(&identitymatrix);
12447 VectorCopy(r_refdef.view.origin, rsurface.localvieworigin);
12448 Vector4Copy(r_refdef.fogplane, rsurface.fogplane);
12449 rsurface.fograngerecip = r_refdef.fograngerecip;
12450 rsurface.fogheightfade = r_refdef.fogheightfade;
12451 rsurface.fogplaneviewdist = r_refdef.fogplaneviewdist;
12452 rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
12453 VectorSet(rsurface.modellight_ambient, 0, 0, 0);
12454 VectorSet(rsurface.modellight_diffuse, 0, 0, 0);
12455 VectorSet(rsurface.modellight_lightdir, 0, 0, 1);
12456 VectorSet(rsurface.colormap_pantscolor, 0, 0, 0);
12457 VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0);
12458 VectorSet(rsurface.colormod, r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale);
12459 rsurface.colormod[3] = 1;
12460 VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value);
12461 memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend));
12462 rsurface.frameblend[0].lerp = 1;
12463 rsurface.ent_alttextures = false;
12464 rsurface.basepolygonfactor = r_refdef.polygonfactor;
12465 rsurface.basepolygonoffset = r_refdef.polygonoffset;
12466 rsurface.modelvertex3f = model->surfmesh.data_vertex3f;
12467 rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12468 rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f;
12469 rsurface.modelsvector3f = model->surfmesh.data_svector3f;
12470 rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12471 rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f;
12472 rsurface.modeltvector3f = model->surfmesh.data_tvector3f;
12473 rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12474 rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f;
12475 rsurface.modelnormal3f = model->surfmesh.data_normal3f;
12476 rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12477 rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f;
12478 rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f;
12479 rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12480 rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f;
12481 rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f;
12482 rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12483 rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f;
12484 rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f;
12485 rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12486 rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
12487 rsurface.modelelement3i = model->surfmesh.data_element3i;
12488 rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer;
12489 rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset;
12490 rsurface.modelelement3s = model->surfmesh.data_element3s;
12491 rsurface.modelelement3s_indexbuffer = model->surfmesh.data_element3s_indexbuffer;
12492 rsurface.modelelement3s_bufferoffset = model->surfmesh.data_element3s_bufferoffset;
12493 rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets;
12494 rsurface.modelnumvertices = model->surfmesh.num_vertices;
12495 rsurface.modelnumtriangles = model->surfmesh.num_triangles;
12496 rsurface.modelsurfaces = model->data_surfaces;
12497 rsurface.modelvertexmesh = model->surfmesh.vertexmesh;
12498 rsurface.modelvertexmeshbuffer = model->surfmesh.vertexmeshbuffer;
12499 rsurface.modelvertex3fbuffer = model->surfmesh.vertex3fbuffer;
12500 rsurface.modelgeneratedvertex = false;
12501 rsurface.batchgeneratedvertex = false;
12502 rsurface.batchfirstvertex = 0;
12503 rsurface.batchnumvertices = 0;
12504 rsurface.batchfirsttriangle = 0;
12505 rsurface.batchnumtriangles = 0;
12506 rsurface.batchvertex3f = NULL;
12507 rsurface.batchvertex3f_vertexbuffer = NULL;
12508 rsurface.batchvertex3f_bufferoffset = 0;
12509 rsurface.batchsvector3f = NULL;
12510 rsurface.batchsvector3f_vertexbuffer = NULL;
12511 rsurface.batchsvector3f_bufferoffset = 0;
12512 rsurface.batchtvector3f = NULL;
12513 rsurface.batchtvector3f_vertexbuffer = NULL;
12514 rsurface.batchtvector3f_bufferoffset = 0;
12515 rsurface.batchnormal3f = NULL;
12516 rsurface.batchnormal3f_vertexbuffer = NULL;
12517 rsurface.batchnormal3f_bufferoffset = 0;
12518 rsurface.batchlightmapcolor4f = NULL;
12519 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
12520 rsurface.batchlightmapcolor4f_bufferoffset = 0;
12521 rsurface.batchtexcoordtexture2f = NULL;
12522 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
12523 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
12524 rsurface.batchtexcoordlightmap2f = NULL;
12525 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
12526 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
12527 rsurface.batchvertexmesh = NULL;
12528 rsurface.batchvertexmeshbuffer = NULL;
12529 rsurface.batchvertex3fbuffer = NULL;
12530 rsurface.batchelement3i = NULL;
12531 rsurface.batchelement3i_indexbuffer = NULL;
12532 rsurface.batchelement3i_bufferoffset = 0;
12533 rsurface.batchelement3s = NULL;
12534 rsurface.batchelement3s_indexbuffer = NULL;
12535 rsurface.batchelement3s_bufferoffset = 0;
12536 rsurface.passcolor4f = NULL;
12537 rsurface.passcolor4f_vertexbuffer = NULL;
12538 rsurface.passcolor4f_bufferoffset = 0;
12541 void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass)
12543 dp_model_t *model = ent->model;
12544 //if (rsurface.entity == ent && (!model->surfmesh.isanimated || (!wantnormals && !wanttangents)))
12546 rsurface.entity = (entity_render_t *)ent;
12547 rsurface.skeleton = ent->skeleton;
12548 memcpy(rsurface.userwavefunc_param, ent->userwavefunc_param, sizeof(rsurface.userwavefunc_param));
12549 rsurface.ent_skinnum = ent->skinnum;
12550 rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1;
12551 rsurface.ent_shadertime = ent->shadertime;
12552 rsurface.ent_flags = ent->flags;
12553 rsurface.matrix = ent->matrix;
12554 rsurface.inversematrix = ent->inversematrix;
12555 rsurface.matrixscale = Matrix4x4_ScaleFromMatrix(&rsurface.matrix);
12556 rsurface.inversematrixscale = 1.0f / rsurface.matrixscale;
12557 R_EntityMatrix(&rsurface.matrix);
12558 Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.origin, rsurface.localvieworigin);
12559 Matrix4x4_TransformStandardPlane(&rsurface.inversematrix, r_refdef.fogplane[0], r_refdef.fogplane[1], r_refdef.fogplane[2], r_refdef.fogplane[3], rsurface.fogplane);
12560 rsurface.fogplaneviewdist *= rsurface.inversematrixscale;
12561 rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale;
12562 rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale;
12563 rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
12564 VectorCopy(ent->modellight_ambient, rsurface.modellight_ambient);
12565 VectorCopy(ent->modellight_diffuse, rsurface.modellight_diffuse);
12566 VectorCopy(ent->modellight_lightdir, rsurface.modellight_lightdir);
12567 VectorCopy(ent->colormap_pantscolor, rsurface.colormap_pantscolor);
12568 VectorCopy(ent->colormap_shirtcolor, rsurface.colormap_shirtcolor);
12569 VectorScale(ent->colormod, r_refdef.view.colorscale, rsurface.colormod);
12570 rsurface.colormod[3] = ent->alpha;
12571 VectorScale(ent->glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, rsurface.glowmod);
12572 memcpy(rsurface.frameblend, ent->frameblend, sizeof(ent->frameblend));
12573 rsurface.ent_alttextures = ent->framegroupblend[0].frame != 0;
12574 rsurface.basepolygonfactor = r_refdef.polygonfactor;
12575 rsurface.basepolygonoffset = r_refdef.polygonoffset;
12576 if (ent->model->brush.submodel && !prepass)
12578 rsurface.basepolygonfactor += r_polygonoffset_submodel_factor.value;
12579 rsurface.basepolygonoffset += r_polygonoffset_submodel_offset.value;
12581 if (model->surfmesh.isanimated && model->AnimateVertices && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].subframe != 0))
12583 if (ent->animcache_vertex3f)
12585 rsurface.modelvertex3f = ent->animcache_vertex3f;
12586 rsurface.modelsvector3f = wanttangents ? ent->animcache_svector3f : NULL;
12587 rsurface.modeltvector3f = wanttangents ? ent->animcache_tvector3f : NULL;
12588 rsurface.modelnormal3f = wantnormals ? ent->animcache_normal3f : NULL;
12589 rsurface.modelvertexmesh = ent->animcache_vertexmesh;
12590 rsurface.modelvertexmeshbuffer = ent->animcache_vertexmeshbuffer;
12591 rsurface.modelvertex3fbuffer = ent->animcache_vertex3fbuffer;
12593 else if (wanttangents)
12595 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12596 rsurface.modelsvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12597 rsurface.modeltvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12598 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12599 model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, rsurface.modelnormal3f, rsurface.modelsvector3f, rsurface.modeltvector3f);
12600 rsurface.modelvertexmesh = NULL;
12601 rsurface.modelvertexmeshbuffer = NULL;
12602 rsurface.modelvertex3fbuffer = NULL;
12604 else if (wantnormals)
12606 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12607 rsurface.modelsvector3f = NULL;
12608 rsurface.modeltvector3f = NULL;
12609 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12610 model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, rsurface.modelnormal3f, NULL, NULL);
12611 rsurface.modelvertexmesh = NULL;
12612 rsurface.modelvertexmeshbuffer = NULL;
12613 rsurface.modelvertex3fbuffer = NULL;
12617 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12618 rsurface.modelsvector3f = NULL;
12619 rsurface.modeltvector3f = NULL;
12620 rsurface.modelnormal3f = NULL;
12621 model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, NULL, NULL, NULL);
12622 rsurface.modelvertexmesh = NULL;
12623 rsurface.modelvertexmeshbuffer = NULL;
12624 rsurface.modelvertex3fbuffer = NULL;
12626 rsurface.modelvertex3f_vertexbuffer = 0;
12627 rsurface.modelvertex3f_bufferoffset = 0;
12628 rsurface.modelsvector3f_vertexbuffer = 0;
12629 rsurface.modelsvector3f_bufferoffset = 0;
12630 rsurface.modeltvector3f_vertexbuffer = 0;
12631 rsurface.modeltvector3f_bufferoffset = 0;
12632 rsurface.modelnormal3f_vertexbuffer = 0;
12633 rsurface.modelnormal3f_bufferoffset = 0;
12634 rsurface.modelgeneratedvertex = true;
12638 rsurface.modelvertex3f = model->surfmesh.data_vertex3f;
12639 rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12640 rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f;
12641 rsurface.modelsvector3f = model->surfmesh.data_svector3f;
12642 rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12643 rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f;
12644 rsurface.modeltvector3f = model->surfmesh.data_tvector3f;
12645 rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12646 rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f;
12647 rsurface.modelnormal3f = model->surfmesh.data_normal3f;
12648 rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12649 rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f;
12650 rsurface.modelvertexmesh = model->surfmesh.vertexmesh;
12651 rsurface.modelvertexmeshbuffer = model->surfmesh.vertexmeshbuffer;
12652 rsurface.modelvertex3fbuffer = model->surfmesh.vertex3fbuffer;
12653 rsurface.modelgeneratedvertex = false;
12655 rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f;
12656 rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12657 rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f;
12658 rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f;
12659 rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12660 rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f;
12661 rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f;
12662 rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12663 rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
12664 rsurface.modelelement3i = model->surfmesh.data_element3i;
12665 rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer;
12666 rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset;
12667 rsurface.modelelement3s = model->surfmesh.data_element3s;
12668 rsurface.modelelement3s_indexbuffer = model->surfmesh.data_element3s_indexbuffer;
12669 rsurface.modelelement3s_bufferoffset = model->surfmesh.data_element3s_bufferoffset;
12670 rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets;
12671 rsurface.modelnumvertices = model->surfmesh.num_vertices;
12672 rsurface.modelnumtriangles = model->surfmesh.num_triangles;
12673 rsurface.modelsurfaces = model->data_surfaces;
12674 rsurface.batchgeneratedvertex = false;
12675 rsurface.batchfirstvertex = 0;
12676 rsurface.batchnumvertices = 0;
12677 rsurface.batchfirsttriangle = 0;
12678 rsurface.batchnumtriangles = 0;
12679 rsurface.batchvertex3f = NULL;
12680 rsurface.batchvertex3f_vertexbuffer = NULL;
12681 rsurface.batchvertex3f_bufferoffset = 0;
12682 rsurface.batchsvector3f = NULL;
12683 rsurface.batchsvector3f_vertexbuffer = NULL;
12684 rsurface.batchsvector3f_bufferoffset = 0;
12685 rsurface.batchtvector3f = NULL;
12686 rsurface.batchtvector3f_vertexbuffer = NULL;
12687 rsurface.batchtvector3f_bufferoffset = 0;
12688 rsurface.batchnormal3f = NULL;
12689 rsurface.batchnormal3f_vertexbuffer = NULL;
12690 rsurface.batchnormal3f_bufferoffset = 0;
12691 rsurface.batchlightmapcolor4f = NULL;
12692 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
12693 rsurface.batchlightmapcolor4f_bufferoffset = 0;
12694 rsurface.batchtexcoordtexture2f = NULL;
12695 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
12696 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
12697 rsurface.batchtexcoordlightmap2f = NULL;
12698 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
12699 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
12700 rsurface.batchvertexmesh = NULL;
12701 rsurface.batchvertexmeshbuffer = NULL;
12702 rsurface.batchvertex3fbuffer = NULL;
12703 rsurface.batchelement3i = NULL;
12704 rsurface.batchelement3i_indexbuffer = NULL;
12705 rsurface.batchelement3i_bufferoffset = 0;
12706 rsurface.batchelement3s = NULL;
12707 rsurface.batchelement3s_indexbuffer = NULL;
12708 rsurface.batchelement3s_bufferoffset = 0;
12709 rsurface.passcolor4f = NULL;
12710 rsurface.passcolor4f_vertexbuffer = NULL;
12711 rsurface.passcolor4f_bufferoffset = 0;
12714 void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qboolean wantnormals, qboolean wanttangents)
12716 rsurface.entity = r_refdef.scene.worldentity;
12717 rsurface.skeleton = NULL;
12718 rsurface.ent_skinnum = 0;
12719 rsurface.ent_qwskin = -1;
12720 rsurface.ent_shadertime = shadertime;
12721 rsurface.ent_flags = entflags;
12722 rsurface.modelnumvertices = numvertices;
12723 rsurface.modelnumtriangles = numtriangles;
12724 rsurface.matrix = *matrix;
12725 rsurface.inversematrix = *inversematrix;
12726 rsurface.matrixscale = Matrix4x4_ScaleFromMatrix(&rsurface.matrix);
12727 rsurface.inversematrixscale = 1.0f / rsurface.matrixscale;
12728 R_EntityMatrix(&rsurface.matrix);
12729 Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.origin, rsurface.localvieworigin);
12730 Matrix4x4_TransformStandardPlane(&rsurface.inversematrix, r_refdef.fogplane[0], r_refdef.fogplane[1], r_refdef.fogplane[2], r_refdef.fogplane[3], rsurface.fogplane);
12731 rsurface.fogplaneviewdist *= rsurface.inversematrixscale;
12732 rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale;
12733 rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale;
12734 rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
12735 VectorSet(rsurface.modellight_ambient, 0, 0, 0);
12736 VectorSet(rsurface.modellight_diffuse, 0, 0, 0);
12737 VectorSet(rsurface.modellight_lightdir, 0, 0, 1);
12738 VectorSet(rsurface.colormap_pantscolor, 0, 0, 0);
12739 VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0);
12740 Vector4Set(rsurface.colormod, r * r_refdef.view.colorscale, g * r_refdef.view.colorscale, b * r_refdef.view.colorscale, a);
12741 VectorSet(rsurface.glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value, r_refdef.view.colorscale * r_hdr_glowintensity.value);
12742 memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend));
12743 rsurface.frameblend[0].lerp = 1;
12744 rsurface.ent_alttextures = false;
12745 rsurface.basepolygonfactor = r_refdef.polygonfactor;
12746 rsurface.basepolygonoffset = r_refdef.polygonoffset;
12749 rsurface.modelvertex3f = (float *)vertex3f;
12750 rsurface.modelsvector3f = svector3f ? (float *)svector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12751 rsurface.modeltvector3f = tvector3f ? (float *)tvector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12752 rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12754 else if (wantnormals)
12756 rsurface.modelvertex3f = (float *)vertex3f;
12757 rsurface.modelsvector3f = NULL;
12758 rsurface.modeltvector3f = NULL;
12759 rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12763 rsurface.modelvertex3f = (float *)vertex3f;
12764 rsurface.modelsvector3f = NULL;
12765 rsurface.modeltvector3f = NULL;
12766 rsurface.modelnormal3f = NULL;
12768 rsurface.modelvertexmesh = NULL;
12769 rsurface.modelvertexmeshbuffer = NULL;
12770 rsurface.modelvertex3fbuffer = NULL;
12771 rsurface.modelvertex3f_vertexbuffer = 0;
12772 rsurface.modelvertex3f_bufferoffset = 0;
12773 rsurface.modelsvector3f_vertexbuffer = 0;
12774 rsurface.modelsvector3f_bufferoffset = 0;
12775 rsurface.modeltvector3f_vertexbuffer = 0;
12776 rsurface.modeltvector3f_bufferoffset = 0;
12777 rsurface.modelnormal3f_vertexbuffer = 0;
12778 rsurface.modelnormal3f_bufferoffset = 0;
12779 rsurface.modelgeneratedvertex = true;
12780 rsurface.modellightmapcolor4f = (float *)color4f;
12781 rsurface.modellightmapcolor4f_vertexbuffer = 0;
12782 rsurface.modellightmapcolor4f_bufferoffset = 0;
12783 rsurface.modeltexcoordtexture2f = (float *)texcoord2f;
12784 rsurface.modeltexcoordtexture2f_vertexbuffer = 0;
12785 rsurface.modeltexcoordtexture2f_bufferoffset = 0;
12786 rsurface.modeltexcoordlightmap2f = NULL;
12787 rsurface.modeltexcoordlightmap2f_vertexbuffer = 0;
12788 rsurface.modeltexcoordlightmap2f_bufferoffset = 0;
12789 rsurface.modelelement3i = (int *)element3i;
12790 rsurface.modelelement3i_indexbuffer = NULL;
12791 rsurface.modelelement3i_bufferoffset = 0;
12792 rsurface.modelelement3s = (unsigned short *)element3s;
12793 rsurface.modelelement3s_indexbuffer = NULL;
12794 rsurface.modelelement3s_bufferoffset = 0;
12795 rsurface.modellightmapoffsets = NULL;
12796 rsurface.modelsurfaces = NULL;
12797 rsurface.batchgeneratedvertex = false;
12798 rsurface.batchfirstvertex = 0;
12799 rsurface.batchnumvertices = 0;
12800 rsurface.batchfirsttriangle = 0;
12801 rsurface.batchnumtriangles = 0;
12802 rsurface.batchvertex3f = NULL;
12803 rsurface.batchvertex3f_vertexbuffer = NULL;
12804 rsurface.batchvertex3f_bufferoffset = 0;
12805 rsurface.batchsvector3f = NULL;
12806 rsurface.batchsvector3f_vertexbuffer = NULL;
12807 rsurface.batchsvector3f_bufferoffset = 0;
12808 rsurface.batchtvector3f = NULL;
12809 rsurface.batchtvector3f_vertexbuffer = NULL;
12810 rsurface.batchtvector3f_bufferoffset = 0;
12811 rsurface.batchnormal3f = NULL;
12812 rsurface.batchnormal3f_vertexbuffer = NULL;
12813 rsurface.batchnormal3f_bufferoffset = 0;
12814 rsurface.batchlightmapcolor4f = NULL;
12815 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
12816 rsurface.batchlightmapcolor4f_bufferoffset = 0;
12817 rsurface.batchtexcoordtexture2f = NULL;
12818 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
12819 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
12820 rsurface.batchtexcoordlightmap2f = NULL;
12821 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
12822 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
12823 rsurface.batchvertexmesh = NULL;
12824 rsurface.batchvertexmeshbuffer = NULL;
12825 rsurface.batchvertex3fbuffer = NULL;
12826 rsurface.batchelement3i = NULL;
12827 rsurface.batchelement3i_indexbuffer = NULL;
12828 rsurface.batchelement3i_bufferoffset = 0;
12829 rsurface.batchelement3s = NULL;
12830 rsurface.batchelement3s_indexbuffer = NULL;
12831 rsurface.batchelement3s_bufferoffset = 0;
12832 rsurface.passcolor4f = NULL;
12833 rsurface.passcolor4f_vertexbuffer = NULL;
12834 rsurface.passcolor4f_bufferoffset = 0;
12836 if (rsurface.modelnumvertices && rsurface.modelelement3i)
12838 if ((wantnormals || wanttangents) && !normal3f)
12840 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12841 Mod_BuildNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modelelement3i, rsurface.modelnormal3f, r_smoothnormals_areaweighting.integer != 0);
12843 if (wanttangents && !svector3f)
12845 rsurface.modelsvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12846 rsurface.modeltvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12847 Mod_BuildTextureVectorsFromNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modeltexcoordtexture2f, rsurface.modelnormal3f, rsurface.modelelement3i, rsurface.modelsvector3f, rsurface.modeltvector3f, r_smoothnormals_areaweighting.integer != 0);
12852 float RSurf_FogPoint(const float *v)
12854 // this code is identical to the USEFOGINSIDE/USEFOGOUTSIDE code in the shader
12855 float FogPlaneViewDist = r_refdef.fogplaneviewdist;
12856 float FogPlaneVertexDist = DotProduct(r_refdef.fogplane, v) + r_refdef.fogplane[3];
12857 float FogHeightFade = r_refdef.fogheightfade;
12859 unsigned int fogmasktableindex;
12860 if (r_refdef.fogplaneviewabove)
12861 fogfrac = min(0.0f, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0f, min(0.0f, FogPlaneVertexDist) * FogHeightFade);
12863 fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0f, FogPlaneVertexDist)) * min(1.0f, (min(0.0f, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);
12864 fogmasktableindex = (unsigned int)(VectorDistance(r_refdef.view.origin, v) * fogfrac * r_refdef.fogmasktabledistmultiplier);
12865 return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
12868 float RSurf_FogVertex(const float *v)
12870 // this code is identical to the USEFOGINSIDE/USEFOGOUTSIDE code in the shader
12871 float FogPlaneViewDist = rsurface.fogplaneviewdist;
12872 float FogPlaneVertexDist = DotProduct(rsurface.fogplane, v) + rsurface.fogplane[3];
12873 float FogHeightFade = rsurface.fogheightfade;
12875 unsigned int fogmasktableindex;
12876 if (r_refdef.fogplaneviewabove)
12877 fogfrac = min(0.0f, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0f, min(0.0f, FogPlaneVertexDist) * FogHeightFade);
12879 fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0f, FogPlaneVertexDist)) * min(1.0f, (min(0.0f, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);
12880 fogmasktableindex = (unsigned int)(VectorDistance(rsurface.localvieworigin, v) * fogfrac * rsurface.fogmasktabledistmultiplier);
12881 return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
12884 void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, int numelements, int adjust)
12887 for (i = 0;i < numelements;i++)
12888 outelement3i[i] = inelement3i[i] + adjust;
12891 static const int quadedges[6][2] = {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
12892 extern cvar_t gl_vbo;
12893 void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const msurface_t **texturesurfacelist)
12901 int surfacefirsttriangle;
12902 int surfacenumtriangles;
12903 int surfacefirstvertex;
12904 int surfaceendvertex;
12905 int surfacenumvertices;
12906 int batchnumvertices;
12907 int batchnumtriangles;
12911 qboolean dynamicvertex;
12915 float center[3], forward[3], right[3], up[3], v[3], newforward[3], newright[3], newup[3];
12916 float waveparms[4];
12917 q3shaderinfo_deform_t *deform;
12918 const msurface_t *surface, *firstsurface;
12919 r_vertexmesh_t *vertexmesh;
12920 if (!texturenumsurfaces)
12922 // find vertex range of this surface batch
12924 firstsurface = texturesurfacelist[0];
12925 firsttriangle = firstsurface->num_firsttriangle;
12926 batchnumvertices = 0;
12927 batchnumtriangles = 0;
12928 firstvertex = endvertex = firstsurface->num_firstvertex;
12929 for (i = 0;i < texturenumsurfaces;i++)
12931 surface = texturesurfacelist[i];
12932 if (surface != firstsurface + i)
12934 surfacefirstvertex = surface->num_firstvertex;
12935 surfaceendvertex = surfacefirstvertex + surface->num_vertices;
12936 surfacenumvertices = surface->num_vertices;
12937 surfacenumtriangles = surface->num_triangles;
12938 if (firstvertex > surfacefirstvertex)
12939 firstvertex = surfacefirstvertex;
12940 if (endvertex < surfaceendvertex)
12941 endvertex = surfaceendvertex;
12942 batchnumvertices += surfacenumvertices;
12943 batchnumtriangles += surfacenumtriangles;
12946 // we now know the vertex range used, and if there are any gaps in it
12947 rsurface.batchfirstvertex = firstvertex;
12948 rsurface.batchnumvertices = endvertex - firstvertex;
12949 rsurface.batchfirsttriangle = firsttriangle;
12950 rsurface.batchnumtriangles = batchnumtriangles;
12952 // this variable holds flags for which properties have been updated that
12953 // may require regenerating vertexmesh array...
12956 // check if any dynamic vertex processing must occur
12957 dynamicvertex = false;
12959 // if there is a chance of animated vertex colors, it's a dynamic batch
12960 if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_ARRAY_VERTEXCOLOR)) && texturesurfacelist[0]->lightmapinfo)
12962 dynamicvertex = true;
12963 batchneed |= BATCHNEED_NOGAPS;
12964 needsupdate |= BATCHNEED_VERTEXMESH_VERTEXCOLOR;
12967 for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
12969 switch (deform->deform)
12972 case Q3DEFORM_PROJECTIONSHADOW:
12973 case Q3DEFORM_TEXT0:
12974 case Q3DEFORM_TEXT1:
12975 case Q3DEFORM_TEXT2:
12976 case Q3DEFORM_TEXT3:
12977 case Q3DEFORM_TEXT4:
12978 case Q3DEFORM_TEXT5:
12979 case Q3DEFORM_TEXT6:
12980 case Q3DEFORM_TEXT7:
12981 case Q3DEFORM_NONE:
12983 case Q3DEFORM_AUTOSPRITE:
12984 dynamicvertex = true;
12985 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12986 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12988 case Q3DEFORM_AUTOSPRITE2:
12989 dynamicvertex = true;
12990 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12991 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12993 case Q3DEFORM_NORMAL:
12994 dynamicvertex = true;
12995 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12996 needsupdate |= BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12998 case Q3DEFORM_WAVE:
12999 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
13000 break; // if wavefunc is a nop, ignore this transform
13001 dynamicvertex = true;
13002 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
13003 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
13005 case Q3DEFORM_BULGE:
13006 dynamicvertex = true;
13007 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
13008 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
13010 case Q3DEFORM_MOVE:
13011 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
13012 break; // if wavefunc is a nop, ignore this transform
13013 dynamicvertex = true;
13014 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
13015 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX;
13019 switch(rsurface.texture->tcgen.tcgen)
13022 case Q3TCGEN_TEXTURE:
13024 case Q3TCGEN_LIGHTMAP:
13025 dynamicvertex = true;
13026 batchneed |= BATCHNEED_ARRAY_LIGHTMAP | BATCHNEED_NOGAPS;
13027 needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
13029 case Q3TCGEN_VECTOR:
13030 dynamicvertex = true;
13031 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
13032 needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
13034 case Q3TCGEN_ENVIRONMENT:
13035 dynamicvertex = true;
13036 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS;
13037 needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
13040 if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
13042 dynamicvertex = true;
13043 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
13044 needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
13047 if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
13049 dynamicvertex = true;
13050 batchneed |= BATCHNEED_NOGAPS;
13051 needsupdate |= (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP));
13054 if (dynamicvertex || gaps || rsurface.batchfirstvertex)
13056 // when copying, we need to consider the regeneration of vertexmesh, any dependencies it may have must be set...
13057 if (batchneed & BATCHNEED_VERTEXMESH_VERTEX) batchneed |= BATCHNEED_ARRAY_VERTEX;
13058 if (batchneed & BATCHNEED_VERTEXMESH_NORMAL) batchneed |= BATCHNEED_ARRAY_NORMAL;
13059 if (batchneed & BATCHNEED_VERTEXMESH_VECTOR) batchneed |= BATCHNEED_ARRAY_VECTOR;
13060 if (batchneed & BATCHNEED_VERTEXMESH_VERTEXCOLOR) batchneed |= BATCHNEED_ARRAY_VERTEXCOLOR;
13061 if (batchneed & BATCHNEED_VERTEXMESH_TEXCOORD) batchneed |= BATCHNEED_ARRAY_TEXCOORD;
13062 if (batchneed & BATCHNEED_VERTEXMESH_LIGHTMAP) batchneed |= BATCHNEED_ARRAY_LIGHTMAP;
13065 // when the model data has no vertex buffer (dynamic mesh), we need to
13067 if (vid.useinterleavedarrays ? !rsurface.modelvertexmeshbuffer : !rsurface.modelvertex3f_vertexbuffer)
13068 batchneed |= BATCHNEED_NOGAPS;
13070 // if needsupdate, we have to do a dynamic vertex batch for sure
13071 if (needsupdate & batchneed)
13072 dynamicvertex = true;
13074 // see if we need to build vertexmesh from arrays
13075 if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
13076 dynamicvertex = true;
13078 // if gaps are unacceptable, and there are gaps, it's a dynamic batch...
13079 // also some drivers strongly dislike firstvertex
13080 if ((batchneed & BATCHNEED_NOGAPS) && (gaps || firstvertex))
13081 dynamicvertex = true;
13083 rsurface.batchvertex3f = rsurface.modelvertex3f;
13084 rsurface.batchvertex3f_vertexbuffer = rsurface.modelvertex3f_vertexbuffer;
13085 rsurface.batchvertex3f_bufferoffset = rsurface.modelvertex3f_bufferoffset;
13086 rsurface.batchsvector3f = rsurface.modelsvector3f;
13087 rsurface.batchsvector3f_vertexbuffer = rsurface.modelsvector3f_vertexbuffer;
13088 rsurface.batchsvector3f_bufferoffset = rsurface.modelsvector3f_bufferoffset;
13089 rsurface.batchtvector3f = rsurface.modeltvector3f;
13090 rsurface.batchtvector3f_vertexbuffer = rsurface.modeltvector3f_vertexbuffer;
13091 rsurface.batchtvector3f_bufferoffset = rsurface.modeltvector3f_bufferoffset;
13092 rsurface.batchnormal3f = rsurface.modelnormal3f;
13093 rsurface.batchnormal3f_vertexbuffer = rsurface.modelnormal3f_vertexbuffer;
13094 rsurface.batchnormal3f_bufferoffset = rsurface.modelnormal3f_bufferoffset;
13095 rsurface.batchlightmapcolor4f = rsurface.modellightmapcolor4f;
13096 rsurface.batchlightmapcolor4f_vertexbuffer = rsurface.modellightmapcolor4f_vertexbuffer;
13097 rsurface.batchlightmapcolor4f_bufferoffset = rsurface.modellightmapcolor4f_bufferoffset;
13098 rsurface.batchtexcoordtexture2f = rsurface.modeltexcoordtexture2f;
13099 rsurface.batchtexcoordtexture2f_vertexbuffer = rsurface.modeltexcoordtexture2f_vertexbuffer;
13100 rsurface.batchtexcoordtexture2f_bufferoffset = rsurface.modeltexcoordtexture2f_bufferoffset;
13101 rsurface.batchtexcoordlightmap2f = rsurface.modeltexcoordlightmap2f;
13102 rsurface.batchtexcoordlightmap2f_vertexbuffer = rsurface.modeltexcoordlightmap2f_vertexbuffer;
13103 rsurface.batchtexcoordlightmap2f_bufferoffset = rsurface.modeltexcoordlightmap2f_bufferoffset;
13104 rsurface.batchvertex3fbuffer = rsurface.modelvertex3fbuffer;
13105 rsurface.batchvertexmesh = rsurface.modelvertexmesh;
13106 rsurface.batchvertexmeshbuffer = rsurface.modelvertexmeshbuffer;
13107 rsurface.batchelement3i = rsurface.modelelement3i;
13108 rsurface.batchelement3i_indexbuffer = rsurface.modelelement3i_indexbuffer;
13109 rsurface.batchelement3i_bufferoffset = rsurface.modelelement3i_bufferoffset;
13110 rsurface.batchelement3s = rsurface.modelelement3s;
13111 rsurface.batchelement3s_indexbuffer = rsurface.modelelement3s_indexbuffer;
13112 rsurface.batchelement3s_bufferoffset = rsurface.modelelement3s_bufferoffset;
13114 // if any dynamic vertex processing has to occur in software, we copy the
13115 // entire surface list together before processing to rebase the vertices
13116 // to start at 0 (otherwise we waste a lot of room in a vertex buffer).
13118 // if any gaps exist and we do not have a static vertex buffer, we have to
13119 // copy the surface list together to avoid wasting upload bandwidth on the
13120 // vertices in the gaps.
13122 // if gaps exist and we have a static vertex buffer, we still have to
13123 // combine the index buffer ranges into one dynamic index buffer.
13125 // in all cases we end up with data that can be drawn in one call.
13127 if (!dynamicvertex)
13129 // static vertex data, just set pointers...
13130 rsurface.batchgeneratedvertex = false;
13131 // if there are gaps, we want to build a combined index buffer,
13132 // otherwise use the original static buffer with an appropriate offset
13135 // build a new triangle elements array for this batch
13136 rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
13137 rsurface.batchfirsttriangle = 0;
13139 for (i = 0;i < texturenumsurfaces;i++)
13141 surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
13142 surfacenumtriangles = texturesurfacelist[i]->num_triangles;
13143 memcpy(rsurface.batchelement3i + 3*numtriangles, rsurface.modelelement3i + 3*surfacefirsttriangle, surfacenumtriangles*sizeof(int[3]));
13144 numtriangles += surfacenumtriangles;
13146 rsurface.batchelement3i_indexbuffer = NULL;
13147 rsurface.batchelement3i_bufferoffset = 0;
13148 rsurface.batchelement3s = NULL;
13149 rsurface.batchelement3s_indexbuffer = NULL;
13150 rsurface.batchelement3s_bufferoffset = 0;
13151 if (endvertex <= 65536)
13153 // make a 16bit (unsigned short) index array if possible
13154 rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
13155 for (i = 0;i < numtriangles*3;i++)
13156 rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
13162 // something needs software processing, do it for real...
13163 // we only directly handle separate array data in this case and then
13164 // generate interleaved data if needed...
13165 rsurface.batchgeneratedvertex = true;
13167 // now copy the vertex data into a combined array and make an index array
13168 // (this is what Quake3 does all the time)
13169 //if (gaps || rsurface.batchfirstvertex)
13171 rsurface.batchvertex3fbuffer = NULL;
13172 rsurface.batchvertexmesh = NULL;
13173 rsurface.batchvertexmeshbuffer = NULL;
13174 rsurface.batchvertex3f = NULL;
13175 rsurface.batchvertex3f_vertexbuffer = NULL;
13176 rsurface.batchvertex3f_bufferoffset = 0;
13177 rsurface.batchsvector3f = NULL;
13178 rsurface.batchsvector3f_vertexbuffer = NULL;
13179 rsurface.batchsvector3f_bufferoffset = 0;
13180 rsurface.batchtvector3f = NULL;
13181 rsurface.batchtvector3f_vertexbuffer = NULL;
13182 rsurface.batchtvector3f_bufferoffset = 0;
13183 rsurface.batchnormal3f = NULL;
13184 rsurface.batchnormal3f_vertexbuffer = NULL;
13185 rsurface.batchnormal3f_bufferoffset = 0;
13186 rsurface.batchlightmapcolor4f = NULL;
13187 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
13188 rsurface.batchlightmapcolor4f_bufferoffset = 0;
13189 rsurface.batchtexcoordtexture2f = NULL;
13190 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13191 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13192 rsurface.batchtexcoordlightmap2f = NULL;
13193 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
13194 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
13195 rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
13196 rsurface.batchelement3i_indexbuffer = NULL;
13197 rsurface.batchelement3i_bufferoffset = 0;
13198 rsurface.batchelement3s = NULL;
13199 rsurface.batchelement3s_indexbuffer = NULL;
13200 rsurface.batchelement3s_bufferoffset = 0;
13201 // we'll only be setting up certain arrays as needed
13202 if (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP))
13203 rsurface.batchvertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(batchnumvertices * sizeof(r_vertexmesh_t));
13204 if (batchneed & BATCHNEED_ARRAY_VERTEX)
13205 rsurface.batchvertex3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13206 if (batchneed & BATCHNEED_ARRAY_NORMAL)
13207 rsurface.batchnormal3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13208 if (batchneed & BATCHNEED_ARRAY_VECTOR)
13210 rsurface.batchsvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13211 rsurface.batchtvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13213 if (batchneed & BATCHNEED_ARRAY_VERTEXCOLOR)
13214 rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
13215 if (batchneed & BATCHNEED_ARRAY_TEXCOORD)
13216 rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13217 if (batchneed & BATCHNEED_ARRAY_LIGHTMAP)
13218 rsurface.batchtexcoordlightmap2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13221 for (i = 0;i < texturenumsurfaces;i++)
13223 surfacefirstvertex = texturesurfacelist[i]->num_firstvertex;
13224 surfacenumvertices = texturesurfacelist[i]->num_vertices;
13225 surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
13226 surfacenumtriangles = texturesurfacelist[i]->num_triangles;
13227 // copy only the data requested
13228 if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)) && rsurface.modelvertexmesh)
13229 memcpy(rsurface.batchvertexmesh + numvertices, rsurface.modelvertexmesh + surfacefirstvertex, surfacenumvertices * sizeof(rsurface.batchvertexmesh[0]));
13230 if (batchneed & (BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_ARRAY_LIGHTMAP))
13232 if (batchneed & BATCHNEED_ARRAY_VERTEX)
13233 memcpy(rsurface.batchvertex3f + 3*numvertices, rsurface.modelvertex3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13234 if ((batchneed & BATCHNEED_ARRAY_NORMAL) && rsurface.modelnormal3f)
13235 memcpy(rsurface.batchnormal3f + 3*numvertices, rsurface.modelnormal3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13236 if ((batchneed & BATCHNEED_ARRAY_VECTOR) && rsurface.modelsvector3f)
13238 memcpy(rsurface.batchsvector3f + 3*numvertices, rsurface.modelsvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13239 memcpy(rsurface.batchtvector3f + 3*numvertices, rsurface.modeltvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13241 if ((batchneed & BATCHNEED_ARRAY_VERTEXCOLOR) && rsurface.modellightmapcolor4f)
13242 memcpy(rsurface.batchlightmapcolor4f + 4*numvertices, rsurface.modellightmapcolor4f + 4*surfacefirstvertex, surfacenumvertices * sizeof(float[4]));
13243 if ((batchneed & BATCHNEED_ARRAY_TEXCOORD) && rsurface.modeltexcoordtexture2f)
13244 memcpy(rsurface.batchtexcoordtexture2f + 2*numvertices, rsurface.modeltexcoordtexture2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
13245 if ((batchneed & BATCHNEED_ARRAY_LIGHTMAP) && rsurface.modeltexcoordlightmap2f)
13246 memcpy(rsurface.batchtexcoordlightmap2f + 2*numvertices, rsurface.modeltexcoordlightmap2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
13248 RSurf_RenumberElements(rsurface.modelelement3i + 3*surfacefirsttriangle, rsurface.batchelement3i + 3*numtriangles, 3*surfacenumtriangles, numvertices - surfacefirstvertex);
13249 numvertices += surfacenumvertices;
13250 numtriangles += surfacenumtriangles;
13253 // generate a 16bit index array as well if possible
13254 // (in general, dynamic batches fit)
13255 if (numvertices <= 65536)
13257 rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
13258 for (i = 0;i < numtriangles*3;i++)
13259 rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
13262 // since we've copied everything, the batch now starts at 0
13263 rsurface.batchfirstvertex = 0;
13264 rsurface.batchnumvertices = batchnumvertices;
13265 rsurface.batchfirsttriangle = 0;
13266 rsurface.batchnumtriangles = batchnumtriangles;
13269 // q1bsp surfaces rendered in vertex color mode have to have colors
13270 // calculated based on lightstyles
13271 if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_ARRAY_VERTEXCOLOR)) && texturesurfacelist[0]->lightmapinfo)
13273 // generate color arrays for the surfaces in this list
13277 const int *offsets;
13278 const unsigned char *lm;
13279 rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
13280 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
13281 rsurface.batchlightmapcolor4f_bufferoffset = 0;
13283 for (i = 0;i < texturenumsurfaces;i++)
13285 surface = texturesurfacelist[i];
13286 offsets = rsurface.modellightmapoffsets + surface->num_firstvertex;
13287 surfacenumvertices = surface->num_vertices;
13288 if (surface->lightmapinfo->samples)
13290 for (j = 0;j < surfacenumvertices;j++)
13292 lm = surface->lightmapinfo->samples + offsets[j];
13293 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[0]];
13294 VectorScale(lm, scale, c);
13295 if (surface->lightmapinfo->styles[1] != 255)
13297 size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
13299 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[1]];
13300 VectorMA(c, scale, lm, c);
13301 if (surface->lightmapinfo->styles[2] != 255)
13304 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[2]];
13305 VectorMA(c, scale, lm, c);
13306 if (surface->lightmapinfo->styles[3] != 255)
13309 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[3]];
13310 VectorMA(c, scale, lm, c);
13317 Vector4Set(rsurface.batchlightmapcolor4f + 4*numvertices, min(c[0], 255) * (1.0f / 255.0f), min(c[1], 255) * (1.0f / 255.0f), min(c[2], 255) * (1.0f / 255.0f), 1);
13323 for (j = 0;j < surfacenumvertices;j++)
13325 Vector4Set(rsurface.batchlightmapcolor4f + 4*numvertices, 0, 0, 0, 1);
13332 // if vertices are deformed (sprite flares and things in maps, possibly
13333 // water waves, bulges and other deformations), modify the copied vertices
13335 for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
13337 switch (deform->deform)
13340 case Q3DEFORM_PROJECTIONSHADOW:
13341 case Q3DEFORM_TEXT0:
13342 case Q3DEFORM_TEXT1:
13343 case Q3DEFORM_TEXT2:
13344 case Q3DEFORM_TEXT3:
13345 case Q3DEFORM_TEXT4:
13346 case Q3DEFORM_TEXT5:
13347 case Q3DEFORM_TEXT6:
13348 case Q3DEFORM_TEXT7:
13349 case Q3DEFORM_NONE:
13351 case Q3DEFORM_AUTOSPRITE:
13352 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, newforward);
13353 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.right, newright);
13354 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.up, newup);
13355 VectorNormalize(newforward);
13356 VectorNormalize(newright);
13357 VectorNormalize(newup);
13358 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13359 // rsurface.batchvertex3f_vertexbuffer = NULL;
13360 // rsurface.batchvertex3f_bufferoffset = 0;
13361 // rsurface.batchsvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f);
13362 // rsurface.batchsvector3f_vertexbuffer = NULL;
13363 // rsurface.batchsvector3f_bufferoffset = 0;
13364 // rsurface.batchtvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f);
13365 // rsurface.batchtvector3f_vertexbuffer = NULL;
13366 // rsurface.batchtvector3f_bufferoffset = 0;
13367 // rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13368 // rsurface.batchnormal3f_vertexbuffer = NULL;
13369 // rsurface.batchnormal3f_bufferoffset = 0;
13370 // a single autosprite surface can contain multiple sprites...
13371 for (j = 0;j < batchnumvertices - 3;j += 4)
13373 VectorClear(center);
13374 for (i = 0;i < 4;i++)
13375 VectorAdd(center, rsurface.batchvertex3f + 3*(j+i), center);
13376 VectorScale(center, 0.25f, center);
13377 VectorCopy(rsurface.batchnormal3f + 3*j, forward);
13378 VectorCopy(rsurface.batchsvector3f + 3*j, right);
13379 VectorCopy(rsurface.batchtvector3f + 3*j, up);
13380 for (i = 0;i < 4;i++)
13382 VectorSubtract(rsurface.batchvertex3f + 3*(j+i), center, v);
13383 VectorMAMAMAM(1, center, DotProduct(forward, v), newforward, DotProduct(right, v), newright, DotProduct(up, v), newup, rsurface.batchvertex3f + 3*(j+i));
13386 // if we get here, BATCHNEED_ARRAY_NORMAL and BATCHNEED_ARRAY_VECTOR are in batchneed, so no need to check
13387 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13388 Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchsvector3f, rsurface.batchtvector3f, r_smoothnormals_areaweighting.integer != 0);
13390 case Q3DEFORM_AUTOSPRITE2:
13391 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, newforward);
13392 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.right, newright);
13393 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.up, newup);
13394 VectorNormalize(newforward);
13395 VectorNormalize(newright);
13396 VectorNormalize(newup);
13397 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13398 // rsurface.batchvertex3f_vertexbuffer = NULL;
13399 // rsurface.batchvertex3f_bufferoffset = 0;
13401 const float *v1, *v2;
13411 memset(shortest, 0, sizeof(shortest));
13412 // a single autosprite surface can contain multiple sprites...
13413 for (j = 0;j < batchnumvertices - 3;j += 4)
13415 VectorClear(center);
13416 for (i = 0;i < 4;i++)
13417 VectorAdd(center, rsurface.batchvertex3f + 3*(j+i), center);
13418 VectorScale(center, 0.25f, center);
13419 // find the two shortest edges, then use them to define the
13420 // axis vectors for rotating around the central axis
13421 for (i = 0;i < 6;i++)
13423 v1 = rsurface.batchvertex3f + 3*(j+quadedges[i][0]);
13424 v2 = rsurface.batchvertex3f + 3*(j+quadedges[i][1]);
13425 l = VectorDistance2(v1, v2);
13426 // this length bias tries to make sense of square polygons, assuming they are meant to be upright
13427 if (v1[2] != v2[2])
13428 l += (1.0f / 1024.0f);
13429 if (shortest[0].length2 > l || i == 0)
13431 shortest[1] = shortest[0];
13432 shortest[0].length2 = l;
13433 shortest[0].v1 = v1;
13434 shortest[0].v2 = v2;
13436 else if (shortest[1].length2 > l || i == 1)
13438 shortest[1].length2 = l;
13439 shortest[1].v1 = v1;
13440 shortest[1].v2 = v2;
13443 VectorLerp(shortest[0].v1, 0.5f, shortest[0].v2, start);
13444 VectorLerp(shortest[1].v1, 0.5f, shortest[1].v2, end);
13445 // this calculates the right vector from the shortest edge
13446 // and the up vector from the edge midpoints
13447 VectorSubtract(shortest[0].v1, shortest[0].v2, right);
13448 VectorNormalize(right);
13449 VectorSubtract(end, start, up);
13450 VectorNormalize(up);
13451 // calculate a forward vector to use instead of the original plane normal (this is how we get a new right vector)
13452 VectorSubtract(rsurface.localvieworigin, center, forward);
13453 //Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, forward);
13454 VectorNegate(forward, forward);
13455 VectorReflect(forward, 0, up, forward);
13456 VectorNormalize(forward);
13457 CrossProduct(up, forward, newright);
13458 VectorNormalize(newright);
13459 // rotate the quad around the up axis vector, this is made
13460 // especially easy by the fact we know the quad is flat,
13461 // so we only have to subtract the center position and
13462 // measure distance along the right vector, and then
13463 // multiply that by the newright vector and add back the
13465 // we also need to subtract the old position to undo the
13466 // displacement from the center, which we do with a
13467 // DotProduct, the subtraction/addition of center is also
13468 // optimized into DotProducts here
13469 l = DotProduct(right, center);
13470 for (i = 0;i < 4;i++)
13472 v1 = rsurface.batchvertex3f + 3*(j+i);
13473 f = DotProduct(right, v1) - l;
13474 VectorMAMAM(1, v1, -f, right, f, newright, rsurface.batchvertex3f + 3*(j+i));
13478 if(batchneed & (BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR)) // otherwise these can stay NULL
13480 // rsurface.batchnormal3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13481 // rsurface.batchnormal3f_vertexbuffer = NULL;
13482 // rsurface.batchnormal3f_bufferoffset = 0;
13483 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13485 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13487 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13488 // rsurface.batchsvector3f_vertexbuffer = NULL;
13489 // rsurface.batchsvector3f_bufferoffset = 0;
13490 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13491 // rsurface.batchtvector3f_vertexbuffer = NULL;
13492 // rsurface.batchtvector3f_bufferoffset = 0;
13493 Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchsvector3f, rsurface.batchtvector3f, r_smoothnormals_areaweighting.integer != 0);
13496 case Q3DEFORM_NORMAL:
13497 // deform the normals to make reflections wavey
13498 rsurface.batchnormal3f = (float *)R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13499 rsurface.batchnormal3f_vertexbuffer = NULL;
13500 rsurface.batchnormal3f_bufferoffset = 0;
13501 for (j = 0;j < batchnumvertices;j++)
13504 float *normal = rsurface.batchnormal3f + 3*j;
13505 VectorScale(rsurface.batchvertex3f + 3*j, 0.98f, vertex);
13506 normal[0] = rsurface.batchnormal3f[j*3+0] + deform->parms[0] * noise4f( vertex[0], vertex[1], vertex[2], r_refdef.scene.time * deform->parms[1]);
13507 normal[1] = rsurface.batchnormal3f[j*3+1] + deform->parms[0] * noise4f( 98 + vertex[0], vertex[1], vertex[2], r_refdef.scene.time * deform->parms[1]);
13508 normal[2] = rsurface.batchnormal3f[j*3+2] + deform->parms[0] * noise4f(196 + vertex[0], vertex[1], vertex[2], r_refdef.scene.time * deform->parms[1]);
13509 VectorNormalize(normal);
13511 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13513 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13514 // rsurface.batchsvector3f_vertexbuffer = NULL;
13515 // rsurface.batchsvector3f_bufferoffset = 0;
13516 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13517 // rsurface.batchtvector3f_vertexbuffer = NULL;
13518 // rsurface.batchtvector3f_bufferoffset = 0;
13519 Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchsvector3f, rsurface.batchtvector3f, r_smoothnormals_areaweighting.integer != 0);
13522 case Q3DEFORM_WAVE:
13523 // deform vertex array to make wavey water and flags and such
13524 waveparms[0] = deform->waveparms[0];
13525 waveparms[1] = deform->waveparms[1];
13526 waveparms[2] = deform->waveparms[2];
13527 waveparms[3] = deform->waveparms[3];
13528 if(!R_TestQ3WaveFunc(deform->wavefunc, waveparms))
13529 break; // if wavefunc is a nop, don't make a dynamic vertex array
13530 // this is how a divisor of vertex influence on deformation
13531 animpos = deform->parms[0] ? 1.0f / deform->parms[0] : 100.0f;
13532 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
13533 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13534 // rsurface.batchvertex3f_vertexbuffer = NULL;
13535 // rsurface.batchvertex3f_bufferoffset = 0;
13536 // rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13537 // rsurface.batchnormal3f_vertexbuffer = NULL;
13538 // rsurface.batchnormal3f_bufferoffset = 0;
13539 for (j = 0;j < batchnumvertices;j++)
13541 // if the wavefunc depends on time, evaluate it per-vertex
13544 waveparms[2] = deform->waveparms[2] + (rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+1] + rsurface.batchvertex3f[j*3+2]) * animpos;
13545 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
13547 VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.batchvertex3f + 3*j);
13549 // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
13550 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13551 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13553 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13554 // rsurface.batchsvector3f_vertexbuffer = NULL;
13555 // rsurface.batchsvector3f_bufferoffset = 0;
13556 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13557 // rsurface.batchtvector3f_vertexbuffer = NULL;
13558 // rsurface.batchtvector3f_bufferoffset = 0;
13559 Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchsvector3f, rsurface.batchtvector3f, r_smoothnormals_areaweighting.integer != 0);
13562 case Q3DEFORM_BULGE:
13563 // deform vertex array to make the surface have moving bulges
13564 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13565 // rsurface.batchvertex3f_vertexbuffer = NULL;
13566 // rsurface.batchvertex3f_bufferoffset = 0;
13567 // rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13568 // rsurface.batchnormal3f_vertexbuffer = NULL;
13569 // rsurface.batchnormal3f_bufferoffset = 0;
13570 for (j = 0;j < batchnumvertices;j++)
13572 scale = sin(rsurface.batchtexcoordtexture2f[j*2+0] * deform->parms[0] + r_refdef.scene.time * deform->parms[2]) * deform->parms[1];
13573 VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.batchvertex3f + 3*j);
13575 // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
13576 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13577 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13579 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13580 // rsurface.batchsvector3f_vertexbuffer = NULL;
13581 // rsurface.batchsvector3f_bufferoffset = 0;
13582 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13583 // rsurface.batchtvector3f_vertexbuffer = NULL;
13584 // rsurface.batchtvector3f_bufferoffset = 0;
13585 Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchsvector3f, rsurface.batchtvector3f, r_smoothnormals_areaweighting.integer != 0);
13588 case Q3DEFORM_MOVE:
13589 // deform vertex array
13590 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
13591 break; // if wavefunc is a nop, don't make a dynamic vertex array
13592 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, deform->waveparms);
13593 VectorScale(deform->parms, scale, waveparms);
13594 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13595 // rsurface.batchvertex3f_vertexbuffer = NULL;
13596 // rsurface.batchvertex3f_bufferoffset = 0;
13597 for (j = 0;j < batchnumvertices;j++)
13598 VectorAdd(rsurface.batchvertex3f + 3*j, waveparms, rsurface.batchvertex3f + 3*j);
13603 // generate texcoords based on the chosen texcoord source
13604 switch(rsurface.texture->tcgen.tcgen)
13607 case Q3TCGEN_TEXTURE:
13609 case Q3TCGEN_LIGHTMAP:
13610 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13611 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13612 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13613 if (rsurface.batchtexcoordlightmap2f)
13614 memcpy(rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordtexture2f, batchnumvertices * sizeof(float[2]));
13616 case Q3TCGEN_VECTOR:
13617 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13618 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13619 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13620 for (j = 0;j < batchnumvertices;j++)
13622 rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
13623 rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
13626 case Q3TCGEN_ENVIRONMENT:
13627 // make environment reflections using a spheremap
13628 rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13629 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13630 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13631 for (j = 0;j < batchnumvertices;j++)
13633 // identical to Q3A's method, but executed in worldspace so
13634 // carried models can be shiny too
13636 float viewer[3], d, reflected[3], worldreflected[3];
13638 VectorSubtract(rsurface.localvieworigin, rsurface.batchvertex3f + 3*j, viewer);
13639 // VectorNormalize(viewer);
13641 d = DotProduct(rsurface.batchnormal3f + 3*j, viewer);
13643 reflected[0] = rsurface.batchnormal3f[j*3+0]*2*d - viewer[0];
13644 reflected[1] = rsurface.batchnormal3f[j*3+1]*2*d - viewer[1];
13645 reflected[2] = rsurface.batchnormal3f[j*3+2]*2*d - viewer[2];
13646 // note: this is proportinal to viewer, so we can normalize later
13648 Matrix4x4_Transform3x3(&rsurface.matrix, reflected, worldreflected);
13649 VectorNormalize(worldreflected);
13651 // note: this sphere map only uses world x and z!
13652 // so positive and negative y will LOOK THE SAME.
13653 rsurface.batchtexcoordtexture2f[j*2+0] = 0.5 + 0.5 * worldreflected[1];
13654 rsurface.batchtexcoordtexture2f[j*2+1] = 0.5 - 0.5 * worldreflected[2];
13658 // the only tcmod that needs software vertex processing is turbulent, so
13659 // check for it here and apply the changes if needed
13660 // and we only support that as the first one
13661 // (handling a mixture of turbulent and other tcmods would be problematic
13662 // without punting it entirely to a software path)
13663 if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
13665 amplitude = rsurface.texture->tcmods[0].parms[1];
13666 animpos = rsurface.texture->tcmods[0].parms[2] + r_refdef.scene.time * rsurface.texture->tcmods[0].parms[3];
13667 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13668 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13669 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13670 for (j = 0;j < batchnumvertices;j++)
13672 rsurface.batchtexcoordtexture2f[j*2+0] += amplitude * sin(((rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+2]) * 1.0 / 1024.0f + animpos) * M_PI * 2);
13673 rsurface.batchtexcoordtexture2f[j*2+1] += amplitude * sin(((rsurface.batchvertex3f[j*3+1] ) * 1.0 / 1024.0f + animpos) * M_PI * 2);
13677 if (needsupdate & batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP))
13679 // convert the modified arrays to vertex structs
13680 // rsurface.batchvertexmesh = R_FrameData_Alloc(batchnumvertices * sizeof(r_vertexmesh_t));
13681 // rsurface.batchvertexmeshbuffer = NULL;
13682 if (batchneed & BATCHNEED_VERTEXMESH_VERTEX)
13683 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13684 VectorCopy(rsurface.batchvertex3f + 3*j, vertexmesh->vertex3f);
13685 if (batchneed & BATCHNEED_VERTEXMESH_NORMAL)
13686 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13687 VectorCopy(rsurface.batchnormal3f + 3*j, vertexmesh->normal3f);
13688 if (batchneed & BATCHNEED_VERTEXMESH_VECTOR)
13690 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13692 VectorCopy(rsurface.batchsvector3f + 3*j, vertexmesh->svector3f);
13693 VectorCopy(rsurface.batchtvector3f + 3*j, vertexmesh->tvector3f);
13696 if ((batchneed & BATCHNEED_VERTEXMESH_VERTEXCOLOR) && rsurface.batchlightmapcolor4f)
13697 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13698 Vector4Scale(rsurface.batchlightmapcolor4f + 4*j, 255.0f, vertexmesh->color4ub);
13699 if (batchneed & BATCHNEED_VERTEXMESH_TEXCOORD)
13700 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13701 Vector2Copy(rsurface.batchtexcoordtexture2f + 2*j, vertexmesh->texcoordtexture2f);
13702 if ((batchneed & BATCHNEED_VERTEXMESH_LIGHTMAP) && rsurface.batchtexcoordlightmap2f)
13703 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13704 Vector2Copy(rsurface.batchtexcoordlightmap2f + 2*j, vertexmesh->texcoordlightmap2f);
13708 void RSurf_DrawBatch(void)
13710 // sometimes a zero triangle surface (usually a degenerate patch) makes it
13711 // through the pipeline, killing it earlier in the pipeline would have
13712 // per-surface overhead rather than per-batch overhead, so it's best to
13713 // reject it here, before it hits glDraw.
13714 if (rsurface.batchnumtriangles == 0)
13717 // batch debugging code
13718 if (r_test.integer && rsurface.entity == r_refdef.scene.worldentity && rsurface.batchvertex3f == r_refdef.scene.worldentity->model->surfmesh.data_vertex3f)
13724 e = rsurface.batchelement3i + rsurface.batchfirsttriangle*3;
13725 for (i = 0;i < rsurface.batchnumtriangles*3;i++)
13728 for (j = 0;j < rsurface.entity->model->num_surfaces;j++)
13730 if (c >= rsurface.modelsurfaces[j].num_firstvertex && c < (rsurface.modelsurfaces[j].num_firstvertex + rsurface.modelsurfaces[j].num_vertices))
13732 if (rsurface.modelsurfaces[j].texture != rsurface.texture)
13733 Sys_Error("RSurf_DrawBatch: index %i uses different texture (%s) than surface %i which it belongs to (which uses %s)\n", c, rsurface.texture->name, j, rsurface.modelsurfaces[j].texture->name);
13740 R_Mesh_Draw(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchfirsttriangle, rsurface.batchnumtriangles, rsurface.batchelement3i, rsurface.batchelement3i_indexbuffer, rsurface.batchelement3i_bufferoffset, rsurface.batchelement3s, rsurface.batchelement3s_indexbuffer, rsurface.batchelement3s_bufferoffset);
13743 static int RSurf_FindWaterPlaneForSurface(const msurface_t *surface)
13745 // pick the closest matching water plane
13746 int planeindex, vertexindex, bestplaneindex = -1;
13750 r_waterstate_waterplane_t *p;
13751 qboolean prepared = false;
13753 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
13755 if(p->camera_entity != rsurface.texture->camera_entity)
13760 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, 1, &surface);
13762 if(rsurface.batchnumvertices == 0)
13765 for (vertexindex = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3;vertexindex < rsurface.batchnumvertices;vertexindex++, v += 3)
13767 Matrix4x4_Transform(&rsurface.matrix, v, vert);
13768 d += fabs(PlaneDiff(vert, &p->plane));
13770 if (bestd > d || bestplaneindex < 0)
13773 bestplaneindex = planeindex;
13776 return bestplaneindex;
13777 // NOTE: this MAY return a totally unrelated water plane; we can ignore
13778 // this situation though, as it might be better to render single larger
13779 // batches with useless stuff (backface culled for example) than to
13780 // render multiple smaller batches
13783 static void RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray(void)
13786 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13787 rsurface.passcolor4f_vertexbuffer = 0;
13788 rsurface.passcolor4f_bufferoffset = 0;
13789 for (i = 0;i < rsurface.batchnumvertices;i++)
13790 Vector4Set(rsurface.passcolor4f + 4*i, 0.5f, 0.5f, 0.5f, 1.0f);
13793 static void RSurf_DrawBatch_GL11_ApplyFog(void)
13800 if (rsurface.passcolor4f)
13802 // generate color arrays
13803 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13804 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13805 rsurface.passcolor4f_vertexbuffer = 0;
13806 rsurface.passcolor4f_bufferoffset = 0;
13807 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4, c2 += 4)
13809 f = RSurf_FogVertex(v);
13818 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13819 rsurface.passcolor4f_vertexbuffer = 0;
13820 rsurface.passcolor4f_bufferoffset = 0;
13821 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c2 += 4)
13823 f = RSurf_FogVertex(v);
13832 static void RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors(void)
13839 if (!rsurface.passcolor4f)
13841 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13842 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13843 rsurface.passcolor4f_vertexbuffer = 0;
13844 rsurface.passcolor4f_bufferoffset = 0;
13845 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4, c2 += 4)
13847 f = RSurf_FogVertex(v);
13848 c2[0] = c[0] * f + r_refdef.fogcolor[0] * (1 - f);
13849 c2[1] = c[1] * f + r_refdef.fogcolor[1] * (1 - f);
13850 c2[2] = c[2] * f + r_refdef.fogcolor[2] * (1 - f);
13855 static void RSurf_DrawBatch_GL11_ApplyColor(float r, float g, float b, float a)
13860 if (!rsurface.passcolor4f)
13862 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13863 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13864 rsurface.passcolor4f_vertexbuffer = 0;
13865 rsurface.passcolor4f_bufferoffset = 0;
13866 for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
13875 static void RSurf_DrawBatch_GL11_ApplyAmbient(void)
13880 if (!rsurface.passcolor4f)
13882 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13883 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13884 rsurface.passcolor4f_vertexbuffer = 0;
13885 rsurface.passcolor4f_bufferoffset = 0;
13886 for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
13888 c2[0] = c[0] + r_refdef.scene.ambient;
13889 c2[1] = c[1] + r_refdef.scene.ambient;
13890 c2[2] = c[2] + r_refdef.scene.ambient;
13895 static void RSurf_DrawBatch_GL11_Lightmap(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13898 rsurface.passcolor4f = NULL;
13899 rsurface.passcolor4f_vertexbuffer = 0;
13900 rsurface.passcolor4f_bufferoffset = 0;
13901 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
13902 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
13903 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
13904 GL_Color(r, g, b, a);
13905 R_Mesh_TexBind(0, rsurface.lightmaptexture);
13909 static void RSurf_DrawBatch_GL11_Unlit(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13911 // TODO: optimize applyfog && applycolor case
13912 // just apply fog if necessary, and tint the fog color array if necessary
13913 rsurface.passcolor4f = NULL;
13914 rsurface.passcolor4f_vertexbuffer = 0;
13915 rsurface.passcolor4f_bufferoffset = 0;
13916 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
13917 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
13918 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
13919 GL_Color(r, g, b, a);
13923 static void RSurf_DrawBatch_GL11_VertexColor(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13926 rsurface.passcolor4f = rsurface.batchlightmapcolor4f;
13927 rsurface.passcolor4f_vertexbuffer = rsurface.batchlightmapcolor4f_vertexbuffer;
13928 rsurface.passcolor4f_bufferoffset = rsurface.batchlightmapcolor4f_bufferoffset;
13929 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
13930 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
13931 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
13932 GL_Color(r, g, b, a);
13936 static void RSurf_DrawBatch_GL11_ClampColor(void)
13941 if (!rsurface.passcolor4f)
13943 for (i = 0, c1 = rsurface.passcolor4f + 4*rsurface.batchfirstvertex, c2 = rsurface.passcolor4f + 4*rsurface.batchfirstvertex;i < rsurface.batchnumvertices;i++, c1 += 4, c2 += 4)
13945 c2[0] = bound(0.0f, c1[0], 1.0f);
13946 c2[1] = bound(0.0f, c1[1], 1.0f);
13947 c2[2] = bound(0.0f, c1[2], 1.0f);
13948 c2[3] = bound(0.0f, c1[3], 1.0f);
13952 static void RSurf_DrawBatch_GL11_ApplyFakeLight(void)
13962 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13963 rsurface.passcolor4f_vertexbuffer = 0;
13964 rsurface.passcolor4f_bufferoffset = 0;
13965 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, n = rsurface.batchnormal3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, n += 3, c += 4)
13967 f = -DotProduct(r_refdef.view.forward, n);
13969 f = f * 0.85 + 0.15; // work around so stuff won't get black
13970 f *= r_refdef.lightmapintensity;
13971 Vector4Set(c, f, f, f, 1);
13975 static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13977 RSurf_DrawBatch_GL11_ApplyFakeLight();
13978 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
13979 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
13980 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
13981 GL_Color(r, g, b, a);
13985 static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor)
13993 vec3_t ambientcolor;
13994 vec3_t diffusecolor;
13998 VectorCopy(rsurface.modellight_lightdir, lightdir);
13999 f = 0.5f * r_refdef.lightmapintensity;
14000 ambientcolor[0] = rsurface.modellight_ambient[0] * *r * f;
14001 ambientcolor[1] = rsurface.modellight_ambient[1] * *g * f;
14002 ambientcolor[2] = rsurface.modellight_ambient[2] * *b * f;
14003 diffusecolor[0] = rsurface.modellight_diffuse[0] * *r * f;
14004 diffusecolor[1] = rsurface.modellight_diffuse[1] * *g * f;
14005 diffusecolor[2] = rsurface.modellight_diffuse[2] * *b * f;
14007 if (VectorLength2(diffusecolor) > 0)
14009 // q3-style directional shading
14010 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
14011 rsurface.passcolor4f_vertexbuffer = 0;
14012 rsurface.passcolor4f_bufferoffset = 0;
14013 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, n = rsurface.batchnormal3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, n += 3, c += 4)
14015 if ((f = DotProduct(n, lightdir)) > 0)
14016 VectorMA(ambientcolor, f, diffusecolor, c);
14018 VectorCopy(ambientcolor, c);
14025 *applycolor = false;
14029 *r = ambientcolor[0];
14030 *g = ambientcolor[1];
14031 *b = ambientcolor[2];
14032 rsurface.passcolor4f = NULL;
14033 rsurface.passcolor4f_vertexbuffer = 0;
14034 rsurface.passcolor4f_bufferoffset = 0;
14038 static void RSurf_DrawBatch_GL11_VertexShade(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
14040 RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, &applycolor);
14041 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
14042 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
14043 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
14044 GL_Color(r, g, b, a);
14048 static void RSurf_DrawBatch_GL11_MakeFogColor(float r, float g, float b, float a)
14054 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4)
14056 f = 1 - RSurf_FogVertex(v);
14064 void RSurf_SetupDepthAndCulling(void)
14066 // submodels are biased to avoid z-fighting with world surfaces that they
14067 // may be exactly overlapping (avoids z-fighting artifacts on certain
14068 // doors and things in Quake maps)
14069 GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
14070 GL_PolygonOffset(rsurface.basepolygonfactor + rsurface.texture->biaspolygonfactor, rsurface.basepolygonoffset + rsurface.texture->biaspolygonoffset);
14071 GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
14072 GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_refdef.view.cullface_back);
14075 static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist)
14077 // transparent sky would be ridiculous
14078 if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
14080 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14081 skyrenderlater = true;
14082 RSurf_SetupDepthAndCulling();
14083 GL_DepthMask(true);
14084 // LordHavoc: HalfLife maps have freaky skypolys so don't use
14085 // skymasking on them, and Quake3 never did sky masking (unlike
14086 // software Quake and software Quake2), so disable the sky masking
14087 // in Quake3 maps as it causes problems with q3map2 sky tricks,
14088 // and skymasking also looks very bad when noclipping outside the
14089 // level, so don't use it then either.
14090 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis)
14092 R_Mesh_ResetTextureState();
14093 if (skyrendermasked)
14095 R_SetupShader_DepthOrShadow();
14096 // depth-only (masking)
14097 GL_ColorMask(0,0,0,0);
14098 // just to make sure that braindead drivers don't draw
14099 // anything despite that colormask...
14100 GL_BlendFunc(GL_ZERO, GL_ONE);
14101 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14102 if (rsurface.batchvertex3fbuffer)
14103 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
14105 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
14109 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14111 GL_BlendFunc(GL_ONE, GL_ZERO);
14112 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14113 GL_Color(r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], 1);
14114 R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
14117 if (skyrendermasked)
14118 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
14120 R_Mesh_ResetTextureState();
14121 GL_Color(1, 1, 1, 1);
14124 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
14125 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
14126 static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
14128 if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA)))
14132 // render screenspace normalmap to texture
14133 GL_DepthMask(true);
14134 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL);
14139 // bind lightmap texture
14141 // water/refraction/reflection/camera surfaces have to be handled specially
14142 if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA | MATERIALFLAG_REFLECTION)))
14144 int start, end, startplaneindex;
14145 for (start = 0;start < texturenumsurfaces;start = end)
14147 startplaneindex = RSurf_FindWaterPlaneForSurface(texturesurfacelist[start]);
14148 if(startplaneindex < 0)
14150 // this happens if the plane e.g. got backface culled and thus didn't get a water plane. We can just ignore this.
14151 // Con_Printf("No matching water plane for surface with material flags 0x%08x - PLEASE DEBUG THIS\n", rsurface.texture->currentmaterialflags);
14155 for (end = start + 1;end < texturenumsurfaces && startplaneindex == RSurf_FindWaterPlaneForSurface(texturesurfacelist[end]);end++)
14157 // now that we have a batch using the same planeindex, render it
14158 if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)))
14160 // render water or distortion background
14161 GL_DepthMask(true);
14162 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start, (void *)(r_waterstate.waterplanes + startplaneindex));
14164 // blend surface on top
14165 GL_DepthMask(false);
14166 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL);
14169 else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION))
14171 // render surface with reflection texture as input
14172 GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
14173 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, (void *)(r_waterstate.waterplanes + startplaneindex));
14180 // render surface batch normally
14181 GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
14182 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL);
14186 static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)
14188 // OpenGL 1.3 path - anything not completely ancient
14189 qboolean applycolor;
14192 const texturelayer_t *layer;
14193 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14194 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
14196 for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++)
14199 int layertexrgbscale;
14200 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14202 if (layerindex == 0)
14203 GL_AlphaTest(true);
14206 GL_AlphaTest(false);
14207 GL_DepthFunc(GL_EQUAL);
14210 GL_DepthMask(layer->depthmask && writedepth);
14211 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
14212 if (layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2)
14214 layertexrgbscale = 4;
14215 VectorScale(layer->color, 0.25f, layercolor);
14217 else if (layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1)
14219 layertexrgbscale = 2;
14220 VectorScale(layer->color, 0.5f, layercolor);
14224 layertexrgbscale = 1;
14225 VectorScale(layer->color, 1.0f, layercolor);
14227 layercolor[3] = layer->color[3];
14228 applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
14229 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, 0, 0);
14230 applyfog = r_refdef.fogenabled && (rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED);
14231 switch (layer->type)
14233 case TEXTURELAYERTYPE_LITTEXTURE:
14234 // single-pass lightmapped texture with 2x rgbscale
14235 R_Mesh_TexBind(0, r_texture_white);
14236 R_Mesh_TexMatrix(0, NULL);
14237 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14238 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
14239 R_Mesh_TexBind(1, layer->texture);
14240 R_Mesh_TexMatrix(1, &layer->texmatrix);
14241 R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
14242 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14243 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14244 RSurf_DrawBatch_GL11_VertexShade(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14245 else if (FAKELIGHT_ENABLED)
14246 RSurf_DrawBatch_GL11_FakeLight(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14247 else if (rsurface.uselightmaptexture)
14248 RSurf_DrawBatch_GL11_Lightmap(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14250 RSurf_DrawBatch_GL11_VertexColor(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14252 case TEXTURELAYERTYPE_TEXTURE:
14253 // singletexture unlit texture with transparency support
14254 R_Mesh_TexBind(0, layer->texture);
14255 R_Mesh_TexMatrix(0, &layer->texmatrix);
14256 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
14257 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14258 R_Mesh_TexBind(1, 0);
14259 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14260 RSurf_DrawBatch_GL11_Unlit(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14262 case TEXTURELAYERTYPE_FOG:
14263 // singletexture fogging
14264 if (layer->texture)
14266 R_Mesh_TexBind(0, layer->texture);
14267 R_Mesh_TexMatrix(0, &layer->texmatrix);
14268 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
14269 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14273 R_Mesh_TexBind(0, 0);
14274 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14276 R_Mesh_TexBind(1, 0);
14277 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14278 // generate a color array for the fog pass
14279 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
14280 RSurf_DrawBatch_GL11_MakeFogColor(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
14284 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
14287 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14289 GL_DepthFunc(GL_LEQUAL);
14290 GL_AlphaTest(false);
14294 static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)
14296 // OpenGL 1.1 - crusty old voodoo path
14299 const texturelayer_t *layer;
14300 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | ((!rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.modeltexcoordlightmap2f ? BATCHNEED_ARRAY_LIGHTMAP : 0) | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14301 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
14303 for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++)
14305 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14307 if (layerindex == 0)
14308 GL_AlphaTest(true);
14311 GL_AlphaTest(false);
14312 GL_DepthFunc(GL_EQUAL);
14315 GL_DepthMask(layer->depthmask && writedepth);
14316 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
14317 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, 0, 0);
14318 applyfog = r_refdef.fogenabled && (rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED);
14319 switch (layer->type)
14321 case TEXTURELAYERTYPE_LITTEXTURE:
14322 if (layer->blendfunc1 == GL_ONE && layer->blendfunc2 == GL_ZERO)
14324 // two-pass lit texture with 2x rgbscale
14325 // first the lightmap pass
14326 R_Mesh_TexBind(0, r_texture_white);
14327 R_Mesh_TexMatrix(0, NULL);
14328 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14329 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
14330 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14331 RSurf_DrawBatch_GL11_VertexShade(1, 1, 1, 1, false, false);
14332 else if (FAKELIGHT_ENABLED)
14333 RSurf_DrawBatch_GL11_FakeLight(1, 1, 1, 1, false, false);
14334 else if (rsurface.uselightmaptexture)
14335 RSurf_DrawBatch_GL11_Lightmap(1, 1, 1, 1, false, false);
14337 RSurf_DrawBatch_GL11_VertexColor(1, 1, 1, 1, false, false);
14338 // then apply the texture to it
14339 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
14340 R_Mesh_TexBind(0, layer->texture);
14341 R_Mesh_TexMatrix(0, &layer->texmatrix);
14342 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14343 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14344 RSurf_DrawBatch_GL11_Unlit(layer->color[0] * 0.5f, layer->color[1] * 0.5f, layer->color[2] * 0.5f, layer->color[3], layer->color[0] != 2 || layer->color[1] != 2 || layer->color[2] != 2 || layer->color[3] != 1, false);
14348 // single pass vertex-lighting-only texture with 1x rgbscale and transparency support
14349 R_Mesh_TexBind(0, layer->texture);
14350 R_Mesh_TexMatrix(0, &layer->texmatrix);
14351 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14352 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14353 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14354 RSurf_DrawBatch_GL11_VertexShade(layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
14356 RSurf_DrawBatch_GL11_VertexColor(layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
14359 case TEXTURELAYERTYPE_TEXTURE:
14360 // singletexture unlit texture with transparency support
14361 R_Mesh_TexBind(0, layer->texture);
14362 R_Mesh_TexMatrix(0, &layer->texmatrix);
14363 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14364 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14365 RSurf_DrawBatch_GL11_Unlit(layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
14367 case TEXTURELAYERTYPE_FOG:
14368 // singletexture fogging
14369 if (layer->texture)
14371 R_Mesh_TexBind(0, layer->texture);
14372 R_Mesh_TexMatrix(0, &layer->texmatrix);
14373 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14374 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14378 R_Mesh_TexBind(0, 0);
14379 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14381 // generate a color array for the fog pass
14382 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
14383 RSurf_DrawBatch_GL11_MakeFogColor(layer->color[0], layer->color[1], layer->color[2], layer->color[3]);
14387 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
14390 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14392 GL_DepthFunc(GL_LEQUAL);
14393 GL_AlphaTest(false);
14397 static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)
14401 r_vertexgeneric_t *batchvertex;
14404 GL_AlphaTest(false);
14405 // R_Mesh_ResetTextureState();
14406 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14408 if(rsurface.texture && rsurface.texture->currentskinframe)
14410 memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c));
14411 c[3] *= rsurface.texture->currentalpha;
14421 if (rsurface.texture->pantstexture || rsurface.texture->shirttexture)
14423 c[0] = 0.5 * (rsurface.colormap_pantscolor[0] * 0.3 + rsurface.colormap_shirtcolor[0] * 0.7);
14424 c[1] = 0.5 * (rsurface.colormap_pantscolor[1] * 0.3 + rsurface.colormap_shirtcolor[1] * 0.7);
14425 c[2] = 0.5 * (rsurface.colormap_pantscolor[2] * 0.3 + rsurface.colormap_shirtcolor[2] * 0.7);
14428 // brighten it up (as texture value 127 means "unlit")
14429 c[0] *= 2 * r_refdef.view.colorscale;
14430 c[1] *= 2 * r_refdef.view.colorscale;
14431 c[2] *= 2 * r_refdef.view.colorscale;
14433 if(rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA)
14434 c[3] *= r_wateralpha.value;
14436 if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1)
14438 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
14439 GL_DepthMask(false);
14441 else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
14443 GL_BlendFunc(GL_ONE, GL_ONE);
14444 GL_DepthMask(false);
14446 else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14448 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // can't do alpha test without texture, so let's blend instead
14449 GL_DepthMask(false);
14451 else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
14453 GL_BlendFunc(rsurface.texture->customblendfunc[0], rsurface.texture->customblendfunc[1]);
14454 GL_DepthMask(false);
14458 GL_BlendFunc(GL_ONE, GL_ZERO);
14459 GL_DepthMask(writedepth);
14462 if (r_showsurfaces.integer == 3)
14464 rsurface.passcolor4f = NULL;
14466 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
14468 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14470 rsurface.passcolor4f = NULL;
14471 rsurface.passcolor4f_vertexbuffer = 0;
14472 rsurface.passcolor4f_bufferoffset = 0;
14474 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14476 qboolean applycolor = true;
14479 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14481 r_refdef.lightmapintensity = 1;
14482 RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor);
14483 r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
14485 else if (FAKELIGHT_ENABLED)
14487 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14489 r_refdef.lightmapintensity = r_fakelight_intensity.value;
14490 RSurf_DrawBatch_GL11_ApplyFakeLight();
14491 r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
14495 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14497 rsurface.passcolor4f = rsurface.batchlightmapcolor4f;
14498 rsurface.passcolor4f_vertexbuffer = rsurface.batchlightmapcolor4f_vertexbuffer;
14499 rsurface.passcolor4f_bufferoffset = rsurface.batchlightmapcolor4f_bufferoffset;
14502 if(!rsurface.passcolor4f)
14503 RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray();
14505 RSurf_DrawBatch_GL11_ApplyAmbient();
14506 RSurf_DrawBatch_GL11_ApplyColor(c[0], c[1], c[2], c[3]);
14507 if(r_refdef.fogenabled)
14508 RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors();
14509 RSurf_DrawBatch_GL11_ClampColor();
14511 R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.passcolor4f, NULL);
14512 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14515 else if (!r_refdef.view.showdebug)
14517 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14518 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchnumvertices);
14519 for (j = 0, vi = rsurface.batchfirstvertex;j < rsurface.batchnumvertices;j++, vi++)
14521 VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
14522 Vector4Set(batchvertex[vi].color4ub, 0, 0, 0, 255);
14524 R_Mesh_PrepareVertices_Generic_Unlock();
14527 else if (r_showsurfaces.integer == 4)
14529 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14530 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchnumvertices);
14531 for (j = 0, vi = rsurface.batchfirstvertex;j < rsurface.batchnumvertices;j++, vi++)
14533 unsigned char c = vi << 3;
14534 VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
14535 Vector4Set(batchvertex[vi].color4ub, c, c, c, 255);
14537 R_Mesh_PrepareVertices_Generic_Unlock();
14540 else if (r_showsurfaces.integer == 2)
14543 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14544 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(3*rsurface.batchnumtriangles);
14545 for (j = 0, e = rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle;j < rsurface.batchnumtriangles;j++, e += 3)
14547 unsigned char c = (j + rsurface.batchfirsttriangle) << 3;
14548 VectorCopy(rsurface.batchvertex3f + 3*e[0], batchvertex[j*3+0].vertex3f);
14549 VectorCopy(rsurface.batchvertex3f + 3*e[1], batchvertex[j*3+1].vertex3f);
14550 VectorCopy(rsurface.batchvertex3f + 3*e[2], batchvertex[j*3+2].vertex3f);
14551 Vector4Set(batchvertex[j*3+0].color4ub, c, c, c, 255);
14552 Vector4Set(batchvertex[j*3+1].color4ub, c, c, c, 255);
14553 Vector4Set(batchvertex[j*3+2].color4ub, c, c, c, 255);
14555 R_Mesh_PrepareVertices_Generic_Unlock();
14556 R_Mesh_Draw(0, rsurface.batchnumtriangles*3, 0, rsurface.batchnumtriangles, NULL, NULL, 0, NULL, NULL, 0);
14560 int texturesurfaceindex;
14562 const msurface_t *surface;
14563 unsigned char surfacecolor4ub[4];
14564 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14565 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchfirstvertex + rsurface.batchnumvertices);
14567 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
14569 surface = texturesurfacelist[texturesurfaceindex];
14570 k = (int)(((size_t)surface) / sizeof(msurface_t));
14571 Vector4Set(surfacecolor4ub, (k & 0xF) << 4, (k & 0xF0), (k & 0xF00) >> 4, 255);
14572 for (j = 0;j < surface->num_vertices;j++)
14574 VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
14575 Vector4Copy(surfacecolor4ub, batchvertex[vi].color4ub);
14579 R_Mesh_PrepareVertices_Generic_Unlock();
14584 static void R_DrawWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
14587 RSurf_SetupDepthAndCulling();
14588 if (r_showsurfaces.integer)
14590 R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist, writedepth);
14593 switch (vid.renderpath)
14595 case RENDERPATH_GL20:
14596 case RENDERPATH_CGGL:
14597 case RENDERPATH_D3D9:
14598 case RENDERPATH_D3D10:
14599 case RENDERPATH_D3D11:
14600 case RENDERPATH_SOFT:
14601 case RENDERPATH_GLES2:
14602 R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14604 case RENDERPATH_GL13:
14605 R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth);
14607 case RENDERPATH_GL11:
14608 R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist, writedepth);
14614 static void R_DrawModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
14617 RSurf_SetupDepthAndCulling();
14618 if (r_showsurfaces.integer)
14620 R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist, writedepth);
14623 switch (vid.renderpath)
14625 case RENDERPATH_GL20:
14626 case RENDERPATH_CGGL:
14627 case RENDERPATH_D3D9:
14628 case RENDERPATH_D3D10:
14629 case RENDERPATH_D3D11:
14630 case RENDERPATH_SOFT:
14631 case RENDERPATH_GLES2:
14632 R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14634 case RENDERPATH_GL13:
14635 R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth);
14637 case RENDERPATH_GL11:
14638 R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist, writedepth);
14644 static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
14647 int texturenumsurfaces, endsurface;
14648 texture_t *texture;
14649 const msurface_t *surface;
14650 #define MAXBATCH_TRANSPARENTSURFACES 256
14651 const msurface_t *texturesurfacelist[MAXBATCH_TRANSPARENTSURFACES];
14653 // if the model is static it doesn't matter what value we give for
14654 // wantnormals and wanttangents, so this logic uses only rules applicable
14655 // to a model, knowing that they are meaningless otherwise
14656 if (ent == r_refdef.scene.worldentity)
14657 RSurf_ActiveWorldEntity();
14658 else if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
14659 RSurf_ActiveModelEntity(ent, false, false, false);
14662 switch (vid.renderpath)
14664 case RENDERPATH_GL20:
14665 case RENDERPATH_CGGL:
14666 case RENDERPATH_D3D9:
14667 case RENDERPATH_D3D10:
14668 case RENDERPATH_D3D11:
14669 case RENDERPATH_SOFT:
14670 case RENDERPATH_GLES2:
14671 RSurf_ActiveModelEntity(ent, true, true, false);
14673 case RENDERPATH_GL13:
14674 case RENDERPATH_GL11:
14675 RSurf_ActiveModelEntity(ent, true, false, false);
14680 if (r_transparentdepthmasking.integer)
14682 qboolean setup = false;
14683 for (i = 0;i < numsurfaces;i = j)
14686 surface = rsurface.modelsurfaces + surfacelist[i];
14687 texture = surface->texture;
14688 rsurface.texture = R_GetCurrentTexture(texture);
14689 rsurface.lightmaptexture = NULL;
14690 rsurface.deluxemaptexture = NULL;
14691 rsurface.uselightmaptexture = false;
14692 // scan ahead until we find a different texture
14693 endsurface = min(i + 1024, numsurfaces);
14694 texturenumsurfaces = 0;
14695 texturesurfacelist[texturenumsurfaces++] = surface;
14696 for (;j < endsurface;j++)
14698 surface = rsurface.modelsurfaces + surfacelist[j];
14699 if (texture != surface->texture)
14701 texturesurfacelist[texturenumsurfaces++] = surface;
14703 if (!(rsurface.texture->currentmaterialflags & MATERIALFLAG_TRANSDEPTH))
14705 // render the range of surfaces as depth
14709 GL_ColorMask(0,0,0,0);
14711 GL_DepthTest(true);
14712 GL_BlendFunc(GL_ONE, GL_ZERO);
14713 GL_DepthMask(true);
14714 GL_AlphaTest(false);
14715 // R_Mesh_ResetTextureState();
14716 R_SetupShader_DepthOrShadow();
14718 RSurf_SetupDepthAndCulling();
14719 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
14720 if (rsurface.batchvertex3fbuffer)
14721 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
14723 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
14727 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
14730 for (i = 0;i < numsurfaces;i = j)
14733 surface = rsurface.modelsurfaces + surfacelist[i];
14734 texture = surface->texture;
14735 rsurface.texture = R_GetCurrentTexture(texture);
14736 // scan ahead until we find a different texture
14737 endsurface = min(i + MAXBATCH_TRANSPARENTSURFACES, numsurfaces);
14738 texturenumsurfaces = 0;
14739 texturesurfacelist[texturenumsurfaces++] = surface;
14740 if(FAKELIGHT_ENABLED)
14742 rsurface.lightmaptexture = NULL;
14743 rsurface.deluxemaptexture = NULL;
14744 rsurface.uselightmaptexture = false;
14745 for (;j < endsurface;j++)
14747 surface = rsurface.modelsurfaces + surfacelist[j];
14748 if (texture != surface->texture)
14750 texturesurfacelist[texturenumsurfaces++] = surface;
14755 rsurface.lightmaptexture = surface->lightmaptexture;
14756 rsurface.deluxemaptexture = surface->deluxemaptexture;
14757 rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
14758 for (;j < endsurface;j++)
14760 surface = rsurface.modelsurfaces + surfacelist[j];
14761 if (texture != surface->texture || rsurface.lightmaptexture != surface->lightmaptexture)
14763 texturesurfacelist[texturenumsurfaces++] = surface;
14766 // render the range of surfaces
14767 if (ent == r_refdef.scene.worldentity)
14768 R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
14770 R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
14772 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
14773 GL_AlphaTest(false);
14776 static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, const entity_render_t *queueentity)
14778 // transparent surfaces get pushed off into the transparent queue
14779 int surfacelistindex;
14780 const msurface_t *surface;
14781 vec3_t tempcenter, center;
14782 for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++)
14784 surface = texturesurfacelist[surfacelistindex];
14785 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
14786 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
14787 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
14788 Matrix4x4_Transform(&rsurface.matrix, tempcenter, center);
14789 if (queueentity->transparent_offset) // transparent offset
14791 center[0] += r_refdef.view.forward[0]*queueentity->transparent_offset;
14792 center[1] += r_refdef.view.forward[1]*queueentity->transparent_offset;
14793 center[2] += r_refdef.view.forward[2]*queueentity->transparent_offset;
14795 R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight);
14799 static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msurface_t **texturesurfacelist)
14801 if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHATEST)))
14803 if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION)))
14805 RSurf_SetupDepthAndCulling();
14806 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
14807 if (rsurface.batchvertex3fbuffer)
14808 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
14810 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
14814 static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
14816 const entity_render_t *queueentity = r_refdef.scene.worldentity;
14819 R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist);
14822 if (!rsurface.texture->currentnumlayers)
14824 if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
14825 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14827 R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14829 else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer)
14830 R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
14831 else if (!rsurface.texture->currentnumlayers)
14833 else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
14835 // in the deferred case, transparent surfaces were queued during prepass
14836 if (!r_shadow_usingdeferredprepass)
14837 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14841 // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier
14842 R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST), prepass);
14847 void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
14850 texture_t *texture;
14851 R_FrameData_SetMark();
14852 // break the surface list down into batches by texture and use of lightmapping
14853 for (i = 0;i < numsurfaces;i = j)
14856 // texture is the base texture pointer, rsurface.texture is the
14857 // current frame/skin the texture is directing us to use (for example
14858 // if a model has 2 skins and it is on skin 1, then skin 0 tells us to
14859 // use skin 1 instead)
14860 texture = surfacelist[i]->texture;
14861 rsurface.texture = R_GetCurrentTexture(texture);
14862 if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
14864 // if this texture is not the kind we want, skip ahead to the next one
14865 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14869 if(FAKELIGHT_ENABLED || depthonly || prepass)
14871 rsurface.lightmaptexture = NULL;
14872 rsurface.deluxemaptexture = NULL;
14873 rsurface.uselightmaptexture = false;
14874 // simply scan ahead until we find a different texture or lightmap state
14875 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14880 rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
14881 rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
14882 rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL;
14883 // simply scan ahead until we find a different texture or lightmap state
14884 for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
14887 // render the range of surfaces
14888 R_ProcessWorldTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass);
14890 R_FrameData_ReturnToMark();
14893 static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, const entity_render_t *queueentity, qboolean prepass)
14897 R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist);
14900 if (!rsurface.texture->currentnumlayers)
14902 if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
14903 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14905 R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14907 else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer)
14908 R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
14909 else if (!rsurface.texture->currentnumlayers)
14911 else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
14913 // in the deferred case, transparent surfaces were queued during prepass
14914 if (!r_shadow_usingdeferredprepass)
14915 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14919 // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier
14920 R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST), prepass);
14925 void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
14928 texture_t *texture;
14929 R_FrameData_SetMark();
14930 // break the surface list down into batches by texture and use of lightmapping
14931 for (i = 0;i < numsurfaces;i = j)
14934 // texture is the base texture pointer, rsurface.texture is the
14935 // current frame/skin the texture is directing us to use (for example
14936 // if a model has 2 skins and it is on skin 1, then skin 0 tells us to
14937 // use skin 1 instead)
14938 texture = surfacelist[i]->texture;
14939 rsurface.texture = R_GetCurrentTexture(texture);
14940 if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
14942 // if this texture is not the kind we want, skip ahead to the next one
14943 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14947 if(FAKELIGHT_ENABLED || depthonly || prepass)
14949 rsurface.lightmaptexture = NULL;
14950 rsurface.deluxemaptexture = NULL;
14951 rsurface.uselightmaptexture = false;
14952 // simply scan ahead until we find a different texture or lightmap state
14953 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14958 rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
14959 rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
14960 rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL;
14961 // simply scan ahead until we find a different texture or lightmap state
14962 for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
14965 // render the range of surfaces
14966 R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, ent, prepass);
14968 R_FrameData_ReturnToMark();
14971 float locboxvertex3f[6*4*3] =
14973 1,0,1, 1,0,0, 1,1,0, 1,1,1,
14974 0,1,1, 0,1,0, 0,0,0, 0,0,1,
14975 1,1,1, 1,1,0, 0,1,0, 0,1,1,
14976 0,0,1, 0,0,0, 1,0,0, 1,0,1,
14977 0,0,1, 1,0,1, 1,1,1, 0,1,1,
14978 1,0,0, 0,0,0, 0,1,0, 1,1,0
14981 unsigned short locboxelements[6*2*3] =
14986 12,13,14, 12,14,15,
14987 16,17,18, 16,18,19,
14991 void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
14994 cl_locnode_t *loc = (cl_locnode_t *)ent;
14996 float vertex3f[6*4*3];
14998 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
14999 GL_DepthMask(false);
15000 GL_DepthRange(0, 1);
15001 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
15002 GL_DepthTest(true);
15003 GL_CullFace(GL_NONE);
15004 R_EntityMatrix(&identitymatrix);
15006 // R_Mesh_ResetTextureState();
15008 i = surfacelist[0];
15009 GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_refdef.view.colorscale,
15010 ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_refdef.view.colorscale,
15011 ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_refdef.view.colorscale,
15012 surfacelist[0] < 0 ? 0.5f : 0.125f);
15014 if (VectorCompare(loc->mins, loc->maxs))
15016 VectorSet(size, 2, 2, 2);
15017 VectorMA(loc->mins, -0.5f, size, mins);
15021 VectorCopy(loc->mins, mins);
15022 VectorSubtract(loc->maxs, loc->mins, size);
15025 for (i = 0;i < 6*4*3;)
15026 for (j = 0;j < 3;j++, i++)
15027 vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i];
15029 R_Mesh_PrepareVertices_Generic_Arrays(6*4, vertex3f, NULL, NULL);
15030 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
15031 R_Mesh_Draw(0, 6*4, 0, 6*2, NULL, NULL, 0, locboxelements, NULL, 0);
15034 void R_DrawLocs(void)
15037 cl_locnode_t *loc, *nearestloc;
15039 nearestloc = CL_Locs_FindNearest(cl.movement_origin);
15040 for (loc = cl.locnodes, index = 0;loc;loc = loc->next, index++)
15042 VectorLerp(loc->mins, 0.5f, loc->maxs, center);
15043 R_MeshQueue_AddTransparent(center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL);
15047 void R_DecalSystem_Reset(decalsystem_t *decalsystem)
15049 if (decalsystem->decals)
15050 Mem_Free(decalsystem->decals);
15051 memset(decalsystem, 0, sizeof(*decalsystem));
15054 static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float *v0, const float *v1, const float *v2, const float *t0, const float *t1, const float *t2, const float *c0, const float *c1, const float *c2, int triangleindex, int surfaceindex, int decalsequence)
15057 tridecal_t *decals;
15060 // expand or initialize the system
15061 if (decalsystem->maxdecals <= decalsystem->numdecals)
15063 decalsystem_t old = *decalsystem;
15064 qboolean useshortelements;
15065 decalsystem->maxdecals = max(16, decalsystem->maxdecals * 2);
15066 useshortelements = decalsystem->maxdecals * 3 <= 65536;
15067 decalsystem->decals = (tridecal_t *)Mem_Alloc(cls.levelmempool, decalsystem->maxdecals * (sizeof(tridecal_t) + sizeof(float[3][3]) + sizeof(float[3][2]) + sizeof(float[3][4]) + sizeof(int[3]) + (useshortelements ? sizeof(unsigned short[3]) : 0)));
15068 decalsystem->color4f = (float *)(decalsystem->decals + decalsystem->maxdecals);
15069 decalsystem->texcoord2f = (float *)(decalsystem->color4f + decalsystem->maxdecals*12);
15070 decalsystem->vertex3f = (float *)(decalsystem->texcoord2f + decalsystem->maxdecals*6);
15071 decalsystem->element3i = (int *)(decalsystem->vertex3f + decalsystem->maxdecals*9);
15072 decalsystem->element3s = (useshortelements ? ((unsigned short *)(decalsystem->element3i + decalsystem->maxdecals*3)) : NULL);
15073 if (decalsystem->numdecals)
15074 memcpy(decalsystem->decals, old.decals, decalsystem->numdecals * sizeof(tridecal_t));
15076 Mem_Free(old.decals);
15077 for (i = 0;i < decalsystem->maxdecals*3;i++)
15078 decalsystem->element3i[i] = i;
15079 if (useshortelements)
15080 for (i = 0;i < decalsystem->maxdecals*3;i++)
15081 decalsystem->element3s[i] = i;
15084 // grab a decal and search for another free slot for the next one
15085 decals = decalsystem->decals;
15086 decal = decalsystem->decals + (i = decalsystem->freedecal++);
15087 for (i = decalsystem->freedecal;i < decalsystem->numdecals && decals[i].color4ub[0][3];i++)
15089 decalsystem->freedecal = i;
15090 if (decalsystem->numdecals <= i)
15091 decalsystem->numdecals = i + 1;
15093 // initialize the decal
15095 decal->triangleindex = triangleindex;
15096 decal->surfaceindex = surfaceindex;
15097 decal->decalsequence = decalsequence;
15098 decal->color4ub[0][0] = (unsigned char)(c0[0]*255.0f);
15099 decal->color4ub[0][1] = (unsigned char)(c0[1]*255.0f);
15100 decal->color4ub[0][2] = (unsigned char)(c0[2]*255.0f);
15101 decal->color4ub[0][3] = 255;
15102 decal->color4ub[1][0] = (unsigned char)(c1[0]*255.0f);
15103 decal->color4ub[1][1] = (unsigned char)(c1[1]*255.0f);
15104 decal->color4ub[1][2] = (unsigned char)(c1[2]*255.0f);
15105 decal->color4ub[1][3] = 255;
15106 decal->color4ub[2][0] = (unsigned char)(c2[0]*255.0f);
15107 decal->color4ub[2][1] = (unsigned char)(c2[1]*255.0f);
15108 decal->color4ub[2][2] = (unsigned char)(c2[2]*255.0f);
15109 decal->color4ub[2][3] = 255;
15110 decal->vertex3f[0][0] = v0[0];
15111 decal->vertex3f[0][1] = v0[1];
15112 decal->vertex3f[0][2] = v0[2];
15113 decal->vertex3f[1][0] = v1[0];
15114 decal->vertex3f[1][1] = v1[1];
15115 decal->vertex3f[1][2] = v1[2];
15116 decal->vertex3f[2][0] = v2[0];
15117 decal->vertex3f[2][1] = v2[1];
15118 decal->vertex3f[2][2] = v2[2];
15119 decal->texcoord2f[0][0] = t0[0];
15120 decal->texcoord2f[0][1] = t0[1];
15121 decal->texcoord2f[1][0] = t1[0];
15122 decal->texcoord2f[1][1] = t1[1];
15123 decal->texcoord2f[2][0] = t2[0];
15124 decal->texcoord2f[2][1] = t2[1];
15127 extern cvar_t cl_decals_bias;
15128 extern cvar_t cl_decals_models;
15129 extern cvar_t cl_decals_newsystem_intensitymultiplier;
15130 // baseparms, parms, temps
15131 static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, int decalsequence, qboolean dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex)
15136 const float *vertex3f;
15138 float points[2][9][3];
15145 e = rsurface.modelelement3i + 3*triangleindex;
15147 vertex3f = rsurface.modelvertex3f;
15149 for (cornerindex = 0;cornerindex < 3;cornerindex++)
15151 index = 3*e[cornerindex];
15152 VectorCopy(vertex3f + index, v[cornerindex]);
15155 //TriangleNormal(v[0], v[1], v[2], normal);
15156 //if (DotProduct(normal, localnormal) < 0.0f)
15158 // clip by each of the box planes formed from the projection matrix
15159 // if anything survives, we emit the decal
15160 numpoints = PolygonF_Clip(3 , v[0] , planes[0][0], planes[0][1], planes[0][2], planes[0][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
15163 numpoints = PolygonF_Clip(numpoints, points[1][0], planes[1][0], planes[1][1], planes[1][2], planes[1][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
15166 numpoints = PolygonF_Clip(numpoints, points[0][0], planes[2][0], planes[2][1], planes[2][2], planes[2][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
15169 numpoints = PolygonF_Clip(numpoints, points[1][0], planes[3][0], planes[3][1], planes[3][2], planes[3][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
15172 numpoints = PolygonF_Clip(numpoints, points[0][0], planes[4][0], planes[4][1], planes[4][2], planes[4][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
15175 numpoints = PolygonF_Clip(numpoints, points[1][0], planes[5][0], planes[5][1], planes[5][2], planes[5][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), v[0]);
15178 // some part of the triangle survived, so we have to accept it...
15181 // dynamic always uses the original triangle
15183 for (cornerindex = 0;cornerindex < 3;cornerindex++)
15185 index = 3*e[cornerindex];
15186 VectorCopy(vertex3f + index, v[cornerindex]);
15189 for (cornerindex = 0;cornerindex < numpoints;cornerindex++)
15191 // convert vertex positions to texcoords
15192 Matrix4x4_Transform(projection, v[cornerindex], temp);
15193 tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
15194 tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
15195 // calculate distance fade from the projection origin
15196 f = a * (1.0f-fabs(temp[0])) * cl_decals_newsystem_intensitymultiplier.value;
15197 f = bound(0.0f, f, 1.0f);
15198 c[cornerindex][0] = r * f;
15199 c[cornerindex][1] = g * f;
15200 c[cornerindex][2] = b * f;
15201 c[cornerindex][3] = 1.0f;
15202 //VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
15205 R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[1], v[2], tc[0], tc[1], tc[2], c[0], c[1], c[2], triangleindex, surfaceindex, decalsequence);
15207 for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
15208 R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence);
15210 static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence)
15212 matrix4x4_t projection;
15213 decalsystem_t *decalsystem;
15216 const msurface_t *surface;
15217 const msurface_t *surfaces;
15218 const int *surfacelist;
15219 const texture_t *texture;
15221 int numsurfacelist;
15222 int surfacelistindex;
15225 float localorigin[3];
15226 float localnormal[3];
15227 float localmins[3];
15228 float localmaxs[3];
15231 float planes[6][4];
15234 int bih_triangles_count;
15235 int bih_triangles[256];
15236 int bih_surfaces[256];
15238 decalsystem = &ent->decalsystem;
15239 model = ent->model;
15240 if (!model || !ent->allowdecals || ent->alpha < 1 || (ent->flags & (RENDER_ADDITIVE | RENDER_NODEPTHTEST)))
15242 R_DecalSystem_Reset(&ent->decalsystem);
15246 if (!model->brush.data_leafs && !cl_decals_models.integer)
15248 if (decalsystem->model)
15249 R_DecalSystem_Reset(decalsystem);
15253 if (decalsystem->model != model)
15254 R_DecalSystem_Reset(decalsystem);
15255 decalsystem->model = model;
15257 RSurf_ActiveModelEntity(ent, false, false, false);
15259 Matrix4x4_Transform(&rsurface.inversematrix, worldorigin, localorigin);
15260 Matrix4x4_Transform3x3(&rsurface.inversematrix, worldnormal, localnormal);
15261 VectorNormalize(localnormal);
15262 localsize = worldsize*rsurface.inversematrixscale;
15263 localmins[0] = localorigin[0] - localsize;
15264 localmins[1] = localorigin[1] - localsize;
15265 localmins[2] = localorigin[2] - localsize;
15266 localmaxs[0] = localorigin[0] + localsize;
15267 localmaxs[1] = localorigin[1] + localsize;
15268 localmaxs[2] = localorigin[2] + localsize;
15270 //VectorCopy(localnormal, planes[4]);
15271 //VectorVectors(planes[4], planes[2], planes[0]);
15272 AnglesFromVectors(angles, localnormal, NULL, false);
15273 AngleVectors(angles, planes[0], planes[2], planes[4]);
15274 VectorNegate(planes[0], planes[1]);
15275 VectorNegate(planes[2], planes[3]);
15276 VectorNegate(planes[4], planes[5]);
15277 planes[0][3] = DotProduct(planes[0], localorigin) - localsize;
15278 planes[1][3] = DotProduct(planes[1], localorigin) - localsize;
15279 planes[2][3] = DotProduct(planes[2], localorigin) - localsize;
15280 planes[3][3] = DotProduct(planes[3], localorigin) - localsize;
15281 planes[4][3] = DotProduct(planes[4], localorigin) - localsize;
15282 planes[5][3] = DotProduct(planes[5], localorigin) - localsize;
15287 matrix4x4_t forwardprojection;
15288 Matrix4x4_CreateFromQuakeEntity(&forwardprojection, localorigin[0], localorigin[1], localorigin[2], angles[0], angles[1], angles[2], localsize);
15289 Matrix4x4_Invert_Simple(&projection, &forwardprojection);
15294 float projectionvector[4][3];
15295 VectorScale(planes[0], ilocalsize, projectionvector[0]);
15296 VectorScale(planes[2], ilocalsize, projectionvector[1]);
15297 VectorScale(planes[4], ilocalsize, projectionvector[2]);
15298 projectionvector[0][0] = planes[0][0] * ilocalsize;
15299 projectionvector[0][1] = planes[1][0] * ilocalsize;
15300 projectionvector[0][2] = planes[2][0] * ilocalsize;
15301 projectionvector[1][0] = planes[0][1] * ilocalsize;
15302 projectionvector[1][1] = planes[1][1] * ilocalsize;
15303 projectionvector[1][2] = planes[2][1] * ilocalsize;
15304 projectionvector[2][0] = planes[0][2] * ilocalsize;
15305 projectionvector[2][1] = planes[1][2] * ilocalsize;
15306 projectionvector[2][2] = planes[2][2] * ilocalsize;
15307 projectionvector[3][0] = -(localorigin[0]*projectionvector[0][0]+localorigin[1]*projectionvector[1][0]+localorigin[2]*projectionvector[2][0]);
15308 projectionvector[3][1] = -(localorigin[0]*projectionvector[0][1]+localorigin[1]*projectionvector[1][1]+localorigin[2]*projectionvector[2][1]);
15309 projectionvector[3][2] = -(localorigin[0]*projectionvector[0][2]+localorigin[1]*projectionvector[1][2]+localorigin[2]*projectionvector[2][2]);
15310 Matrix4x4_FromVectors(&projection, projectionvector[0], projectionvector[1], projectionvector[2], projectionvector[3]);
15314 dynamic = model->surfmesh.isanimated;
15315 numsurfacelist = model->nummodelsurfaces;
15316 surfacelist = model->sortedmodelsurfaces;
15317 surfaces = model->data_surfaces;
15320 bih_triangles_count = -1;
15323 if(model->render_bih.numleafs)
15324 bih = &model->render_bih;
15325 else if(model->collision_bih.numleafs)
15326 bih = &model->collision_bih;
15329 bih_triangles_count = BIH_GetTriangleListForBox(bih, sizeof(bih_triangles) / sizeof(*bih_triangles), bih_triangles, bih_surfaces, localmins, localmaxs);
15330 if(bih_triangles_count == 0)
15332 if(bih_triangles_count > (int) (sizeof(bih_triangles) / sizeof(*bih_triangles))) // hit too many, likely bad anyway
15334 if(bih_triangles_count > 0)
15336 for (triangleindex = 0; triangleindex < bih_triangles_count; ++triangleindex)
15338 surfaceindex = bih_surfaces[triangleindex];
15339 surface = surfaces + surfaceindex;
15340 texture = surface->texture;
15341 if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
15343 if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
15345 R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, bih_triangles[triangleindex], surfaceindex);
15350 for (surfacelistindex = 0;surfacelistindex < numsurfacelist;surfacelistindex++)
15352 surfaceindex = surfacelist[surfacelistindex];
15353 surface = surfaces + surfaceindex;
15354 // check cull box first because it rejects more than any other check
15355 if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
15357 // skip transparent surfaces
15358 texture = surface->texture;
15359 if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
15361 if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
15363 numtriangles = surface->num_triangles;
15364 for (triangleindex = 0; triangleindex < numtriangles; triangleindex++)
15365 R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, triangleindex + surface->num_firsttriangle, surfaceindex);
15370 // do not call this outside of rendering code - use R_DecalSystem_SplatEntities instead
15371 static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence)
15373 int renderentityindex;
15374 float worldmins[3];
15375 float worldmaxs[3];
15376 entity_render_t *ent;
15378 if (!cl_decals_newsystem.integer)
15381 worldmins[0] = worldorigin[0] - worldsize;
15382 worldmins[1] = worldorigin[1] - worldsize;
15383 worldmins[2] = worldorigin[2] - worldsize;
15384 worldmaxs[0] = worldorigin[0] + worldsize;
15385 worldmaxs[1] = worldorigin[1] + worldsize;
15386 worldmaxs[2] = worldorigin[2] + worldsize;
15388 R_DecalSystem_SplatEntity(r_refdef.scene.worldentity, worldorigin, worldnormal, r, g, b, a, s1, t1, s2, t2, worldsize, decalsequence);
15390 for (renderentityindex = 0;renderentityindex < r_refdef.scene.numentities;renderentityindex++)
15392 ent = r_refdef.scene.entities[renderentityindex];
15393 if (!BoxesOverlap(ent->mins, ent->maxs, worldmins, worldmaxs))
15396 R_DecalSystem_SplatEntity(ent, worldorigin, worldnormal, r, g, b, a, s1, t1, s2, t2, worldsize, decalsequence);
15400 typedef struct r_decalsystem_splatqueue_s
15402 vec3_t worldorigin;
15403 vec3_t worldnormal;
15409 r_decalsystem_splatqueue_t;
15411 int r_decalsystem_numqueued = 0;
15412 r_decalsystem_splatqueue_t r_decalsystem_queue[MAX_DECALSYSTEM_QUEUE];
15414 void R_DecalSystem_SplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize)
15416 r_decalsystem_splatqueue_t *queue;
15418 if (!cl_decals_newsystem.integer || r_decalsystem_numqueued == MAX_DECALSYSTEM_QUEUE)
15421 queue = &r_decalsystem_queue[r_decalsystem_numqueued++];
15422 VectorCopy(worldorigin, queue->worldorigin);
15423 VectorCopy(worldnormal, queue->worldnormal);
15424 Vector4Set(queue->color, r, g, b, a);
15425 Vector4Set(queue->tcrange, s1, t1, s2, t2);
15426 queue->worldsize = worldsize;
15427 queue->decalsequence = cl.decalsequence++;
15430 static void R_DecalSystem_ApplySplatEntitiesQueue(void)
15433 r_decalsystem_splatqueue_t *queue;
15435 for (i = 0, queue = r_decalsystem_queue;i < r_decalsystem_numqueued;i++, queue++)
15436 R_DecalSystem_ApplySplatEntities(queue->worldorigin, queue->worldnormal, queue->color[0], queue->color[1], queue->color[2], queue->color[3], queue->tcrange[0], queue->tcrange[1], queue->tcrange[2], queue->tcrange[3], queue->worldsize, queue->decalsequence);
15437 r_decalsystem_numqueued = 0;
15440 extern cvar_t cl_decals_max;
15441 static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
15444 decalsystem_t *decalsystem = &ent->decalsystem;
15451 if (!decalsystem->numdecals)
15454 if (r_showsurfaces.integer)
15457 if (ent->model != decalsystem->model || ent->alpha < 1 || (ent->flags & RENDER_ADDITIVE))
15459 R_DecalSystem_Reset(decalsystem);
15463 killsequence = cl.decalsequence - max(1, cl_decals_max.integer);
15464 lifetime = cl_decals_time.value + cl_decals_fadetime.value;
15466 if (decalsystem->lastupdatetime)
15467 frametime = (cl.time - decalsystem->lastupdatetime);
15470 decalsystem->lastupdatetime = cl.time;
15471 decal = decalsystem->decals;
15472 numdecals = decalsystem->numdecals;
15474 for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
15476 if (decal->color4ub[0][3])
15478 decal->lived += frametime;
15479 if (killsequence - decal->decalsequence > 0 || decal->lived >= lifetime)
15481 memset(decal, 0, sizeof(*decal));
15482 if (decalsystem->freedecal > i)
15483 decalsystem->freedecal = i;
15487 decal = decalsystem->decals;
15488 while (numdecals > 0 && !decal[numdecals-1].color4ub[0][3])
15491 // collapse the array by shuffling the tail decals into the gaps
15494 while (decalsystem->freedecal < numdecals && decal[decalsystem->freedecal].color4ub[0][3])
15495 decalsystem->freedecal++;
15496 if (decalsystem->freedecal == numdecals)
15498 decal[decalsystem->freedecal] = decal[--numdecals];
15501 decalsystem->numdecals = numdecals;
15503 if (numdecals <= 0)
15505 // if there are no decals left, reset decalsystem
15506 R_DecalSystem_Reset(decalsystem);
15510 extern skinframe_t *decalskinframe;
15511 static void R_DrawModelDecals_Entity(entity_render_t *ent)
15514 decalsystem_t *decalsystem = &ent->decalsystem;
15523 const unsigned char *surfacevisible = ent == r_refdef.scene.worldentity ? r_refdef.viewcache.world_surfacevisible : NULL;
15526 numdecals = decalsystem->numdecals;
15530 if (r_showsurfaces.integer)
15533 if (ent->model != decalsystem->model || ent->alpha < 1 || (ent->flags & RENDER_ADDITIVE))
15535 R_DecalSystem_Reset(decalsystem);
15539 // if the model is static it doesn't matter what value we give for
15540 // wantnormals and wanttangents, so this logic uses only rules applicable
15541 // to a model, knowing that they are meaningless otherwise
15542 if (ent == r_refdef.scene.worldentity)
15543 RSurf_ActiveWorldEntity();
15545 RSurf_ActiveModelEntity(ent, false, false, false);
15547 decalsystem->lastupdatetime = cl.time;
15548 decal = decalsystem->decals;
15550 faderate = 1.0f / max(0.001f, cl_decals_fadetime.value);
15552 // update vertex positions for animated models
15553 v3f = decalsystem->vertex3f;
15554 c4f = decalsystem->color4f;
15555 t2f = decalsystem->texcoord2f;
15556 for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
15558 if (!decal->color4ub[0][3])
15561 if (surfacevisible && !surfacevisible[decal->surfaceindex])
15564 // update color values for fading decals
15565 if (decal->lived >= cl_decals_time.value)
15567 alpha = 1 - faderate * (decal->lived - cl_decals_time.value);
15568 alpha *= (1.0f/255.0f);
15571 alpha = 1.0f/255.0f;
15573 c4f[ 0] = decal->color4ub[0][0] * alpha;
15574 c4f[ 1] = decal->color4ub[0][1] * alpha;
15575 c4f[ 2] = decal->color4ub[0][2] * alpha;
15577 c4f[ 4] = decal->color4ub[1][0] * alpha;
15578 c4f[ 5] = decal->color4ub[1][1] * alpha;
15579 c4f[ 6] = decal->color4ub[1][2] * alpha;
15581 c4f[ 8] = decal->color4ub[2][0] * alpha;
15582 c4f[ 9] = decal->color4ub[2][1] * alpha;
15583 c4f[10] = decal->color4ub[2][2] * alpha;
15586 t2f[0] = decal->texcoord2f[0][0];
15587 t2f[1] = decal->texcoord2f[0][1];
15588 t2f[2] = decal->texcoord2f[1][0];
15589 t2f[3] = decal->texcoord2f[1][1];
15590 t2f[4] = decal->texcoord2f[2][0];
15591 t2f[5] = decal->texcoord2f[2][1];
15593 // update vertex positions for animated models
15594 if (decal->triangleindex >= 0 && decal->triangleindex < rsurface.modelnumtriangles)
15596 e = rsurface.modelelement3i + 3*decal->triangleindex;
15597 VectorCopy(rsurface.modelvertex3f + 3*e[0], v3f);
15598 VectorCopy(rsurface.modelvertex3f + 3*e[1], v3f + 3);
15599 VectorCopy(rsurface.modelvertex3f + 3*e[2], v3f + 6);
15603 VectorCopy(decal->vertex3f[0], v3f);
15604 VectorCopy(decal->vertex3f[1], v3f + 3);
15605 VectorCopy(decal->vertex3f[2], v3f + 6);
15608 if (r_refdef.fogenabled)
15610 alpha = RSurf_FogVertex(v3f);
15611 VectorScale(c4f, alpha, c4f);
15612 alpha = RSurf_FogVertex(v3f + 3);
15613 VectorScale(c4f + 4, alpha, c4f + 4);
15614 alpha = RSurf_FogVertex(v3f + 6);
15615 VectorScale(c4f + 8, alpha, c4f + 8);
15626 r_refdef.stats.drawndecals += numtris;
15628 // now render the decals all at once
15629 // (this assumes they all use one particle font texture!)
15630 RSurf_ActiveCustomEntity(&rsurface.matrix, &rsurface.inversematrix, rsurface.ent_flags, rsurface.ent_shadertime, 1, 1, 1, 1, numdecals*3, decalsystem->vertex3f, decalsystem->texcoord2f, NULL, NULL, NULL, decalsystem->color4f, numtris, decalsystem->element3i, decalsystem->element3s, false, false);
15631 // R_Mesh_ResetTextureState();
15632 R_Mesh_PrepareVertices_Generic_Arrays(numtris * 3, decalsystem->vertex3f, decalsystem->color4f, decalsystem->texcoord2f);
15633 GL_DepthMask(false);
15634 GL_DepthRange(0, 1);
15635 GL_PolygonOffset(rsurface.basepolygonfactor + r_polygonoffset_decals_factor.value, rsurface.basepolygonoffset + r_polygonoffset_decals_offset.value);
15636 GL_DepthTest(true);
15637 GL_CullFace(GL_NONE);
15638 GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
15639 R_SetupShader_Generic(decalskinframe->base, NULL, GL_MODULATE, 1);
15640 R_Mesh_Draw(0, numtris * 3, 0, numtris, decalsystem->element3i, NULL, 0, decalsystem->element3s, NULL, 0);
15644 static void R_DrawModelDecals(void)
15648 // fade faster when there are too many decals
15649 numdecals = r_refdef.scene.worldentity->decalsystem.numdecals;
15650 for (i = 0;i < r_refdef.scene.numentities;i++)
15651 numdecals += r_refdef.scene.entities[i]->decalsystem.numdecals;
15653 R_DrawModelDecals_FadeEntity(r_refdef.scene.worldentity);
15654 for (i = 0;i < r_refdef.scene.numentities;i++)
15655 if (r_refdef.scene.entities[i]->decalsystem.numdecals)
15656 R_DrawModelDecals_FadeEntity(r_refdef.scene.entities[i]);
15658 R_DecalSystem_ApplySplatEntitiesQueue();
15660 numdecals = r_refdef.scene.worldentity->decalsystem.numdecals;
15661 for (i = 0;i < r_refdef.scene.numentities;i++)
15662 numdecals += r_refdef.scene.entities[i]->decalsystem.numdecals;
15664 r_refdef.stats.totaldecals += numdecals;
15666 if (r_showsurfaces.integer)
15669 R_DrawModelDecals_Entity(r_refdef.scene.worldentity);
15671 for (i = 0;i < r_refdef.scene.numentities;i++)
15673 if (!r_refdef.viewcache.entityvisible[i])
15675 if (r_refdef.scene.entities[i]->decalsystem.numdecals)
15676 R_DrawModelDecals_Entity(r_refdef.scene.entities[i]);
15680 extern cvar_t mod_collision_bih;
15681 void R_DrawDebugModel(void)
15683 entity_render_t *ent = rsurface.entity;
15684 int i, j, k, l, flagsmask;
15685 const msurface_t *surface;
15686 dp_model_t *model = ent->model;
15689 switch(vid.renderpath)
15691 case RENDERPATH_GL11:
15692 case RENDERPATH_GL13:
15693 case RENDERPATH_GL20:
15694 case RENDERPATH_CGGL:
15696 case RENDERPATH_D3D9:
15697 //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15699 case RENDERPATH_D3D10:
15700 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15702 case RENDERPATH_D3D11:
15703 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15705 case RENDERPATH_SOFT:
15706 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15708 case RENDERPATH_GLES2:
15709 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15713 flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL;
15715 // R_Mesh_ResetTextureState();
15716 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
15717 GL_DepthRange(0, 1);
15718 GL_DepthTest(!r_showdisabledepthtest.integer);
15719 GL_DepthMask(false);
15720 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
15722 if (r_showcollisionbrushes.value > 0 && model->collision_bih.numleafs)
15726 qboolean cullbox = ent == r_refdef.scene.worldentity;
15727 const q3mbrush_t *brush;
15728 const bih_t *bih = &model->collision_bih;
15729 const bih_leaf_t *bihleaf;
15730 float vertex3f[3][3];
15731 GL_PolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);
15733 for (bihleafindex = 0, bihleaf = bih->leafs;bihleafindex < bih->numleafs;bihleafindex++, bihleaf++)
15735 if (cullbox && R_CullBox(bihleaf->mins, bihleaf->maxs))
15737 switch (bihleaf->type)
15740 brush = model->brush.data_brushes + bihleaf->itemindex;
15741 if (brush->colbrushf && brush->colbrushf->numtriangles)
15743 GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
15744 R_Mesh_PrepareVertices_Generic_Arrays(brush->colbrushf->numpoints, brush->colbrushf->points->v, NULL, NULL);
15745 R_Mesh_Draw(0, brush->colbrushf->numpoints, 0, brush->colbrushf->numtriangles, brush->colbrushf->elements, NULL, 0, NULL, NULL, 0);
15748 case BIH_COLLISIONTRIANGLE:
15749 triangleindex = bihleaf->itemindex;
15750 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+0], vertex3f[0]);
15751 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+1], vertex3f[1]);
15752 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+2], vertex3f[2]);
15753 GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
15754 R_Mesh_PrepareVertices_Generic_Arrays(3, vertex3f[0], NULL, NULL);
15755 R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
15757 case BIH_RENDERTRIANGLE:
15758 triangleindex = bihleaf->itemindex;
15759 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+0], vertex3f[0]);
15760 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+1], vertex3f[1]);
15761 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+2], vertex3f[2]);
15762 GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
15763 R_Mesh_PrepareVertices_Generic_Arrays(3, vertex3f[0], NULL, NULL);
15764 R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
15770 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
15772 if (r_showtris.integer || (r_shownormals.value != 0))
15774 if (r_showdisabledepthtest.integer)
15776 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
15777 GL_DepthMask(false);
15781 GL_BlendFunc(GL_ONE, GL_ZERO);
15782 GL_DepthMask(true);
15784 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
15786 if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
15788 rsurface.texture = R_GetCurrentTexture(surface->texture);
15789 if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
15791 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_NOGAPS, 1, &surface);
15792 if (r_showtris.value > 0)
15794 if (!rsurface.texture->currentlayers->depthmask)
15795 GL_Color(r_refdef.view.colorscale, 0, 0, r_showtris.value);
15796 else if (ent == r_refdef.scene.worldentity)
15797 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, r_showtris.value);
15799 GL_Color(0, r_refdef.view.colorscale, 0, r_showtris.value);
15800 R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
15801 qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
15803 qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
15806 if (r_shownormals.value < 0)
15808 qglBegin(GL_LINES);
15809 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15811 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15812 GL_Color(0, 0, r_refdef.view.colorscale, 1);
15813 qglVertex3f(v[0], v[1], v[2]);
15814 VectorMA(v, -r_shownormals.value, rsurface.batchnormal3f + l * 3, v);
15815 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15816 qglVertex3f(v[0], v[1], v[2]);
15821 if (r_shownormals.value > 0 && rsurface.batchsvector3f)
15823 qglBegin(GL_LINES);
15824 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15826 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15827 GL_Color(r_refdef.view.colorscale, 0, 0, 1);
15828 qglVertex3f(v[0], v[1], v[2]);
15829 VectorMA(v, r_shownormals.value, rsurface.batchsvector3f + l * 3, v);
15830 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15831 qglVertex3f(v[0], v[1], v[2]);
15835 qglBegin(GL_LINES);
15836 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15838 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15839 GL_Color(0, r_refdef.view.colorscale, 0, 1);
15840 qglVertex3f(v[0], v[1], v[2]);
15841 VectorMA(v, r_shownormals.value, rsurface.batchtvector3f + l * 3, v);
15842 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15843 qglVertex3f(v[0], v[1], v[2]);
15847 qglBegin(GL_LINES);
15848 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15850 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15851 GL_Color(0, 0, r_refdef.view.colorscale, 1);
15852 qglVertex3f(v[0], v[1], v[2]);
15853 VectorMA(v, r_shownormals.value, rsurface.batchnormal3f + l * 3, v);
15854 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15855 qglVertex3f(v[0], v[1], v[2]);
15862 rsurface.texture = NULL;
15866 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
15867 int r_maxsurfacelist = 0;
15868 const msurface_t **r_surfacelist = NULL;
15869 void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
15871 int i, j, endj, flagsmask;
15872 dp_model_t *model = r_refdef.scene.worldmodel;
15873 msurface_t *surfaces;
15874 unsigned char *update;
15875 int numsurfacelist = 0;
15879 if (r_maxsurfacelist < model->num_surfaces)
15881 r_maxsurfacelist = model->num_surfaces;
15883 Mem_Free((msurface_t**)r_surfacelist);
15884 r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist));
15887 RSurf_ActiveWorldEntity();
15889 surfaces = model->data_surfaces;
15890 update = model->brushq1.lightmapupdateflags;
15892 // update light styles on this submodel
15893 if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
15895 model_brush_lightstyleinfo_t *style;
15896 for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
15898 if (style->value != r_refdef.scene.lightstylevalue[style->style])
15900 int *list = style->surfacelist;
15901 style->value = r_refdef.scene.lightstylevalue[style->style];
15902 for (j = 0;j < style->numsurfaces;j++)
15903 update[list[j]] = true;
15908 flagsmask = skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL;
15912 R_DrawDebugModel();
15913 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
15917 rsurface.lightmaptexture = NULL;
15918 rsurface.deluxemaptexture = NULL;
15919 rsurface.uselightmaptexture = false;
15920 rsurface.texture = NULL;
15921 rsurface.rtlight = NULL;
15922 numsurfacelist = 0;
15923 // add visible surfaces to draw list
15924 for (i = 0;i < model->nummodelsurfaces;i++)
15926 j = model->sortedmodelsurfaces[i];
15927 if (r_refdef.viewcache.world_surfacevisible[j])
15928 r_surfacelist[numsurfacelist++] = surfaces + j;
15930 // update lightmaps if needed
15931 if (model->brushq1.firstrender)
15933 model->brushq1.firstrender = false;
15934 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
15936 R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j);
15940 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
15941 if (r_refdef.viewcache.world_surfacevisible[j])
15943 R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j);
15945 // don't do anything if there were no surfaces
15946 if (!numsurfacelist)
15948 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
15951 R_QueueWorldSurfaceList(numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
15952 GL_AlphaTest(false);
15954 // add to stats if desired
15955 if (r_speeds.integer && !skysurfaces && !depthonly)
15957 r_refdef.stats.world_surfaces += numsurfacelist;
15958 for (j = 0;j < numsurfacelist;j++)
15959 r_refdef.stats.world_triangles += r_surfacelist[j]->num_triangles;
15962 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
15965 void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
15967 int i, j, endj, flagsmask;
15968 dp_model_t *model = ent->model;
15969 msurface_t *surfaces;
15970 unsigned char *update;
15971 int numsurfacelist = 0;
15975 if (r_maxsurfacelist < model->num_surfaces)
15977 r_maxsurfacelist = model->num_surfaces;
15979 Mem_Free((msurface_t **)r_surfacelist);
15980 r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist));
15983 // if the model is static it doesn't matter what value we give for
15984 // wantnormals and wanttangents, so this logic uses only rules applicable
15985 // to a model, knowing that they are meaningless otherwise
15986 if (ent == r_refdef.scene.worldentity)
15987 RSurf_ActiveWorldEntity();
15988 else if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
15989 RSurf_ActiveModelEntity(ent, false, false, false);
15991 RSurf_ActiveModelEntity(ent, true, true, true);
15992 else if (depthonly)
15994 switch (vid.renderpath)
15996 case RENDERPATH_GL20:
15997 case RENDERPATH_CGGL:
15998 case RENDERPATH_D3D9:
15999 case RENDERPATH_D3D10:
16000 case RENDERPATH_D3D11:
16001 case RENDERPATH_SOFT:
16002 case RENDERPATH_GLES2:
16003 RSurf_ActiveModelEntity(ent, model->wantnormals, model->wanttangents, false);
16005 case RENDERPATH_GL13:
16006 case RENDERPATH_GL11:
16007 RSurf_ActiveModelEntity(ent, model->wantnormals, false, false);
16013 switch (vid.renderpath)
16015 case RENDERPATH_GL20:
16016 case RENDERPATH_CGGL:
16017 case RENDERPATH_D3D9:
16018 case RENDERPATH_D3D10:
16019 case RENDERPATH_D3D11:
16020 case RENDERPATH_SOFT:
16021 case RENDERPATH_GLES2:
16022 RSurf_ActiveModelEntity(ent, true, true, false);
16024 case RENDERPATH_GL13:
16025 case RENDERPATH_GL11:
16026 RSurf_ActiveModelEntity(ent, true, false, false);
16031 surfaces = model->data_surfaces;
16032 update = model->brushq1.lightmapupdateflags;
16034 // update light styles
16035 if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
16037 model_brush_lightstyleinfo_t *style;
16038 for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
16040 if (style->value != r_refdef.scene.lightstylevalue[style->style])
16042 int *list = style->surfacelist;
16043 style->value = r_refdef.scene.lightstylevalue[style->style];
16044 for (j = 0;j < style->numsurfaces;j++)
16045 update[list[j]] = true;
16050 flagsmask = skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL;
16054 R_DrawDebugModel();
16055 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
16059 rsurface.lightmaptexture = NULL;
16060 rsurface.deluxemaptexture = NULL;
16061 rsurface.uselightmaptexture = false;
16062 rsurface.texture = NULL;
16063 rsurface.rtlight = NULL;
16064 numsurfacelist = 0;
16065 // add visible surfaces to draw list
16066 for (i = 0;i < model->nummodelsurfaces;i++)
16067 r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i];
16068 // don't do anything if there were no surfaces
16069 if (!numsurfacelist)
16071 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
16074 // update lightmaps if needed
16078 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
16083 R_BuildLightMap(ent, surfaces + j);
16088 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
16090 R_BuildLightMap(ent, surfaces + j);
16091 R_QueueModelSurfaceList(ent, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
16092 GL_AlphaTest(false);
16094 // add to stats if desired
16095 if (r_speeds.integer && !skysurfaces && !depthonly)
16097 r_refdef.stats.entities_surfaces += numsurfacelist;
16098 for (j = 0;j < numsurfacelist;j++)
16099 r_refdef.stats.entities_triangles += r_surfacelist[j]->num_triangles;
16102 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
16105 void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass)
16107 static texture_t texture;
16108 static msurface_t surface;
16109 const msurface_t *surfacelist = &surface;
16111 // fake enough texture and surface state to render this geometry
16113 texture.update_lastrenderframe = -1; // regenerate this texture
16114 texture.basematerialflags = materialflags | MATERIALFLAG_CUSTOMSURFACE | MATERIALFLAG_WALL;
16115 texture.currentskinframe = skinframe;
16116 texture.currenttexmatrix = *texmatrix; // requires MATERIALFLAG_CUSTOMSURFACE
16117 texture.offsetmapping = OFFSETMAPPING_OFF;
16118 texture.offsetscale = 1;
16119 texture.specularscalemod = 1;
16120 texture.specularpowermod = 1;
16122 surface.texture = &texture;
16123 surface.num_triangles = numtriangles;
16124 surface.num_firsttriangle = firsttriangle;
16125 surface.num_vertices = numvertices;
16126 surface.num_firstvertex = firstvertex;
16129 rsurface.texture = R_GetCurrentTexture(surface.texture);
16130 rsurface.lightmaptexture = NULL;
16131 rsurface.deluxemaptexture = NULL;
16132 rsurface.uselightmaptexture = false;
16133 R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);
16136 void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass)
16138 static msurface_t surface;
16139 const msurface_t *surfacelist = &surface;
16141 // fake enough texture and surface state to render this geometry
16142 surface.texture = texture;
16143 surface.num_triangles = numtriangles;
16144 surface.num_firsttriangle = firsttriangle;
16145 surface.num_vertices = numvertices;
16146 surface.num_firstvertex = firstvertex;
16149 rsurface.texture = R_GetCurrentTexture(surface.texture);
16150 rsurface.lightmaptexture = NULL;
16151 rsurface.deluxemaptexture = NULL;
16152 rsurface.uselightmaptexture = false;
16153 R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);