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++;}
5211 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
5214 Con_Printf("^1GLSL shader %s failed! some features may not work properly.\n", permutationname);
5218 Mem_Free(vertexstring);
5220 Mem_Free(geometrystring);
5222 Mem_Free(fragmentstring);
5225 void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutation)
5227 r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation);
5228 if (r_glsl_permutation != perm)
5230 r_glsl_permutation = perm;
5231 if (!r_glsl_permutation->program)
5233 if (!r_glsl_permutation->compiled)
5234 R_GLSL_CompilePermutation(perm, mode, permutation);
5235 if (!r_glsl_permutation->program)
5237 // remove features until we find a valid permutation
5239 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
5241 // reduce i more quickly whenever it would not remove any bits
5242 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
5243 if (!(permutation & j))
5246 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
5247 if (!r_glsl_permutation->compiled)
5248 R_GLSL_CompilePermutation(perm, mode, permutation);
5249 if (r_glsl_permutation->program)
5252 if (i >= SHADERPERMUTATION_COUNT)
5254 //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
5255 r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
5256 qglUseProgram(0);CHECKGLERROR
5257 return; // no bit left to clear, entire mode is broken
5262 qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
5264 if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
5265 if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
5266 if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
5270 #include <Cg/cgGL.h>
5271 struct r_cg_permutation_s;
5272 typedef struct r_cg_permutation_s
5274 /// hash lookup data
5275 struct r_cg_permutation_s *hashnext;
5277 unsigned int permutation;
5279 /// indicates if we have tried compiling this permutation already
5281 /// 0 if compilation failed
5284 /// locations of detected parameters in programs, or NULL if not found
5285 CGparameter vp_EyePosition;
5286 CGparameter vp_FogPlane;
5287 CGparameter vp_LightDir;
5288 CGparameter vp_LightPosition;
5289 CGparameter vp_ModelToLight;
5290 CGparameter vp_TexMatrix;
5291 CGparameter vp_BackgroundTexMatrix;
5292 CGparameter vp_ModelViewProjectionMatrix;
5293 CGparameter vp_ModelViewMatrix;
5294 CGparameter vp_ShadowMapMatrix;
5296 CGparameter fp_Texture_First;
5297 CGparameter fp_Texture_Second;
5298 CGparameter fp_Texture_GammaRamps;
5299 CGparameter fp_Texture_Normal;
5300 CGparameter fp_Texture_Color;
5301 CGparameter fp_Texture_Gloss;
5302 CGparameter fp_Texture_Glow;
5303 CGparameter fp_Texture_SecondaryNormal;
5304 CGparameter fp_Texture_SecondaryColor;
5305 CGparameter fp_Texture_SecondaryGloss;
5306 CGparameter fp_Texture_SecondaryGlow;
5307 CGparameter fp_Texture_Pants;
5308 CGparameter fp_Texture_Shirt;
5309 CGparameter fp_Texture_FogHeightTexture;
5310 CGparameter fp_Texture_FogMask;
5311 CGparameter fp_Texture_Lightmap;
5312 CGparameter fp_Texture_Deluxemap;
5313 CGparameter fp_Texture_Attenuation;
5314 CGparameter fp_Texture_Cube;
5315 CGparameter fp_Texture_Refraction;
5316 CGparameter fp_Texture_Reflection;
5317 CGparameter fp_Texture_ShadowMap2D;
5318 CGparameter fp_Texture_CubeProjection;
5319 CGparameter fp_Texture_ScreenDepth;
5320 CGparameter fp_Texture_ScreenNormalMap;
5321 CGparameter fp_Texture_ScreenDiffuse;
5322 CGparameter fp_Texture_ScreenSpecular;
5323 CGparameter fp_Texture_ReflectMask;
5324 CGparameter fp_Texture_ReflectCube;
5325 CGparameter fp_Alpha;
5326 CGparameter fp_BloomBlur_Parameters;
5327 CGparameter fp_ClientTime;
5328 CGparameter fp_Color_Ambient;
5329 CGparameter fp_Color_Diffuse;
5330 CGparameter fp_Color_Specular;
5331 CGparameter fp_Color_Glow;
5332 CGparameter fp_Color_Pants;
5333 CGparameter fp_Color_Shirt;
5334 CGparameter fp_DeferredColor_Ambient;
5335 CGparameter fp_DeferredColor_Diffuse;
5336 CGparameter fp_DeferredColor_Specular;
5337 CGparameter fp_DeferredMod_Diffuse;
5338 CGparameter fp_DeferredMod_Specular;
5339 CGparameter fp_DistortScaleRefractReflect;
5340 CGparameter fp_EyePosition;
5341 CGparameter fp_FogColor;
5342 CGparameter fp_FogHeightFade;
5343 CGparameter fp_FogPlane;
5344 CGparameter fp_FogPlaneViewDist;
5345 CGparameter fp_FogRangeRecip;
5346 CGparameter fp_LightColor;
5347 CGparameter fp_LightDir;
5348 CGparameter fp_LightPosition;
5349 CGparameter fp_OffsetMapping_Scale;
5350 CGparameter fp_PixelSize;
5351 CGparameter fp_ReflectColor;
5352 CGparameter fp_ReflectFactor;
5353 CGparameter fp_ReflectOffset;
5354 CGparameter fp_RefractColor;
5355 CGparameter fp_Saturation;
5356 CGparameter fp_ScreenCenterRefractReflect;
5357 CGparameter fp_ScreenScaleRefractReflect;
5358 CGparameter fp_ScreenToDepth;
5359 CGparameter fp_ShadowMap_Parameters;
5360 CGparameter fp_ShadowMap_TextureScale;
5361 CGparameter fp_SpecularPower;
5362 CGparameter fp_UserVec1;
5363 CGparameter fp_UserVec2;
5364 CGparameter fp_UserVec3;
5365 CGparameter fp_UserVec4;
5366 CGparameter fp_ViewTintColor;
5367 CGparameter fp_ViewToLight;
5368 CGparameter fp_PixelToScreenTexCoord;
5369 CGparameter fp_ModelToReflectCube;
5370 CGparameter fp_BloomColorSubtract;
5371 CGparameter fp_NormalmapScrollBlend;
5375 /// information about each possible shader permutation
5376 r_cg_permutation_t *r_cg_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
5377 /// currently selected permutation
5378 r_cg_permutation_t *r_cg_permutation;
5379 /// storage for permutations linked in the hash table
5380 memexpandablearray_t r_cg_permutationarray;
5382 #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));}}
5384 static r_cg_permutation_t *R_CG_FindPermutation(unsigned int mode, unsigned int permutation)
5386 //unsigned int hashdepth = 0;
5387 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
5388 r_cg_permutation_t *p;
5389 for (p = r_cg_permutationhash[mode][hashindex];p;p = p->hashnext)
5391 if (p->mode == mode && p->permutation == permutation)
5393 //if (hashdepth > 10)
5394 // Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5399 p = (r_cg_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_cg_permutationarray);
5401 p->permutation = permutation;
5402 p->hashnext = r_cg_permutationhash[mode][hashindex];
5403 r_cg_permutationhash[mode][hashindex] = p;
5404 //if (hashdepth > 10)
5405 // Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5409 static char *R_CG_GetText(const char *filename, qboolean printfromdisknotice)
5412 if (!filename || !filename[0])
5414 if (!strcmp(filename, "cg/default.cg"))
5416 if (!cgshaderstring)
5418 cgshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5420 Con_DPrintf("Loading shaders from file %s...\n", filename);
5422 cgshaderstring = (char *)builtincgshaderstring;
5424 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(cgshaderstring) + 1);
5425 memcpy(shaderstring, cgshaderstring, strlen(cgshaderstring) + 1);
5426 return shaderstring;
5428 shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5431 if (printfromdisknotice)
5432 Con_DPrintf("from disk %s... ", filename);
5433 return shaderstring;
5435 return shaderstring;
5438 static void R_CG_CacheShader(r_cg_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
5440 // TODO: load or create .fp and .vp shader files
5443 static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, unsigned int permutation)
5446 shadermodeinfo_t *modeinfo = cgshadermodeinfo + mode;
5447 int vertstring_length = 0;
5448 int geomstring_length = 0;
5449 int fragstring_length = 0;
5451 char *vertexstring, *geometrystring, *fragmentstring;
5452 char *vertstring, *geomstring, *fragstring;
5453 char permutationname[256];
5454 char cachename[256];
5455 CGprofile vertexProfile;
5456 CGprofile fragmentProfile;
5457 int vertstrings_count = 0;
5458 int geomstrings_count = 0;
5459 int fragstrings_count = 0;
5460 const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
5461 const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
5462 const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
5470 permutationname[0] = 0;
5472 vertexstring = R_CG_GetText(modeinfo->vertexfilename, true);
5473 geometrystring = R_CG_GetText(modeinfo->geometryfilename, false);
5474 fragmentstring = R_CG_GetText(modeinfo->fragmentfilename, false);
5476 strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
5477 strlcat(cachename, "cg/", sizeof(cachename));
5479 // the first pretext is which type of shader to compile as
5480 // (later these will all be bound together as a program object)
5481 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
5482 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
5483 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
5485 // the second pretext is the mode (for example a light source)
5486 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
5487 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
5488 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
5489 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
5490 strlcat(cachename, modeinfo->name, sizeof(cachename));
5492 // now add all the permutation pretexts
5493 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
5495 if (permutation & (1<<i))
5497 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
5498 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
5499 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
5500 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
5501 strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
5505 // keep line numbers correct
5506 vertstrings_list[vertstrings_count++] = "\n";
5507 geomstrings_list[geomstrings_count++] = "\n";
5508 fragstrings_list[fragstrings_count++] = "\n";
5513 R_CompileShader_AddStaticParms(mode, permutation);
5514 memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5515 vertstrings_count += shaderstaticparms_count;
5516 memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5517 geomstrings_count += shaderstaticparms_count;
5518 memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
5519 fragstrings_count += shaderstaticparms_count;
5521 // replace spaces in the cachename with _ characters
5522 for (i = 0;cachename[i];i++)
5523 if (cachename[i] == ' ')
5526 // now append the shader text itself
5527 vertstrings_list[vertstrings_count++] = vertexstring;
5528 geomstrings_list[geomstrings_count++] = geometrystring;
5529 fragstrings_list[fragstrings_count++] = fragmentstring;
5531 // if any sources were NULL, clear the respective list
5533 vertstrings_count = 0;
5534 if (!geometrystring)
5535 geomstrings_count = 0;
5536 if (!fragmentstring)
5537 fragstrings_count = 0;
5539 vertstring_length = 0;
5540 for (i = 0;i < vertstrings_count;i++)
5541 vertstring_length += strlen(vertstrings_list[i]);
5542 vertstring = t = Mem_Alloc(tempmempool, vertstring_length + 1);
5543 for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
5544 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
5546 geomstring_length = 0;
5547 for (i = 0;i < geomstrings_count;i++)
5548 geomstring_length += strlen(geomstrings_list[i]);
5549 geomstring = t = Mem_Alloc(tempmempool, geomstring_length + 1);
5550 for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
5551 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
5553 fragstring_length = 0;
5554 for (i = 0;i < fragstrings_count;i++)
5555 fragstring_length += strlen(fragstrings_list[i]);
5556 fragstring = t = Mem_Alloc(tempmempool, fragstring_length + 1);
5557 for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
5558 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
5562 //vertexProfile = CG_PROFILE_ARBVP1;
5563 //fragmentProfile = CG_PROFILE_ARBFP1;
5564 vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);CHECKCGERROR
5565 fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);CHECKCGERROR
5566 //cgGLSetOptimalOptions(vertexProfile);CHECKCGERROR
5567 //cgGLSetOptimalOptions(fragmentProfile);CHECKCGERROR
5568 //cgSetAutoCompile(vid.cgcontext, CG_COMPILE_MANUAL);CHECKCGERROR
5571 // try to load the cached shader, or generate one
5572 R_CG_CacheShader(p, cachename, vertstring, fragstring);
5574 // if caching failed, do a dynamic compile for now
5576 if (vertstring[0] && !p->vprogram)
5577 p->vprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, vertstring, vertexProfile, NULL, NULL);
5579 if (fragstring[0] && !p->fprogram)
5580 p->fprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, fragstring, fragmentProfile, NULL, NULL);
5583 // look up all the uniform variable names we care about, so we don't
5584 // have to look them up every time we set them
5588 cgGLLoadProgram(p->vprogram);CHECKCGERROR CHECKGLERROR
5589 cgGLEnableProfile(vertexProfile);CHECKCGERROR CHECKGLERROR
5590 p->vp_EyePosition = cgGetNamedParameter(p->vprogram, "EyePosition");
5591 p->vp_FogPlane = cgGetNamedParameter(p->vprogram, "FogPlane");
5592 p->vp_LightDir = cgGetNamedParameter(p->vprogram, "LightDir");
5593 p->vp_LightPosition = cgGetNamedParameter(p->vprogram, "LightPosition");
5594 p->vp_ModelToLight = cgGetNamedParameter(p->vprogram, "ModelToLight");
5595 p->vp_TexMatrix = cgGetNamedParameter(p->vprogram, "TexMatrix");
5596 p->vp_BackgroundTexMatrix = cgGetNamedParameter(p->vprogram, "BackgroundTexMatrix");
5597 p->vp_ModelViewProjectionMatrix = cgGetNamedParameter(p->vprogram, "ModelViewProjectionMatrix");
5598 p->vp_ModelViewMatrix = cgGetNamedParameter(p->vprogram, "ModelViewMatrix");
5599 p->vp_ShadowMapMatrix = cgGetNamedParameter(p->vprogram, "ShadowMapMatrix");
5605 cgGLLoadProgram(p->fprogram);CHECKCGERROR CHECKGLERROR
5606 cgGLEnableProfile(fragmentProfile);CHECKCGERROR CHECKGLERROR
5607 p->fp_Texture_First = cgGetNamedParameter(p->fprogram, "Texture_First");
5608 p->fp_Texture_Second = cgGetNamedParameter(p->fprogram, "Texture_Second");
5609 p->fp_Texture_GammaRamps = cgGetNamedParameter(p->fprogram, "Texture_GammaRamps");
5610 p->fp_Texture_Normal = cgGetNamedParameter(p->fprogram, "Texture_Normal");
5611 p->fp_Texture_Color = cgGetNamedParameter(p->fprogram, "Texture_Color");
5612 p->fp_Texture_Gloss = cgGetNamedParameter(p->fprogram, "Texture_Gloss");
5613 p->fp_Texture_Glow = cgGetNamedParameter(p->fprogram, "Texture_Glow");
5614 p->fp_Texture_SecondaryNormal = cgGetNamedParameter(p->fprogram, "Texture_SecondaryNormal");
5615 p->fp_Texture_SecondaryColor = cgGetNamedParameter(p->fprogram, "Texture_SecondaryColor");
5616 p->fp_Texture_SecondaryGloss = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGloss");
5617 p->fp_Texture_SecondaryGlow = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGlow");
5618 p->fp_Texture_Pants = cgGetNamedParameter(p->fprogram, "Texture_Pants");
5619 p->fp_Texture_Shirt = cgGetNamedParameter(p->fprogram, "Texture_Shirt");
5620 p->fp_Texture_FogHeightTexture = cgGetNamedParameter(p->fprogram, "Texture_FogHeightTexture");
5621 p->fp_Texture_FogMask = cgGetNamedParameter(p->fprogram, "Texture_FogMask");
5622 p->fp_Texture_Lightmap = cgGetNamedParameter(p->fprogram, "Texture_Lightmap");
5623 p->fp_Texture_Deluxemap = cgGetNamedParameter(p->fprogram, "Texture_Deluxemap");
5624 p->fp_Texture_Attenuation = cgGetNamedParameter(p->fprogram, "Texture_Attenuation");
5625 p->fp_Texture_Cube = cgGetNamedParameter(p->fprogram, "Texture_Cube");
5626 p->fp_Texture_Refraction = cgGetNamedParameter(p->fprogram, "Texture_Refraction");
5627 p->fp_Texture_Reflection = cgGetNamedParameter(p->fprogram, "Texture_Reflection");
5628 p->fp_Texture_ShadowMap2D = cgGetNamedParameter(p->fprogram, "Texture_ShadowMap2D");
5629 p->fp_Texture_CubeProjection = cgGetNamedParameter(p->fprogram, "Texture_CubeProjection");
5630 p->fp_Texture_ScreenDepth = cgGetNamedParameter(p->fprogram, "Texture_ScreenDepth");
5631 p->fp_Texture_ScreenNormalMap = cgGetNamedParameter(p->fprogram, "Texture_ScreenNormalMap");
5632 p->fp_Texture_ScreenDiffuse = cgGetNamedParameter(p->fprogram, "Texture_ScreenDiffuse");
5633 p->fp_Texture_ScreenSpecular = cgGetNamedParameter(p->fprogram, "Texture_ScreenSpecular");
5634 p->fp_Texture_ReflectMask = cgGetNamedParameter(p->fprogram, "Texture_ReflectMask");
5635 p->fp_Texture_ReflectCube = cgGetNamedParameter(p->fprogram, "Texture_ReflectCube");
5636 p->fp_Alpha = cgGetNamedParameter(p->fprogram, "Alpha");
5637 p->fp_BloomBlur_Parameters = cgGetNamedParameter(p->fprogram, "BloomBlur_Parameters");
5638 p->fp_ClientTime = cgGetNamedParameter(p->fprogram, "ClientTime");
5639 p->fp_Color_Ambient = cgGetNamedParameter(p->fprogram, "Color_Ambient");
5640 p->fp_Color_Diffuse = cgGetNamedParameter(p->fprogram, "Color_Diffuse");
5641 p->fp_Color_Specular = cgGetNamedParameter(p->fprogram, "Color_Specular");
5642 p->fp_Color_Glow = cgGetNamedParameter(p->fprogram, "Color_Glow");
5643 p->fp_Color_Pants = cgGetNamedParameter(p->fprogram, "Color_Pants");
5644 p->fp_Color_Shirt = cgGetNamedParameter(p->fprogram, "Color_Shirt");
5645 p->fp_DeferredColor_Ambient = cgGetNamedParameter(p->fprogram, "DeferredColor_Ambient");
5646 p->fp_DeferredColor_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredColor_Diffuse");
5647 p->fp_DeferredColor_Specular = cgGetNamedParameter(p->fprogram, "DeferredColor_Specular");
5648 p->fp_DeferredMod_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredMod_Diffuse");
5649 p->fp_DeferredMod_Specular = cgGetNamedParameter(p->fprogram, "DeferredMod_Specular");
5650 p->fp_DistortScaleRefractReflect = cgGetNamedParameter(p->fprogram, "DistortScaleRefractReflect");
5651 p->fp_EyePosition = cgGetNamedParameter(p->fprogram, "EyePosition");
5652 p->fp_FogColor = cgGetNamedParameter(p->fprogram, "FogColor");
5653 p->fp_FogHeightFade = cgGetNamedParameter(p->fprogram, "FogHeightFade");
5654 p->fp_FogPlane = cgGetNamedParameter(p->fprogram, "FogPlane");
5655 p->fp_FogPlaneViewDist = cgGetNamedParameter(p->fprogram, "FogPlaneViewDist");
5656 p->fp_FogRangeRecip = cgGetNamedParameter(p->fprogram, "FogRangeRecip");
5657 p->fp_LightColor = cgGetNamedParameter(p->fprogram, "LightColor");
5658 p->fp_LightDir = cgGetNamedParameter(p->fprogram, "LightDir");
5659 p->fp_LightPosition = cgGetNamedParameter(p->fprogram, "LightPosition");
5660 p->fp_OffsetMapping_Scale = cgGetNamedParameter(p->fprogram, "OffsetMapping_Scale");
5661 p->fp_PixelSize = cgGetNamedParameter(p->fprogram, "PixelSize");
5662 p->fp_ReflectColor = cgGetNamedParameter(p->fprogram, "ReflectColor");
5663 p->fp_ReflectFactor = cgGetNamedParameter(p->fprogram, "ReflectFactor");
5664 p->fp_ReflectOffset = cgGetNamedParameter(p->fprogram, "ReflectOffset");
5665 p->fp_RefractColor = cgGetNamedParameter(p->fprogram, "RefractColor");
5666 p->fp_Saturation = cgGetNamedParameter(p->fprogram, "Saturation");
5667 p->fp_ScreenCenterRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenCenterRefractReflect");
5668 p->fp_ScreenScaleRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenScaleRefractReflect");
5669 p->fp_ScreenToDepth = cgGetNamedParameter(p->fprogram, "ScreenToDepth");
5670 p->fp_ShadowMap_Parameters = cgGetNamedParameter(p->fprogram, "ShadowMap_Parameters");
5671 p->fp_ShadowMap_TextureScale = cgGetNamedParameter(p->fprogram, "ShadowMap_TextureScale");
5672 p->fp_SpecularPower = cgGetNamedParameter(p->fprogram, "SpecularPower");
5673 p->fp_UserVec1 = cgGetNamedParameter(p->fprogram, "UserVec1");
5674 p->fp_UserVec2 = cgGetNamedParameter(p->fprogram, "UserVec2");
5675 p->fp_UserVec3 = cgGetNamedParameter(p->fprogram, "UserVec3");
5676 p->fp_UserVec4 = cgGetNamedParameter(p->fprogram, "UserVec4");
5677 p->fp_ViewTintColor = cgGetNamedParameter(p->fprogram, "ViewTintColor");
5678 p->fp_ViewToLight = cgGetNamedParameter(p->fprogram, "ViewToLight");
5679 p->fp_PixelToScreenTexCoord = cgGetNamedParameter(p->fprogram, "PixelToScreenTexCoord");
5680 p->fp_ModelToReflectCube = cgGetNamedParameter(p->fprogram, "ModelToReflectCube");
5681 p->fp_BloomColorSubtract = cgGetNamedParameter(p->fprogram, "BloomColorSubtract");
5682 p->fp_NormalmapScrollBlend = cgGetNamedParameter(p->fprogram, "NormalmapScrollBlend");
5686 if ((p->vprogram || !vertstring[0]) && (p->fprogram || !fragstring[0]))
5687 Con_DPrintf("^5CG shader %s compiled.\n", permutationname);
5689 Con_Printf("^1CG shader %s failed! some features may not work properly.\n", permutationname);
5693 Mem_Free(vertstring);
5695 Mem_Free(geomstring);
5697 Mem_Free(fragstring);
5699 Mem_Free(vertexstring);
5701 Mem_Free(geometrystring);
5703 Mem_Free(fragmentstring);
5706 void R_SetupShader_SetPermutationCG(unsigned int mode, unsigned int permutation)
5708 r_cg_permutation_t *perm = R_CG_FindPermutation(mode, permutation);
5711 if (r_cg_permutation != perm)
5713 r_cg_permutation = perm;
5714 if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
5716 if (!r_cg_permutation->compiled)
5717 R_CG_CompilePermutation(perm, mode, permutation);
5718 if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
5720 // remove features until we find a valid permutation
5722 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
5724 // reduce i more quickly whenever it would not remove any bits
5725 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
5726 if (!(permutation & j))
5729 r_cg_permutation = R_CG_FindPermutation(mode, permutation);
5730 if (!r_cg_permutation->compiled)
5731 R_CG_CompilePermutation(perm, mode, permutation);
5732 if (r_cg_permutation->vprogram || r_cg_permutation->fprogram)
5735 if (i >= SHADERPERMUTATION_COUNT)
5737 //Con_Printf("Could not find a working Cg shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
5738 r_cg_permutation = R_CG_FindPermutation(mode, permutation);
5739 return; // no bit left to clear, entire mode is broken
5745 if (r_cg_permutation->vprogram)
5747 cgGLLoadProgram(r_cg_permutation->vprogram);CHECKCGERROR CHECKGLERROR
5748 cgGLBindProgram(r_cg_permutation->vprogram);CHECKCGERROR CHECKGLERROR
5749 cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
5753 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
5754 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
5756 if (r_cg_permutation->fprogram)
5758 cgGLLoadProgram(r_cg_permutation->fprogram);CHECKCGERROR CHECKGLERROR
5759 cgGLBindProgram(r_cg_permutation->fprogram);CHECKCGERROR CHECKGLERROR
5760 cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
5764 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
5765 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
5769 if (r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR
5770 if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR
5771 if (r_cg_permutation->fp_ClientTime) cgGLSetParameter1f(r_cg_permutation->fp_ClientTime, cl.time);CHECKCGERROR
5774 void CG_BindTexture(CGparameter param, rtexture_t *tex)
5776 cgGLSetTextureParameter(param, R_GetTexture(tex));
5777 cgGLEnableTextureParameter(param);
5785 extern LPDIRECT3DDEVICE9 vid_d3d9dev;
5786 extern D3DCAPS9 vid_d3d9caps;
5789 struct r_hlsl_permutation_s;
5790 typedef struct r_hlsl_permutation_s
5792 /// hash lookup data
5793 struct r_hlsl_permutation_s *hashnext;
5795 unsigned int permutation;
5797 /// indicates if we have tried compiling this permutation already
5799 /// NULL if compilation failed
5800 IDirect3DVertexShader9 *vertexshader;
5801 IDirect3DPixelShader9 *pixelshader;
5803 r_hlsl_permutation_t;
5805 typedef enum D3DVSREGISTER_e
5807 D3DVSREGISTER_TexMatrix = 0, // float4x4
5808 D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
5809 D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
5810 D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
5811 D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
5812 D3DVSREGISTER_ModelToLight = 20, // float4x4
5813 D3DVSREGISTER_EyePosition = 24,
5814 D3DVSREGISTER_FogPlane = 25,
5815 D3DVSREGISTER_LightDir = 26,
5816 D3DVSREGISTER_LightPosition = 27,
5820 typedef enum D3DPSREGISTER_e
5822 D3DPSREGISTER_Alpha = 0,
5823 D3DPSREGISTER_BloomBlur_Parameters = 1,
5824 D3DPSREGISTER_ClientTime = 2,
5825 D3DPSREGISTER_Color_Ambient = 3,
5826 D3DPSREGISTER_Color_Diffuse = 4,
5827 D3DPSREGISTER_Color_Specular = 5,
5828 D3DPSREGISTER_Color_Glow = 6,
5829 D3DPSREGISTER_Color_Pants = 7,
5830 D3DPSREGISTER_Color_Shirt = 8,
5831 D3DPSREGISTER_DeferredColor_Ambient = 9,
5832 D3DPSREGISTER_DeferredColor_Diffuse = 10,
5833 D3DPSREGISTER_DeferredColor_Specular = 11,
5834 D3DPSREGISTER_DeferredMod_Diffuse = 12,
5835 D3DPSREGISTER_DeferredMod_Specular = 13,
5836 D3DPSREGISTER_DistortScaleRefractReflect = 14,
5837 D3DPSREGISTER_EyePosition = 15, // unused
5838 D3DPSREGISTER_FogColor = 16,
5839 D3DPSREGISTER_FogHeightFade = 17,
5840 D3DPSREGISTER_FogPlane = 18,
5841 D3DPSREGISTER_FogPlaneViewDist = 19,
5842 D3DPSREGISTER_FogRangeRecip = 20,
5843 D3DPSREGISTER_LightColor = 21,
5844 D3DPSREGISTER_LightDir = 22, // unused
5845 D3DPSREGISTER_LightPosition = 23,
5846 D3DPSREGISTER_OffsetMapping_Scale = 24,
5847 D3DPSREGISTER_PixelSize = 25,
5848 D3DPSREGISTER_ReflectColor = 26,
5849 D3DPSREGISTER_ReflectFactor = 27,
5850 D3DPSREGISTER_ReflectOffset = 28,
5851 D3DPSREGISTER_RefractColor = 29,
5852 D3DPSREGISTER_Saturation = 30,
5853 D3DPSREGISTER_ScreenCenterRefractReflect = 31,
5854 D3DPSREGISTER_ScreenScaleRefractReflect = 32,
5855 D3DPSREGISTER_ScreenToDepth = 33,
5856 D3DPSREGISTER_ShadowMap_Parameters = 34,
5857 D3DPSREGISTER_ShadowMap_TextureScale = 35,
5858 D3DPSREGISTER_SpecularPower = 36,
5859 D3DPSREGISTER_UserVec1 = 37,
5860 D3DPSREGISTER_UserVec2 = 38,
5861 D3DPSREGISTER_UserVec3 = 39,
5862 D3DPSREGISTER_UserVec4 = 40,
5863 D3DPSREGISTER_ViewTintColor = 41,
5864 D3DPSREGISTER_PixelToScreenTexCoord = 42,
5865 D3DPSREGISTER_BloomColorSubtract = 43,
5866 D3DPSREGISTER_ViewToLight = 44, // float4x4
5867 D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
5868 D3DPSREGISTER_NormalmapScrollBlend = 52,
5873 /// information about each possible shader permutation
5874 r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
5875 /// currently selected permutation
5876 r_hlsl_permutation_t *r_hlsl_permutation;
5877 /// storage for permutations linked in the hash table
5878 memexpandablearray_t r_hlsl_permutationarray;
5880 static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, unsigned int permutation)
5882 //unsigned int hashdepth = 0;
5883 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
5884 r_hlsl_permutation_t *p;
5885 for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
5887 if (p->mode == mode && p->permutation == permutation)
5889 //if (hashdepth > 10)
5890 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5895 p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
5897 p->permutation = permutation;
5898 p->hashnext = r_hlsl_permutationhash[mode][hashindex];
5899 r_hlsl_permutationhash[mode][hashindex] = p;
5900 //if (hashdepth > 10)
5901 // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
5905 static char *R_HLSL_GetText(const char *filename, qboolean printfromdisknotice)
5908 if (!filename || !filename[0])
5910 if (!strcmp(filename, "hlsl/default.hlsl"))
5912 if (!hlslshaderstring)
5914 hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5915 if (hlslshaderstring)
5916 Con_DPrintf("Loading shaders from file %s...\n", filename);
5918 hlslshaderstring = (char *)builtincgshaderstring;
5920 shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
5921 memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
5922 return shaderstring;
5924 shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
5927 if (printfromdisknotice)
5928 Con_DPrintf("from disk %s... ", filename);
5929 return shaderstring;
5931 return shaderstring;
5935 //#include <d3dx9shader.h>
5936 //#include <d3dx9mesh.h>
5938 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
5940 DWORD *vsbin = NULL;
5941 DWORD *psbin = NULL;
5942 fs_offset_t vsbinsize;
5943 fs_offset_t psbinsize;
5944 // IDirect3DVertexShader9 *vs = NULL;
5945 // IDirect3DPixelShader9 *ps = NULL;
5946 ID3DXBuffer *vslog = NULL;
5947 ID3DXBuffer *vsbuffer = NULL;
5948 ID3DXConstantTable *vsconstanttable = NULL;
5949 ID3DXBuffer *pslog = NULL;
5950 ID3DXBuffer *psbuffer = NULL;
5951 ID3DXConstantTable *psconstanttable = NULL;
5954 char temp[MAX_INPUTLINE];
5955 const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
5956 qboolean debugshader = gl_paranoid.integer != 0;
5957 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
5958 if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
5961 vsbin = (DWORD *)FS_LoadFile(va("%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
5962 psbin = (DWORD *)FS_LoadFile(va("%s.psbin", cachename), r_main_mempool, true, &psbinsize);
5964 if ((!vsbin && vertstring) || (!psbin && fragstring))
5966 const char* dllnames_d3dx9 [] =
5990 dllhandle_t d3dx9_dll = NULL;
5991 HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
5992 HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
5993 HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
5994 dllfunction_t d3dx9_dllfuncs[] =
5996 {"D3DXCompileShaderFromFileA", (void **) &qD3DXCompileShaderFromFileA},
5997 {"D3DXPreprocessShader", (void **) &qD3DXPreprocessShader},
5998 {"D3DXCompileShader", (void **) &qD3DXCompileShader},
6001 if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
6003 DWORD shaderflags = 0;
6005 shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
6006 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
6007 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
6008 if (vertstring && vertstring[0])
6012 // vsresult = qD3DXPreprocessShader(vertstring, strlen(vertstring), NULL, NULL, &vsbuffer, &vslog);
6013 // FS_WriteFile(va("%s_vs.fx", cachename), vsbuffer->GetBufferPointer(), vsbuffer->GetBufferSize());
6014 FS_WriteFile(va("%s_vs.fx", cachename), vertstring, strlen(vertstring));
6015 vsresult = qD3DXCompileShaderFromFileA(va("%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
6018 vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
6021 vsbinsize = vsbuffer->GetBufferSize();
6022 vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
6023 memcpy(vsbin, vsbuffer->GetBufferPointer(), vsbinsize);
6024 vsbuffer->Release();
6028 strlcpy(temp, (const char *)vslog->GetBufferPointer(), min(sizeof(temp), vslog->GetBufferSize()));
6029 Con_Printf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
6033 if (fragstring && fragstring[0])
6037 // psresult = qD3DXPreprocessShader(fragstring, strlen(fragstring), NULL, NULL, &psbuffer, &pslog);
6038 // FS_WriteFile(va("%s_ps.fx", cachename), psbuffer->GetBufferPointer(), psbuffer->GetBufferSize());
6039 FS_WriteFile(va("%s_ps.fx", cachename), fragstring, strlen(fragstring));
6040 psresult = qD3DXCompileShaderFromFileA(va("%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
6043 psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
6046 psbinsize = psbuffer->GetBufferSize();
6047 psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
6048 memcpy(psbin, psbuffer->GetBufferPointer(), psbinsize);
6049 psbuffer->Release();
6053 strlcpy(temp, (const char *)pslog->GetBufferPointer(), min(sizeof(temp), pslog->GetBufferSize()));
6054 Con_Printf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
6058 Sys_UnloadLibrary(&d3dx9_dll);
6061 Con_Printf("Unable to compile shader - D3DXCompileShader function not found\n");
6065 vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
6066 if (FAILED(vsresult))
6067 Con_Printf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
6068 psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
6069 if (FAILED(psresult))
6070 Con_Printf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
6072 // free the shader data
6073 vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
6074 psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
6077 static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
6080 shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
6081 int vertstring_length = 0;
6082 int geomstring_length = 0;
6083 int fragstring_length = 0;
6085 char *vertexstring, *geometrystring, *fragmentstring;
6086 char *vertstring, *geomstring, *fragstring;
6087 char permutationname[256];
6088 char cachename[256];
6089 int vertstrings_count = 0;
6090 int geomstrings_count = 0;
6091 int fragstrings_count = 0;
6092 const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
6093 const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
6094 const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
6099 p->vertexshader = NULL;
6100 p->pixelshader = NULL;
6102 permutationname[0] = 0;
6104 vertexstring = R_HLSL_GetText(modeinfo->vertexfilename, true);
6105 geometrystring = R_HLSL_GetText(modeinfo->geometryfilename, false);
6106 fragmentstring = R_HLSL_GetText(modeinfo->fragmentfilename, false);
6108 strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
6109 strlcat(cachename, "hlsl/", sizeof(cachename));
6111 // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
6112 vertstrings_count = 0;
6113 geomstrings_count = 0;
6114 fragstrings_count = 0;
6115 vertstrings_list[vertstrings_count++] = "#define HLSL\n";
6116 geomstrings_list[geomstrings_count++] = "#define HLSL\n";
6117 fragstrings_list[fragstrings_count++] = "#define HLSL\n";
6119 // the first pretext is which type of shader to compile as
6120 // (later these will all be bound together as a program object)
6121 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
6122 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
6123 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
6125 // the second pretext is the mode (for example a light source)
6126 vertstrings_list[vertstrings_count++] = modeinfo->pretext;
6127 geomstrings_list[geomstrings_count++] = modeinfo->pretext;
6128 fragstrings_list[fragstrings_count++] = modeinfo->pretext;
6129 strlcat(permutationname, modeinfo->name, sizeof(permutationname));
6130 strlcat(cachename, modeinfo->name, sizeof(cachename));
6132 // now add all the permutation pretexts
6133 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6135 if (permutation & (1<<i))
6137 vertstrings_list[vertstrings_count++] = shaderpermutationinfo[i].pretext;
6138 geomstrings_list[geomstrings_count++] = shaderpermutationinfo[i].pretext;
6139 fragstrings_list[fragstrings_count++] = shaderpermutationinfo[i].pretext;
6140 strlcat(permutationname, shaderpermutationinfo[i].name, sizeof(permutationname));
6141 strlcat(cachename, shaderpermutationinfo[i].name, sizeof(cachename));
6145 // keep line numbers correct
6146 vertstrings_list[vertstrings_count++] = "\n";
6147 geomstrings_list[geomstrings_count++] = "\n";
6148 fragstrings_list[fragstrings_count++] = "\n";
6153 R_CompileShader_AddStaticParms(mode, permutation);
6154 memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
6155 vertstrings_count += shaderstaticparms_count;
6156 memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
6157 geomstrings_count += shaderstaticparms_count;
6158 memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
6159 fragstrings_count += shaderstaticparms_count;
6161 // replace spaces in the cachename with _ characters
6162 for (i = 0;cachename[i];i++)
6163 if (cachename[i] == ' ')
6166 // now append the shader text itself
6167 vertstrings_list[vertstrings_count++] = vertexstring;
6168 geomstrings_list[geomstrings_count++] = geometrystring;
6169 fragstrings_list[fragstrings_count++] = fragmentstring;
6171 // if any sources were NULL, clear the respective list
6173 vertstrings_count = 0;
6174 if (!geometrystring)
6175 geomstrings_count = 0;
6176 if (!fragmentstring)
6177 fragstrings_count = 0;
6179 vertstring_length = 0;
6180 for (i = 0;i < vertstrings_count;i++)
6181 vertstring_length += strlen(vertstrings_list[i]);
6182 vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
6183 for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
6184 memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
6186 geomstring_length = 0;
6187 for (i = 0;i < geomstrings_count;i++)
6188 geomstring_length += strlen(geomstrings_list[i]);
6189 geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
6190 for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
6191 memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
6193 fragstring_length = 0;
6194 for (i = 0;i < fragstrings_count;i++)
6195 fragstring_length += strlen(fragstrings_list[i]);
6196 fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
6197 for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
6198 memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
6200 // try to load the cached shader, or generate one
6201 R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
6203 if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
6204 Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
6206 Con_Printf("^1HLSL shader %s failed! some features may not work properly.\n", permutationname);
6210 Mem_Free(vertstring);
6212 Mem_Free(geomstring);
6214 Mem_Free(fragstring);
6216 Mem_Free(vertexstring);
6218 Mem_Free(geometrystring);
6220 Mem_Free(fragmentstring);
6223 static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
6224 static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
6225 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);}
6226 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);}
6227 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);}
6228 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);}
6230 static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
6231 static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
6232 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);}
6233 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);}
6234 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);}
6235 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);}
6237 void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
6239 r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
6240 if (r_hlsl_permutation != perm)
6242 r_hlsl_permutation = perm;
6243 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
6245 if (!r_hlsl_permutation->compiled)
6246 R_HLSL_CompilePermutation(perm, mode, permutation);
6247 if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
6249 // remove features until we find a valid permutation
6251 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6253 // reduce i more quickly whenever it would not remove any bits
6254 int j = 1<<(SHADERPERMUTATION_COUNT-1-i);
6255 if (!(permutation & j))
6258 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
6259 if (!r_hlsl_permutation->compiled)
6260 R_HLSL_CompilePermutation(perm, mode, permutation);
6261 if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
6264 if (i >= SHADERPERMUTATION_COUNT)
6266 //Con_Printf("Could not find a working Cg shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
6267 r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
6268 return; // no bit left to clear, entire mode is broken
6272 IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
6273 IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
6275 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
6276 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
6277 hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
6281 void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
6283 DPSOFTRAST_SetShader(mode, permutation);
6284 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
6285 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
6286 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
6289 void R_GLSL_Restart_f(void)
6291 unsigned int i, limit;
6292 if (glslshaderstring && glslshaderstring != builtinshaderstring && glslshaderstring != builtingles2shaderstring)
6293 Mem_Free(glslshaderstring);
6294 glslshaderstring = NULL;
6295 if (cgshaderstring && cgshaderstring != builtincgshaderstring)
6296 Mem_Free(cgshaderstring);
6297 cgshaderstring = NULL;
6298 if (hlslshaderstring && hlslshaderstring != builtincgshaderstring)
6299 Mem_Free(hlslshaderstring);
6300 hlslshaderstring = NULL;
6301 switch(vid.renderpath)
6303 case RENDERPATH_D3D9:
6306 r_hlsl_permutation_t *p;
6307 r_hlsl_permutation = NULL;
6308 // cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6309 // cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6310 // cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6311 // cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6312 limit = Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
6313 for (i = 0;i < limit;i++)
6315 if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
6317 if (p->vertexshader)
6318 IDirect3DVertexShader9_Release(p->vertexshader);
6320 IDirect3DPixelShader9_Release(p->pixelshader);
6321 Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
6324 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
6328 case RENDERPATH_D3D10:
6329 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6331 case RENDERPATH_D3D11:
6332 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6334 case RENDERPATH_GL20:
6335 case RENDERPATH_GLES2:
6337 r_glsl_permutation_t *p;
6338 r_glsl_permutation = NULL;
6339 limit = Mem_ExpandableArray_IndexRange(&r_glsl_permutationarray);
6340 for (i = 0;i < limit;i++)
6342 if ((p = (r_glsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_glsl_permutationarray, i)))
6344 GL_Backend_FreeProgram(p->program);
6345 Mem_ExpandableArray_FreeRecord(&r_glsl_permutationarray, (void*)p);
6348 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
6351 case RENDERPATH_CGGL:
6354 r_cg_permutation_t *p;
6355 r_cg_permutation = NULL;
6356 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6357 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
6358 cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6359 cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
6360 limit = Mem_ExpandableArray_IndexRange(&r_cg_permutationarray);
6361 for (i = 0;i < limit;i++)
6363 if ((p = (r_cg_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_cg_permutationarray, i)))
6366 cgDestroyProgram(p->vprogram);
6368 cgDestroyProgram(p->fprogram);
6369 Mem_ExpandableArray_FreeRecord(&r_cg_permutationarray, (void*)p);
6372 memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
6376 case RENDERPATH_GL13:
6377 case RENDERPATH_GL11:
6379 case RENDERPATH_SOFT:
6384 void R_GLSL_DumpShader_f(void)
6389 file = FS_OpenRealFile("glsl/default.glsl", "w", false);
6392 FS_Print(file, "/* The engine may define the following macros:\n");
6393 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6394 for (i = 0;i < SHADERMODE_COUNT;i++)
6395 FS_Print(file, glslshadermodeinfo[i].pretext);
6396 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6397 FS_Print(file, shaderpermutationinfo[i].pretext);
6398 FS_Print(file, "*/\n");
6399 FS_Print(file, builtinshaderstring);
6401 Con_Printf("glsl/default.glsl written\n");
6404 Con_Printf("failed to write to glsl/default.glsl\n");
6406 file = FS_OpenRealFile("gles2/default.glsl", "w", false);
6409 FS_Print(file, "/* The engine may define the following macros:\n");
6410 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6411 for (i = 0;i < SHADERMODE_COUNT;i++)
6412 FS_Print(file, glslshadermodeinfo[i].pretext);
6413 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6414 FS_Print(file, shaderpermutationinfo[i].pretext);
6415 FS_Print(file, "*/\n");
6416 FS_Print(file, builtingles2shaderstring);
6418 Con_Printf("gles2/default.glsl written\n");
6421 Con_Printf("failed to write to glsl/default.glsl\n");
6424 file = FS_OpenRealFile("cg/default.cg", "w", false);
6427 FS_Print(file, "/* The engine may define the following macros:\n");
6428 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6429 for (i = 0;i < SHADERMODE_COUNT;i++)
6430 FS_Print(file, cgshadermodeinfo[i].pretext);
6431 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6432 FS_Print(file, shaderpermutationinfo[i].pretext);
6433 FS_Print(file, "*/\n");
6434 FS_Print(file, builtincgshaderstring);
6436 Con_Printf("cg/default.cg written\n");
6439 Con_Printf("failed to write to cg/default.cg\n");
6442 file = FS_OpenRealFile("hlsl/default.hlsl", "w", false);
6445 FS_Print(file, "/* The engine may define the following macros:\n");
6446 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
6447 for (i = 0;i < SHADERMODE_COUNT;i++)
6448 FS_Print(file, hlslshadermodeinfo[i].pretext);
6449 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
6450 FS_Print(file, shaderpermutationinfo[i].pretext);
6451 FS_Print(file, "*/\n");
6452 FS_Print(file, builtincgshaderstring);
6454 Con_Printf("hlsl/default.hlsl written\n");
6457 Con_Printf("failed to write to hlsl/default.hlsl\n");
6460 void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale)
6463 texturemode = GL_MODULATE;
6464 switch (vid.renderpath)
6466 case RENDERPATH_D3D9:
6468 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))));
6469 R_Mesh_TexBind(GL20TU_FIRST , first );
6470 R_Mesh_TexBind(GL20TU_SECOND, second);
6473 case RENDERPATH_D3D10:
6474 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6476 case RENDERPATH_D3D11:
6477 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6479 case RENDERPATH_GL20:
6480 case RENDERPATH_GLES2:
6481 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))));
6482 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
6483 R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
6485 case RENDERPATH_CGGL:
6488 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))));
6489 if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , first );CHECKCGERROR
6490 if (r_cg_permutation->fp_Texture_Second) CG_BindTexture(r_cg_permutation->fp_Texture_Second, second);CHECKCGERROR
6493 case RENDERPATH_GL13:
6494 R_Mesh_TexBind(0, first );
6495 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
6496 R_Mesh_TexBind(1, second);
6498 R_Mesh_TexCombine(1, texturemode, texturemode, rgbscale, 1);
6500 case RENDERPATH_GL11:
6501 R_Mesh_TexBind(0, first );
6503 case RENDERPATH_SOFT:
6504 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))));
6505 R_Mesh_TexBind(GL20TU_FIRST , first );
6506 R_Mesh_TexBind(GL20TU_SECOND, second);
6511 void R_SetupShader_DepthOrShadow(void)
6513 switch (vid.renderpath)
6515 case RENDERPATH_D3D9:
6517 R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, 0);
6520 case RENDERPATH_D3D10:
6521 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6523 case RENDERPATH_D3D11:
6524 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6526 case RENDERPATH_GL20:
6527 case RENDERPATH_GLES2:
6528 R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, 0);
6530 case RENDERPATH_CGGL:
6532 R_SetupShader_SetPermutationCG(SHADERMODE_DEPTH_OR_SHADOW, 0);
6535 case RENDERPATH_GL13:
6536 R_Mesh_TexBind(0, 0);
6537 R_Mesh_TexBind(1, 0);
6539 case RENDERPATH_GL11:
6540 R_Mesh_TexBind(0, 0);
6542 case RENDERPATH_SOFT:
6543 R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, 0);
6548 void R_SetupShader_ShowDepth(void)
6550 switch (vid.renderpath)
6552 case RENDERPATH_D3D9:
6554 R_SetupShader_SetPermutationHLSL(SHADERMODE_SHOWDEPTH, 0);
6557 case RENDERPATH_D3D10:
6558 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6560 case RENDERPATH_D3D11:
6561 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
6563 case RENDERPATH_GL20:
6564 case RENDERPATH_GLES2:
6565 R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, 0);
6567 case RENDERPATH_CGGL:
6569 R_SetupShader_SetPermutationCG(SHADERMODE_SHOWDEPTH, 0);
6572 case RENDERPATH_GL13:
6574 case RENDERPATH_GL11:
6576 case RENDERPATH_SOFT:
6577 R_SetupShader_SetPermutationSoft(SHADERMODE_SHOWDEPTH, 0);
6582 extern qboolean r_shadow_usingdeferredprepass;
6583 extern cvar_t r_shadow_deferred_8bitrange;
6584 extern rtexture_t *r_shadow_attenuationgradienttexture;
6585 extern rtexture_t *r_shadow_attenuation2dtexture;
6586 extern rtexture_t *r_shadow_attenuation3dtexture;
6587 extern qboolean r_shadow_usingshadowmap2d;
6588 extern qboolean r_shadow_usingshadowmaportho;
6589 extern float r_shadow_shadowmap_texturescale[2];
6590 extern float r_shadow_shadowmap_parameters[4];
6591 extern qboolean r_shadow_shadowmapvsdct;
6592 extern qboolean r_shadow_shadowmapsampler;
6593 extern int r_shadow_shadowmappcf;
6594 extern rtexture_t *r_shadow_shadowmap2dtexture;
6595 extern rtexture_t *r_shadow_shadowmap2dcolortexture;
6596 extern rtexture_t *r_shadow_shadowmapvsdcttexture;
6597 extern matrix4x4_t r_shadow_shadowmapmatrix;
6598 extern int r_shadow_shadowmaplod; // changes for each light based on distance
6599 extern int r_shadow_prepass_width;
6600 extern int r_shadow_prepass_height;
6601 extern rtexture_t *r_shadow_prepassgeometrydepthtexture;
6602 extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
6603 extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
6604 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
6605 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
6606 static qboolean R_BlendFuncAllowsColormod(int src, int dst)
6608 // a blendfunc allows colormod if:
6609 // a) it can never keep the destination pixel invariant, or
6610 // b) it can keep the destination pixel invariant, and still can do so if colormodded
6611 // this is to prevent unintended side effects from colormod
6614 // IF there is a (s, sa) for which for all (d, da),
6615 // s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
6616 // THEN, for this (s, sa) and all (colormod, d, da):
6617 // s*colormod * src(s*colormod, d, sa, da) + d * dst(s*colormod, d, sa, da) == d
6618 // OBVIOUSLY, this means that
6619 // s*colormod * src(s*colormod, d, sa, da) = 0
6620 // dst(s*colormod, d, sa, da) = 1
6622 // note: not caring about GL_SRC_ALPHA_SATURATE and following here, these are unused in DP code
6624 // main condition to leave dst color invariant:
6625 // s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
6627 // s * 0 + d * dst(s, d, sa, da) == d
6628 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6629 // => colormod is a problem for GL_SRC_COLOR only
6631 // s + d * dst(s, d, sa, da) == d
6633 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6634 // => colormod is never problematic for these
6635 // src == GL_SRC_COLOR:
6636 // s*s + d * dst(s, d, sa, da) == d
6638 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6639 // => colormod is never problematic for these
6640 // src == GL_ONE_MINUS_SRC_COLOR:
6641 // s*(1-s) + d * dst(s, d, sa, da) == d
6642 // => s == 0 or s == 1
6643 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6644 // => colormod is a problem for GL_SRC_COLOR only
6645 // src == GL_DST_COLOR
6646 // s*d + d * dst(s, d, sa, da) == d
6648 // => dst == GL_ZERO/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6649 // => colormod is always a problem
6652 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6653 // => colormod is never problematic for these
6654 // => BUT, we do not know s! We must assume it is problematic
6655 // then... except in GL_ONE case, where we know all invariant
6657 // src == GL_ONE_MINUS_DST_COLOR
6658 // s*(1-d) + d * dst(s, d, sa, da) == d
6659 // => s == 0 (1-d is impossible to handle for our desired result)
6660 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6661 // => colormod is never problematic for these
6662 // src == GL_SRC_ALPHA
6663 // s*sa + d * dst(s, d, sa, da) == d
6664 // => s == 0, or sa == 0
6665 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6666 // => colormod breaks in the case GL_SRC_COLOR only
6667 // src == GL_ONE_MINUS_SRC_ALPHA
6668 // s*(1-sa) + d * dst(s, d, sa, da) == d
6669 // => s == 0, or sa == 1
6670 // => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6671 // => colormod breaks in the case GL_SRC_COLOR only
6672 // src == GL_DST_ALPHA
6673 // s*da + d * dst(s, d, sa, da) == d
6675 // => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
6676 // => colormod is never problematic for these
6681 case GL_ONE_MINUS_SRC_COLOR:
6683 case GL_ONE_MINUS_SRC_ALPHA:
6684 if(dst == GL_SRC_COLOR)
6689 case GL_ONE_MINUS_DST_COLOR:
6691 case GL_ONE_MINUS_DST_ALPHA:
6701 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)
6703 // select a permutation of the lighting shader appropriate to this
6704 // combination of texture, entity, light source, and fogging, only use the
6705 // minimum features necessary to avoid wasting rendering time in the
6706 // fragment shader on features that are not being used
6707 unsigned int permutation = 0;
6708 unsigned int mode = 0;
6709 qboolean allow_colormod;
6710 static float dummy_colormod[3] = {1, 1, 1};
6711 float *colormod = rsurface.colormod;
6713 r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
6714 if (rsurfacepass == RSURFPASS_BACKGROUND)
6716 // distorted background
6717 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
6719 mode = SHADERMODE_WATER;
6720 if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
6721 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND;
6722 if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
6724 // this is the right thing to do for wateralpha
6725 GL_BlendFunc(GL_ONE, GL_ZERO);
6726 allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
6730 // this is the right thing to do for entity alpha
6731 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6732 allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6735 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
6737 mode = SHADERMODE_REFRACTION;
6738 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6739 allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6743 mode = SHADERMODE_GENERIC;
6744 permutation |= SHADERPERMUTATION_DIFFUSE;
6745 GL_BlendFunc(GL_ONE, GL_ZERO);
6746 allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
6748 GL_AlphaTest(false);
6750 else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
6752 if (r_glsl_offsetmapping.integer)
6754 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6755 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6756 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6757 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6758 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6760 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6761 if (r_glsl_offsetmapping_reliefmapping.integer)
6762 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6765 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6766 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6767 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
6768 permutation |= SHADERPERMUTATION_ALPHAKILL;
6769 // normalmap (deferred prepass), may use alpha test on diffuse
6770 mode = SHADERMODE_DEFERREDGEOMETRY;
6771 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6772 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6773 GL_AlphaTest(false);
6774 GL_BlendFunc(GL_ONE, GL_ZERO);
6775 allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
6777 else if (rsurfacepass == RSURFPASS_RTLIGHT)
6779 if (r_glsl_offsetmapping.integer)
6781 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6782 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6783 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6784 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6785 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6787 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6788 if (r_glsl_offsetmapping_reliefmapping.integer)
6789 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6792 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6793 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6795 mode = SHADERMODE_LIGHTSOURCE;
6796 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6797 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6798 if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
6799 permutation |= SHADERPERMUTATION_CUBEFILTER;
6800 if (diffusescale > 0)
6801 permutation |= SHADERPERMUTATION_DIFFUSE;
6802 if (specularscale > 0)
6803 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
6804 if (r_refdef.fogenabled)
6805 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6806 if (rsurface.texture->colormapping)
6807 permutation |= SHADERPERMUTATION_COLORMAPPING;
6808 if (r_shadow_usingshadowmap2d)
6810 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6811 if(r_shadow_shadowmapvsdct)
6812 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
6814 if (r_shadow_shadowmapsampler)
6815 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6816 if (r_shadow_shadowmappcf > 1)
6817 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6818 else if (r_shadow_shadowmappcf)
6819 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6821 if (rsurface.texture->reflectmasktexture)
6822 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6823 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6824 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
6825 allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE);
6827 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
6829 if (r_glsl_offsetmapping.integer)
6831 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6832 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6833 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6834 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6835 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6837 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6838 if (r_glsl_offsetmapping_reliefmapping.integer)
6839 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6842 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6843 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6844 // unshaded geometry (fullbright or ambient model lighting)
6845 mode = SHADERMODE_FLATCOLOR;
6846 ambientscale = diffusescale = specularscale = 0;
6847 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
6848 permutation |= SHADERPERMUTATION_GLOW;
6849 if (r_refdef.fogenabled)
6850 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6851 if (rsurface.texture->colormapping)
6852 permutation |= SHADERPERMUTATION_COLORMAPPING;
6853 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
6855 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
6856 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6858 if (r_shadow_shadowmapsampler)
6859 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6860 if (r_shadow_shadowmappcf > 1)
6861 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6862 else if (r_shadow_shadowmappcf)
6863 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6865 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
6866 permutation |= SHADERPERMUTATION_REFLECTION;
6867 if (rsurface.texture->reflectmasktexture)
6868 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6869 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6870 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6871 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6873 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
6875 if (r_glsl_offsetmapping.integer)
6877 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6878 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6879 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6880 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6881 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6883 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6884 if (r_glsl_offsetmapping_reliefmapping.integer)
6885 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6888 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6889 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6890 // directional model lighting
6891 mode = SHADERMODE_LIGHTDIRECTION;
6892 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
6893 permutation |= SHADERPERMUTATION_GLOW;
6894 permutation |= SHADERPERMUTATION_DIFFUSE;
6895 if (specularscale > 0)
6896 permutation |= SHADERPERMUTATION_SPECULAR;
6897 if (r_refdef.fogenabled)
6898 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6899 if (rsurface.texture->colormapping)
6900 permutation |= SHADERPERMUTATION_COLORMAPPING;
6901 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
6903 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
6904 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6906 if (r_shadow_shadowmapsampler)
6907 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6908 if (r_shadow_shadowmappcf > 1)
6909 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6910 else if (r_shadow_shadowmappcf)
6911 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6913 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
6914 permutation |= SHADERPERMUTATION_REFLECTION;
6915 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
6916 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
6917 if (rsurface.texture->reflectmasktexture)
6918 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6919 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6920 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6921 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6923 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
6925 if (r_glsl_offsetmapping.integer)
6927 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6928 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6929 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6930 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6931 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6933 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6934 if (r_glsl_offsetmapping_reliefmapping.integer)
6935 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6938 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6939 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6940 // ambient model lighting
6941 mode = SHADERMODE_LIGHTDIRECTION;
6942 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
6943 permutation |= SHADERPERMUTATION_GLOW;
6944 if (r_refdef.fogenabled)
6945 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6946 if (rsurface.texture->colormapping)
6947 permutation |= SHADERPERMUTATION_COLORMAPPING;
6948 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
6950 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
6951 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6953 if (r_shadow_shadowmapsampler)
6954 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
6955 if (r_shadow_shadowmappcf > 1)
6956 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
6957 else if (r_shadow_shadowmappcf)
6958 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
6960 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
6961 permutation |= SHADERPERMUTATION_REFLECTION;
6962 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
6963 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
6964 if (rsurface.texture->reflectmasktexture)
6965 permutation |= SHADERPERMUTATION_REFLECTCUBE;
6966 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
6967 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6968 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
6972 if (r_glsl_offsetmapping.integer)
6974 if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
6975 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6976 else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
6977 permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6978 else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
6980 permutation |= SHADERPERMUTATION_OFFSETMAPPING;
6981 if (r_glsl_offsetmapping_reliefmapping.integer)
6982 permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
6985 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
6986 permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
6988 if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer)
6989 permutation |= SHADERPERMUTATION_GLOW;
6990 if (r_refdef.fogenabled)
6991 permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
6992 if (rsurface.texture->colormapping)
6993 permutation |= SHADERPERMUTATION_COLORMAPPING;
6994 if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
6996 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
6997 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
6999 if (r_shadow_shadowmapsampler)
7000 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
7001 if (r_shadow_shadowmappcf > 1)
7002 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
7003 else if (r_shadow_shadowmappcf)
7004 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
7006 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
7007 permutation |= SHADERPERMUTATION_REFLECTION;
7008 if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED))
7009 permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
7010 if (rsurface.texture->reflectmasktexture)
7011 permutation |= SHADERPERMUTATION_REFLECTCUBE;
7012 if (FAKELIGHT_ENABLED)
7014 // fake lightmapping (q1bsp, q3bsp, fullbright map)
7015 mode = SHADERMODE_FAKELIGHT;
7016 permutation |= SHADERPERMUTATION_DIFFUSE;
7017 if (specularscale > 0)
7018 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7020 else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
7022 // deluxemapping (light direction texture)
7023 if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
7024 mode = SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE;
7026 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
7027 permutation |= SHADERPERMUTATION_DIFFUSE;
7028 if (specularscale > 0)
7029 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7031 else if (r_glsl_deluxemapping.integer >= 2 && rsurface.uselightmaptexture)
7033 // fake deluxemapping (uniform light direction in tangentspace)
7034 mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
7035 permutation |= SHADERPERMUTATION_DIFFUSE;
7036 if (specularscale > 0)
7037 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7039 else if (rsurface.uselightmaptexture)
7041 // ordinary lightmapping (q1bsp, q3bsp)
7042 mode = SHADERMODE_LIGHTMAP;
7046 // ordinary vertex coloring (q3bsp)
7047 mode = SHADERMODE_VERTEXCOLOR;
7049 GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
7050 GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
7051 allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
7054 colormod = dummy_colormod;
7055 switch(vid.renderpath)
7057 case RENDERPATH_D3D9:
7059 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);
7060 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
7061 R_SetupShader_SetPermutationHLSL(mode, permutation);
7062 Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
7063 if (mode == SHADERMODE_LIGHTSOURCE)
7065 Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
7066 hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7070 if (mode == SHADERMODE_LIGHTDIRECTION)
7072 hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
7075 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
7076 Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
7077 Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
7078 hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7079 hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
7081 if (mode == SHADERMODE_LIGHTSOURCE)
7083 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7084 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
7085 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
7086 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
7087 hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
7089 // additive passes are only darkened by fog, not tinted
7090 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
7091 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7095 if (mode == SHADERMODE_FLATCOLOR)
7097 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
7099 else if (mode == SHADERMODE_LIGHTDIRECTION)
7101 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]);
7102 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
7103 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);
7104 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);
7105 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7106 hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
7107 hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
7111 hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
7112 hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
7113 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);
7114 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);
7115 hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7117 // additive passes are only darkened by fog, not tinted
7118 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7119 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
7121 hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7122 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);
7123 hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
7124 hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
7125 hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
7126 hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
7127 hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
7128 hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
7129 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7130 if (mode == SHADERMODE_WATER)
7131 hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
7133 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7134 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7135 hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
7136 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));
7137 hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7138 if (rsurface.texture->pantstexture)
7139 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7141 hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
7142 if (rsurface.texture->shirttexture)
7143 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7145 hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
7146 hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
7147 hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
7148 hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
7149 hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
7150 hlslPSSetParameter1f(D3DPSREGISTER_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
7151 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7152 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
7154 R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
7155 R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
7156 R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
7157 R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
7158 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
7159 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
7160 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
7161 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
7162 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
7163 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
7164 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
7165 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
7166 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
7167 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
7168 R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
7169 R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
7170 if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7171 if (rsurfacepass == RSURFPASS_BACKGROUND)
7173 R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
7174 if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
7175 R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7179 if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7181 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
7182 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7183 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
7184 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
7185 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7187 R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
7188 if (rsurface.rtlight)
7190 if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7191 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7196 case RENDERPATH_D3D10:
7197 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7199 case RENDERPATH_D3D11:
7200 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7202 case RENDERPATH_GL20:
7203 case RENDERPATH_GLES2:
7204 if (!vid.useinterleavedarrays)
7206 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);
7207 R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
7208 R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
7209 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
7210 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
7211 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
7212 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
7213 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
7217 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);
7218 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
7220 R_SetupShader_SetPermutationGLSL(mode, permutation);
7221 if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
7222 if (mode == SHADERMODE_LIGHTSOURCE)
7224 if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
7225 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7226 if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
7227 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
7228 if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
7229 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);
7231 // additive passes are only darkened by fog, not tinted
7232 if (r_glsl_permutation->loc_FogColor >= 0)
7233 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
7234 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7238 if (mode == SHADERMODE_FLATCOLOR)
7240 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
7242 else if (mode == SHADERMODE_LIGHTDIRECTION)
7244 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]);
7245 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]);
7246 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);
7247 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);
7248 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);
7249 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]);
7250 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]);
7254 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]);
7255 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]);
7256 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);
7257 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);
7258 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);
7260 // additive passes are only darkened by fog, not tinted
7261 if (r_glsl_permutation->loc_FogColor >= 0)
7263 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7264 qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
7266 qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7268 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);
7269 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]);
7270 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]);
7271 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]);
7272 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]);
7273 if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
7274 if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
7275 if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7276 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]);
7278 if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
7279 if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
7280 if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
7281 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]);
7282 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]);
7284 if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
7285 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));
7286 if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7287 if (r_glsl_permutation->loc_Color_Pants >= 0)
7289 if (rsurface.texture->pantstexture)
7290 qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7292 qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
7294 if (r_glsl_permutation->loc_Color_Shirt >= 0)
7296 if (rsurface.texture->shirttexture)
7297 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7299 qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
7301 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]);
7302 if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
7303 if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
7304 if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
7305 if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale);
7306 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]);
7307 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
7309 if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white );
7310 if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white );
7311 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps , r_texture_gammaramps );
7312 if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , rsurface.texture->nmaptexture );
7313 if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , rsurface.texture->basetexture );
7314 if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , rsurface.texture->glosstexture );
7315 if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , rsurface.texture->glowtexture );
7316 if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , rsurface.texture->backgroundnmaptexture );
7317 if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );
7318 if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );
7319 if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );
7320 if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , rsurface.texture->pantstexture );
7321 if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , rsurface.texture->shirttexture );
7322 if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , rsurface.texture->reflectmasktexture );
7323 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);
7324 if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture );
7325 if (r_glsl_permutation->tex_Texture_FogMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask , r_texture_fogattenuation );
7326 if (r_glsl_permutation->tex_Texture_Lightmap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
7327 if (r_glsl_permutation->tex_Texture_Deluxemap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
7328 if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
7329 if (rsurfacepass == RSURFPASS_BACKGROUND)
7331 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);
7332 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);
7333 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);
7337 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);
7339 if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );
7340 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
7341 if (r_glsl_permutation->tex_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );
7342 if (r_glsl_permutation->tex_Texture_ScreenSpecular >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );
7343 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7345 if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2dtexture );
7346 if (rsurface.rtlight)
7348 if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
7349 if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
7354 case RENDERPATH_CGGL:
7356 if (!vid.useinterleavedarrays)
7358 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);
7359 R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
7360 R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
7361 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
7362 R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
7363 R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
7364 R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
7365 R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
7369 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);
7370 R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
7372 R_SetupShader_SetPermutationCG(mode, permutation);
7373 if (r_cg_permutation->fp_ModelToReflectCube) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->fp_ModelToReflectCube, m16f);}CHECKCGERROR
7374 if (mode == SHADERMODE_LIGHTSOURCE)
7376 if (r_cg_permutation->vp_ModelToLight) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelToLight, m16f);}CHECKCGERROR
7377 if (r_cg_permutation->vp_LightPosition) cgGLSetParameter3f(r_cg_permutation->vp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);CHECKCGERROR
7381 if (mode == SHADERMODE_LIGHTDIRECTION)
7383 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
7386 if (r_cg_permutation->vp_TexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_TexMatrix, m16f);}CHECKCGERROR
7387 if (r_cg_permutation->vp_BackgroundTexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_BackgroundTexMatrix, m16f);}CHECKCGERROR
7388 if (r_cg_permutation->vp_ShadowMapMatrix) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ShadowMapMatrix, m16f);}CHECKGLERROR
7389 if (r_cg_permutation->vp_EyePosition) cgGLSetParameter3f(r_cg_permutation->vp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
7390 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
7393 if (mode == SHADERMODE_LIGHTSOURCE)
7395 if (r_cg_permutation->fp_LightPosition) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);CHECKCGERROR
7396 if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKCGERROR
7397 if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);CHECKCGERROR
7398 if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);CHECKCGERROR
7399 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
7401 // additive passes are only darkened by fog, not tinted
7402 if (r_cg_permutation->fp_FogColor) cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);CHECKCGERROR
7403 if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
7407 if (mode == SHADERMODE_FLATCOLOR)
7409 if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, colormod[0], colormod[1], colormod[2]);CHECKCGERROR
7411 else if (mode == SHADERMODE_LIGHTDIRECTION)
7413 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
7414 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
7415 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
7416 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
7417 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
7418 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
7419 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
7423 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
7424 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
7425 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
7426 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
7427 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
7429 // additive passes are only darkened by fog, not tinted
7430 if (r_cg_permutation->fp_FogColor)
7432 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7433 cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);
7435 cgGLSetParameter3f(r_cg_permutation->fp_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7438 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
7439 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
7440 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
7441 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
7442 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
7443 if (r_cg_permutation->fp_ReflectFactor) cgGLSetParameter1f(r_cg_permutation->fp_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);CHECKCGERROR
7444 if (r_cg_permutation->fp_ReflectOffset) cgGLSetParameter1f(r_cg_permutation->fp_ReflectOffset, rsurface.texture->reflectmin);CHECKCGERROR
7445 if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
7446 if (r_cg_permutation->fp_NormalmapScrollBlend) cgGLSetParameter2f(r_cg_permutation->fp_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
7448 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
7449 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
7450 if (r_cg_permutation->fp_Color_Glow) cgGLSetParameter3f(r_cg_permutation->fp_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);CHECKCGERROR
7451 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
7452 if (r_cg_permutation->fp_EyePosition) cgGLSetParameter3f(r_cg_permutation->fp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
7453 if (r_cg_permutation->fp_Color_Pants)
7455 if (rsurface.texture->pantstexture)
7456 cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7458 cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, 0, 0, 0);
7461 if (r_cg_permutation->fp_Color_Shirt)
7463 if (rsurface.texture->shirttexture)
7464 cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7466 cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, 0, 0, 0);
7469 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
7470 if (r_cg_permutation->fp_FogPlaneViewDist) cgGLSetParameter1f(r_cg_permutation->fp_FogPlaneViewDist, rsurface.fogplaneviewdist);CHECKCGERROR
7471 if (r_cg_permutation->fp_FogRangeRecip) cgGLSetParameter1f(r_cg_permutation->fp_FogRangeRecip, rsurface.fograngerecip);CHECKCGERROR
7472 if (r_cg_permutation->fp_FogHeightFade) cgGLSetParameter1f(r_cg_permutation->fp_FogHeightFade, rsurface.fogheightfade);CHECKCGERROR
7473 if (r_cg_permutation->fp_OffsetMapping_Scale) cgGLSetParameter1f(r_cg_permutation->fp_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);CHECKCGERROR
7474 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
7475 if (r_cg_permutation->fp_PixelToScreenTexCoord) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
7477 // if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , r_texture_white );CHECKCGERROR
7478 // if (r_cg_permutation->fp_Texture_Second ) CG_BindTexture(r_cg_permutation->fp_Texture_Second , r_texture_white );CHECKCGERROR
7479 // if (r_cg_permutation->fp_Texture_GammaRamps ) CG_BindTexture(r_cg_permutation->fp_Texture_GammaRamps , r_texture_gammaramps );CHECKCGERROR
7480 if (r_cg_permutation->fp_Texture_Normal ) CG_BindTexture(r_cg_permutation->fp_Texture_Normal , rsurface.texture->nmaptexture );CHECKCGERROR
7481 if (r_cg_permutation->fp_Texture_Color ) CG_BindTexture(r_cg_permutation->fp_Texture_Color , rsurface.texture->basetexture );CHECKCGERROR
7482 if (r_cg_permutation->fp_Texture_Gloss ) CG_BindTexture(r_cg_permutation->fp_Texture_Gloss , rsurface.texture->glosstexture );CHECKCGERROR
7483 if (r_cg_permutation->fp_Texture_Glow ) CG_BindTexture(r_cg_permutation->fp_Texture_Glow , rsurface.texture->glowtexture );CHECKCGERROR
7484 if (r_cg_permutation->fp_Texture_SecondaryNormal) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryNormal, rsurface.texture->backgroundnmaptexture );CHECKCGERROR
7485 if (r_cg_permutation->fp_Texture_SecondaryColor ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );CHECKCGERROR
7486 if (r_cg_permutation->fp_Texture_SecondaryGloss ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );CHECKCGERROR
7487 if (r_cg_permutation->fp_Texture_SecondaryGlow ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );CHECKCGERROR
7488 if (r_cg_permutation->fp_Texture_Pants ) CG_BindTexture(r_cg_permutation->fp_Texture_Pants , rsurface.texture->pantstexture );CHECKCGERROR
7489 if (r_cg_permutation->fp_Texture_Shirt ) CG_BindTexture(r_cg_permutation->fp_Texture_Shirt , rsurface.texture->shirttexture );CHECKCGERROR
7490 if (r_cg_permutation->fp_Texture_ReflectMask ) CG_BindTexture(r_cg_permutation->fp_Texture_ReflectMask , rsurface.texture->reflectmasktexture );CHECKCGERROR
7491 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
7492 if (r_cg_permutation->fp_Texture_FogHeightTexture) CG_BindTexture(r_cg_permutation->fp_Texture_FogHeightTexture, r_texture_fogheighttexture );CHECKCGERROR
7493 if (r_cg_permutation->fp_Texture_FogMask ) CG_BindTexture(r_cg_permutation->fp_Texture_FogMask , r_texture_fogattenuation );CHECKCGERROR
7494 if (r_cg_permutation->fp_Texture_Lightmap ) CG_BindTexture(r_cg_permutation->fp_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);CHECKCGERROR
7495 if (r_cg_permutation->fp_Texture_Deluxemap ) CG_BindTexture(r_cg_permutation->fp_Texture_Deluxemap , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);CHECKCGERROR
7496 if (r_cg_permutation->fp_Texture_Attenuation ) CG_BindTexture(r_cg_permutation->fp_Texture_Attenuation , r_shadow_attenuationgradienttexture );CHECKCGERROR
7497 if (rsurfacepass == RSURFPASS_BACKGROUND)
7499 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
7500 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
7501 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
7505 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
7507 if (r_cg_permutation->fp_Texture_ScreenDepth ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );CHECKCGERROR
7508 if (r_cg_permutation->fp_Texture_ScreenNormalMap) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture );CHECKCGERROR
7509 if (r_cg_permutation->fp_Texture_ScreenDiffuse ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );CHECKCGERROR
7510 if (r_cg_permutation->fp_Texture_ScreenSpecular ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );CHECKCGERROR
7511 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7513 if (r_cg_permutation->fp_Texture_ShadowMap2D ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );CHECKCGERROR
7514 if (rsurface.rtlight)
7516 if (r_cg_permutation->fp_Texture_Cube ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube , rsurface.rtlight->currentcubemap );CHECKCGERROR
7517 if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );CHECKCGERROR
7524 case RENDERPATH_GL13:
7525 case RENDERPATH_GL11:
7527 case RENDERPATH_SOFT:
7528 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);
7529 R_Mesh_PrepareVertices_Mesh_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchsvector3f, rsurface.batchtvector3f, rsurface.batchnormal3f, rsurface.batchlightmapcolor4f, rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f);
7530 R_SetupShader_SetPermutationSoft(mode, permutation);
7531 {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
7532 if (mode == SHADERMODE_LIGHTSOURCE)
7534 {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
7535 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
7536 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
7537 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
7538 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
7539 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
7541 // additive passes are only darkened by fog, not tinted
7542 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
7543 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7547 if (mode == SHADERMODE_FLATCOLOR)
7549 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
7551 else if (mode == SHADERMODE_LIGHTDIRECTION)
7553 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]);
7554 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
7555 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);
7556 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);
7557 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7558 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]);
7559 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
7563 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
7564 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
7565 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);
7566 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);
7567 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
7569 // additive passes are only darkened by fog, not tinted
7570 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
7571 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
7573 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
7574 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);
7575 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
7576 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
7577 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]);
7578 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]);
7579 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
7580 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
7581 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7582 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
7584 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
7585 {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
7586 {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
7587 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7588 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]);
7590 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
7591 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));
7592 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
7593 if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
7595 if (rsurface.texture->pantstexture)
7596 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
7598 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
7600 if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
7602 if (rsurface.texture->shirttexture)
7603 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
7605 DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
7607 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
7608 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist);
7609 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
7610 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
7611 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale);
7612 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7613 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
7615 R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
7616 R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
7617 R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
7618 R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
7619 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
7620 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
7621 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
7622 if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
7623 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
7624 if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
7625 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
7626 if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
7627 if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
7628 if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
7629 R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
7630 R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
7631 if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7632 if (rsurfacepass == RSURFPASS_BACKGROUND)
7634 R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
7635 if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
7636 R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7640 if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
7642 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
7643 // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7644 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
7645 if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
7646 if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
7648 R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
7649 if (rsurface.rtlight)
7651 if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7652 if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7659 void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
7661 // select a permutation of the lighting shader appropriate to this
7662 // combination of texture, entity, light source, and fogging, only use the
7663 // minimum features necessary to avoid wasting rendering time in the
7664 // fragment shader on features that are not being used
7665 unsigned int permutation = 0;
7666 unsigned int mode = 0;
7667 const float *lightcolorbase = rtlight->currentcolor;
7668 float ambientscale = rtlight->ambientscale;
7669 float diffusescale = rtlight->diffusescale;
7670 float specularscale = rtlight->specularscale;
7671 // this is the location of the light in view space
7672 vec3_t viewlightorigin;
7673 // this transforms from view space (camera) to light space (cubemap)
7674 matrix4x4_t viewtolight;
7675 matrix4x4_t lighttoview;
7676 float viewtolight16f[16];
7677 float range = 1.0f / r_shadow_deferred_8bitrange.value;
7679 mode = SHADERMODE_DEFERREDLIGHTSOURCE;
7680 if (rtlight->currentcubemap != r_texture_whitecube)
7681 permutation |= SHADERPERMUTATION_CUBEFILTER;
7682 if (diffusescale > 0)
7683 permutation |= SHADERPERMUTATION_DIFFUSE;
7684 if (specularscale > 0)
7685 permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
7686 if (r_shadow_usingshadowmap2d)
7688 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
7689 if (r_shadow_shadowmapvsdct)
7690 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
7692 if (r_shadow_shadowmapsampler)
7693 permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
7694 if (r_shadow_shadowmappcf > 1)
7695 permutation |= SHADERPERMUTATION_SHADOWMAPPCF2;
7696 else if (r_shadow_shadowmappcf)
7697 permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
7699 Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
7700 Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
7701 Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
7702 Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
7703 switch(vid.renderpath)
7705 case RENDERPATH_D3D9:
7707 R_SetupShader_SetPermutationHLSL(mode, permutation);
7708 hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
7709 hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f);
7710 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
7711 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
7712 hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
7713 hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7714 hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
7715 hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
7716 hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7717 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
7719 R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7720 R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthcolortexture );
7721 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7722 R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7723 R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dcolortexture );
7724 R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7727 case RENDERPATH_D3D10:
7728 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7730 case RENDERPATH_D3D11:
7731 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
7733 case RENDERPATH_GL20:
7734 case RENDERPATH_GLES2:
7735 R_SetupShader_SetPermutationGLSL(mode, permutation);
7736 if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f( r_glsl_permutation->loc_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
7737 if (r_glsl_permutation->loc_ViewToLight >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ViewToLight , 1, false, viewtolight16f);
7738 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);
7739 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);
7740 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);
7741 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]);
7742 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]);
7743 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));
7744 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]);
7745 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height);
7747 if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
7748 if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );
7749 if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
7750 if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
7751 if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );
7752 if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
7754 case RENDERPATH_CGGL:
7756 R_SetupShader_SetPermutationCG(mode, permutation);
7757 if (r_cg_permutation->fp_LightPosition ) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);CHECKCGERROR
7758 if (r_cg_permutation->fp_ViewToLight ) cgGLSetMatrixParameterfc(r_cg_permutation->fp_ViewToLight, viewtolight16f);CHECKCGERROR
7759 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
7760 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
7761 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
7762 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
7763 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
7764 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
7765 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
7766 if (r_cg_permutation->fp_PixelToScreenTexCoord ) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
7768 if (r_cg_permutation->fp_Texture_Attenuation ) CG_BindTexture(r_cg_permutation->fp_Texture_Attenuation , r_shadow_attenuationgradienttexture );CHECKCGERROR
7769 if (r_cg_permutation->fp_Texture_ScreenDepth ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );CHECKCGERROR
7770 if (r_cg_permutation->fp_Texture_ScreenNormalMap ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture );CHECKCGERROR
7771 if (r_cg_permutation->fp_Texture_Cube ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube , rsurface.rtlight->currentcubemap );CHECKCGERROR
7772 if (r_cg_permutation->fp_Texture_ShadowMap2D ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );CHECKCGERROR
7773 if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );CHECKCGERROR
7776 case RENDERPATH_GL13:
7777 case RENDERPATH_GL11:
7779 case RENDERPATH_SOFT:
7780 R_SetupShader_SetPermutationGLSL(mode, permutation);
7781 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
7782 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ViewToLightM1 , 1, false, viewtolight16f);
7783 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
7784 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
7785 DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
7786 DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
7787 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]);
7788 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));
7789 DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
7790 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
7792 R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
7793 R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
7794 R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
7795 R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
7796 R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dtexture );
7797 R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
7802 #define SKINFRAME_HASH 1024
7806 int loadsequence; // incremented each level change
7807 memexpandablearray_t array;
7808 skinframe_t *hash[SKINFRAME_HASH];
7811 r_skinframe_t r_skinframe;
7813 void R_SkinFrame_PrepareForPurge(void)
7815 r_skinframe.loadsequence++;
7816 // wrap it without hitting zero
7817 if (r_skinframe.loadsequence >= 200)
7818 r_skinframe.loadsequence = 1;
7821 void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
7825 // mark the skinframe as used for the purging code
7826 skinframe->loadsequence = r_skinframe.loadsequence;
7829 void R_SkinFrame_Purge(void)
7833 for (i = 0;i < SKINFRAME_HASH;i++)
7835 for (s = r_skinframe.hash[i];s;s = s->next)
7837 if (s->loadsequence && s->loadsequence != r_skinframe.loadsequence)
7839 if (s->merged == s->base)
7841 // FIXME: maybe pass a pointer to the pointer to R_PurgeTexture and reset it to NULL inside? [11/29/2007 Black]
7842 R_PurgeTexture(s->stain );s->stain = NULL;
7843 R_PurgeTexture(s->merged);s->merged = NULL;
7844 R_PurgeTexture(s->base );s->base = NULL;
7845 R_PurgeTexture(s->pants );s->pants = NULL;
7846 R_PurgeTexture(s->shirt );s->shirt = NULL;
7847 R_PurgeTexture(s->nmap );s->nmap = NULL;
7848 R_PurgeTexture(s->gloss );s->gloss = NULL;
7849 R_PurgeTexture(s->glow );s->glow = NULL;
7850 R_PurgeTexture(s->fog );s->fog = NULL;
7851 R_PurgeTexture(s->reflect);s->reflect = NULL;
7852 s->loadsequence = 0;
7858 skinframe_t *R_SkinFrame_FindNextByName( skinframe_t *last, const char *name ) {
7860 char basename[MAX_QPATH];
7862 Image_StripImageExtension(name, basename, sizeof(basename));
7864 if( last == NULL ) {
7866 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
7867 item = r_skinframe.hash[hashindex];
7872 // linearly search through the hash bucket
7873 for( ; item ; item = item->next ) {
7874 if( !strcmp( item->basename, basename ) ) {
7881 skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qboolean add)
7885 char basename[MAX_QPATH];
7887 Image_StripImageExtension(name, basename, sizeof(basename));
7889 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
7890 for (item = r_skinframe.hash[hashindex];item;item = item->next)
7891 if (!strcmp(item->basename, basename) && item->textureflags == textureflags && item->comparewidth == comparewidth && item->compareheight == compareheight && item->comparecrc == comparecrc)
7895 rtexture_t *dyntexture;
7896 // check whether its a dynamic texture
7897 dyntexture = CL_GetDynTexture( basename );
7898 if (!add && !dyntexture)
7900 item = (skinframe_t *)Mem_ExpandableArray_AllocRecord(&r_skinframe.array);
7901 memset(item, 0, sizeof(*item));
7902 strlcpy(item->basename, basename, sizeof(item->basename));
7903 item->base = dyntexture; // either NULL or dyntexture handle
7904 item->textureflags = textureflags;
7905 item->comparewidth = comparewidth;
7906 item->compareheight = compareheight;
7907 item->comparecrc = comparecrc;
7908 item->next = r_skinframe.hash[hashindex];
7909 r_skinframe.hash[hashindex] = item;
7911 else if( item->base == NULL )
7913 rtexture_t *dyntexture;
7914 // check whether its a dynamic texture
7915 // 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]
7916 dyntexture = CL_GetDynTexture( basename );
7917 item->base = dyntexture; // either NULL or dyntexture handle
7920 R_SkinFrame_MarkUsed(item);
7924 #define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \
7926 unsigned long long avgcolor[5], wsum; \
7934 for(pix = 0; pix < cnt; ++pix) \
7937 for(comp = 0; comp < 3; ++comp) \
7939 if(w) /* ignore perfectly black pixels because that is better for model skins */ \
7942 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
7944 for(comp = 0; comp < 3; ++comp) \
7945 avgcolor[comp] += getpixel * w; \
7948 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
7949 avgcolor[4] += getpixel; \
7951 if(avgcolor[3] == 0) /* no pixels seen? even worse */ \
7953 skinframe->avgcolor[0] = avgcolor[2] / (255.0 * avgcolor[3]); \
7954 skinframe->avgcolor[1] = avgcolor[1] / (255.0 * avgcolor[3]); \
7955 skinframe->avgcolor[2] = avgcolor[0] / (255.0 * avgcolor[3]); \
7956 skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \
7959 extern cvar_t gl_picmip;
7960 skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain)
7963 unsigned char *pixels;
7964 unsigned char *bumppixels;
7965 unsigned char *basepixels = NULL;
7966 int basepixels_width = 0;
7967 int basepixels_height = 0;
7968 skinframe_t *skinframe;
7969 rtexture_t *ddsbase = NULL;
7970 qboolean ddshasalpha = false;
7971 float ddsavgcolor[4];
7972 char basename[MAX_QPATH];
7973 int miplevel = R_PicmipForFlags(textureflags);
7974 int savemiplevel = miplevel;
7977 if (cls.state == ca_dedicated)
7980 // return an existing skinframe if already loaded
7981 // if loading of the first image fails, don't make a new skinframe as it
7982 // would cause all future lookups of this to be missing
7983 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
7984 if (skinframe && skinframe->base)
7987 Image_StripImageExtension(name, basename, sizeof(basename));
7989 // check for DDS texture file first
7990 if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
7992 basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer != 0, &miplevel);
7993 if (basepixels == NULL)
7997 // FIXME handle miplevel
7999 if (developer_loading.integer)
8000 Con_Printf("loading skin \"%s\"\n", name);
8002 // we've got some pixels to store, so really allocate this new texture now
8004 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, true);
8005 skinframe->stain = NULL;
8006 skinframe->merged = NULL;
8007 skinframe->base = NULL;
8008 skinframe->pants = NULL;
8009 skinframe->shirt = NULL;
8010 skinframe->nmap = NULL;
8011 skinframe->gloss = NULL;
8012 skinframe->glow = NULL;
8013 skinframe->fog = NULL;
8014 skinframe->reflect = NULL;
8015 skinframe->hasalpha = false;
8019 skinframe->base = ddsbase;
8020 skinframe->hasalpha = ddshasalpha;
8021 VectorCopy(ddsavgcolor, skinframe->avgcolor);
8022 if (r_loadfog && skinframe->hasalpha)
8023 skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
8024 //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]);
8028 basepixels_width = image_width;
8029 basepixels_height = image_height;
8030 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);
8031 if (textureflags & TEXF_ALPHA)
8033 for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
8035 if (basepixels[j] < 255)
8037 skinframe->hasalpha = true;
8041 if (r_loadfog && skinframe->hasalpha)
8043 // has transparent pixels
8044 pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
8045 for (j = 0;j < image_width * image_height * 4;j += 4)
8050 pixels[j+3] = basepixels[j+3];
8052 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);
8056 R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
8057 //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]);
8058 if (r_savedds && qglGetCompressedTexImageARB && skinframe->base)
8059 R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true, skinframe->hasalpha);
8060 if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog)
8061 R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true, true);
8066 mymiplevel = savemiplevel;
8067 if (r_loadnormalmap)
8068 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);
8069 skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8071 skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8072 skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8073 skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8074 skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
8077 // _norm is the name used by tenebrae and has been adopted as standard
8078 if (r_loadnormalmap && skinframe->nmap == NULL)
8080 mymiplevel = savemiplevel;
8081 if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
8083 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);
8087 else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
8089 pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
8090 Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value);
8091 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);
8093 Mem_Free(bumppixels);
8095 else if (r_shadow_bumpscale_basetexture.value > 0)
8097 pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4);
8098 Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value);
8099 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);
8102 if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap)
8103 R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true, true);
8106 // _luma is supported only for tenebrae compatibility
8107 // _glow is the preferred name
8108 mymiplevel = savemiplevel;
8109 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))))
8111 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);
8112 if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
8113 R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true, true);
8114 Mem_Free(pixels);pixels = NULL;
8117 mymiplevel = savemiplevel;
8118 if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8120 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);
8121 if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
8122 R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true, true);
8127 mymiplevel = savemiplevel;
8128 if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8130 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);
8131 if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
8132 R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true, false);
8137 mymiplevel = savemiplevel;
8138 if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8140 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);
8141 if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
8142 R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true, false);
8147 mymiplevel = savemiplevel;
8148 if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
8150 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);
8151 if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
8152 R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true, true);
8158 Mem_Free(basepixels);
8163 // this is only used by .spr32 sprites, HL .spr files, HL .bsp files
8164 skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height)
8167 unsigned char *temp1, *temp2;
8168 skinframe_t *skinframe;
8170 if (cls.state == ca_dedicated)
8173 // if already loaded just return it, otherwise make a new skinframe
8174 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height*4) : 0, true);
8175 if (skinframe && skinframe->base)
8178 skinframe->stain = NULL;
8179 skinframe->merged = NULL;
8180 skinframe->base = NULL;
8181 skinframe->pants = NULL;
8182 skinframe->shirt = NULL;
8183 skinframe->nmap = NULL;
8184 skinframe->gloss = NULL;
8185 skinframe->glow = NULL;
8186 skinframe->fog = NULL;
8187 skinframe->reflect = NULL;
8188 skinframe->hasalpha = false;
8190 // if no data was provided, then clearly the caller wanted to get a blank skinframe
8194 if (developer_loading.integer)
8195 Con_Printf("loading 32bit skin \"%s\"\n", name);
8197 if (r_loadnormalmap && r_shadow_bumpscale_basetexture.value > 0)
8199 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
8200 temp2 = temp1 + width * height * 4;
8201 Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
8202 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);
8205 skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, textureflags, -1, NULL);
8206 if (textureflags & TEXF_ALPHA)
8208 for (i = 3;i < width * height * 4;i += 4)
8210 if (skindata[i] < 255)
8212 skinframe->hasalpha = true;
8216 if (r_loadfog && skinframe->hasalpha)
8218 unsigned char *fogpixels = (unsigned char *)Mem_Alloc(tempmempool, width * height * 4);
8219 memcpy(fogpixels, skindata, width * height * 4);
8220 for (i = 0;i < width * height * 4;i += 4)
8221 fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
8222 skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, textureflags, -1, NULL);
8223 Mem_Free(fogpixels);
8227 R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, skindata[4 * pix + comp]);
8228 //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]);
8233 skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height)
8237 skinframe_t *skinframe;
8239 if (cls.state == ca_dedicated)
8242 // if already loaded just return it, otherwise make a new skinframe
8243 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
8244 if (skinframe && skinframe->base)
8247 skinframe->stain = NULL;
8248 skinframe->merged = NULL;
8249 skinframe->base = NULL;
8250 skinframe->pants = NULL;
8251 skinframe->shirt = NULL;
8252 skinframe->nmap = NULL;
8253 skinframe->gloss = NULL;
8254 skinframe->glow = NULL;
8255 skinframe->fog = NULL;
8256 skinframe->reflect = NULL;
8257 skinframe->hasalpha = false;
8259 // if no data was provided, then clearly the caller wanted to get a blank skinframe
8263 if (developer_loading.integer)
8264 Con_Printf("loading quake skin \"%s\"\n", name);
8266 // 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)
8267 skinframe->qpixels = (unsigned char *)Mem_Alloc(r_main_mempool, width*height); // FIXME LEAK
8268 memcpy(skinframe->qpixels, skindata, width*height);
8269 skinframe->qwidth = width;
8270 skinframe->qheight = height;
8273 for (i = 0;i < width * height;i++)
8274 featuresmask |= palette_featureflags[skindata[i]];
8276 skinframe->hasalpha = false;
8277 skinframe->qhascolormapping = loadpantsandshirt && (featuresmask & (PALETTEFEATURE_PANTS | PALETTEFEATURE_SHIRT));
8278 skinframe->qgeneratenmap = r_shadow_bumpscale_basetexture.value > 0;
8279 skinframe->qgeneratemerged = true;
8280 skinframe->qgeneratebase = skinframe->qhascolormapping;
8281 skinframe->qgenerateglow = loadglowtexture && (featuresmask & PALETTEFEATURE_GLOW);
8283 R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette_bgra_complete)[skindata[pix]*4 + comp]);
8284 //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]);
8289 static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboolean colormapped)
8293 unsigned char *skindata;
8295 if (!skinframe->qpixels)
8298 if (!skinframe->qhascolormapping)
8299 colormapped = false;
8303 if (!skinframe->qgeneratebase)
8308 if (!skinframe->qgeneratemerged)
8312 width = skinframe->qwidth;
8313 height = skinframe->qheight;
8314 skindata = skinframe->qpixels;
8316 if (skinframe->qgeneratenmap)
8318 unsigned char *temp1, *temp2;
8319 skinframe->qgeneratenmap = false;
8320 temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
8321 temp2 = temp1 + width * height * 4;
8322 // use either a custom palette or the quake palette
8323 Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
8324 Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
8325 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);
8329 if (skinframe->qgenerateglow)
8331 skinframe->qgenerateglow = false;
8332 skinframe->glow = R_LoadTexture2D(r_main_texturepool, va("%s_glow", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow
8337 skinframe->qgeneratebase = false;
8338 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);
8339 skinframe->pants = R_LoadTexture2D(r_main_texturepool, va("%s_pants", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_pantsaswhite);
8340 skinframe->shirt = R_LoadTexture2D(r_main_texturepool, va("%s_shirt", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_shirtaswhite);
8344 skinframe->qgeneratemerged = false;
8345 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);
8348 if (!skinframe->qgeneratemerged && !skinframe->qgeneratebase)
8350 Mem_Free(skinframe->qpixels);
8351 skinframe->qpixels = NULL;
8355 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)
8358 skinframe_t *skinframe;
8360 if (cls.state == ca_dedicated)
8363 // if already loaded just return it, otherwise make a new skinframe
8364 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
8365 if (skinframe && skinframe->base)
8368 skinframe->stain = NULL;
8369 skinframe->merged = NULL;
8370 skinframe->base = NULL;
8371 skinframe->pants = NULL;
8372 skinframe->shirt = NULL;
8373 skinframe->nmap = NULL;
8374 skinframe->gloss = NULL;
8375 skinframe->glow = NULL;
8376 skinframe->fog = NULL;
8377 skinframe->reflect = NULL;
8378 skinframe->hasalpha = false;
8380 // if no data was provided, then clearly the caller wanted to get a blank skinframe
8384 if (developer_loading.integer)
8385 Con_Printf("loading embedded 8bit image \"%s\"\n", name);
8387 skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, palette);
8388 if (textureflags & TEXF_ALPHA)
8390 for (i = 0;i < width * height;i++)
8392 if (((unsigned char *)palette)[skindata[i]*4+3] < 255)
8394 skinframe->hasalpha = true;
8398 if (r_loadfog && skinframe->hasalpha)
8399 skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, alphapalette);
8402 R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
8403 //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]);
8408 skinframe_t *R_SkinFrame_LoadMissing(void)
8410 skinframe_t *skinframe;
8412 if (cls.state == ca_dedicated)
8415 skinframe = R_SkinFrame_Find("missing", TEXF_FORCENEAREST, 0, 0, 0, true);
8416 skinframe->stain = NULL;
8417 skinframe->merged = NULL;
8418 skinframe->base = NULL;
8419 skinframe->pants = NULL;
8420 skinframe->shirt = NULL;
8421 skinframe->nmap = NULL;
8422 skinframe->gloss = NULL;
8423 skinframe->glow = NULL;
8424 skinframe->fog = NULL;
8425 skinframe->reflect = NULL;
8426 skinframe->hasalpha = false;
8428 skinframe->avgcolor[0] = rand() / RAND_MAX;
8429 skinframe->avgcolor[1] = rand() / RAND_MAX;
8430 skinframe->avgcolor[2] = rand() / RAND_MAX;
8431 skinframe->avgcolor[3] = 1;
8436 //static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
8437 typedef struct suffixinfo_s
8440 qboolean flipx, flipy, flipdiagonal;
8443 static suffixinfo_t suffix[3][6] =
8446 {"px", false, false, false},
8447 {"nx", false, false, false},
8448 {"py", false, false, false},
8449 {"ny", false, false, false},
8450 {"pz", false, false, false},
8451 {"nz", false, false, false}
8454 {"posx", false, false, false},
8455 {"negx", false, false, false},
8456 {"posy", false, false, false},
8457 {"negy", false, false, false},
8458 {"posz", false, false, false},
8459 {"negz", false, false, false}
8462 {"rt", true, false, true},
8463 {"lf", false, true, true},
8464 {"ft", true, true, false},
8465 {"bk", false, false, false},
8466 {"up", true, false, true},
8467 {"dn", true, false, true}
8471 static int componentorder[4] = {0, 1, 2, 3};
8473 rtexture_t *R_LoadCubemap(const char *basename)
8475 int i, j, cubemapsize;
8476 unsigned char *cubemappixels, *image_buffer;
8477 rtexture_t *cubemaptexture;
8479 // must start 0 so the first loadimagepixels has no requested width/height
8481 cubemappixels = NULL;
8482 cubemaptexture = NULL;
8483 // keep trying different suffix groups (posx, px, rt) until one loads
8484 for (j = 0;j < 3 && !cubemappixels;j++)
8486 // load the 6 images in the suffix group
8487 for (i = 0;i < 6;i++)
8489 // generate an image name based on the base and and suffix
8490 dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix);
8492 if ((image_buffer = loadimagepixelsbgra(name, false, false, r_texture_convertsRGB_cubemap.integer != 0, NULL)))
8494 // an image loaded, make sure width and height are equal
8495 if (image_width == image_height && (!cubemappixels || image_width == cubemapsize))
8497 // if this is the first image to load successfully, allocate the cubemap memory
8498 if (!cubemappixels && image_width >= 1)
8500 cubemapsize = image_width;
8501 // note this clears to black, so unavailable sides are black
8502 cubemappixels = (unsigned char *)Mem_Alloc(tempmempool, 6*cubemapsize*cubemapsize*4);
8504 // copy the image with any flipping needed by the suffix (px and posx types don't need flipping)
8506 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);
8509 Con_Printf("Cubemap image \"%s\" (%ix%i) is not square, OpenGL requires square cubemaps.\n", name, image_width, image_height);
8511 Mem_Free(image_buffer);
8515 // if a cubemap loaded, upload it
8518 if (developer_loading.integer)
8519 Con_Printf("loading cubemap \"%s\"\n", basename);
8521 cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
8522 Mem_Free(cubemappixels);
8526 Con_DPrintf("failed to load cubemap \"%s\"\n", basename);
8527 if (developer_loading.integer)
8529 Con_Printf("(tried tried images ");
8530 for (j = 0;j < 3;j++)
8531 for (i = 0;i < 6;i++)
8532 Con_Printf("%s\"%s%s.tga\"", j + i > 0 ? ", " : "", basename, suffix[j][i].suffix);
8533 Con_Print(" and was unable to find any of them).\n");
8536 return cubemaptexture;
8539 rtexture_t *R_GetCubemap(const char *basename)
8542 for (i = 0;i < r_texture_numcubemaps;i++)
8543 if (!strcasecmp(r_texture_cubemaps[i].basename, basename))
8544 return r_texture_cubemaps[i].texture ? r_texture_cubemaps[i].texture : r_texture_whitecube;
8545 if (i >= MAX_CUBEMAPS)
8546 return r_texture_whitecube;
8547 r_texture_numcubemaps++;
8548 strlcpy(r_texture_cubemaps[i].basename, basename, sizeof(r_texture_cubemaps[i].basename));
8549 r_texture_cubemaps[i].texture = R_LoadCubemap(r_texture_cubemaps[i].basename);
8550 return r_texture_cubemaps[i].texture;
8553 void R_FreeCubemaps(void)
8556 for (i = 0;i < r_texture_numcubemaps;i++)
8558 if (developer_loading.integer)
8559 Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i].basename);
8560 if (r_texture_cubemaps[i].texture)
8561 R_FreeTexture(r_texture_cubemaps[i].texture);
8563 r_texture_numcubemaps = 0;
8566 void R_Main_FreeViewCache(void)
8568 if (r_refdef.viewcache.entityvisible)
8569 Mem_Free(r_refdef.viewcache.entityvisible);
8570 if (r_refdef.viewcache.world_pvsbits)
8571 Mem_Free(r_refdef.viewcache.world_pvsbits);
8572 if (r_refdef.viewcache.world_leafvisible)
8573 Mem_Free(r_refdef.viewcache.world_leafvisible);
8574 if (r_refdef.viewcache.world_surfacevisible)
8575 Mem_Free(r_refdef.viewcache.world_surfacevisible);
8576 memset(&r_refdef.viewcache, 0, sizeof(r_refdef.viewcache));
8579 void R_Main_ResizeViewCache(void)
8581 int numentities = r_refdef.scene.numentities;
8582 int numclusters = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusters : 1;
8583 int numclusterbytes = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_pvsclusterbytes : 1;
8584 int numleafs = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->brush.num_leafs : 1;
8585 int numsurfaces = r_refdef.scene.worldmodel ? r_refdef.scene.worldmodel->num_surfaces : 1;
8586 if (r_refdef.viewcache.maxentities < numentities)
8588 r_refdef.viewcache.maxentities = numentities;
8589 if (r_refdef.viewcache.entityvisible)
8590 Mem_Free(r_refdef.viewcache.entityvisible);
8591 r_refdef.viewcache.entityvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
8593 if (r_refdef.viewcache.world_numclusters != numclusters)
8595 r_refdef.viewcache.world_numclusters = numclusters;
8596 r_refdef.viewcache.world_numclusterbytes = numclusterbytes;
8597 if (r_refdef.viewcache.world_pvsbits)
8598 Mem_Free(r_refdef.viewcache.world_pvsbits);
8599 r_refdef.viewcache.world_pvsbits = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
8601 if (r_refdef.viewcache.world_numleafs != numleafs)
8603 r_refdef.viewcache.world_numleafs = numleafs;
8604 if (r_refdef.viewcache.world_leafvisible)
8605 Mem_Free(r_refdef.viewcache.world_leafvisible);
8606 r_refdef.viewcache.world_leafvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
8608 if (r_refdef.viewcache.world_numsurfaces != numsurfaces)
8610 r_refdef.viewcache.world_numsurfaces = numsurfaces;
8611 if (r_refdef.viewcache.world_surfacevisible)
8612 Mem_Free(r_refdef.viewcache.world_surfacevisible);
8613 r_refdef.viewcache.world_surfacevisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
8617 extern rtexture_t *loadingscreentexture;
8618 void gl_main_start(void)
8620 loadingscreentexture = NULL;
8621 r_texture_blanknormalmap = NULL;
8622 r_texture_white = NULL;
8623 r_texture_grey128 = NULL;
8624 r_texture_black = NULL;
8625 r_texture_whitecube = NULL;
8626 r_texture_normalizationcube = NULL;
8627 r_texture_fogattenuation = NULL;
8628 r_texture_fogheighttexture = NULL;
8629 r_texture_gammaramps = NULL;
8630 r_texture_numcubemaps = 0;
8632 r_loaddds = r_texture_dds_load.integer != 0;
8633 r_savedds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_save.integer;
8635 switch(vid.renderpath)
8637 case RENDERPATH_GL20:
8638 case RENDERPATH_CGGL:
8639 case RENDERPATH_D3D9:
8640 case RENDERPATH_D3D10:
8641 case RENDERPATH_D3D11:
8642 case RENDERPATH_SOFT:
8643 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
8644 Cvar_SetValueQuick(&gl_combine, 1);
8645 Cvar_SetValueQuick(&r_glsl, 1);
8646 r_loadnormalmap = true;
8650 case RENDERPATH_GL13:
8651 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
8652 Cvar_SetValueQuick(&gl_combine, 1);
8653 Cvar_SetValueQuick(&r_glsl, 0);
8654 r_loadnormalmap = false;
8655 r_loadgloss = false;
8658 case RENDERPATH_GL11:
8659 Cvar_SetValueQuick(&r_textureunits, vid.texunits);
8660 Cvar_SetValueQuick(&gl_combine, 0);
8661 Cvar_SetValueQuick(&r_glsl, 0);
8662 r_loadnormalmap = false;
8663 r_loadgloss = false;
8666 case RENDERPATH_GLES2:
8667 Cvar_SetValueQuick(&r_textureunits, 1);
8668 Cvar_SetValueQuick(&gl_combine, 1);
8669 Cvar_SetValueQuick(&r_glsl, 1);
8670 r_loadnormalmap = true;
8671 r_loadgloss = false;
8677 R_FrameData_Reset();
8681 memset(r_queries, 0, sizeof(r_queries));
8683 r_qwskincache = NULL;
8684 r_qwskincache_size = 0;
8686 // set up r_skinframe loading system for textures
8687 memset(&r_skinframe, 0, sizeof(r_skinframe));
8688 r_skinframe.loadsequence = 1;
8689 Mem_ExpandableArray_NewArray(&r_skinframe.array, r_main_mempool, sizeof(skinframe_t), 256);
8691 r_main_texturepool = R_AllocTexturePool();
8692 R_BuildBlankTextures();
8694 if (vid.support.arb_texture_cube_map)
8697 R_BuildNormalizationCube();
8699 r_texture_fogattenuation = NULL;
8700 r_texture_fogheighttexture = NULL;
8701 r_texture_gammaramps = NULL;
8702 //r_texture_fogintensity = NULL;
8703 memset(&r_bloomstate, 0, sizeof(r_bloomstate));
8704 memset(&r_waterstate, 0, sizeof(r_waterstate));
8705 r_glsl_permutation = NULL;
8706 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
8707 Mem_ExpandableArray_NewArray(&r_glsl_permutationarray, r_main_mempool, sizeof(r_glsl_permutation_t), 256);
8708 glslshaderstring = NULL;
8710 r_cg_permutation = NULL;
8711 memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
8712 Mem_ExpandableArray_NewArray(&r_cg_permutationarray, r_main_mempool, sizeof(r_cg_permutation_t), 256);
8713 cgshaderstring = NULL;
8716 r_hlsl_permutation = NULL;
8717 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
8718 Mem_ExpandableArray_NewArray(&r_hlsl_permutationarray, r_main_mempool, sizeof(r_hlsl_permutation_t), 256);
8719 hlslshaderstring = NULL;
8721 memset(&r_svbsp, 0, sizeof (r_svbsp));
8723 r_refdef.fogmasktable_density = 0;
8726 void gl_main_shutdown(void)
8729 R_FrameData_Reset();
8731 R_Main_FreeViewCache();
8733 switch(vid.renderpath)
8735 case RENDERPATH_GL11:
8736 case RENDERPATH_GL13:
8737 case RENDERPATH_GL20:
8738 case RENDERPATH_CGGL:
8740 qglDeleteQueriesARB(r_maxqueries, r_queries);
8742 case RENDERPATH_D3D9:
8743 //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8745 case RENDERPATH_D3D10:
8746 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8748 case RENDERPATH_D3D11:
8749 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8751 case RENDERPATH_SOFT:
8753 case RENDERPATH_GLES2:
8754 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
8760 memset(r_queries, 0, sizeof(r_queries));
8762 r_qwskincache = NULL;
8763 r_qwskincache_size = 0;
8765 // clear out the r_skinframe state
8766 Mem_ExpandableArray_FreeArray(&r_skinframe.array);
8767 memset(&r_skinframe, 0, sizeof(r_skinframe));
8770 Mem_Free(r_svbsp.nodes);
8771 memset(&r_svbsp, 0, sizeof (r_svbsp));
8772 R_FreeTexturePool(&r_main_texturepool);
8773 loadingscreentexture = NULL;
8774 r_texture_blanknormalmap = NULL;
8775 r_texture_white = NULL;
8776 r_texture_grey128 = NULL;
8777 r_texture_black = NULL;
8778 r_texture_whitecube = NULL;
8779 r_texture_normalizationcube = NULL;
8780 r_texture_fogattenuation = NULL;
8781 r_texture_fogheighttexture = NULL;
8782 r_texture_gammaramps = NULL;
8783 r_texture_numcubemaps = 0;
8784 //r_texture_fogintensity = NULL;
8785 memset(&r_bloomstate, 0, sizeof(r_bloomstate));
8786 memset(&r_waterstate, 0, sizeof(r_waterstate));
8789 r_glsl_permutation = NULL;
8790 memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
8791 Mem_ExpandableArray_FreeArray(&r_glsl_permutationarray);
8792 glslshaderstring = NULL;
8794 r_cg_permutation = NULL;
8795 memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
8796 Mem_ExpandableArray_FreeArray(&r_cg_permutationarray);
8797 cgshaderstring = NULL;
8800 r_hlsl_permutation = NULL;
8801 memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
8802 Mem_ExpandableArray_FreeArray(&r_hlsl_permutationarray);
8803 hlslshaderstring = NULL;
8807 extern void CL_ParseEntityLump(char *entitystring);
8808 void gl_main_newmap(void)
8810 // FIXME: move this code to client
8811 char *entities, entname[MAX_QPATH];
8813 Mem_Free(r_qwskincache);
8814 r_qwskincache = NULL;
8815 r_qwskincache_size = 0;
8818 dpsnprintf(entname, sizeof(entname), "%s.ent", cl.worldnamenoextension);
8819 if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
8821 CL_ParseEntityLump(entities);
8825 if (cl.worldmodel->brush.entities)
8826 CL_ParseEntityLump(cl.worldmodel->brush.entities);
8828 R_Main_FreeViewCache();
8830 R_FrameData_Reset();
8833 void GL_Main_Init(void)
8835 r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
8837 Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed");
8838 Cmd_AddCommand("r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl");
8839 // FIXME: the client should set up r_refdef.fog stuff including the fogmasktable
8840 if (gamemode == GAME_NEHAHRA)
8842 Cvar_RegisterVariable (&gl_fogenable);
8843 Cvar_RegisterVariable (&gl_fogdensity);
8844 Cvar_RegisterVariable (&gl_fogred);
8845 Cvar_RegisterVariable (&gl_foggreen);
8846 Cvar_RegisterVariable (&gl_fogblue);
8847 Cvar_RegisterVariable (&gl_fogstart);
8848 Cvar_RegisterVariable (&gl_fogend);
8849 Cvar_RegisterVariable (&gl_skyclip);
8851 Cvar_RegisterVariable(&r_motionblur);
8852 Cvar_RegisterVariable(&r_motionblur_maxblur);
8853 Cvar_RegisterVariable(&r_motionblur_bmin);
8854 Cvar_RegisterVariable(&r_motionblur_vmin);
8855 Cvar_RegisterVariable(&r_motionblur_vmax);
8856 Cvar_RegisterVariable(&r_motionblur_vcoeff);
8857 Cvar_RegisterVariable(&r_motionblur_randomize);
8858 Cvar_RegisterVariable(&r_damageblur);
8859 Cvar_RegisterVariable(&r_equalize_entities_fullbright);
8860 Cvar_RegisterVariable(&r_equalize_entities_minambient);
8861 Cvar_RegisterVariable(&r_equalize_entities_by);
8862 Cvar_RegisterVariable(&r_equalize_entities_to);
8863 Cvar_RegisterVariable(&r_depthfirst);
8864 Cvar_RegisterVariable(&r_useinfinitefarclip);
8865 Cvar_RegisterVariable(&r_farclip_base);
8866 Cvar_RegisterVariable(&r_farclip_world);
8867 Cvar_RegisterVariable(&r_nearclip);
8868 Cvar_RegisterVariable(&r_showbboxes);
8869 Cvar_RegisterVariable(&r_showsurfaces);
8870 Cvar_RegisterVariable(&r_showtris);
8871 Cvar_RegisterVariable(&r_shownormals);
8872 Cvar_RegisterVariable(&r_showlighting);
8873 Cvar_RegisterVariable(&r_showshadowvolumes);
8874 Cvar_RegisterVariable(&r_showcollisionbrushes);
8875 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonfactor);
8876 Cvar_RegisterVariable(&r_showcollisionbrushes_polygonoffset);
8877 Cvar_RegisterVariable(&r_showdisabledepthtest);
8878 Cvar_RegisterVariable(&r_drawportals);
8879 Cvar_RegisterVariable(&r_drawentities);
8880 Cvar_RegisterVariable(&r_draw2d);
8881 Cvar_RegisterVariable(&r_drawworld);
8882 Cvar_RegisterVariable(&r_cullentities_trace);
8883 Cvar_RegisterVariable(&r_cullentities_trace_samples);
8884 Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
8885 Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
8886 Cvar_RegisterVariable(&r_cullentities_trace_delay);
8887 Cvar_RegisterVariable(&r_drawviewmodel);
8888 Cvar_RegisterVariable(&r_drawexteriormodel);
8889 Cvar_RegisterVariable(&r_speeds);
8890 Cvar_RegisterVariable(&r_fullbrights);
8891 Cvar_RegisterVariable(&r_wateralpha);
8892 Cvar_RegisterVariable(&r_dynamic);
8893 Cvar_RegisterVariable(&r_fakelight);
8894 Cvar_RegisterVariable(&r_fakelight_intensity);
8895 Cvar_RegisterVariable(&r_fullbright);
8896 Cvar_RegisterVariable(&r_shadows);
8897 Cvar_RegisterVariable(&r_shadows_darken);
8898 Cvar_RegisterVariable(&r_shadows_drawafterrtlighting);
8899 Cvar_RegisterVariable(&r_shadows_castfrombmodels);
8900 Cvar_RegisterVariable(&r_shadows_throwdistance);
8901 Cvar_RegisterVariable(&r_shadows_throwdirection);
8902 Cvar_RegisterVariable(&r_shadows_focus);
8903 Cvar_RegisterVariable(&r_shadows_shadowmapscale);
8904 Cvar_RegisterVariable(&r_q1bsp_skymasking);
8905 Cvar_RegisterVariable(&r_polygonoffset_submodel_factor);
8906 Cvar_RegisterVariable(&r_polygonoffset_submodel_offset);
8907 Cvar_RegisterVariable(&r_polygonoffset_decals_factor);
8908 Cvar_RegisterVariable(&r_polygonoffset_decals_offset);
8909 Cvar_RegisterVariable(&r_fog_exp2);
8910 Cvar_RegisterVariable(&r_drawfog);
8911 Cvar_RegisterVariable(&r_transparentdepthmasking);
8912 Cvar_RegisterVariable(&r_texture_dds_load);
8913 Cvar_RegisterVariable(&r_texture_dds_save);
8914 Cvar_RegisterVariable(&r_texture_convertsRGB_2d);
8915 Cvar_RegisterVariable(&r_texture_convertsRGB_skin);
8916 Cvar_RegisterVariable(&r_texture_convertsRGB_cubemap);
8917 Cvar_RegisterVariable(&r_texture_convertsRGB_skybox);
8918 Cvar_RegisterVariable(&r_texture_convertsRGB_particles);
8919 Cvar_RegisterVariable(&r_textureunits);
8920 Cvar_RegisterVariable(&gl_combine);
8921 Cvar_RegisterVariable(&r_glsl);
8922 Cvar_RegisterVariable(&r_glsl_deluxemapping);
8923 Cvar_RegisterVariable(&r_glsl_offsetmapping);
8924 Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
8925 Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
8926 Cvar_RegisterVariable(&r_glsl_postprocess);
8927 Cvar_RegisterVariable(&r_glsl_postprocess_uservec1);
8928 Cvar_RegisterVariable(&r_glsl_postprocess_uservec2);
8929 Cvar_RegisterVariable(&r_glsl_postprocess_uservec3);
8930 Cvar_RegisterVariable(&r_glsl_postprocess_uservec4);
8931 Cvar_RegisterVariable(&r_glsl_postprocess_uservec1_enable);
8932 Cvar_RegisterVariable(&r_glsl_postprocess_uservec2_enable);
8933 Cvar_RegisterVariable(&r_glsl_postprocess_uservec3_enable);
8934 Cvar_RegisterVariable(&r_glsl_postprocess_uservec4_enable);
8936 Cvar_RegisterVariable(&r_water);
8937 Cvar_RegisterVariable(&r_water_resolutionmultiplier);
8938 Cvar_RegisterVariable(&r_water_clippingplanebias);
8939 Cvar_RegisterVariable(&r_water_refractdistort);
8940 Cvar_RegisterVariable(&r_water_reflectdistort);
8941 Cvar_RegisterVariable(&r_water_scissormode);
8942 Cvar_RegisterVariable(&r_lerpsprites);
8943 Cvar_RegisterVariable(&r_lerpmodels);
8944 Cvar_RegisterVariable(&r_lerplightstyles);
8945 Cvar_RegisterVariable(&r_waterscroll);
8946 Cvar_RegisterVariable(&r_bloom);
8947 Cvar_RegisterVariable(&r_bloom_colorscale);
8948 Cvar_RegisterVariable(&r_bloom_brighten);
8949 Cvar_RegisterVariable(&r_bloom_blur);
8950 Cvar_RegisterVariable(&r_bloom_resolution);
8951 Cvar_RegisterVariable(&r_bloom_colorexponent);
8952 Cvar_RegisterVariable(&r_bloom_colorsubtract);
8953 Cvar_RegisterVariable(&r_hdr);
8954 Cvar_RegisterVariable(&r_hdr_scenebrightness);
8955 Cvar_RegisterVariable(&r_hdr_glowintensity);
8956 Cvar_RegisterVariable(&r_hdr_range);
8957 Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
8958 Cvar_RegisterVariable(&developer_texturelogging);
8959 Cvar_RegisterVariable(&gl_lightmaps);
8960 Cvar_RegisterVariable(&r_test);
8961 Cvar_RegisterVariable(&r_glsl_saturation);
8962 Cvar_RegisterVariable(&r_glsl_saturation_redcompensate);
8963 Cvar_RegisterVariable(&r_framedatasize);
8964 if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
8965 Cvar_SetValue("r_fullbrights", 0);
8966 R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap, NULL, NULL);
8968 Cvar_RegisterVariable(&r_track_sprites);
8969 Cvar_RegisterVariable(&r_track_sprites_flags);
8970 Cvar_RegisterVariable(&r_track_sprites_scalew);
8971 Cvar_RegisterVariable(&r_track_sprites_scaleh);
8972 Cvar_RegisterVariable(&r_overheadsprites_perspective);
8973 Cvar_RegisterVariable(&r_overheadsprites_pushback);
8974 Cvar_RegisterVariable(&r_overheadsprites_scalex);
8975 Cvar_RegisterVariable(&r_overheadsprites_scaley);
8978 extern void R_Textures_Init(void);
8979 extern void GL_Draw_Init(void);
8980 extern void GL_Main_Init(void);
8981 extern void R_Shadow_Init(void);
8982 extern void R_Sky_Init(void);
8983 extern void GL_Surf_Init(void);
8984 extern void R_Particles_Init(void);
8985 extern void R_Explosion_Init(void);
8986 extern void gl_backend_init(void);
8987 extern void Sbar_Init(void);
8988 extern void R_LightningBeams_Init(void);
8989 extern void Mod_RenderInit(void);
8990 extern void Font_Init(void);
8992 void Render_Init(void)
9005 R_LightningBeams_Init();
9014 extern char *ENGINE_EXTENSIONS;
9017 gl_renderer = (const char *)qglGetString(GL_RENDERER);
9018 gl_vendor = (const char *)qglGetString(GL_VENDOR);
9019 gl_version = (const char *)qglGetString(GL_VERSION);
9020 gl_extensions = (const char *)qglGetString(GL_EXTENSIONS);
9024 if (!gl_platformextensions)
9025 gl_platformextensions = "";
9027 Con_Printf("GL_VENDOR: %s\n", gl_vendor);
9028 Con_Printf("GL_RENDERER: %s\n", gl_renderer);
9029 Con_Printf("GL_VERSION: %s\n", gl_version);
9030 Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions);
9031 Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
9033 VID_CheckExtensions();
9035 // LordHavoc: report supported extensions
9036 Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
9038 // clear to black (loading plaque will be seen over this)
9039 GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
9042 int R_CullBox(const vec3_t mins, const vec3_t maxs)
9046 for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
9048 // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
9051 p = r_refdef.view.frustum + i;
9056 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9060 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9064 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9068 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9072 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9076 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9080 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9084 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9092 int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
9096 for (i = 0;i < numplanes;i++)
9103 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9107 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
9111 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9115 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
9119 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9123 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
9127 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9131 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
9139 //==================================================================================
9141 // LordHavoc: this stores temporary data used within the same frame
9143 typedef struct r_framedata_mem_s
9145 struct r_framedata_mem_s *purge; // older mem block to free on next frame
9146 size_t size; // how much usable space
9147 size_t current; // how much space in use
9148 size_t mark; // last "mark" location, temporary memory can be freed by returning to this
9149 size_t wantedsize; // how much space was allocated
9150 unsigned char *data; // start of real data (16byte aligned)
9154 static r_framedata_mem_t *r_framedata_mem;
9156 void R_FrameData_Reset(void)
9158 while (r_framedata_mem)
9160 r_framedata_mem_t *next = r_framedata_mem->purge;
9161 Mem_Free(r_framedata_mem);
9162 r_framedata_mem = next;
9166 void R_FrameData_Resize(void)
9169 wantedsize = (size_t)(r_framedatasize.value * 1024*1024);
9170 wantedsize = bound(65536, wantedsize, 1000*1024*1024);
9171 if (!r_framedata_mem || r_framedata_mem->wantedsize != wantedsize)
9173 r_framedata_mem_t *newmem = (r_framedata_mem_t *)Mem_Alloc(r_main_mempool, wantedsize);
9174 newmem->wantedsize = wantedsize;
9175 newmem->data = (unsigned char *)(((size_t)(newmem+1) + 15) & ~15);
9176 newmem->size = (unsigned char *)newmem + wantedsize - newmem->data;
9177 newmem->current = 0;
9179 newmem->purge = r_framedata_mem;
9180 r_framedata_mem = newmem;
9184 void R_FrameData_NewFrame(void)
9186 R_FrameData_Resize();
9187 if (!r_framedata_mem)
9189 // if we ran out of space on the last frame, free the old memory now
9190 while (r_framedata_mem->purge)
9192 // repeatedly remove the second item in the list, leaving only head
9193 r_framedata_mem_t *next = r_framedata_mem->purge->purge;
9194 Mem_Free(r_framedata_mem->purge);
9195 r_framedata_mem->purge = next;
9197 // reset the current mem pointer
9198 r_framedata_mem->current = 0;
9199 r_framedata_mem->mark = 0;
9202 void *R_FrameData_Alloc(size_t size)
9206 // align to 16 byte boundary - the data pointer is already aligned, so we
9207 // only need to ensure the size of every allocation is also aligned
9208 size = (size + 15) & ~15;
9210 while (!r_framedata_mem || r_framedata_mem->current + size > r_framedata_mem->size)
9212 // emergency - we ran out of space, allocate more memory
9213 Cvar_SetValueQuick(&r_framedatasize, bound(0.25f, r_framedatasize.value * 2.0f, 128.0f));
9214 R_FrameData_Resize();
9217 data = r_framedata_mem->data + r_framedata_mem->current;
9218 r_framedata_mem->current += size;
9220 // count the usage for stats
9221 r_refdef.stats.framedatacurrent = max(r_refdef.stats.framedatacurrent, (int)r_framedata_mem->current);
9222 r_refdef.stats.framedatasize = max(r_refdef.stats.framedatasize, (int)r_framedata_mem->size);
9224 return (void *)data;
9227 void *R_FrameData_Store(size_t size, void *data)
9229 void *d = R_FrameData_Alloc(size);
9231 memcpy(d, data, size);
9235 void R_FrameData_SetMark(void)
9237 if (!r_framedata_mem)
9239 r_framedata_mem->mark = r_framedata_mem->current;
9242 void R_FrameData_ReturnToMark(void)
9244 if (!r_framedata_mem)
9246 r_framedata_mem->current = r_framedata_mem->mark;
9249 //==================================================================================
9251 // LordHavoc: animcache originally written by Echon, rewritten since then
9254 * Animation cache prevents re-generating mesh data for an animated model
9255 * multiple times in one frame for lighting, shadowing, reflections, etc.
9258 void R_AnimCache_Free(void)
9262 void R_AnimCache_ClearCache(void)
9265 entity_render_t *ent;
9267 for (i = 0;i < r_refdef.scene.numentities;i++)
9269 ent = r_refdef.scene.entities[i];
9270 ent->animcache_vertex3f = NULL;
9271 ent->animcache_normal3f = NULL;
9272 ent->animcache_svector3f = NULL;
9273 ent->animcache_tvector3f = NULL;
9274 ent->animcache_vertexmesh = NULL;
9275 ent->animcache_vertex3fbuffer = NULL;
9276 ent->animcache_vertexmeshbuffer = NULL;
9280 void R_AnimCache_UpdateEntityMeshBuffers(entity_render_t *ent, int numvertices)
9284 // check if we need the meshbuffers
9285 if (!vid.useinterleavedarrays)
9288 if (!ent->animcache_vertexmesh && ent->animcache_normal3f)
9289 ent->animcache_vertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
9290 // TODO: upload vertex3f buffer?
9291 if (ent->animcache_vertexmesh)
9293 memcpy(ent->animcache_vertexmesh, ent->model->surfmesh.vertexmesh, sizeof(r_vertexmesh_t)*numvertices);
9294 for (i = 0;i < numvertices;i++)
9295 memcpy(ent->animcache_vertexmesh[i].vertex3f, ent->animcache_vertex3f + 3*i, sizeof(float[3]));
9296 if (ent->animcache_svector3f)
9297 for (i = 0;i < numvertices;i++)
9298 memcpy(ent->animcache_vertexmesh[i].svector3f, ent->animcache_svector3f + 3*i, sizeof(float[3]));
9299 if (ent->animcache_tvector3f)
9300 for (i = 0;i < numvertices;i++)
9301 memcpy(ent->animcache_vertexmesh[i].tvector3f, ent->animcache_tvector3f + 3*i, sizeof(float[3]));
9302 if (ent->animcache_normal3f)
9303 for (i = 0;i < numvertices;i++)
9304 memcpy(ent->animcache_vertexmesh[i].normal3f, ent->animcache_normal3f + 3*i, sizeof(float[3]));
9305 // TODO: upload vertexmeshbuffer?
9309 qboolean R_AnimCache_GetEntity(entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
9311 dp_model_t *model = ent->model;
9313 // see if it's already cached this frame
9314 if (ent->animcache_vertex3f)
9316 // add normals/tangents if needed (this only happens with multiple views, reflections, cameras, etc)
9317 if (wantnormals || wanttangents)
9319 if (ent->animcache_normal3f)
9320 wantnormals = false;
9321 if (ent->animcache_svector3f)
9322 wanttangents = false;
9323 if (wantnormals || wanttangents)
9325 numvertices = model->surfmesh.num_vertices;
9327 ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9330 ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9331 ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9333 model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? ent->animcache_normal3f : NULL, wanttangents ? ent->animcache_svector3f : NULL, wanttangents ? ent->animcache_tvector3f : NULL);
9334 R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
9340 // see if this ent is worth caching
9341 if (!model || !model->Draw || !model->surfmesh.isanimated || !model->AnimateVertices || (ent->frameblend[0].lerp == 1 && ent->frameblend[0].subframe == 0 && !ent->skeleton))
9343 // get some memory for this entity and generate mesh data
9344 numvertices = model->surfmesh.num_vertices;
9345 ent->animcache_vertex3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9347 ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9350 ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9351 ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
9353 model->AnimateVertices(model, ent->frameblend, ent->skeleton, ent->animcache_vertex3f, ent->animcache_normal3f, ent->animcache_svector3f, ent->animcache_tvector3f);
9354 R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
9359 void R_AnimCache_CacheVisibleEntities(void)
9362 qboolean wantnormals = true;
9363 qboolean wanttangents = !r_showsurfaces.integer;
9365 switch(vid.renderpath)
9367 case RENDERPATH_GL20:
9368 case RENDERPATH_CGGL:
9369 case RENDERPATH_D3D9:
9370 case RENDERPATH_D3D10:
9371 case RENDERPATH_D3D11:
9372 case RENDERPATH_GLES2:
9374 case RENDERPATH_GL13:
9375 case RENDERPATH_GL11:
9376 wanttangents = false;
9378 case RENDERPATH_SOFT:
9382 if (r_shownormals.integer)
9383 wanttangents = wantnormals = true;
9385 // TODO: thread this
9386 // NOTE: R_PrepareRTLights() also caches entities
9388 for (i = 0;i < r_refdef.scene.numentities;i++)
9389 if (r_refdef.viewcache.entityvisible[i])
9390 R_AnimCache_GetEntity(r_refdef.scene.entities[i], wantnormals, wanttangents);
9393 //==================================================================================
9395 static void R_View_UpdateEntityLighting (void)
9398 entity_render_t *ent;
9399 vec3_t tempdiffusenormal, avg;
9400 vec_t f, fa, fd, fdd;
9401 qboolean skipunseen = r_shadows.integer != 1; //|| R_Shadow_ShadowMappingEnabled();
9403 for (i = 0;i < r_refdef.scene.numentities;i++)
9405 ent = r_refdef.scene.entities[i];
9407 // skip unseen models
9408 if (!r_refdef.viewcache.entityvisible[i] && skipunseen)
9412 if (ent->model && ent->model->brush.num_leafs)
9414 // TODO: use modellight for r_ambient settings on world?
9415 VectorSet(ent->modellight_ambient, 0, 0, 0);
9416 VectorSet(ent->modellight_diffuse, 0, 0, 0);
9417 VectorSet(ent->modellight_lightdir, 0, 0, 1);
9421 // fetch the lighting from the worldmodel data
9422 VectorClear(ent->modellight_ambient);
9423 VectorClear(ent->modellight_diffuse);
9424 VectorClear(tempdiffusenormal);
9425 if ((ent->flags & RENDER_LIGHT) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
9428 Matrix4x4_OriginFromMatrix(&ent->matrix, org);
9430 // complete lightning for lit sprites
9431 // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
9432 if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
9434 if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
9435 org[2] = org[2] + r_overheadsprites_pushback.value;
9436 R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, ent->modellight_lightdir, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
9439 r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
9441 if(ent->flags & RENDER_EQUALIZE)
9443 // first fix up ambient lighting...
9444 if(r_equalize_entities_minambient.value > 0)
9446 fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
9449 fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]);
9450 if(fa < r_equalize_entities_minambient.value * fd)
9453 // fa'/fd' = minambient
9454 // fa'+0.25*fd' = fa+0.25*fd
9456 // fa' = fd' * minambient
9457 // fd'*(0.25+minambient) = fa+0.25*fd
9459 // fd' = (fa+0.25*fd) * 1 / (0.25+minambient)
9460 // fa' = (fa+0.25*fd) * minambient / (0.25+minambient)
9462 fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value);
9463 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
9464 VectorMA(ent->modellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient);
9465 VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
9470 if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
9472 fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
9473 fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
9477 // adjust brightness and saturation to target
9478 avg[0] = avg[1] = avg[2] = fa / f;
9479 VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
9480 avg[0] = avg[1] = avg[2] = fd / f;
9481 VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
9487 VectorSet(ent->modellight_ambient, 1, 1, 1);
9489 // move the light direction into modelspace coordinates for lighting code
9490 Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
9491 if(VectorLength2(ent->modellight_lightdir) == 0)
9492 VectorSet(ent->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
9493 VectorNormalize(ent->modellight_lightdir);
9497 #define MAX_LINEOFSIGHTTRACES 64
9499 static qboolean R_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
9502 vec3_t boxmins, boxmaxs;
9505 dp_model_t *model = r_refdef.scene.worldmodel;
9507 if (!model || !model->brush.TraceLineOfSight)
9510 // expand the box a little
9511 boxmins[0] = (enlarge+1) * entboxmins[0] - enlarge * entboxmaxs[0];
9512 boxmaxs[0] = (enlarge+1) * entboxmaxs[0] - enlarge * entboxmins[0];
9513 boxmins[1] = (enlarge+1) * entboxmins[1] - enlarge * entboxmaxs[1];
9514 boxmaxs[1] = (enlarge+1) * entboxmaxs[1] - enlarge * entboxmins[1];
9515 boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2];
9516 boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2];
9518 // return true if eye is inside enlarged box
9519 if (BoxesOverlap(boxmins, boxmaxs, eye, eye))
9523 VectorCopy(eye, start);
9524 VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, end);
9525 if (model->brush.TraceLineOfSight(model, start, end))
9528 // try various random positions
9529 for (i = 0;i < numsamples;i++)
9531 VectorSet(end, lhrandom(boxmins[0], boxmaxs[0]), lhrandom(boxmins[1], boxmaxs[1]), lhrandom(boxmins[2], boxmaxs[2]));
9532 if (model->brush.TraceLineOfSight(model, start, end))
9540 static void R_View_UpdateEntityVisible (void)
9545 entity_render_t *ent;
9547 renderimask = r_refdef.envmap ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL)
9548 : r_waterstate.renderingrefraction ? (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL)
9549 : (chase_active.integer || r_waterstate.renderingscene) ? RENDER_VIEWMODEL
9550 : RENDER_EXTERIORMODEL;
9551 if (!r_drawviewmodel.integer)
9552 renderimask |= RENDER_VIEWMODEL;
9553 if (!r_drawexteriormodel.integer)
9554 renderimask |= RENDER_EXTERIORMODEL;
9555 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs)
9557 // worldmodel can check visibility
9558 memset(r_refdef.viewcache.entityvisible, 0, r_refdef.scene.numentities);
9559 for (i = 0;i < r_refdef.scene.numentities;i++)
9561 ent = r_refdef.scene.entities[i];
9562 if (!(ent->flags & renderimask))
9563 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)))
9564 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))
9565 r_refdef.viewcache.entityvisible[i] = true;
9567 if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane)
9568 // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling
9570 for (i = 0;i < r_refdef.scene.numentities;i++)
9572 ent = r_refdef.scene.entities[i];
9573 if(r_refdef.viewcache.entityvisible[i] && !(ent->flags & (RENDER_VIEWMODEL | RENDER_NOCULL | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
9575 samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer;
9577 continue; // temp entities do pvs only
9578 if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
9579 ent->last_trace_visibility = realtime;
9580 if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
9581 r_refdef.viewcache.entityvisible[i] = 0;
9588 // no worldmodel or it can't check visibility
9589 for (i = 0;i < r_refdef.scene.numentities;i++)
9591 ent = r_refdef.scene.entities[i];
9592 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));
9597 /// only used if skyrendermasked, and normally returns false
9598 int R_DrawBrushModelsSky (void)
9601 entity_render_t *ent;
9604 for (i = 0;i < r_refdef.scene.numentities;i++)
9606 if (!r_refdef.viewcache.entityvisible[i])
9608 ent = r_refdef.scene.entities[i];
9609 if (!ent->model || !ent->model->DrawSky)
9611 ent->model->DrawSky(ent);
9617 static void R_DrawNoModel(entity_render_t *ent);
9618 static void R_DrawModels(void)
9621 entity_render_t *ent;
9623 for (i = 0;i < r_refdef.scene.numentities;i++)
9625 if (!r_refdef.viewcache.entityvisible[i])
9627 ent = r_refdef.scene.entities[i];
9628 r_refdef.stats.entities++;
9629 if (ent->model && ent->model->Draw != NULL)
9630 ent->model->Draw(ent);
9636 static void R_DrawModelsDepth(void)
9639 entity_render_t *ent;
9641 for (i = 0;i < r_refdef.scene.numentities;i++)
9643 if (!r_refdef.viewcache.entityvisible[i])
9645 ent = r_refdef.scene.entities[i];
9646 if (ent->model && ent->model->DrawDepth != NULL)
9647 ent->model->DrawDepth(ent);
9651 static void R_DrawModelsDebug(void)
9654 entity_render_t *ent;
9656 for (i = 0;i < r_refdef.scene.numentities;i++)
9658 if (!r_refdef.viewcache.entityvisible[i])
9660 ent = r_refdef.scene.entities[i];
9661 if (ent->model && ent->model->DrawDebug != NULL)
9662 ent->model->DrawDebug(ent);
9666 static void R_DrawModelsAddWaterPlanes(void)
9669 entity_render_t *ent;
9671 for (i = 0;i < r_refdef.scene.numentities;i++)
9673 if (!r_refdef.viewcache.entityvisible[i])
9675 ent = r_refdef.scene.entities[i];
9676 if (ent->model && ent->model->DrawAddWaterPlanes != NULL)
9677 ent->model->DrawAddWaterPlanes(ent);
9681 static void R_View_SetFrustum(const int *scissor)
9684 double fpx = +1, fnx = -1, fpy = +1, fny = -1;
9685 vec3_t forward, left, up, origin, v;
9689 // flipped x coordinates (because x points left here)
9690 fpx = 1.0 - 2.0 * (scissor[0] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
9691 fnx = 1.0 - 2.0 * (scissor[0] + scissor[2] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
9693 // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
9694 switch(vid.renderpath)
9696 case RENDERPATH_D3D9:
9697 case RENDERPATH_D3D10:
9698 case RENDERPATH_D3D11:
9699 case RENDERPATH_SOFT:
9700 // non-flipped y coordinates
9701 fny = -1.0 + 2.0 * (vid.height - scissor[1] - scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9702 fpy = -1.0 + 2.0 * (vid.height - scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9704 case RENDERPATH_GL11:
9705 case RENDERPATH_GL13:
9706 case RENDERPATH_GL20:
9707 case RENDERPATH_CGGL:
9708 case RENDERPATH_GLES2:
9709 // non-flipped y coordinates
9710 fny = -1.0 + 2.0 * (scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9711 fpy = -1.0 + 2.0 * (scissor[1] + scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
9716 // we can't trust r_refdef.view.forward and friends in reflected scenes
9717 Matrix4x4_ToVectors(&r_refdef.view.matrix, forward, left, up, origin);
9720 r_refdef.view.frustum[0].normal[0] = 0 - 1.0 / r_refdef.view.frustum_x;
9721 r_refdef.view.frustum[0].normal[1] = 0 - 0;
9722 r_refdef.view.frustum[0].normal[2] = -1 - 0;
9723 r_refdef.view.frustum[1].normal[0] = 0 + 1.0 / r_refdef.view.frustum_x;
9724 r_refdef.view.frustum[1].normal[1] = 0 + 0;
9725 r_refdef.view.frustum[1].normal[2] = -1 + 0;
9726 r_refdef.view.frustum[2].normal[0] = 0 - 0;
9727 r_refdef.view.frustum[2].normal[1] = 0 - 1.0 / r_refdef.view.frustum_y;
9728 r_refdef.view.frustum[2].normal[2] = -1 - 0;
9729 r_refdef.view.frustum[3].normal[0] = 0 + 0;
9730 r_refdef.view.frustum[3].normal[1] = 0 + 1.0 / r_refdef.view.frustum_y;
9731 r_refdef.view.frustum[3].normal[2] = -1 + 0;
9735 zNear = r_refdef.nearclip;
9736 nudge = 1.0 - 1.0 / (1<<23);
9737 r_refdef.view.frustum[4].normal[0] = 0 - 0;
9738 r_refdef.view.frustum[4].normal[1] = 0 - 0;
9739 r_refdef.view.frustum[4].normal[2] = -1 - -nudge;
9740 r_refdef.view.frustum[4].dist = 0 - -2 * zNear * nudge;
9741 r_refdef.view.frustum[5].normal[0] = 0 + 0;
9742 r_refdef.view.frustum[5].normal[1] = 0 + 0;
9743 r_refdef.view.frustum[5].normal[2] = -1 + -nudge;
9744 r_refdef.view.frustum[5].dist = 0 + -2 * zNear * nudge;
9750 r_refdef.view.frustum[0].normal[0] = m[3] - m[0];
9751 r_refdef.view.frustum[0].normal[1] = m[7] - m[4];
9752 r_refdef.view.frustum[0].normal[2] = m[11] - m[8];
9753 r_refdef.view.frustum[0].dist = m[15] - m[12];
9755 r_refdef.view.frustum[1].normal[0] = m[3] + m[0];
9756 r_refdef.view.frustum[1].normal[1] = m[7] + m[4];
9757 r_refdef.view.frustum[1].normal[2] = m[11] + m[8];
9758 r_refdef.view.frustum[1].dist = m[15] + m[12];
9760 r_refdef.view.frustum[2].normal[0] = m[3] - m[1];
9761 r_refdef.view.frustum[2].normal[1] = m[7] - m[5];
9762 r_refdef.view.frustum[2].normal[2] = m[11] - m[9];
9763 r_refdef.view.frustum[2].dist = m[15] - m[13];
9765 r_refdef.view.frustum[3].normal[0] = m[3] + m[1];
9766 r_refdef.view.frustum[3].normal[1] = m[7] + m[5];
9767 r_refdef.view.frustum[3].normal[2] = m[11] + m[9];
9768 r_refdef.view.frustum[3].dist = m[15] + m[13];
9770 r_refdef.view.frustum[4].normal[0] = m[3] - m[2];
9771 r_refdef.view.frustum[4].normal[1] = m[7] - m[6];
9772 r_refdef.view.frustum[4].normal[2] = m[11] - m[10];
9773 r_refdef.view.frustum[4].dist = m[15] - m[14];
9775 r_refdef.view.frustum[5].normal[0] = m[3] + m[2];
9776 r_refdef.view.frustum[5].normal[1] = m[7] + m[6];
9777 r_refdef.view.frustum[5].normal[2] = m[11] + m[10];
9778 r_refdef.view.frustum[5].dist = m[15] + m[14];
9781 if (r_refdef.view.useperspective)
9783 // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
9784 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]);
9785 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]);
9786 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]);
9787 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]);
9789 // then the normals from the corners relative to origin
9790 CrossProduct(r_refdef.view.frustumcorner[2], r_refdef.view.frustumcorner[0], r_refdef.view.frustum[0].normal);
9791 CrossProduct(r_refdef.view.frustumcorner[1], r_refdef.view.frustumcorner[3], r_refdef.view.frustum[1].normal);
9792 CrossProduct(r_refdef.view.frustumcorner[0], r_refdef.view.frustumcorner[1], r_refdef.view.frustum[2].normal);
9793 CrossProduct(r_refdef.view.frustumcorner[3], r_refdef.view.frustumcorner[2], r_refdef.view.frustum[3].normal);
9795 // in a NORMAL view, forward cross left == up
9796 // in a REFLECTED view, forward cross left == down
9797 // so our cross products above need to be adjusted for a left handed coordinate system
9798 CrossProduct(forward, left, v);
9799 if(DotProduct(v, up) < 0)
9801 VectorNegate(r_refdef.view.frustum[0].normal, r_refdef.view.frustum[0].normal);
9802 VectorNegate(r_refdef.view.frustum[1].normal, r_refdef.view.frustum[1].normal);
9803 VectorNegate(r_refdef.view.frustum[2].normal, r_refdef.view.frustum[2].normal);
9804 VectorNegate(r_refdef.view.frustum[3].normal, r_refdef.view.frustum[3].normal);
9807 // Leaving those out was a mistake, those were in the old code, and they
9808 // fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix
9809 // I couldn't reproduce it after adding those normalizations. --blub
9810 VectorNormalize(r_refdef.view.frustum[0].normal);
9811 VectorNormalize(r_refdef.view.frustum[1].normal);
9812 VectorNormalize(r_refdef.view.frustum[2].normal);
9813 VectorNormalize(r_refdef.view.frustum[3].normal);
9815 // make the corners absolute
9816 VectorAdd(r_refdef.view.frustumcorner[0], r_refdef.view.origin, r_refdef.view.frustumcorner[0]);
9817 VectorAdd(r_refdef.view.frustumcorner[1], r_refdef.view.origin, r_refdef.view.frustumcorner[1]);
9818 VectorAdd(r_refdef.view.frustumcorner[2], r_refdef.view.origin, r_refdef.view.frustumcorner[2]);
9819 VectorAdd(r_refdef.view.frustumcorner[3], r_refdef.view.origin, r_refdef.view.frustumcorner[3]);
9822 VectorCopy(forward, r_refdef.view.frustum[4].normal);
9824 r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal);
9825 r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal);
9826 r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[2].normal);
9827 r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[3].normal);
9828 r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[4].normal) + r_refdef.nearclip;
9832 VectorScale(left, -r_refdef.view.ortho_x, r_refdef.view.frustum[0].normal);
9833 VectorScale(left, r_refdef.view.ortho_x, r_refdef.view.frustum[1].normal);
9834 VectorScale(up, -r_refdef.view.ortho_y, r_refdef.view.frustum[2].normal);
9835 VectorScale(up, r_refdef.view.ortho_y, r_refdef.view.frustum[3].normal);
9836 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) + r_refdef.view.ortho_x;
9838 r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal) + r_refdef.view.ortho_x;
9839 r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[2].normal) + r_refdef.view.ortho_y;
9840 r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[3].normal) + r_refdef.view.ortho_y;
9841 r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[4].normal) + r_refdef.nearclip;
9843 r_refdef.view.numfrustumplanes = 5;
9845 if (r_refdef.view.useclipplane)
9847 r_refdef.view.numfrustumplanes = 6;
9848 r_refdef.view.frustum[5] = r_refdef.view.clipplane;
9851 for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
9852 PlaneClassify(r_refdef.view.frustum + i);
9854 // LordHavoc: note to all quake engine coders, Quake had a special case
9855 // for 90 degrees which assumed a square view (wrong), so I removed it,
9856 // Quake2 has it disabled as well.
9858 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
9859 //RotatePointAroundVector( r_refdef.view.frustum[0].normal, up, forward, -(90 - r_refdef.fov_x / 2));
9860 //r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, frustum[0].normal);
9861 //PlaneClassify(&frustum[0]);
9863 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
9864 //RotatePointAroundVector( r_refdef.view.frustum[1].normal, up, forward, (90 - r_refdef.fov_x / 2));
9865 //r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, frustum[1].normal);
9866 //PlaneClassify(&frustum[1]);
9868 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
9869 //RotatePointAroundVector( r_refdef.view.frustum[2].normal, left, forward, -(90 - r_refdef.fov_y / 2));
9870 //r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, frustum[2].normal);
9871 //PlaneClassify(&frustum[2]);
9873 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
9874 //RotatePointAroundVector( r_refdef.view.frustum[3].normal, left, forward, (90 - r_refdef.fov_y / 2));
9875 //r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, frustum[3].normal);
9876 //PlaneClassify(&frustum[3]);
9879 //VectorCopy(forward, r_refdef.view.frustum[4].normal);
9880 //r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, frustum[4].normal) + r_nearclip.value;
9881 //PlaneClassify(&frustum[4]);
9884 void R_View_UpdateWithScissor(const int *myscissor)
9886 R_Main_ResizeViewCache();
9887 R_View_SetFrustum(myscissor);
9888 R_View_WorldVisibility(r_refdef.view.useclipplane);
9889 R_View_UpdateEntityVisible();
9890 R_View_UpdateEntityLighting();
9893 void R_View_Update(void)
9895 R_Main_ResizeViewCache();
9896 R_View_SetFrustum(NULL);
9897 R_View_WorldVisibility(r_refdef.view.useclipplane);
9898 R_View_UpdateEntityVisible();
9899 R_View_UpdateEntityLighting();
9902 void R_SetupView(qboolean allowwaterclippingplane)
9904 const float *customclipplane = NULL;
9906 if (r_refdef.view.useclipplane && allowwaterclippingplane)
9908 // LordHavoc: couldn't figure out how to make this approach the
9909 vec_t dist = r_refdef.view.clipplane.dist - r_water_clippingplanebias.value;
9910 vec_t viewdist = DotProduct(r_refdef.view.origin, r_refdef.view.clipplane.normal);
9911 if (viewdist < r_refdef.view.clipplane.dist + r_water_clippingplanebias.value)
9912 dist = r_refdef.view.clipplane.dist;
9913 plane[0] = r_refdef.view.clipplane.normal[0];
9914 plane[1] = r_refdef.view.clipplane.normal[1];
9915 plane[2] = r_refdef.view.clipplane.normal[2];
9917 customclipplane = plane;
9920 if (!r_refdef.view.useperspective)
9921 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);
9922 else if (vid.stencil && r_useinfinitefarclip.integer)
9923 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);
9925 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);
9926 R_SetViewport(&r_refdef.view.viewport);
9929 void R_EntityMatrix(const matrix4x4_t *matrix)
9931 if (gl_modelmatrixchanged || memcmp(matrix, &gl_modelmatrix, sizeof(matrix4x4_t)))
9933 gl_modelmatrixchanged = false;
9934 gl_modelmatrix = *matrix;
9935 Matrix4x4_Concat(&gl_modelviewmatrix, &gl_viewmatrix, &gl_modelmatrix);
9936 Matrix4x4_Concat(&gl_modelviewprojectionmatrix, &gl_projectionmatrix, &gl_modelviewmatrix);
9937 Matrix4x4_ToArrayFloatGL(&gl_modelviewmatrix, gl_modelview16f);
9938 Matrix4x4_ToArrayFloatGL(&gl_modelviewprojectionmatrix, gl_modelviewprojection16f);
9940 switch(vid.renderpath)
9942 case RENDERPATH_D3D9:
9944 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
9945 hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
9948 case RENDERPATH_D3D10:
9949 Con_DPrintf("FIXME D3D10 shader %s:%i\n", __FILE__, __LINE__);
9951 case RENDERPATH_D3D11:
9952 Con_DPrintf("FIXME D3D11 shader %s:%i\n", __FILE__, __LINE__);
9954 case RENDERPATH_GL20:
9955 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
9956 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
9957 qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
9959 case RENDERPATH_CGGL:
9962 if (r_cg_permutation && r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR
9963 if (r_cg_permutation && r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR
9964 qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
9967 case RENDERPATH_GL13:
9968 case RENDERPATH_GL11:
9969 qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
9971 case RENDERPATH_SOFT:
9972 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
9973 DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
9975 case RENDERPATH_GLES2:
9976 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
9977 if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
9983 void R_ResetViewRendering2D(void)
9985 r_viewport_t viewport;
9988 // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom
9989 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);
9990 R_SetViewport(&viewport);
9991 GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
9992 GL_Color(1, 1, 1, 1);
9993 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
9994 GL_BlendFunc(GL_ONE, GL_ZERO);
9995 GL_AlphaTest(false);
9996 GL_ScissorTest(false);
9997 GL_DepthMask(false);
9998 GL_DepthRange(0, 1);
9999 GL_DepthTest(false);
10000 GL_DepthFunc(GL_LEQUAL);
10001 R_EntityMatrix(&identitymatrix);
10002 R_Mesh_ResetTextureState();
10003 GL_PolygonOffset(0, 0);
10004 R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
10005 switch(vid.renderpath)
10007 case RENDERPATH_GL11:
10008 case RENDERPATH_GL13:
10009 case RENDERPATH_GL20:
10010 case RENDERPATH_CGGL:
10011 case RENDERPATH_GLES2:
10012 qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
10014 case RENDERPATH_D3D9:
10015 case RENDERPATH_D3D10:
10016 case RENDERPATH_D3D11:
10017 case RENDERPATH_SOFT:
10020 GL_CullFace(GL_NONE);
10023 void R_ResetViewRendering3D(void)
10028 GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height);
10029 GL_Color(1, 1, 1, 1);
10030 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
10031 GL_BlendFunc(GL_ONE, GL_ZERO);
10032 GL_AlphaTest(false);
10033 GL_ScissorTest(true);
10034 GL_DepthMask(true);
10035 GL_DepthRange(0, 1);
10036 GL_DepthTest(true);
10037 GL_DepthFunc(GL_LEQUAL);
10038 R_EntityMatrix(&identitymatrix);
10039 R_Mesh_ResetTextureState();
10040 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
10041 R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
10042 switch(vid.renderpath)
10044 case RENDERPATH_GL11:
10045 case RENDERPATH_GL13:
10046 case RENDERPATH_GL20:
10047 case RENDERPATH_CGGL:
10048 case RENDERPATH_GLES2:
10049 qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
10051 case RENDERPATH_D3D9:
10052 case RENDERPATH_D3D10:
10053 case RENDERPATH_D3D11:
10054 case RENDERPATH_SOFT:
10057 GL_CullFace(r_refdef.view.cullface_back);
10062 R_RenderView_UpdateViewVectors
10065 static void R_RenderView_UpdateViewVectors(void)
10067 // break apart the view matrix into vectors for various purposes
10068 // it is important that this occurs outside the RenderScene function because that can be called from reflection renders, where the vectors come out wrong
10069 // however the r_refdef.view.origin IS updated in RenderScene intentionally - otherwise the sky renders at the wrong origin, etc
10070 Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin);
10071 VectorNegate(r_refdef.view.left, r_refdef.view.right);
10072 // make an inverted copy of the view matrix for tracking sprites
10073 Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix);
10076 void R_RenderScene(void);
10077 void R_RenderWaterPlanes(void);
10079 static void R_Water_StartFrame(void)
10082 int waterwidth, waterheight, texturewidth, textureheight, camerawidth, cameraheight;
10083 r_waterstate_waterplane_t *p;
10085 if (vid.width > (int)vid.maxtexturesize_2d || vid.height > (int)vid.maxtexturesize_2d)
10088 switch(vid.renderpath)
10090 case RENDERPATH_GL20:
10091 case RENDERPATH_CGGL:
10092 case RENDERPATH_D3D9:
10093 case RENDERPATH_D3D10:
10094 case RENDERPATH_D3D11:
10095 case RENDERPATH_SOFT:
10097 case RENDERPATH_GL13:
10098 case RENDERPATH_GL11:
10099 case RENDERPATH_GLES2:
10103 // set waterwidth and waterheight to the water resolution that will be
10104 // used (often less than the screen resolution for faster rendering)
10105 waterwidth = (int)bound(1, vid.width * r_water_resolutionmultiplier.value, vid.width);
10106 waterheight = (int)bound(1, vid.height * r_water_resolutionmultiplier.value, vid.height);
10108 // calculate desired texture sizes
10109 // can't use water if the card does not support the texture size
10110 if (!r_water.integer || r_showsurfaces.integer)
10111 texturewidth = textureheight = waterwidth = waterheight = camerawidth = cameraheight = 0;
10112 else if (vid.support.arb_texture_non_power_of_two)
10114 texturewidth = waterwidth;
10115 textureheight = waterheight;
10116 camerawidth = waterwidth;
10117 cameraheight = waterheight;
10121 for (texturewidth = 1;texturewidth < waterwidth ;texturewidth *= 2);
10122 for (textureheight = 1;textureheight < waterheight;textureheight *= 2);
10123 for (camerawidth = 1;camerawidth <= waterwidth; camerawidth *= 2); camerawidth /= 2;
10124 for (cameraheight = 1;cameraheight <= waterheight;cameraheight *= 2); cameraheight /= 2;
10127 // allocate textures as needed
10128 if (r_waterstate.texturewidth != texturewidth || r_waterstate.textureheight != textureheight || r_waterstate.camerawidth != camerawidth || r_waterstate.cameraheight != cameraheight)
10130 r_waterstate.maxwaterplanes = MAX_WATERPLANES;
10131 for (i = 0, p = r_waterstate.waterplanes;i < r_waterstate.maxwaterplanes;i++, p++)
10133 if (p->texture_refraction)
10134 R_FreeTexture(p->texture_refraction);
10135 p->texture_refraction = NULL;
10136 if (p->texture_reflection)
10137 R_FreeTexture(p->texture_reflection);
10138 p->texture_reflection = NULL;
10139 if (p->texture_camera)
10140 R_FreeTexture(p->texture_camera);
10141 p->texture_camera = NULL;
10143 memset(&r_waterstate, 0, sizeof(r_waterstate));
10144 r_waterstate.texturewidth = texturewidth;
10145 r_waterstate.textureheight = textureheight;
10146 r_waterstate.camerawidth = camerawidth;
10147 r_waterstate.cameraheight = cameraheight;
10150 if (r_waterstate.texturewidth)
10152 r_waterstate.enabled = true;
10154 // when doing a reduced render (HDR) we want to use a smaller area
10155 r_waterstate.waterwidth = (int)bound(1, r_refdef.view.width * r_water_resolutionmultiplier.value, r_refdef.view.width);
10156 r_waterstate.waterheight = (int)bound(1, r_refdef.view.height * r_water_resolutionmultiplier.value, r_refdef.view.height);
10158 // set up variables that will be used in shader setup
10159 r_waterstate.screenscale[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
10160 r_waterstate.screenscale[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
10161 r_waterstate.screencenter[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
10162 r_waterstate.screencenter[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
10165 r_waterstate.maxwaterplanes = MAX_WATERPLANES;
10166 r_waterstate.numwaterplanes = 0;
10169 void R_Water_AddWaterPlane(msurface_t *surface, int entno)
10171 int triangleindex, planeindex;
10177 r_waterstate_waterplane_t *p;
10178 texture_t *t = R_GetCurrentTexture(surface->texture);
10180 // just use the first triangle with a valid normal for any decisions
10181 VectorClear(normal);
10182 for (triangleindex = 0, e = rsurface.modelelement3i + surface->num_firsttriangle * 3;triangleindex < surface->num_triangles;triangleindex++, e += 3)
10184 Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[0]*3, vert[0]);
10185 Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[1]*3, vert[1]);
10186 Matrix4x4_Transform(&rsurface.matrix, rsurface.modelvertex3f + e[2]*3, vert[2]);
10187 TriangleNormal(vert[0], vert[1], vert[2], normal);
10188 if (VectorLength2(normal) >= 0.001)
10192 VectorCopy(normal, plane.normal);
10193 VectorNormalize(plane.normal);
10194 plane.dist = DotProduct(vert[0], plane.normal);
10195 PlaneClassify(&plane);
10196 if (PlaneDiff(r_refdef.view.origin, &plane) < 0)
10198 // skip backfaces (except if nocullface is set)
10199 if (!(t->currentmaterialflags & MATERIALFLAG_NOCULLFACE))
10201 VectorNegate(plane.normal, plane.normal);
10203 PlaneClassify(&plane);
10207 // find a matching plane if there is one
10208 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
10209 if(p->camera_entity == t->camera_entity)
10210 if (fabs(PlaneDiff(vert[0], &p->plane)) < 1 && fabs(PlaneDiff(vert[1], &p->plane)) < 1 && fabs(PlaneDiff(vert[2], &p->plane)) < 1)
10212 if (planeindex >= r_waterstate.maxwaterplanes)
10213 return; // nothing we can do, out of planes
10215 // if this triangle does not fit any known plane rendered this frame, add one
10216 if (planeindex >= r_waterstate.numwaterplanes)
10218 // store the new plane
10219 r_waterstate.numwaterplanes++;
10221 // clear materialflags and pvs
10222 p->materialflags = 0;
10223 p->pvsvalid = false;
10224 p->camera_entity = t->camera_entity;
10225 VectorCopy(surface->mins, p->mins);
10226 VectorCopy(surface->maxs, p->maxs);
10231 p->mins[0] = min(p->mins[0], surface->mins[0]);
10232 p->mins[1] = min(p->mins[1], surface->mins[1]);
10233 p->mins[2] = min(p->mins[2], surface->mins[2]);
10234 p->maxs[0] = max(p->maxs[0], surface->maxs[0]);
10235 p->maxs[1] = max(p->maxs[1], surface->maxs[1]);
10236 p->maxs[2] = max(p->maxs[2], surface->maxs[2]);
10238 // merge this surface's materialflags into the waterplane
10239 p->materialflags |= t->currentmaterialflags;
10240 if(!(p->materialflags & MATERIALFLAG_CAMERA))
10242 // merge this surface's PVS into the waterplane
10243 VectorMAM(0.5f, surface->mins, 0.5f, surface->maxs, center);
10244 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS
10245 && r_refdef.scene.worldmodel->brush.PointInLeaf && r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, center)->clusterindex >= 0)
10247 r_refdef.scene.worldmodel->brush.FatPVS(r_refdef.scene.worldmodel, center, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid);
10248 p->pvsvalid = true;
10253 static void R_Water_ProcessPlanes(void)
10256 r_refdef_view_t originalview;
10257 r_refdef_view_t myview;
10259 r_waterstate_waterplane_t *p;
10262 originalview = r_refdef.view;
10264 // make sure enough textures are allocated
10265 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
10267 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
10269 if (!p->texture_refraction)
10270 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);
10271 if (!p->texture_refraction)
10274 else if (p->materialflags & MATERIALFLAG_CAMERA)
10276 if (!p->texture_camera)
10277 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);
10278 if (!p->texture_camera)
10282 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
10284 if (!p->texture_reflection)
10285 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);
10286 if (!p->texture_reflection)
10292 r_refdef.view = originalview;
10293 r_refdef.view.showdebug = false;
10294 r_refdef.view.width = r_waterstate.waterwidth;
10295 r_refdef.view.height = r_waterstate.waterheight;
10296 r_refdef.view.useclipplane = true;
10297 myview = r_refdef.view;
10298 r_waterstate.renderingscene = true;
10299 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
10301 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
10303 r_refdef.view = myview;
10304 if(r_water_scissormode.integer)
10307 if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
10308 continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
10311 // render reflected scene and copy into texture
10312 Matrix4x4_Reflect(&r_refdef.view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
10313 // update the r_refdef.view.origin because otherwise the sky renders at the wrong location (amongst other problems)
10314 Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin);
10315 r_refdef.view.clipplane = p->plane;
10317 // reverse the cullface settings for this render
10318 r_refdef.view.cullface_front = GL_FRONT;
10319 r_refdef.view.cullface_back = GL_BACK;
10320 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.num_pvsclusterbytes)
10322 r_refdef.view.usecustompvs = true;
10324 memcpy(r_refdef.viewcache.world_pvsbits, p->pvsbits, r_refdef.scene.worldmodel->brush.num_pvsclusterbytes);
10326 memset(r_refdef.viewcache.world_pvsbits, 0xFF, r_refdef.scene.worldmodel->brush.num_pvsclusterbytes);
10329 R_ResetViewRendering3D();
10330 R_ClearScreen(r_refdef.fogenabled);
10331 if(r_water_scissormode.integer & 2)
10332 R_View_UpdateWithScissor(myscissor);
10335 if(r_water_scissormode.integer & 1)
10336 GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
10339 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);
10342 // render the normal view scene and copy into texture
10343 // (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)
10344 if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
10346 r_refdef.view = myview;
10347 if(r_water_scissormode.integer)
10350 if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
10351 continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
10354 r_waterstate.renderingrefraction = true;
10356 r_refdef.view.clipplane = p->plane;
10357 VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal);
10358 r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist;
10360 if((p->materialflags & MATERIALFLAG_CAMERA) && p->camera_entity)
10362 // we need to perform a matrix transform to render the view... so let's get the transformation matrix
10363 r_waterstate.renderingrefraction = false; // we don't want to hide the player model from these ones
10364 CL_VM_TransformView(p->camera_entity - MAX_EDICTS, &r_refdef.view.matrix, &r_refdef.view.clipplane, visorigin);
10365 R_RenderView_UpdateViewVectors();
10366 if(r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
10368 r_refdef.view.usecustompvs = true;
10369 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);
10373 PlaneClassify(&r_refdef.view.clipplane);
10375 R_ResetViewRendering3D();
10376 R_ClearScreen(r_refdef.fogenabled);
10377 if(r_water_scissormode.integer & 2)
10378 R_View_UpdateWithScissor(myscissor);
10381 if(r_water_scissormode.integer & 1)
10382 GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
10385 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);
10386 r_waterstate.renderingrefraction = false;
10388 else if (p->materialflags & MATERIALFLAG_CAMERA)
10390 r_refdef.view = myview;
10392 r_refdef.view.clipplane = p->plane;
10393 VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal);
10394 r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist;
10396 r_refdef.view.width = r_waterstate.camerawidth;
10397 r_refdef.view.height = r_waterstate.cameraheight;
10398 r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
10399 r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
10401 if(p->camera_entity)
10403 // we need to perform a matrix transform to render the view... so let's get the transformation matrix
10404 CL_VM_TransformView(p->camera_entity - MAX_EDICTS, &r_refdef.view.matrix, &r_refdef.view.clipplane, visorigin);
10407 // note: all of the view is used for displaying... so
10408 // there is no use in scissoring
10410 // reverse the cullface settings for this render
10411 r_refdef.view.cullface_front = GL_FRONT;
10412 r_refdef.view.cullface_back = GL_BACK;
10413 // also reverse the view matrix
10414 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
10415 R_RenderView_UpdateViewVectors();
10416 if(p->camera_entity && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
10418 r_refdef.view.usecustompvs = true;
10419 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);
10422 // camera needs no clipplane
10423 r_refdef.view.useclipplane = false;
10425 PlaneClassify(&r_refdef.view.clipplane);
10427 R_ResetViewRendering3D();
10428 R_ClearScreen(r_refdef.fogenabled);
10432 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);
10433 r_waterstate.renderingrefraction = false;
10437 r_waterstate.renderingscene = false;
10438 r_refdef.view = originalview;
10439 R_ResetViewRendering3D();
10440 R_ClearScreen(r_refdef.fogenabled);
10444 r_refdef.view = originalview;
10445 r_waterstate.renderingscene = false;
10446 Cvar_SetValueQuick(&r_water, 0);
10447 Con_Printf("R_Water_ProcessPlanes: Error: texture creation failed! Turned off r_water.\n");
10451 void R_Bloom_StartFrame(void)
10453 int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight;
10455 switch(vid.renderpath)
10457 case RENDERPATH_GL20:
10458 case RENDERPATH_CGGL:
10459 case RENDERPATH_D3D9:
10460 case RENDERPATH_D3D10:
10461 case RENDERPATH_D3D11:
10462 case RENDERPATH_SOFT:
10464 case RENDERPATH_GL13:
10465 case RENDERPATH_GL11:
10466 case RENDERPATH_GLES2:
10470 // set bloomwidth and bloomheight to the bloom resolution that will be
10471 // used (often less than the screen resolution for faster rendering)
10472 r_bloomstate.bloomwidth = bound(1, r_bloom_resolution.integer, vid.height);
10473 r_bloomstate.bloomheight = r_bloomstate.bloomwidth * vid.height / vid.width;
10474 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, vid.height);
10475 r_bloomstate.bloomwidth = bound(1, r_bloomstate.bloomwidth, (int)vid.maxtexturesize_2d);
10476 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, (int)vid.maxtexturesize_2d);
10478 // calculate desired texture sizes
10479 if (vid.support.arb_texture_non_power_of_two)
10481 screentexturewidth = r_refdef.view.width;
10482 screentextureheight = r_refdef.view.height;
10483 bloomtexturewidth = r_bloomstate.bloomwidth;
10484 bloomtextureheight = r_bloomstate.bloomheight;
10488 for (screentexturewidth = 1;screentexturewidth < vid.width ;screentexturewidth *= 2);
10489 for (screentextureheight = 1;screentextureheight < vid.height ;screentextureheight *= 2);
10490 for (bloomtexturewidth = 1;bloomtexturewidth < r_bloomstate.bloomwidth ;bloomtexturewidth *= 2);
10491 for (bloomtextureheight = 1;bloomtextureheight < r_bloomstate.bloomheight;bloomtextureheight *= 2);
10494 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))
10496 Cvar_SetValueQuick(&r_hdr, 0);
10497 Cvar_SetValueQuick(&r_bloom, 0);
10498 Cvar_SetValueQuick(&r_motionblur, 0);
10499 Cvar_SetValueQuick(&r_damageblur, 0);
10502 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)))
10503 screentexturewidth = screentextureheight = 0;
10504 if (!r_hdr.integer && !r_bloom.integer)
10505 bloomtexturewidth = bloomtextureheight = 0;
10507 // allocate textures as needed
10508 if (r_bloomstate.screentexturewidth != screentexturewidth || r_bloomstate.screentextureheight != screentextureheight)
10510 if (r_bloomstate.texture_screen)
10511 R_FreeTexture(r_bloomstate.texture_screen);
10512 r_bloomstate.texture_screen = NULL;
10513 r_bloomstate.screentexturewidth = screentexturewidth;
10514 r_bloomstate.screentextureheight = screentextureheight;
10515 if (r_bloomstate.screentexturewidth && r_bloomstate.screentextureheight)
10516 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);
10518 if (r_bloomstate.bloomtexturewidth != bloomtexturewidth || r_bloomstate.bloomtextureheight != bloomtextureheight)
10520 if (r_bloomstate.texture_bloom)
10521 R_FreeTexture(r_bloomstate.texture_bloom);
10522 r_bloomstate.texture_bloom = NULL;
10523 r_bloomstate.bloomtexturewidth = bloomtexturewidth;
10524 r_bloomstate.bloomtextureheight = bloomtextureheight;
10525 if (r_bloomstate.bloomtexturewidth && r_bloomstate.bloomtextureheight)
10526 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);
10529 // when doing a reduced render (HDR) we want to use a smaller area
10530 r_bloomstate.bloomwidth = bound(1, r_bloom_resolution.integer, r_refdef.view.height);
10531 r_bloomstate.bloomheight = r_bloomstate.bloomwidth * r_refdef.view.height / r_refdef.view.width;
10532 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, r_refdef.view.height);
10533 r_bloomstate.bloomwidth = bound(1, r_bloomstate.bloomwidth, r_bloomstate.bloomtexturewidth);
10534 r_bloomstate.bloomheight = bound(1, r_bloomstate.bloomheight, r_bloomstate.bloomtextureheight);
10536 // set up a texcoord array for the full resolution screen image
10537 // (we have to keep this around to copy back during final render)
10538 r_bloomstate.screentexcoord2f[0] = 0;
10539 r_bloomstate.screentexcoord2f[1] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight;
10540 r_bloomstate.screentexcoord2f[2] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth;
10541 r_bloomstate.screentexcoord2f[3] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight;
10542 r_bloomstate.screentexcoord2f[4] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth;
10543 r_bloomstate.screentexcoord2f[5] = 0;
10544 r_bloomstate.screentexcoord2f[6] = 0;
10545 r_bloomstate.screentexcoord2f[7] = 0;
10547 // set up a texcoord array for the reduced resolution bloom image
10548 // (which will be additive blended over the screen image)
10549 r_bloomstate.bloomtexcoord2f[0] = 0;
10550 r_bloomstate.bloomtexcoord2f[1] = (float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10551 r_bloomstate.bloomtexcoord2f[2] = (float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10552 r_bloomstate.bloomtexcoord2f[3] = (float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10553 r_bloomstate.bloomtexcoord2f[4] = (float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10554 r_bloomstate.bloomtexcoord2f[5] = 0;
10555 r_bloomstate.bloomtexcoord2f[6] = 0;
10556 r_bloomstate.bloomtexcoord2f[7] = 0;
10558 switch(vid.renderpath)
10560 case RENDERPATH_GL11:
10561 case RENDERPATH_GL13:
10562 case RENDERPATH_GL20:
10563 case RENDERPATH_CGGL:
10564 case RENDERPATH_SOFT:
10565 case RENDERPATH_GLES2:
10567 case RENDERPATH_D3D9:
10568 case RENDERPATH_D3D10:
10569 case RENDERPATH_D3D11:
10572 for (i = 0;i < 4;i++)
10574 r_bloomstate.screentexcoord2f[i*2+0] += 0.5f / (float)r_bloomstate.screentexturewidth;
10575 r_bloomstate.screentexcoord2f[i*2+1] += 0.5f / (float)r_bloomstate.screentextureheight;
10576 r_bloomstate.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_bloomstate.bloomtexturewidth;
10577 r_bloomstate.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_bloomstate.bloomtextureheight;
10583 if (r_hdr.integer || r_bloom.integer)
10585 r_bloomstate.enabled = true;
10586 r_bloomstate.hdr = r_hdr.integer != 0;
10589 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);
10592 void R_Bloom_CopyBloomTexture(float colorscale)
10594 r_refdef.stats.bloom++;
10596 // scale down screen texture to the bloom texture size
10598 R_SetViewport(&r_bloomstate.viewport);
10599 GL_BlendFunc(GL_ONE, GL_ZERO);
10600 GL_Color(colorscale, colorscale, colorscale, 1);
10601 // 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...
10602 switch(vid.renderpath)
10604 case RENDERPATH_GL11:
10605 case RENDERPATH_GL13:
10606 case RENDERPATH_GL20:
10607 case RENDERPATH_CGGL:
10608 case RENDERPATH_SOFT:
10609 case RENDERPATH_GLES2:
10610 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10612 case RENDERPATH_D3D9:
10613 case RENDERPATH_D3D10:
10614 case RENDERPATH_D3D11:
10615 R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10618 // TODO: do boxfilter scale-down in shader?
10619 R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1);
10620 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10621 r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
10623 // we now have a bloom image in the framebuffer
10624 // copy it into the bloom image texture for later processing
10625 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);
10626 r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
10629 void R_Bloom_CopyHDRTexture(void)
10631 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);
10632 r_refdef.stats.bloom_copypixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
10635 void R_Bloom_MakeTexture(void)
10638 float xoffset, yoffset, r, brighten;
10640 r_refdef.stats.bloom++;
10642 R_ResetViewRendering2D();
10644 // we have a bloom image in the framebuffer
10646 R_SetViewport(&r_bloomstate.viewport);
10648 for (x = 1;x < min(r_bloom_colorexponent.value, 32);)
10651 r = bound(0, r_bloom_colorexponent.value / x, 1);
10652 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
10654 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.bloomtexcoord2f);
10655 R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1);
10656 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10657 r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
10659 // copy the vertically blurred bloom view to a texture
10660 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);
10661 r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
10664 range = r_bloom_blur.integer * r_bloomstate.bloomwidth / 320;
10665 brighten = r_bloom_brighten.value;
10667 brighten *= r_hdr_range.value;
10668 brighten = sqrt(brighten);
10670 brighten *= (3 * range) / (2 * range - 1); // compensate for the "dot particle"
10671 R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1);
10673 for (dir = 0;dir < 2;dir++)
10675 // blend on at multiple vertical offsets to achieve a vertical blur
10676 // TODO: do offset blends using GLSL
10677 // TODO instead of changing the texcoords, change the target positions to prevent artifacts at edges
10678 GL_BlendFunc(GL_ONE, GL_ZERO);
10679 for (x = -range;x <= range;x++)
10681 if (!dir){xoffset = 0;yoffset = x;}
10682 else {xoffset = x;yoffset = 0;}
10683 xoffset /= (float)r_bloomstate.bloomtexturewidth;
10684 yoffset /= (float)r_bloomstate.bloomtextureheight;
10685 // compute a texcoord array with the specified x and y offset
10686 r_bloomstate.offsettexcoord2f[0] = xoffset+0;
10687 r_bloomstate.offsettexcoord2f[1] = yoffset+(float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10688 r_bloomstate.offsettexcoord2f[2] = xoffset+(float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10689 r_bloomstate.offsettexcoord2f[3] = yoffset+(float)r_bloomstate.bloomheight / (float)r_bloomstate.bloomtextureheight;
10690 r_bloomstate.offsettexcoord2f[4] = xoffset+(float)r_bloomstate.bloomwidth / (float)r_bloomstate.bloomtexturewidth;
10691 r_bloomstate.offsettexcoord2f[5] = yoffset+0;
10692 r_bloomstate.offsettexcoord2f[6] = xoffset+0;
10693 r_bloomstate.offsettexcoord2f[7] = yoffset+0;
10694 // this r value looks like a 'dot' particle, fading sharply to
10695 // black at the edges
10696 // (probably not realistic but looks good enough)
10697 //r = ((range*range+1)/((float)(x*x+1)))/(range*2+1);
10698 //r = brighten/(range*2+1);
10699 r = brighten / (range * 2 + 1);
10701 r *= (1 - x*x/(float)(range*range));
10702 GL_Color(r, r, r, 1);
10703 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.offsettexcoord2f);
10704 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10705 r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
10706 GL_BlendFunc(GL_ONE, GL_ONE);
10709 // copy the vertically blurred bloom view to a texture
10710 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);
10711 r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
10715 void R_HDR_RenderBloomTexture(void)
10717 int oldwidth, oldheight;
10718 float oldcolorscale;
10719 qboolean oldwaterstate;
10721 oldwaterstate = r_waterstate.enabled;
10722 oldcolorscale = r_refdef.view.colorscale;
10723 oldwidth = r_refdef.view.width;
10724 oldheight = r_refdef.view.height;
10725 r_refdef.view.width = r_bloomstate.bloomwidth;
10726 r_refdef.view.height = r_bloomstate.bloomheight;
10728 if(r_hdr.integer < 2)
10729 r_waterstate.enabled = false;
10731 // TODO: support GL_EXT_framebuffer_object rather than reusing the framebuffer? it might improve SLI performance.
10732 // TODO: add exposure compensation features
10733 // TODO: add fp16 framebuffer support (using GL_EXT_framebuffer_object)
10735 r_refdef.view.showdebug = false;
10736 r_refdef.view.colorscale *= r_bloom_colorscale.value / bound(1, r_hdr_range.value, 16);
10738 R_ResetViewRendering3D();
10740 R_ClearScreen(r_refdef.fogenabled);
10741 if (r_timereport_active)
10742 R_TimeReport("HDRclear");
10745 if (r_timereport_active)
10746 R_TimeReport("visibility");
10748 // only do secondary renders with HDR if r_hdr is 2 or higher
10749 r_waterstate.numwaterplanes = 0;
10750 if (r_waterstate.enabled)
10751 R_RenderWaterPlanes();
10753 r_refdef.view.showdebug = true;
10755 r_waterstate.numwaterplanes = 0;
10757 R_ResetViewRendering2D();
10759 R_Bloom_CopyHDRTexture();
10760 R_Bloom_MakeTexture();
10762 // restore the view settings
10763 r_waterstate.enabled = oldwaterstate;
10764 r_refdef.view.width = oldwidth;
10765 r_refdef.view.height = oldheight;
10766 r_refdef.view.colorscale = oldcolorscale;
10768 R_ResetViewRendering3D();
10770 R_ClearScreen(r_refdef.fogenabled);
10771 if (r_timereport_active)
10772 R_TimeReport("viewclear");
10775 static void R_BlendView(void)
10777 unsigned int permutation;
10778 float uservecs[4][4];
10780 switch (vid.renderpath)
10782 case RENDERPATH_GL20:
10783 case RENDERPATH_CGGL:
10784 case RENDERPATH_D3D9:
10785 case RENDERPATH_D3D10:
10786 case RENDERPATH_D3D11:
10787 case RENDERPATH_SOFT:
10788 case RENDERPATH_GLES2:
10790 (r_bloomstate.texture_bloom ? SHADERPERMUTATION_BLOOM : 0)
10791 | (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VIEWTINT : 0)
10792 | ((v_glslgamma.value && !vid_gammatables_trivial) ? SHADERPERMUTATION_GAMMARAMPS : 0)
10793 | (r_glsl_postprocess.integer ? SHADERPERMUTATION_POSTPROCESSING : 0)
10794 | ((!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) ? SHADERPERMUTATION_SATURATION : 0);
10796 if (r_bloomstate.texture_screen)
10798 // make sure the buffer is available
10799 if (r_bloom_blur.value < 1) { Cvar_SetValueQuick(&r_bloom_blur, 1); }
10801 R_ResetViewRendering2D();
10803 if(!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0))
10805 // declare variables
10807 static float avgspeed;
10809 speed = VectorLength(cl.movement_velocity);
10811 cl.motionbluralpha = bound(0, (cl.time - cl.oldtime) / max(0.001, r_motionblur_vcoeff.value), 1);
10812 avgspeed = avgspeed * (1 - cl.motionbluralpha) + speed * cl.motionbluralpha;
10814 speed = (avgspeed - r_motionblur_vmin.value) / max(1, r_motionblur_vmax.value - r_motionblur_vmin.value);
10815 speed = bound(0, speed, 1);
10816 speed = speed * (1 - r_motionblur_bmin.value) + r_motionblur_bmin.value;
10818 // calculate values into a standard alpha
10819 cl.motionbluralpha = 1 - exp(-
10821 (r_motionblur.value * speed / 80)
10823 (r_damageblur.value * (cl.cshifts[CSHIFT_DAMAGE].percent / 1600))
10826 max(0.0001, cl.time - cl.oldtime) // fps independent
10829 cl.motionbluralpha *= lhrandom(1 - r_motionblur_randomize.value, 1 + r_motionblur_randomize.value);
10830 cl.motionbluralpha = bound(0, cl.motionbluralpha, r_motionblur_maxblur.value);
10832 if (cl.motionbluralpha > 0 && !r_refdef.envmap)
10834 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
10835 GL_Color(1, 1, 1, cl.motionbluralpha);
10836 switch(vid.renderpath)
10838 case RENDERPATH_GL11:
10839 case RENDERPATH_GL13:
10840 case RENDERPATH_GL20:
10841 case RENDERPATH_CGGL:
10842 case RENDERPATH_SOFT:
10843 case RENDERPATH_GLES2:
10844 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10846 case RENDERPATH_D3D9:
10847 case RENDERPATH_D3D10:
10848 case RENDERPATH_D3D11:
10849 R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_bloomstate.screentexcoord2f);
10852 R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1);
10853 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10854 r_refdef.stats.bloom_drawpixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
10858 // copy view into the screen texture
10859 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);
10860 r_refdef.stats.bloom_copypixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
10862 else if (!r_bloomstate.texture_bloom)
10864 // we may still have to do view tint...
10865 if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
10867 // apply a color tint to the whole view
10868 R_ResetViewRendering2D();
10869 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10870 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
10871 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
10872 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
10873 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10875 break; // no screen processing, no bloom, skip it
10878 if (r_bloomstate.texture_bloom && !r_bloomstate.hdr)
10880 // render simple bloom effect
10881 // copy the screen and shrink it and darken it for the bloom process
10882 R_Bloom_CopyBloomTexture(r_bloom_colorscale.value);
10883 // make the bloom texture
10884 R_Bloom_MakeTexture();
10887 #if _MSC_VER >= 1400
10888 #define sscanf sscanf_s
10890 memset(uservecs, 0, sizeof(uservecs));
10891 if (r_glsl_postprocess_uservec1_enable.integer)
10892 sscanf(r_glsl_postprocess_uservec1.string, "%f %f %f %f", &uservecs[0][0], &uservecs[0][1], &uservecs[0][2], &uservecs[0][3]);
10893 if (r_glsl_postprocess_uservec2_enable.integer)
10894 sscanf(r_glsl_postprocess_uservec2.string, "%f %f %f %f", &uservecs[1][0], &uservecs[1][1], &uservecs[1][2], &uservecs[1][3]);
10895 if (r_glsl_postprocess_uservec3_enable.integer)
10896 sscanf(r_glsl_postprocess_uservec3.string, "%f %f %f %f", &uservecs[2][0], &uservecs[2][1], &uservecs[2][2], &uservecs[2][3]);
10897 if (r_glsl_postprocess_uservec4_enable.integer)
10898 sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &uservecs[3][0], &uservecs[3][1], &uservecs[3][2], &uservecs[3][3]);
10900 R_ResetViewRendering2D();
10901 GL_Color(1, 1, 1, 1);
10902 GL_BlendFunc(GL_ONE, GL_ZERO);
10904 switch(vid.renderpath)
10906 case RENDERPATH_GL20:
10907 case RENDERPATH_GLES2:
10908 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10909 R_SetupShader_SetPermutationGLSL(SHADERMODE_POSTPROCESS, permutation);
10910 if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_bloomstate.texture_screen);
10911 if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_bloomstate.texture_bloom );
10912 if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps );
10913 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]);
10914 if (r_glsl_permutation->loc_PixelSize >= 0) qglUniform2f(r_glsl_permutation->loc_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
10915 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]);
10916 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]);
10917 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]);
10918 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]);
10919 if (r_glsl_permutation->loc_Saturation >= 0) qglUniform1f(r_glsl_permutation->loc_Saturation , r_glsl_saturation.value);
10920 if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
10921 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);
10923 case RENDERPATH_CGGL:
10925 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10926 R_SetupShader_SetPermutationCG(SHADERMODE_POSTPROCESS, permutation);
10927 if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , r_bloomstate.texture_screen);CHECKCGERROR
10928 if (r_cg_permutation->fp_Texture_Second ) CG_BindTexture(r_cg_permutation->fp_Texture_Second , r_bloomstate.texture_bloom );CHECKCGERROR
10929 if (r_cg_permutation->fp_Texture_GammaRamps) CG_BindTexture(r_cg_permutation->fp_Texture_GammaRamps, r_texture_gammaramps );CHECKCGERROR
10930 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
10931 if (r_cg_permutation->fp_PixelSize ) cgGLSetParameter2f( r_cg_permutation->fp_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);CHECKCGERROR
10932 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
10933 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
10934 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
10935 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
10936 if (r_cg_permutation->fp_Saturation ) cgGLSetParameter1f( r_cg_permutation->fp_Saturation , r_glsl_saturation.value);CHECKCGERROR
10937 if (r_cg_permutation->fp_PixelToScreenTexCoord) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
10938 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);
10941 case RENDERPATH_D3D9:
10943 // 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...
10944 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_d3dscreenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10945 R_SetupShader_SetPermutationHLSL(SHADERMODE_POSTPROCESS, permutation);
10946 R_Mesh_TexBind(GL20TU_FIRST , r_bloomstate.texture_screen);
10947 R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom );
10948 R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
10949 hlslPSSetParameter4f(D3DPSREGISTER_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10950 hlslPSSetParameter2f(D3DPSREGISTER_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
10951 hlslPSSetParameter4f(D3DPSREGISTER_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
10952 hlslPSSetParameter4f(D3DPSREGISTER_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
10953 hlslPSSetParameter4f(D3DPSREGISTER_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
10954 hlslPSSetParameter4f(D3DPSREGISTER_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
10955 hlslPSSetParameter1f(D3DPSREGISTER_Saturation , r_glsl_saturation.value);
10956 hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
10957 hlslPSSetParameter4f(D3DPSREGISTER_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
10960 case RENDERPATH_D3D10:
10961 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
10963 case RENDERPATH_D3D11:
10964 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
10966 case RENDERPATH_SOFT:
10967 R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
10968 R_SetupShader_SetPermutationSoft(SHADERMODE_POSTPROCESS, permutation);
10969 R_Mesh_TexBind(GL20TU_FIRST , r_bloomstate.texture_screen);
10970 R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom );
10971 R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
10972 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10973 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
10974 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
10975 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
10976 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
10977 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
10978 DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Saturation , r_glsl_saturation.value);
10979 DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
10980 DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
10985 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
10986 r_refdef.stats.bloom_drawpixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
10988 case RENDERPATH_GL13:
10989 case RENDERPATH_GL11:
10990 if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
10992 // apply a color tint to the whole view
10993 R_ResetViewRendering2D();
10994 GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
10995 R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
10996 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
10997 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
10998 R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
11004 matrix4x4_t r_waterscrollmatrix;
11006 void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as that changes colorscale!
11008 if (r_refdef.fog_density)
11010 r_refdef.fogcolor[0] = r_refdef.fog_red;
11011 r_refdef.fogcolor[1] = r_refdef.fog_green;
11012 r_refdef.fogcolor[2] = r_refdef.fog_blue;
11014 Vector4Set(r_refdef.fogplane, 0, 0, 1, -r_refdef.fog_height);
11015 r_refdef.fogplaneviewdist = DotProduct(r_refdef.fogplane, r_refdef.view.origin) + r_refdef.fogplane[3];
11016 r_refdef.fogplaneviewabove = r_refdef.fogplaneviewdist >= 0;
11017 r_refdef.fogheightfade = -0.5f/max(0.125f, r_refdef.fog_fadedepth);
11021 VectorCopy(r_refdef.fogcolor, fogvec);
11022 // color.rgb *= ContrastBoost * SceneBrightness;
11023 VectorScale(fogvec, r_refdef.view.colorscale, fogvec);
11024 r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
11025 r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
11026 r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
11031 void R_UpdateVariables(void)
11033 R_Textures_Frame();
11035 r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f);
11037 r_refdef.farclip = r_farclip_base.value;
11038 if (r_refdef.scene.worldmodel)
11039 r_refdef.farclip += r_refdef.scene.worldmodel->radius * r_farclip_world.value * 2;
11040 r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
11042 if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1)
11043 Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1);
11044 r_refdef.polygonfactor = 0;
11045 r_refdef.polygonoffset = 0;
11046 r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
11047 r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
11049 r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0;
11050 r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
11051 r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
11052 r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
11053 r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
11054 if (FAKELIGHT_ENABLED)
11056 r_refdef.lightmapintensity *= r_fakelight_intensity.value;
11058 if (r_showsurfaces.integer)
11060 r_refdef.scene.rtworld = false;
11061 r_refdef.scene.rtworldshadows = false;
11062 r_refdef.scene.rtdlight = false;
11063 r_refdef.scene.rtdlightshadows = false;
11064 r_refdef.lightmapintensity = 0;
11067 if (gamemode == GAME_NEHAHRA)
11069 if (gl_fogenable.integer)
11071 r_refdef.oldgl_fogenable = true;
11072 r_refdef.fog_density = gl_fogdensity.value;
11073 r_refdef.fog_red = gl_fogred.value;
11074 r_refdef.fog_green = gl_foggreen.value;
11075 r_refdef.fog_blue = gl_fogblue.value;
11076 r_refdef.fog_alpha = 1;
11077 r_refdef.fog_start = 0;
11078 r_refdef.fog_end = gl_skyclip.value;
11079 r_refdef.fog_height = 1<<30;
11080 r_refdef.fog_fadedepth = 128;
11082 else if (r_refdef.oldgl_fogenable)
11084 r_refdef.oldgl_fogenable = false;
11085 r_refdef.fog_density = 0;
11086 r_refdef.fog_red = 0;
11087 r_refdef.fog_green = 0;
11088 r_refdef.fog_blue = 0;
11089 r_refdef.fog_alpha = 0;
11090 r_refdef.fog_start = 0;
11091 r_refdef.fog_end = 0;
11092 r_refdef.fog_height = 1<<30;
11093 r_refdef.fog_fadedepth = 128;
11097 r_refdef.fog_alpha = bound(0, r_refdef.fog_alpha, 1);
11098 r_refdef.fog_start = max(0, r_refdef.fog_start);
11099 r_refdef.fog_end = max(r_refdef.fog_start + 0.01, r_refdef.fog_end);
11101 // R_UpdateFogColor(); // why? R_RenderScene does it anyway
11103 if (r_refdef.fog_density && r_drawfog.integer)
11105 r_refdef.fogenabled = true;
11106 // this is the point where the fog reaches 0.9986 alpha, which we
11107 // consider a good enough cutoff point for the texture
11108 // (0.9986 * 256 == 255.6)
11109 if (r_fog_exp2.integer)
11110 r_refdef.fogrange = 32 / (r_refdef.fog_density * r_refdef.fog_density) + r_refdef.fog_start;
11112 r_refdef.fogrange = 2048 / r_refdef.fog_density + r_refdef.fog_start;
11113 r_refdef.fogrange = bound(r_refdef.fog_start, r_refdef.fogrange, r_refdef.fog_end);
11114 r_refdef.fograngerecip = 1.0f / r_refdef.fogrange;
11115 r_refdef.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * r_refdef.fograngerecip;
11116 if (strcmp(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename))
11117 R_BuildFogHeightTexture();
11118 // fog color was already set
11119 // update the fog texture
11120 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)
11121 R_BuildFogTexture();
11122 r_refdef.fog_height_texcoordscale = 1.0f / max(0.125f, r_refdef.fog_fadedepth);
11123 r_refdef.fog_height_tablescale = r_refdef.fog_height_tablesize * r_refdef.fog_height_texcoordscale;
11126 r_refdef.fogenabled = false;
11128 switch(vid.renderpath)
11130 case RENDERPATH_GL20:
11131 case RENDERPATH_CGGL:
11132 case RENDERPATH_D3D9:
11133 case RENDERPATH_D3D10:
11134 case RENDERPATH_D3D11:
11135 case RENDERPATH_SOFT:
11136 case RENDERPATH_GLES2:
11137 if(v_glslgamma.integer && !vid_gammatables_trivial)
11139 if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial)
11141 // build GLSL gamma texture
11142 #define RAMPWIDTH 256
11143 unsigned short ramp[RAMPWIDTH * 3];
11144 unsigned char rampbgr[RAMPWIDTH][4];
11147 r_texture_gammaramps_serial = vid_gammatables_serial;
11149 VID_BuildGammaTables(&ramp[0], RAMPWIDTH);
11150 for(i = 0; i < RAMPWIDTH; ++i)
11152 rampbgr[i][0] = (unsigned char) (ramp[i + 2 * RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
11153 rampbgr[i][1] = (unsigned char) (ramp[i + RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
11154 rampbgr[i][2] = (unsigned char) (ramp[i] * 255.0 / 65535.0 + 0.5);
11157 if (r_texture_gammaramps)
11159 R_UpdateTexture(r_texture_gammaramps, &rampbgr[0][0], 0, 0, RAMPWIDTH, 1);
11163 r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &rampbgr[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
11169 // remove GLSL gamma texture
11172 case RENDERPATH_GL13:
11173 case RENDERPATH_GL11:
11178 static r_refdef_scene_type_t r_currentscenetype = RST_CLIENT;
11179 static r_refdef_scene_t r_scenes_store[ RST_COUNT ];
11185 void R_SelectScene( r_refdef_scene_type_t scenetype ) {
11186 if( scenetype != r_currentscenetype ) {
11187 // store the old scenetype
11188 r_scenes_store[ r_currentscenetype ] = r_refdef.scene;
11189 r_currentscenetype = scenetype;
11190 // move in the new scene
11191 r_refdef.scene = r_scenes_store[ r_currentscenetype ];
11200 r_refdef_scene_t * R_GetScenePointer( r_refdef_scene_type_t scenetype )
11202 // of course, we could also add a qboolean that provides a lock state and a ReleaseScenePointer function..
11203 if( scenetype == r_currentscenetype ) {
11204 return &r_refdef.scene;
11206 return &r_scenes_store[ scenetype ];
11215 int dpsoftrast_test;
11216 void R_RenderView(void)
11218 matrix4x4_t originalmatrix = r_refdef.view.matrix, offsetmatrix;
11220 dpsoftrast_test = r_test.integer;
11222 if (r_timereport_active)
11223 R_TimeReport("start");
11224 r_textureframe++; // used only by R_GetCurrentTexture
11225 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
11227 if(R_CompileShader_CheckStaticParms())
11228 R_GLSL_Restart_f();
11230 if (!r_drawentities.integer)
11231 r_refdef.scene.numentities = 0;
11233 R_AnimCache_ClearCache();
11234 R_FrameData_NewFrame();
11236 /* adjust for stereo display */
11237 if(R_Stereo_Active())
11239 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);
11240 Matrix4x4_Concat(&r_refdef.view.matrix, &originalmatrix, &offsetmatrix);
11243 if (r_refdef.view.isoverlay)
11245 // TODO: FIXME: move this into its own backend function maybe? [2/5/2008 Andreas]
11246 GL_Clear(GL_DEPTH_BUFFER_BIT, NULL, 1.0f, 0);
11247 R_TimeReport("depthclear");
11249 r_refdef.view.showdebug = false;
11251 r_waterstate.enabled = false;
11252 r_waterstate.numwaterplanes = 0;
11256 r_refdef.view.matrix = originalmatrix;
11262 if (!r_refdef.scene.entities || r_refdef.view.width * r_refdef.view.height == 0 || !r_renderview.integer || cl_videoplaying/* || !r_refdef.scene.worldmodel*/)
11264 r_refdef.view.matrix = originalmatrix;
11265 return; //Host_Error ("R_RenderView: NULL worldmodel");
11268 r_refdef.view.colorscale = r_hdr_scenebrightness.value;
11270 R_RenderView_UpdateViewVectors();
11272 R_Shadow_UpdateWorldLightSelection();
11274 R_Bloom_StartFrame();
11275 R_Water_StartFrame();
11278 if (r_timereport_active)
11279 R_TimeReport("viewsetup");
11281 R_ResetViewRendering3D();
11283 if (r_refdef.view.clear || r_refdef.fogenabled)
11285 R_ClearScreen(r_refdef.fogenabled);
11286 if (r_timereport_active)
11287 R_TimeReport("viewclear");
11289 r_refdef.view.clear = true;
11291 // this produces a bloom texture to be used in R_BlendView() later
11292 if (r_hdr.integer && r_bloomstate.bloomwidth)
11294 R_HDR_RenderBloomTexture();
11295 // we have to bump the texture frame again because r_refdef.view.colorscale is cached in the textures
11296 r_textureframe++; // used only by R_GetCurrentTexture
11299 r_refdef.view.showdebug = true;
11302 if (r_timereport_active)
11303 R_TimeReport("visibility");
11305 r_waterstate.numwaterplanes = 0;
11306 if (r_waterstate.enabled)
11307 R_RenderWaterPlanes();
11310 r_waterstate.numwaterplanes = 0;
11313 if (r_timereport_active)
11314 R_TimeReport("blendview");
11316 GL_Scissor(0, 0, vid.width, vid.height);
11317 GL_ScissorTest(false);
11319 r_refdef.view.matrix = originalmatrix;
11324 void R_RenderWaterPlanes(void)
11326 if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawAddWaterPlanes)
11328 r_refdef.scene.worldmodel->DrawAddWaterPlanes(r_refdef.scene.worldentity);
11329 if (r_timereport_active)
11330 R_TimeReport("waterworld");
11333 // don't let sound skip if going slow
11334 if (r_refdef.scene.extraupdate)
11337 R_DrawModelsAddWaterPlanes();
11338 if (r_timereport_active)
11339 R_TimeReport("watermodels");
11341 if (r_waterstate.numwaterplanes)
11343 R_Water_ProcessPlanes();
11344 if (r_timereport_active)
11345 R_TimeReport("waterscenes");
11349 extern void R_DrawLightningBeams (void);
11350 extern void VM_CL_AddPolygonsToMeshQueue (void);
11351 extern void R_DrawPortals (void);
11352 extern cvar_t cl_locs_show;
11353 static void R_DrawLocs(void);
11354 static void R_DrawEntityBBoxes(void);
11355 static void R_DrawModelDecals(void);
11356 extern void R_DrawModelShadows(void);
11357 extern void R_DrawModelShadowMaps(void);
11358 extern cvar_t cl_decals_newsystem;
11359 extern qboolean r_shadow_usingdeferredprepass;
11360 void R_RenderScene(void)
11362 qboolean shadowmapping = false;
11364 if (r_timereport_active)
11365 R_TimeReport("beginscene");
11367 r_refdef.stats.renders++;
11369 R_UpdateFogColor();
11371 // don't let sound skip if going slow
11372 if (r_refdef.scene.extraupdate)
11375 R_MeshQueue_BeginScene();
11379 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);
11381 if (r_timereport_active)
11382 R_TimeReport("skystartframe");
11384 if (cl.csqc_vidvars.drawworld)
11386 // don't let sound skip if going slow
11387 if (r_refdef.scene.extraupdate)
11390 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawSky)
11392 r_refdef.scene.worldmodel->DrawSky(r_refdef.scene.worldentity);
11393 if (r_timereport_active)
11394 R_TimeReport("worldsky");
11397 if (R_DrawBrushModelsSky() && r_timereport_active)
11398 R_TimeReport("bmodelsky");
11400 if (skyrendermasked && skyrenderlater)
11402 // we have to force off the water clipping plane while rendering sky
11403 R_SetupView(false);
11406 if (r_timereport_active)
11407 R_TimeReport("sky");
11411 R_AnimCache_CacheVisibleEntities();
11412 if (r_timereport_active)
11413 R_TimeReport("animation");
11415 R_Shadow_PrepareLights();
11416 if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0)
11417 R_Shadow_PrepareModelShadows();
11418 if (r_timereport_active)
11419 R_TimeReport("preparelights");
11421 if (R_Shadow_ShadowMappingEnabled())
11422 shadowmapping = true;
11424 if (r_shadow_usingdeferredprepass)
11425 R_Shadow_DrawPrepass();
11427 if (r_depthfirst.integer >= 1 && cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDepth)
11429 r_refdef.scene.worldmodel->DrawDepth(r_refdef.scene.worldentity);
11430 if (r_timereport_active)
11431 R_TimeReport("worlddepth");
11433 if (r_depthfirst.integer >= 2)
11435 R_DrawModelsDepth();
11436 if (r_timereport_active)
11437 R_TimeReport("modeldepth");
11440 if (r_shadows.integer >= 2 && shadowmapping && r_refdef.lightmapintensity > 0)
11442 R_DrawModelShadowMaps();
11443 R_ResetViewRendering3D();
11444 // don't let sound skip if going slow
11445 if (r_refdef.scene.extraupdate)
11449 if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->Draw)
11451 r_refdef.scene.worldmodel->Draw(r_refdef.scene.worldentity);
11452 if (r_timereport_active)
11453 R_TimeReport("world");
11456 // don't let sound skip if going slow
11457 if (r_refdef.scene.extraupdate)
11461 if (r_timereport_active)
11462 R_TimeReport("models");
11464 // don't let sound skip if going slow
11465 if (r_refdef.scene.extraupdate)
11468 if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
11470 R_DrawModelShadows();
11471 R_ResetViewRendering3D();
11472 // don't let sound skip if going slow
11473 if (r_refdef.scene.extraupdate)
11477 if (!r_shadow_usingdeferredprepass)
11479 R_Shadow_DrawLights();
11480 if (r_timereport_active)
11481 R_TimeReport("rtlights");
11484 // don't let sound skip if going slow
11485 if (r_refdef.scene.extraupdate)
11488 if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.lightmapintensity > 0)
11490 R_DrawModelShadows();
11491 R_ResetViewRendering3D();
11492 // don't let sound skip if going slow
11493 if (r_refdef.scene.extraupdate)
11497 if (cl.csqc_vidvars.drawworld)
11499 if (cl_decals_newsystem.integer)
11501 R_DrawModelDecals();
11502 if (r_timereport_active)
11503 R_TimeReport("modeldecals");
11508 if (r_timereport_active)
11509 R_TimeReport("decals");
11513 if (r_timereport_active)
11514 R_TimeReport("particles");
11516 R_DrawExplosions();
11517 if (r_timereport_active)
11518 R_TimeReport("explosions");
11520 R_DrawLightningBeams();
11521 if (r_timereport_active)
11522 R_TimeReport("lightning");
11525 VM_CL_AddPolygonsToMeshQueue();
11527 if (r_refdef.view.showdebug)
11529 if (cl_locs_show.integer)
11532 if (r_timereport_active)
11533 R_TimeReport("showlocs");
11536 if (r_drawportals.integer)
11539 if (r_timereport_active)
11540 R_TimeReport("portals");
11543 if (r_showbboxes.value > 0)
11545 R_DrawEntityBBoxes();
11546 if (r_timereport_active)
11547 R_TimeReport("bboxes");
11551 R_MeshQueue_RenderTransparent();
11552 if (r_timereport_active)
11553 R_TimeReport("drawtrans");
11555 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))
11557 r_refdef.scene.worldmodel->DrawDebug(r_refdef.scene.worldentity);
11558 if (r_timereport_active)
11559 R_TimeReport("worlddebug");
11560 R_DrawModelsDebug();
11561 if (r_timereport_active)
11562 R_TimeReport("modeldebug");
11565 if (cl.csqc_vidvars.drawworld)
11567 R_Shadow_DrawCoronas();
11568 if (r_timereport_active)
11569 R_TimeReport("coronas");
11574 GL_DepthTest(false);
11575 qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
11576 GL_Color(1, 1, 1, 1);
11577 qglBegin(GL_POLYGON);
11578 qglVertex3f(r_refdef.view.frustumcorner[0][0], r_refdef.view.frustumcorner[0][1], r_refdef.view.frustumcorner[0][2]);
11579 qglVertex3f(r_refdef.view.frustumcorner[1][0], r_refdef.view.frustumcorner[1][1], r_refdef.view.frustumcorner[1][2]);
11580 qglVertex3f(r_refdef.view.frustumcorner[3][0], r_refdef.view.frustumcorner[3][1], r_refdef.view.frustumcorner[3][2]);
11581 qglVertex3f(r_refdef.view.frustumcorner[2][0], r_refdef.view.frustumcorner[2][1], r_refdef.view.frustumcorner[2][2]);
11583 qglBegin(GL_POLYGON);
11584 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]);
11585 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]);
11586 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]);
11587 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]);
11589 qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
11593 // don't let sound skip if going slow
11594 if (r_refdef.scene.extraupdate)
11597 R_ResetViewRendering2D();
11600 static const unsigned short bboxelements[36] =
11610 void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
11613 float *v, *c, f1, f2, vertex3f[8*3], color4f[8*4];
11615 RSurf_ActiveWorldEntity();
11617 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
11618 GL_DepthMask(false);
11619 GL_DepthRange(0, 1);
11620 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
11621 // R_Mesh_ResetTextureState();
11623 vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2]; //
11624 vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
11625 vertex3f[ 6] = mins[0];vertex3f[ 7] = maxs[1];vertex3f[ 8] = mins[2];
11626 vertex3f[ 9] = maxs[0];vertex3f[10] = maxs[1];vertex3f[11] = mins[2];
11627 vertex3f[12] = mins[0];vertex3f[13] = mins[1];vertex3f[14] = maxs[2];
11628 vertex3f[15] = maxs[0];vertex3f[16] = mins[1];vertex3f[17] = maxs[2];
11629 vertex3f[18] = mins[0];vertex3f[19] = maxs[1];vertex3f[20] = maxs[2];
11630 vertex3f[21] = maxs[0];vertex3f[22] = maxs[1];vertex3f[23] = maxs[2];
11631 R_FillColors(color4f, 8, cr, cg, cb, ca);
11632 if (r_refdef.fogenabled)
11634 for (i = 0, v = vertex3f, c = color4f;i < 8;i++, v += 3, c += 4)
11636 f1 = RSurf_FogVertex(v);
11638 c[0] = c[0] * f1 + r_refdef.fogcolor[0] * f2;
11639 c[1] = c[1] * f1 + r_refdef.fogcolor[1] * f2;
11640 c[2] = c[2] * f1 + r_refdef.fogcolor[2] * f2;
11643 R_Mesh_PrepareVertices_Generic_Arrays(8, vertex3f, color4f, NULL);
11644 R_Mesh_ResetTextureState();
11645 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
11646 R_Mesh_Draw(0, 8, 0, 12, NULL, NULL, 0, bboxelements, NULL, 0);
11649 static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
11653 prvm_edict_t *edict;
11654 prvm_prog_t *prog_save = prog;
11656 // this function draws bounding boxes of server entities
11660 GL_CullFace(GL_NONE);
11661 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
11665 for (i = 0;i < numsurfaces;i++)
11667 edict = PRVM_EDICT_NUM(surfacelist[i]);
11668 switch ((int)edict->fields.server->solid)
11670 case SOLID_NOT: Vector4Set(color, 1, 1, 1, 0.05);break;
11671 case SOLID_TRIGGER: Vector4Set(color, 1, 0, 1, 0.10);break;
11672 case SOLID_BBOX: Vector4Set(color, 0, 1, 0, 0.10);break;
11673 case SOLID_SLIDEBOX: Vector4Set(color, 1, 0, 0, 0.10);break;
11674 case SOLID_BSP: Vector4Set(color, 0, 0, 1, 0.05);break;
11675 default: Vector4Set(color, 0, 0, 0, 0.50);break;
11677 color[3] *= r_showbboxes.value;
11678 color[3] = bound(0, color[3], 1);
11679 GL_DepthTest(!r_showdisabledepthtest.integer);
11680 GL_CullFace(r_refdef.view.cullface_front);
11681 R_DrawBBoxMesh(edict->priv.server->areamins, edict->priv.server->areamaxs, color[0], color[1], color[2], color[3]);
11687 static void R_DrawEntityBBoxes(void)
11690 prvm_edict_t *edict;
11692 prvm_prog_t *prog_save = prog;
11694 // this function draws bounding boxes of server entities
11700 for (i = 0;i < prog->num_edicts;i++)
11702 edict = PRVM_EDICT_NUM(i);
11703 if (edict->priv.server->free)
11705 // exclude the following for now, as they don't live in world coordinate space and can't be solid:
11706 if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.tag_entity)->edict != 0)
11708 if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.viewmodelforclient)->edict != 0)
11710 VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
11711 R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL);
11717 static const int nomodelelement3i[24] =
11729 static const unsigned short nomodelelement3s[24] =
11741 static const float nomodelvertex3f[6*3] =
11751 static const float nomodelcolor4f[6*4] =
11753 0.0f, 0.0f, 0.5f, 1.0f,
11754 0.0f, 0.0f, 0.5f, 1.0f,
11755 0.0f, 0.5f, 0.0f, 1.0f,
11756 0.0f, 0.5f, 0.0f, 1.0f,
11757 0.5f, 0.0f, 0.0f, 1.0f,
11758 0.5f, 0.0f, 0.0f, 1.0f
11761 void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
11765 float color4f[6*4];
11767 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);
11769 // this is only called once per entity so numsurfaces is always 1, and
11770 // surfacelist is always {0}, so this code does not handle batches
11772 if (rsurface.ent_flags & RENDER_ADDITIVE)
11774 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
11775 GL_DepthMask(false);
11777 else if (rsurface.colormod[3] < 1)
11779 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
11780 GL_DepthMask(false);
11784 GL_BlendFunc(GL_ONE, GL_ZERO);
11785 GL_DepthMask(true);
11787 GL_DepthRange(0, (rsurface.ent_flags & RENDER_VIEWMODEL) ? 0.0625 : 1);
11788 GL_PolygonOffset(rsurface.basepolygonfactor, rsurface.basepolygonoffset);
11789 GL_DepthTest(!(rsurface.ent_flags & RENDER_NODEPTHTEST));
11790 GL_CullFace((rsurface.ent_flags & RENDER_DOUBLESIDED) ? GL_NONE : r_refdef.view.cullface_back);
11791 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
11792 for (i = 0, c = color4f;i < 6;i++, c += 4)
11794 c[0] *= rsurface.colormod[0];
11795 c[1] *= rsurface.colormod[1];
11796 c[2] *= rsurface.colormod[2];
11797 c[3] *= rsurface.colormod[3];
11799 if (r_refdef.fogenabled)
11801 for (i = 0, c = color4f;i < 6;i++, c += 4)
11803 f1 = RSurf_FogVertex(nomodelvertex3f + 3*i);
11805 c[0] = (c[0] * f1 + r_refdef.fogcolor[0] * f2);
11806 c[1] = (c[1] * f1 + r_refdef.fogcolor[1] * f2);
11807 c[2] = (c[2] * f1 + r_refdef.fogcolor[2] * f2);
11810 // R_Mesh_ResetTextureState();
11811 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
11812 R_Mesh_PrepareVertices_Generic_Arrays(6, nomodelvertex3f, color4f, NULL);
11813 R_Mesh_Draw(0, 6, 0, 8, nomodelelement3i, NULL, 0, nomodelelement3s, NULL, 0);
11816 void R_DrawNoModel(entity_render_t *ent)
11819 Matrix4x4_OriginFromMatrix(&ent->matrix, org);
11820 if ((ent->flags & RENDER_ADDITIVE) || (ent->alpha < 1))
11821 R_MeshQueue_AddTransparent(ent->flags & RENDER_NODEPTHTEST ? r_refdef.view.origin : org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight);
11823 R_DrawNoModel_TransparentCallback(ent, rsurface.rtlight, 0, NULL);
11826 void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, float width)
11828 vec3_t right1, right2, diff, normal;
11830 VectorSubtract (org2, org1, normal);
11832 // calculate 'right' vector for start
11833 VectorSubtract (r_refdef.view.origin, org1, diff);
11834 CrossProduct (normal, diff, right1);
11835 VectorNormalize (right1);
11837 // calculate 'right' vector for end
11838 VectorSubtract (r_refdef.view.origin, org2, diff);
11839 CrossProduct (normal, diff, right2);
11840 VectorNormalize (right2);
11842 vert[ 0] = org1[0] + width * right1[0];
11843 vert[ 1] = org1[1] + width * right1[1];
11844 vert[ 2] = org1[2] + width * right1[2];
11845 vert[ 3] = org1[0] - width * right1[0];
11846 vert[ 4] = org1[1] - width * right1[1];
11847 vert[ 5] = org1[2] - width * right1[2];
11848 vert[ 6] = org2[0] - width * right2[0];
11849 vert[ 7] = org2[1] - width * right2[1];
11850 vert[ 8] = org2[2] - width * right2[2];
11851 vert[ 9] = org2[0] + width * right2[0];
11852 vert[10] = org2[1] + width * right2[1];
11853 vert[11] = org2[2] + width * right2[2];
11856 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)
11858 vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
11859 vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
11860 vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
11861 vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
11862 vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
11863 vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
11864 vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
11865 vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
11866 vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
11867 vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
11868 vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
11869 vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
11872 int R_Mesh_AddVertex(rmesh_t *mesh, float x, float y, float z)
11877 VectorSet(v, x, y, z);
11878 for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
11879 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
11881 if (i == mesh->numvertices)
11883 if (mesh->numvertices < mesh->maxvertices)
11885 VectorCopy(v, vertex3f);
11886 mesh->numvertices++;
11888 return mesh->numvertices;
11894 void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
11897 int *e, element[3];
11898 element[0] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);vertex3f += 3;
11899 element[1] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);vertex3f += 3;
11900 e = mesh->element3i + mesh->numtriangles * 3;
11901 for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
11903 element[2] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);
11904 if (mesh->numtriangles < mesh->maxtriangles)
11909 mesh->numtriangles++;
11911 element[1] = element[2];
11915 void R_Mesh_AddPolygon3d(rmesh_t *mesh, int numvertices, double *vertex3d)
11918 int *e, element[3];
11919 element[0] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);vertex3d += 3;
11920 element[1] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);vertex3d += 3;
11921 e = mesh->element3i + mesh->numtriangles * 3;
11922 for (i = 0;i < numvertices - 2;i++, vertex3d += 3)
11924 element[2] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);
11925 if (mesh->numtriangles < mesh->maxtriangles)
11930 mesh->numtriangles++;
11932 element[1] = element[2];
11936 #define R_MESH_PLANE_DIST_EPSILON (1.0 / 32.0)
11937 void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
11939 int planenum, planenum2;
11942 mplane_t *plane, *plane2;
11944 double temppoints[2][256*3];
11945 // figure out how large a bounding box we need to properly compute this brush
11947 for (w = 0;w < numplanes;w++)
11948 maxdist = max(maxdist, fabs(planes[w].dist));
11949 // now make it large enough to enclose the entire brush, and round it off to a reasonable multiple of 1024
11950 maxdist = floor(maxdist * (4.0 / 1024.0) + 1) * 1024.0;
11951 for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
11955 PolygonD_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->dist, maxdist);
11956 for (planenum2 = 0, plane2 = planes;planenum2 < numplanes && tempnumpoints >= 3;planenum2++, plane2++)
11958 if (planenum2 == planenum)
11960 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);
11963 if (tempnumpoints < 3)
11965 // generate elements forming a triangle fan for this polygon
11966 R_Mesh_AddPolygon3d(mesh, tempnumpoints, temppoints[w]);
11970 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)
11972 texturelayer_t *layer;
11973 layer = t->currentlayers + t->currentnumlayers++;
11974 layer->type = type;
11975 layer->depthmask = depthmask;
11976 layer->blendfunc1 = blendfunc1;
11977 layer->blendfunc2 = blendfunc2;
11978 layer->texture = texture;
11979 layer->texmatrix = *matrix;
11980 layer->color[0] = r;
11981 layer->color[1] = g;
11982 layer->color[2] = b;
11983 layer->color[3] = a;
11986 static qboolean R_TestQ3WaveFunc(q3wavefunc_t func, const float *parms)
11988 if(parms[0] == 0 && parms[1] == 0)
11990 if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
11991 if(rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)] == 0)
11996 static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms)
11999 index = parms[2] + r_refdef.scene.time * parms[3];
12000 index -= floor(index);
12001 switch (func & ((1 << Q3WAVEFUNC_USER_SHIFT) - 1))
12004 case Q3WAVEFUNC_NONE:
12005 case Q3WAVEFUNC_NOISE:
12006 case Q3WAVEFUNC_COUNT:
12009 case Q3WAVEFUNC_SIN: f = sin(index * M_PI * 2);break;
12010 case Q3WAVEFUNC_SQUARE: f = index < 0.5 ? 1 : -1;break;
12011 case Q3WAVEFUNC_SAWTOOTH: f = index;break;
12012 case Q3WAVEFUNC_INVERSESAWTOOTH: f = 1 - index;break;
12013 case Q3WAVEFUNC_TRIANGLE:
12015 f = index - floor(index);
12018 else if (index < 2)
12020 else if (index < 3)
12026 f = parms[0] + parms[1] * f;
12027 if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
12028 f *= rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)];
12032 void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags)
12037 matrix4x4_t matrix, temp;
12038 switch(tcmod->tcmod)
12040 case Q3TCMOD_COUNT:
12042 if (currentmaterialflags & MATERIALFLAG_WATERSCROLL)
12043 matrix = r_waterscrollmatrix;
12045 matrix = identitymatrix;
12047 case Q3TCMOD_ENTITYTRANSLATE:
12048 // this is used in Q3 to allow the gamecode to control texcoord
12049 // scrolling on the entity, which is not supported in darkplaces yet.
12050 Matrix4x4_CreateTranslate(&matrix, 0, 0, 0);
12052 case Q3TCMOD_ROTATE:
12053 Matrix4x4_CreateTranslate(&matrix, 0.5, 0.5, 0);
12054 Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * r_refdef.scene.time, 0, 0, 1);
12055 Matrix4x4_ConcatTranslate(&matrix, -0.5, -0.5, 0);
12057 case Q3TCMOD_SCALE:
12058 Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1);
12060 case Q3TCMOD_SCROLL:
12061 Matrix4x4_CreateTranslate(&matrix, tcmod->parms[0] * r_refdef.scene.time, tcmod->parms[1] * r_refdef.scene.time, 0);
12063 case Q3TCMOD_PAGE: // poor man's animmap (to store animations into a single file, useful for HTTP downloaded textures)
12064 w = (int) tcmod->parms[0];
12065 h = (int) tcmod->parms[1];
12066 f = r_refdef.scene.time / (tcmod->parms[2] * w * h);
12068 idx = (int) floor(f * w * h);
12069 Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0);
12071 case Q3TCMOD_STRETCH:
12072 f = 1.0f / R_EvaluateQ3WaveFunc(tcmod->wavefunc, tcmod->waveparms);
12073 Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f);
12075 case Q3TCMOD_TRANSFORM:
12076 VectorSet(tcmat + 0, tcmod->parms[0], tcmod->parms[1], 0);
12077 VectorSet(tcmat + 3, tcmod->parms[2], tcmod->parms[3], 0);
12078 VectorSet(tcmat + 6, 0 , 0 , 1);
12079 VectorSet(tcmat + 9, tcmod->parms[4], tcmod->parms[5], 0);
12080 Matrix4x4_FromArray12FloatGL(&matrix, tcmat);
12082 case Q3TCMOD_TURBULENT:
12083 // this is handled in the RSurf_PrepareVertices function
12084 matrix = identitymatrix;
12088 Matrix4x4_Concat(texmatrix, &matrix, &temp);
12091 void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
12093 int textureflags = (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP | TEXF_COMPRESS;
12094 char name[MAX_QPATH];
12095 skinframe_t *skinframe;
12096 unsigned char pixels[296*194];
12097 strlcpy(cache->name, skinname, sizeof(cache->name));
12098 dpsnprintf(name, sizeof(name), "skins/%s.pcx", cache->name);
12099 if (developer_loading.integer)
12100 Con_Printf("loading %s\n", name);
12101 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
12102 if (!skinframe || !skinframe->base)
12105 fs_offset_t filesize;
12107 f = FS_LoadFile(name, tempmempool, true, &filesize);
12110 if (LoadPCX_QWSkin(f, (int)filesize, pixels, 296, 194))
12111 skinframe = R_SkinFrame_LoadInternalQuake(name, textureflags, true, r_fullbrights.integer, pixels, image_width, image_height);
12115 cache->skinframe = skinframe;
12118 texture_t *R_GetCurrentTexture(texture_t *t)
12121 const entity_render_t *ent = rsurface.entity;
12122 dp_model_t *model = ent->model;
12123 q3shaderinfo_layer_tcmod_t *tcmod;
12125 if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent)
12126 return t->currentframe;
12127 t->update_lastrenderframe = r_textureframe;
12128 t->update_lastrenderentity = (void *)ent;
12130 if(ent && ent->entitynumber >= MAX_EDICTS && ent->entitynumber < 2 * MAX_EDICTS)
12131 t->camera_entity = ent->entitynumber;
12133 t->camera_entity = 0;
12135 // switch to an alternate material if this is a q1bsp animated material
12137 texture_t *texture = t;
12138 int s = rsurface.ent_skinnum;
12139 if ((unsigned int)s >= (unsigned int)model->numskins)
12141 if (model->skinscenes)
12143 if (model->skinscenes[s].framecount > 1)
12144 s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.scene.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
12146 s = model->skinscenes[s].firstframe;
12149 t = t + s * model->num_surfaces;
12152 // use an alternate animation if the entity's frame is not 0,
12153 // and only if the texture has an alternate animation
12154 if (rsurface.ent_alttextures && t->anim_total[1])
12155 t = t->anim_frames[1][(t->anim_total[1] >= 2) ? ((int)(r_refdef.scene.time * 5.0f) % t->anim_total[1]) : 0];
12157 t = t->anim_frames[0][(t->anim_total[0] >= 2) ? ((int)(r_refdef.scene.time * 5.0f) % t->anim_total[0]) : 0];
12159 texture->currentframe = t;
12162 // update currentskinframe to be a qw skin or animation frame
12163 if (rsurface.ent_qwskin >= 0)
12165 i = rsurface.ent_qwskin;
12166 if (!r_qwskincache || r_qwskincache_size != cl.maxclients)
12168 r_qwskincache_size = cl.maxclients;
12170 Mem_Free(r_qwskincache);
12171 r_qwskincache = (r_qwskincache_t *)Mem_Alloc(r_main_mempool, sizeof(*r_qwskincache) * r_qwskincache_size);
12173 if (strcmp(r_qwskincache[i].name, cl.scores[i].qw_skin))
12174 R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin);
12175 t->currentskinframe = r_qwskincache[i].skinframe;
12176 if (t->currentskinframe == NULL)
12177 t->currentskinframe = t->skinframes[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
12179 else if (t->numskinframes >= 2)
12180 t->currentskinframe = t->skinframes[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
12181 if (t->backgroundnumskinframes >= 2)
12182 t->backgroundcurrentskinframe = t->backgroundskinframes[(unsigned int)(t->backgroundskinframerate * (cl.time - rsurface.ent_shadertime)) % t->backgroundnumskinframes];
12184 t->currentmaterialflags = t->basematerialflags;
12185 t->currentalpha = rsurface.colormod[3];
12186 if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer))
12187 t->currentalpha *= r_wateralpha.value;
12188 if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay)
12189 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // we apply wateralpha later
12190 if(!r_waterstate.enabled || r_refdef.view.isoverlay)
12191 t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA);
12192 if (!(rsurface.ent_flags & RENDER_LIGHT))
12193 t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
12194 else if (FAKELIGHT_ENABLED)
12196 // no modellight if using fakelight for the map
12198 else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
12200 // pick a model lighting mode
12201 if (VectorLength2(rsurface.modellight_diffuse) >= (1.0f / 256.0f))
12202 t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL;
12204 t->currentmaterialflags |= MATERIALFLAG_MODELLIGHT;
12206 if (rsurface.ent_flags & RENDER_ADDITIVE)
12207 t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
12208 else if (t->currentalpha < 1)
12209 t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
12210 if (rsurface.ent_flags & RENDER_DOUBLESIDED)
12211 t->currentmaterialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
12212 if (rsurface.ent_flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL))
12213 t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
12214 if (t->backgroundnumskinframes)
12215 t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
12216 if (t->currentmaterialflags & MATERIALFLAG_BLENDED)
12218 if (t->currentmaterialflags & (MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER | MATERIALFLAG_CAMERA))
12219 t->currentmaterialflags &= ~MATERIALFLAG_BLENDED;
12222 t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER | MATERIALFLAG_CAMERA);
12223 if ((t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)) == MATERIALFLAG_BLENDED && r_transparentdepthmasking.integer && !(t->basematerialflags & MATERIALFLAG_BLENDED))
12224 t->currentmaterialflags |= MATERIALFLAG_TRANSDEPTH;
12226 // there is no tcmod
12227 if (t->currentmaterialflags & MATERIALFLAG_WATERSCROLL)
12229 t->currenttexmatrix = r_waterscrollmatrix;
12230 t->currentbackgroundtexmatrix = r_waterscrollmatrix;
12232 else if (!(t->currentmaterialflags & MATERIALFLAG_CUSTOMSURFACE))
12234 Matrix4x4_CreateIdentity(&t->currenttexmatrix);
12235 Matrix4x4_CreateIdentity(&t->currentbackgroundtexmatrix);
12238 for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
12239 R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags);
12240 for (i = 0, tcmod = t->backgroundtcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
12241 R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags);
12243 t->colormapping = VectorLength2(rsurface.colormap_pantscolor) + VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f);
12244 if (t->currentskinframe->qpixels)
12245 R_SkinFrame_GenerateTexturesFromQPixels(t->currentskinframe, t->colormapping);
12246 t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base;
12247 if (!t->basetexture)
12248 t->basetexture = r_texture_notexture;
12249 t->pantstexture = t->colormapping ? t->currentskinframe->pants : NULL;
12250 t->shirttexture = t->colormapping ? t->currentskinframe->shirt : NULL;
12251 t->nmaptexture = t->currentskinframe->nmap;
12252 if (!t->nmaptexture)
12253 t->nmaptexture = r_texture_blanknormalmap;
12254 t->glosstexture = r_texture_black;
12255 t->glowtexture = t->currentskinframe->glow;
12256 t->fogtexture = t->currentskinframe->fog;
12257 t->reflectmasktexture = t->currentskinframe->reflect;
12258 if (t->backgroundnumskinframes)
12260 t->backgroundbasetexture = (!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base;
12261 t->backgroundnmaptexture = t->backgroundcurrentskinframe->nmap;
12262 t->backgroundglosstexture = r_texture_black;
12263 t->backgroundglowtexture = t->backgroundcurrentskinframe->glow;
12264 if (!t->backgroundnmaptexture)
12265 t->backgroundnmaptexture = r_texture_blanknormalmap;
12269 t->backgroundbasetexture = r_texture_white;
12270 t->backgroundnmaptexture = r_texture_blanknormalmap;
12271 t->backgroundglosstexture = r_texture_black;
12272 t->backgroundglowtexture = NULL;
12274 t->specularpower = r_shadow_glossexponent.value;
12275 // TODO: store reference values for these in the texture?
12276 t->specularscale = 0;
12277 if (r_shadow_gloss.integer > 0)
12279 if (t->currentskinframe->gloss || (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss))
12281 if (r_shadow_glossintensity.value > 0)
12283 t->glosstexture = t->currentskinframe->gloss ? t->currentskinframe->gloss : r_texture_white;
12284 t->backgroundglosstexture = (t->backgroundcurrentskinframe && t->backgroundcurrentskinframe->gloss) ? t->backgroundcurrentskinframe->gloss : r_texture_white;
12285 t->specularscale = r_shadow_glossintensity.value;
12288 else if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0)
12290 t->glosstexture = r_texture_white;
12291 t->backgroundglosstexture = r_texture_white;
12292 t->specularscale = r_shadow_gloss2intensity.value;
12293 t->specularpower = r_shadow_gloss2exponent.value;
12296 t->specularscale *= t->specularscalemod;
12297 t->specularpower *= t->specularpowermod;
12299 // lightmaps mode looks bad with dlights using actual texturing, so turn
12300 // off the colormap and glossmap, but leave the normalmap on as it still
12301 // accurately represents the shading involved
12302 if (gl_lightmaps.integer)
12304 t->basetexture = r_texture_grey128;
12305 t->pantstexture = r_texture_black;
12306 t->shirttexture = r_texture_black;
12307 t->nmaptexture = r_texture_blanknormalmap;
12308 t->glosstexture = r_texture_black;
12309 t->glowtexture = NULL;
12310 t->fogtexture = NULL;
12311 t->reflectmasktexture = NULL;
12312 t->backgroundbasetexture = NULL;
12313 t->backgroundnmaptexture = r_texture_blanknormalmap;
12314 t->backgroundglosstexture = r_texture_black;
12315 t->backgroundglowtexture = NULL;
12316 t->specularscale = 0;
12317 t->currentmaterialflags = MATERIALFLAG_WALL | (t->currentmaterialflags & (MATERIALFLAG_NOCULLFACE | MATERIALFLAG_MODELLIGHT | MATERIALFLAG_MODELLIGHT_DIRECTIONAL | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SHORTDEPTHRANGE));
12320 Vector4Set(t->lightmapcolor, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2], t->currentalpha);
12321 VectorClear(t->dlightcolor);
12322 t->currentnumlayers = 0;
12323 if (t->currentmaterialflags & MATERIALFLAG_WALL)
12325 int blendfunc1, blendfunc2;
12326 qboolean depthmask;
12327 if (t->currentmaterialflags & MATERIALFLAG_ADD)
12329 blendfunc1 = GL_SRC_ALPHA;
12330 blendfunc2 = GL_ONE;
12332 else if (t->currentmaterialflags & MATERIALFLAG_ALPHA)
12334 blendfunc1 = GL_SRC_ALPHA;
12335 blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
12337 else if (t->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
12339 blendfunc1 = t->customblendfunc[0];
12340 blendfunc2 = t->customblendfunc[1];
12344 blendfunc1 = GL_ONE;
12345 blendfunc2 = GL_ZERO;
12347 // don't colormod evilblend textures
12348 if(!R_BlendFuncAllowsColormod(blendfunc1, blendfunc2))
12349 VectorSet(t->lightmapcolor, 1, 1, 1);
12350 depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
12351 if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
12353 // fullbright is not affected by r_refdef.lightmapintensity
12354 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]);
12355 if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
12356 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]);
12357 if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
12358 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]);
12362 vec3_t ambientcolor;
12364 // set the color tint used for lights affecting this surface
12365 VectorSet(t->dlightcolor, t->lightmapcolor[0] * t->lightmapcolor[3], t->lightmapcolor[1] * t->lightmapcolor[3], t->lightmapcolor[2] * t->lightmapcolor[3]);
12367 // q3bsp has no lightmap updates, so the lightstylevalue that
12368 // would normally be baked into the lightmap must be
12369 // applied to the color
12370 // FIXME: r_glsl 1 rendering doesn't support overbright lightstyles with this (the default light style is not overbright)
12371 if (model->type == mod_brushq3)
12372 colorscale *= r_refdef.scene.rtlightstylevalue[0];
12373 colorscale *= r_refdef.lightmapintensity;
12374 VectorScale(t->lightmapcolor, r_refdef.scene.ambient, ambientcolor);
12375 VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor);
12376 // basic lit geometry
12377 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]);
12378 // add pants/shirt if needed
12379 if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
12380 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]);
12381 if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
12382 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]);
12383 // now add ambient passes if needed
12384 if (VectorLength2(ambientcolor) >= (1.0f/1048576.0f))
12386 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]);
12387 if (VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f) && t->pantstexture)
12388 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]);
12389 if (VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->shirttexture)
12390 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]);
12393 if (t->glowtexture != NULL && !gl_lightmaps.integer)
12394 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]);
12395 if (r_refdef.fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
12397 // if this is opaque use alpha blend which will darken the earlier
12400 // if this is an alpha blended material, all the earlier passes
12401 // were darkened by fog already, so we only need to add the fog
12402 // color ontop through the fog mask texture
12404 // if this is an additive blended material, all the earlier passes
12405 // were darkened by fog already, and we should not add fog color
12406 // (because the background was not darkened, there is no fog color
12407 // that was lost behind it).
12408 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]);
12412 return t->currentframe;
12415 rsurfacestate_t rsurface;
12417 void RSurf_ActiveWorldEntity(void)
12419 dp_model_t *model = r_refdef.scene.worldmodel;
12420 //if (rsurface.entity == r_refdef.scene.worldentity)
12422 rsurface.entity = r_refdef.scene.worldentity;
12423 rsurface.skeleton = NULL;
12424 memset(rsurface.userwavefunc_param, 0, sizeof(rsurface.userwavefunc_param));
12425 rsurface.ent_skinnum = 0;
12426 rsurface.ent_qwskin = -1;
12427 rsurface.ent_shadertime = 0;
12428 rsurface.ent_flags = r_refdef.scene.worldentity->flags;
12429 rsurface.matrix = identitymatrix;
12430 rsurface.inversematrix = identitymatrix;
12431 rsurface.matrixscale = 1;
12432 rsurface.inversematrixscale = 1;
12433 R_EntityMatrix(&identitymatrix);
12434 VectorCopy(r_refdef.view.origin, rsurface.localvieworigin);
12435 Vector4Copy(r_refdef.fogplane, rsurface.fogplane);
12436 rsurface.fograngerecip = r_refdef.fograngerecip;
12437 rsurface.fogheightfade = r_refdef.fogheightfade;
12438 rsurface.fogplaneviewdist = r_refdef.fogplaneviewdist;
12439 rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
12440 VectorSet(rsurface.modellight_ambient, 0, 0, 0);
12441 VectorSet(rsurface.modellight_diffuse, 0, 0, 0);
12442 VectorSet(rsurface.modellight_lightdir, 0, 0, 1);
12443 VectorSet(rsurface.colormap_pantscolor, 0, 0, 0);
12444 VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0);
12445 VectorSet(rsurface.colormod, r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale);
12446 rsurface.colormod[3] = 1;
12447 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);
12448 memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend));
12449 rsurface.frameblend[0].lerp = 1;
12450 rsurface.ent_alttextures = false;
12451 rsurface.basepolygonfactor = r_refdef.polygonfactor;
12452 rsurface.basepolygonoffset = r_refdef.polygonoffset;
12453 rsurface.modelvertex3f = model->surfmesh.data_vertex3f;
12454 rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12455 rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f;
12456 rsurface.modelsvector3f = model->surfmesh.data_svector3f;
12457 rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12458 rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f;
12459 rsurface.modeltvector3f = model->surfmesh.data_tvector3f;
12460 rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12461 rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f;
12462 rsurface.modelnormal3f = model->surfmesh.data_normal3f;
12463 rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12464 rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f;
12465 rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f;
12466 rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12467 rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f;
12468 rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f;
12469 rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12470 rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f;
12471 rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f;
12472 rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12473 rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
12474 rsurface.modelelement3i = model->surfmesh.data_element3i;
12475 rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer;
12476 rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset;
12477 rsurface.modelelement3s = model->surfmesh.data_element3s;
12478 rsurface.modelelement3s_indexbuffer = model->surfmesh.data_element3s_indexbuffer;
12479 rsurface.modelelement3s_bufferoffset = model->surfmesh.data_element3s_bufferoffset;
12480 rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets;
12481 rsurface.modelnumvertices = model->surfmesh.num_vertices;
12482 rsurface.modelnumtriangles = model->surfmesh.num_triangles;
12483 rsurface.modelsurfaces = model->data_surfaces;
12484 rsurface.modelvertexmesh = model->surfmesh.vertexmesh;
12485 rsurface.modelvertexmeshbuffer = model->surfmesh.vertexmeshbuffer;
12486 rsurface.modelvertex3fbuffer = model->surfmesh.vertex3fbuffer;
12487 rsurface.modelgeneratedvertex = false;
12488 rsurface.batchgeneratedvertex = false;
12489 rsurface.batchfirstvertex = 0;
12490 rsurface.batchnumvertices = 0;
12491 rsurface.batchfirsttriangle = 0;
12492 rsurface.batchnumtriangles = 0;
12493 rsurface.batchvertex3f = NULL;
12494 rsurface.batchvertex3f_vertexbuffer = NULL;
12495 rsurface.batchvertex3f_bufferoffset = 0;
12496 rsurface.batchsvector3f = NULL;
12497 rsurface.batchsvector3f_vertexbuffer = NULL;
12498 rsurface.batchsvector3f_bufferoffset = 0;
12499 rsurface.batchtvector3f = NULL;
12500 rsurface.batchtvector3f_vertexbuffer = NULL;
12501 rsurface.batchtvector3f_bufferoffset = 0;
12502 rsurface.batchnormal3f = NULL;
12503 rsurface.batchnormal3f_vertexbuffer = NULL;
12504 rsurface.batchnormal3f_bufferoffset = 0;
12505 rsurface.batchlightmapcolor4f = NULL;
12506 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
12507 rsurface.batchlightmapcolor4f_bufferoffset = 0;
12508 rsurface.batchtexcoordtexture2f = NULL;
12509 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
12510 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
12511 rsurface.batchtexcoordlightmap2f = NULL;
12512 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
12513 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
12514 rsurface.batchvertexmesh = NULL;
12515 rsurface.batchvertexmeshbuffer = NULL;
12516 rsurface.batchvertex3fbuffer = NULL;
12517 rsurface.batchelement3i = NULL;
12518 rsurface.batchelement3i_indexbuffer = NULL;
12519 rsurface.batchelement3i_bufferoffset = 0;
12520 rsurface.batchelement3s = NULL;
12521 rsurface.batchelement3s_indexbuffer = NULL;
12522 rsurface.batchelement3s_bufferoffset = 0;
12523 rsurface.passcolor4f = NULL;
12524 rsurface.passcolor4f_vertexbuffer = NULL;
12525 rsurface.passcolor4f_bufferoffset = 0;
12528 void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass)
12530 dp_model_t *model = ent->model;
12531 //if (rsurface.entity == ent && (!model->surfmesh.isanimated || (!wantnormals && !wanttangents)))
12533 rsurface.entity = (entity_render_t *)ent;
12534 rsurface.skeleton = ent->skeleton;
12535 memcpy(rsurface.userwavefunc_param, ent->userwavefunc_param, sizeof(rsurface.userwavefunc_param));
12536 rsurface.ent_skinnum = ent->skinnum;
12537 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;
12538 rsurface.ent_shadertime = ent->shadertime;
12539 rsurface.ent_flags = ent->flags;
12540 rsurface.matrix = ent->matrix;
12541 rsurface.inversematrix = ent->inversematrix;
12542 rsurface.matrixscale = Matrix4x4_ScaleFromMatrix(&rsurface.matrix);
12543 rsurface.inversematrixscale = 1.0f / rsurface.matrixscale;
12544 R_EntityMatrix(&rsurface.matrix);
12545 Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.origin, rsurface.localvieworigin);
12546 Matrix4x4_TransformStandardPlane(&rsurface.inversematrix, r_refdef.fogplane[0], r_refdef.fogplane[1], r_refdef.fogplane[2], r_refdef.fogplane[3], rsurface.fogplane);
12547 rsurface.fogplaneviewdist *= rsurface.inversematrixscale;
12548 rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale;
12549 rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale;
12550 rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
12551 VectorCopy(ent->modellight_ambient, rsurface.modellight_ambient);
12552 VectorCopy(ent->modellight_diffuse, rsurface.modellight_diffuse);
12553 VectorCopy(ent->modellight_lightdir, rsurface.modellight_lightdir);
12554 VectorCopy(ent->colormap_pantscolor, rsurface.colormap_pantscolor);
12555 VectorCopy(ent->colormap_shirtcolor, rsurface.colormap_shirtcolor);
12556 VectorScale(ent->colormod, r_refdef.view.colorscale, rsurface.colormod);
12557 rsurface.colormod[3] = ent->alpha;
12558 VectorScale(ent->glowmod, r_refdef.view.colorscale * r_hdr_glowintensity.value, rsurface.glowmod);
12559 memcpy(rsurface.frameblend, ent->frameblend, sizeof(ent->frameblend));
12560 rsurface.ent_alttextures = ent->framegroupblend[0].frame != 0;
12561 rsurface.basepolygonfactor = r_refdef.polygonfactor;
12562 rsurface.basepolygonoffset = r_refdef.polygonoffset;
12563 if (ent->model->brush.submodel && !prepass)
12565 rsurface.basepolygonfactor += r_polygonoffset_submodel_factor.value;
12566 rsurface.basepolygonoffset += r_polygonoffset_submodel_offset.value;
12568 if (model->surfmesh.isanimated && model->AnimateVertices && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].subframe != 0))
12570 if (ent->animcache_vertex3f)
12572 rsurface.modelvertex3f = ent->animcache_vertex3f;
12573 rsurface.modelsvector3f = wanttangents ? ent->animcache_svector3f : NULL;
12574 rsurface.modeltvector3f = wanttangents ? ent->animcache_tvector3f : NULL;
12575 rsurface.modelnormal3f = wantnormals ? ent->animcache_normal3f : NULL;
12576 rsurface.modelvertexmesh = ent->animcache_vertexmesh;
12577 rsurface.modelvertexmeshbuffer = ent->animcache_vertexmeshbuffer;
12578 rsurface.modelvertex3fbuffer = ent->animcache_vertex3fbuffer;
12580 else if (wanttangents)
12582 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12583 rsurface.modelsvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12584 rsurface.modeltvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12585 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12586 model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, rsurface.modelnormal3f, rsurface.modelsvector3f, rsurface.modeltvector3f);
12587 rsurface.modelvertexmesh = NULL;
12588 rsurface.modelvertexmeshbuffer = NULL;
12589 rsurface.modelvertex3fbuffer = NULL;
12591 else if (wantnormals)
12593 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12594 rsurface.modelsvector3f = NULL;
12595 rsurface.modeltvector3f = NULL;
12596 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12597 model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, rsurface.modelnormal3f, NULL, NULL);
12598 rsurface.modelvertexmesh = NULL;
12599 rsurface.modelvertexmeshbuffer = NULL;
12600 rsurface.modelvertex3fbuffer = NULL;
12604 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
12605 rsurface.modelsvector3f = NULL;
12606 rsurface.modeltvector3f = NULL;
12607 rsurface.modelnormal3f = NULL;
12608 model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, NULL, NULL, NULL);
12609 rsurface.modelvertexmesh = NULL;
12610 rsurface.modelvertexmeshbuffer = NULL;
12611 rsurface.modelvertex3fbuffer = NULL;
12613 rsurface.modelvertex3f_vertexbuffer = 0;
12614 rsurface.modelvertex3f_bufferoffset = 0;
12615 rsurface.modelsvector3f_vertexbuffer = 0;
12616 rsurface.modelsvector3f_bufferoffset = 0;
12617 rsurface.modeltvector3f_vertexbuffer = 0;
12618 rsurface.modeltvector3f_bufferoffset = 0;
12619 rsurface.modelnormal3f_vertexbuffer = 0;
12620 rsurface.modelnormal3f_bufferoffset = 0;
12621 rsurface.modelgeneratedvertex = true;
12625 rsurface.modelvertex3f = model->surfmesh.data_vertex3f;
12626 rsurface.modelvertex3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12627 rsurface.modelvertex3f_bufferoffset = model->surfmesh.vbooffset_vertex3f;
12628 rsurface.modelsvector3f = model->surfmesh.data_svector3f;
12629 rsurface.modelsvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12630 rsurface.modelsvector3f_bufferoffset = model->surfmesh.vbooffset_svector3f;
12631 rsurface.modeltvector3f = model->surfmesh.data_tvector3f;
12632 rsurface.modeltvector3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12633 rsurface.modeltvector3f_bufferoffset = model->surfmesh.vbooffset_tvector3f;
12634 rsurface.modelnormal3f = model->surfmesh.data_normal3f;
12635 rsurface.modelnormal3f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12636 rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f;
12637 rsurface.modelvertexmesh = model->surfmesh.vertexmesh;
12638 rsurface.modelvertexmeshbuffer = model->surfmesh.vertexmeshbuffer;
12639 rsurface.modelvertex3fbuffer = model->surfmesh.vertex3fbuffer;
12640 rsurface.modelgeneratedvertex = false;
12642 rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f;
12643 rsurface.modellightmapcolor4f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12644 rsurface.modellightmapcolor4f_bufferoffset = model->surfmesh.vbooffset_lightmapcolor4f;
12645 rsurface.modeltexcoordtexture2f = model->surfmesh.data_texcoordtexture2f;
12646 rsurface.modeltexcoordtexture2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12647 rsurface.modeltexcoordtexture2f_bufferoffset = model->surfmesh.vbooffset_texcoordtexture2f;
12648 rsurface.modeltexcoordlightmap2f = model->surfmesh.data_texcoordlightmap2f;
12649 rsurface.modeltexcoordlightmap2f_vertexbuffer = model->surfmesh.vbo_vertexbuffer;
12650 rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
12651 rsurface.modelelement3i = model->surfmesh.data_element3i;
12652 rsurface.modelelement3i_indexbuffer = model->surfmesh.data_element3i_indexbuffer;
12653 rsurface.modelelement3i_bufferoffset = model->surfmesh.data_element3i_bufferoffset;
12654 rsurface.modelelement3s = model->surfmesh.data_element3s;
12655 rsurface.modelelement3s_indexbuffer = model->surfmesh.data_element3s_indexbuffer;
12656 rsurface.modelelement3s_bufferoffset = model->surfmesh.data_element3s_bufferoffset;
12657 rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets;
12658 rsurface.modelnumvertices = model->surfmesh.num_vertices;
12659 rsurface.modelnumtriangles = model->surfmesh.num_triangles;
12660 rsurface.modelsurfaces = model->data_surfaces;
12661 rsurface.batchgeneratedvertex = false;
12662 rsurface.batchfirstvertex = 0;
12663 rsurface.batchnumvertices = 0;
12664 rsurface.batchfirsttriangle = 0;
12665 rsurface.batchnumtriangles = 0;
12666 rsurface.batchvertex3f = NULL;
12667 rsurface.batchvertex3f_vertexbuffer = NULL;
12668 rsurface.batchvertex3f_bufferoffset = 0;
12669 rsurface.batchsvector3f = NULL;
12670 rsurface.batchsvector3f_vertexbuffer = NULL;
12671 rsurface.batchsvector3f_bufferoffset = 0;
12672 rsurface.batchtvector3f = NULL;
12673 rsurface.batchtvector3f_vertexbuffer = NULL;
12674 rsurface.batchtvector3f_bufferoffset = 0;
12675 rsurface.batchnormal3f = NULL;
12676 rsurface.batchnormal3f_vertexbuffer = NULL;
12677 rsurface.batchnormal3f_bufferoffset = 0;
12678 rsurface.batchlightmapcolor4f = NULL;
12679 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
12680 rsurface.batchlightmapcolor4f_bufferoffset = 0;
12681 rsurface.batchtexcoordtexture2f = NULL;
12682 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
12683 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
12684 rsurface.batchtexcoordlightmap2f = NULL;
12685 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
12686 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
12687 rsurface.batchvertexmesh = NULL;
12688 rsurface.batchvertexmeshbuffer = NULL;
12689 rsurface.batchvertex3fbuffer = NULL;
12690 rsurface.batchelement3i = NULL;
12691 rsurface.batchelement3i_indexbuffer = NULL;
12692 rsurface.batchelement3i_bufferoffset = 0;
12693 rsurface.batchelement3s = NULL;
12694 rsurface.batchelement3s_indexbuffer = NULL;
12695 rsurface.batchelement3s_bufferoffset = 0;
12696 rsurface.passcolor4f = NULL;
12697 rsurface.passcolor4f_vertexbuffer = NULL;
12698 rsurface.passcolor4f_bufferoffset = 0;
12701 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)
12703 rsurface.entity = r_refdef.scene.worldentity;
12704 rsurface.skeleton = NULL;
12705 rsurface.ent_skinnum = 0;
12706 rsurface.ent_qwskin = -1;
12707 rsurface.ent_shadertime = shadertime;
12708 rsurface.ent_flags = entflags;
12709 rsurface.modelnumvertices = numvertices;
12710 rsurface.modelnumtriangles = numtriangles;
12711 rsurface.matrix = *matrix;
12712 rsurface.inversematrix = *inversematrix;
12713 rsurface.matrixscale = Matrix4x4_ScaleFromMatrix(&rsurface.matrix);
12714 rsurface.inversematrixscale = 1.0f / rsurface.matrixscale;
12715 R_EntityMatrix(&rsurface.matrix);
12716 Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.origin, rsurface.localvieworigin);
12717 Matrix4x4_TransformStandardPlane(&rsurface.inversematrix, r_refdef.fogplane[0], r_refdef.fogplane[1], r_refdef.fogplane[2], r_refdef.fogplane[3], rsurface.fogplane);
12718 rsurface.fogplaneviewdist *= rsurface.inversematrixscale;
12719 rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale;
12720 rsurface.fogheightfade = r_refdef.fogheightfade * rsurface.matrixscale;
12721 rsurface.fogmasktabledistmultiplier = FOGMASKTABLEWIDTH * rsurface.fograngerecip;
12722 VectorSet(rsurface.modellight_ambient, 0, 0, 0);
12723 VectorSet(rsurface.modellight_diffuse, 0, 0, 0);
12724 VectorSet(rsurface.modellight_lightdir, 0, 0, 1);
12725 VectorSet(rsurface.colormap_pantscolor, 0, 0, 0);
12726 VectorSet(rsurface.colormap_shirtcolor, 0, 0, 0);
12727 Vector4Set(rsurface.colormod, r * r_refdef.view.colorscale, g * r_refdef.view.colorscale, b * r_refdef.view.colorscale, a);
12728 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);
12729 memset(rsurface.frameblend, 0, sizeof(rsurface.frameblend));
12730 rsurface.frameblend[0].lerp = 1;
12731 rsurface.ent_alttextures = false;
12732 rsurface.basepolygonfactor = r_refdef.polygonfactor;
12733 rsurface.basepolygonoffset = r_refdef.polygonoffset;
12736 rsurface.modelvertex3f = (float *)vertex3f;
12737 rsurface.modelsvector3f = svector3f ? (float *)svector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12738 rsurface.modeltvector3f = tvector3f ? (float *)tvector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12739 rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12741 else if (wantnormals)
12743 rsurface.modelvertex3f = (float *)vertex3f;
12744 rsurface.modelsvector3f = NULL;
12745 rsurface.modeltvector3f = NULL;
12746 rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12750 rsurface.modelvertex3f = (float *)vertex3f;
12751 rsurface.modelsvector3f = NULL;
12752 rsurface.modeltvector3f = NULL;
12753 rsurface.modelnormal3f = NULL;
12755 rsurface.modelvertexmesh = NULL;
12756 rsurface.modelvertexmeshbuffer = NULL;
12757 rsurface.modelvertex3fbuffer = NULL;
12758 rsurface.modelvertex3f_vertexbuffer = 0;
12759 rsurface.modelvertex3f_bufferoffset = 0;
12760 rsurface.modelsvector3f_vertexbuffer = 0;
12761 rsurface.modelsvector3f_bufferoffset = 0;
12762 rsurface.modeltvector3f_vertexbuffer = 0;
12763 rsurface.modeltvector3f_bufferoffset = 0;
12764 rsurface.modelnormal3f_vertexbuffer = 0;
12765 rsurface.modelnormal3f_bufferoffset = 0;
12766 rsurface.modelgeneratedvertex = true;
12767 rsurface.modellightmapcolor4f = (float *)color4f;
12768 rsurface.modellightmapcolor4f_vertexbuffer = 0;
12769 rsurface.modellightmapcolor4f_bufferoffset = 0;
12770 rsurface.modeltexcoordtexture2f = (float *)texcoord2f;
12771 rsurface.modeltexcoordtexture2f_vertexbuffer = 0;
12772 rsurface.modeltexcoordtexture2f_bufferoffset = 0;
12773 rsurface.modeltexcoordlightmap2f = NULL;
12774 rsurface.modeltexcoordlightmap2f_vertexbuffer = 0;
12775 rsurface.modeltexcoordlightmap2f_bufferoffset = 0;
12776 rsurface.modelelement3i = (int *)element3i;
12777 rsurface.modelelement3i_indexbuffer = NULL;
12778 rsurface.modelelement3i_bufferoffset = 0;
12779 rsurface.modelelement3s = (unsigned short *)element3s;
12780 rsurface.modelelement3s_indexbuffer = NULL;
12781 rsurface.modelelement3s_bufferoffset = 0;
12782 rsurface.modellightmapoffsets = NULL;
12783 rsurface.modelsurfaces = NULL;
12784 rsurface.batchgeneratedvertex = false;
12785 rsurface.batchfirstvertex = 0;
12786 rsurface.batchnumvertices = 0;
12787 rsurface.batchfirsttriangle = 0;
12788 rsurface.batchnumtriangles = 0;
12789 rsurface.batchvertex3f = NULL;
12790 rsurface.batchvertex3f_vertexbuffer = NULL;
12791 rsurface.batchvertex3f_bufferoffset = 0;
12792 rsurface.batchsvector3f = NULL;
12793 rsurface.batchsvector3f_vertexbuffer = NULL;
12794 rsurface.batchsvector3f_bufferoffset = 0;
12795 rsurface.batchtvector3f = NULL;
12796 rsurface.batchtvector3f_vertexbuffer = NULL;
12797 rsurface.batchtvector3f_bufferoffset = 0;
12798 rsurface.batchnormal3f = NULL;
12799 rsurface.batchnormal3f_vertexbuffer = NULL;
12800 rsurface.batchnormal3f_bufferoffset = 0;
12801 rsurface.batchlightmapcolor4f = NULL;
12802 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
12803 rsurface.batchlightmapcolor4f_bufferoffset = 0;
12804 rsurface.batchtexcoordtexture2f = NULL;
12805 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
12806 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
12807 rsurface.batchtexcoordlightmap2f = NULL;
12808 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
12809 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
12810 rsurface.batchvertexmesh = NULL;
12811 rsurface.batchvertexmeshbuffer = NULL;
12812 rsurface.batchvertex3fbuffer = NULL;
12813 rsurface.batchelement3i = NULL;
12814 rsurface.batchelement3i_indexbuffer = NULL;
12815 rsurface.batchelement3i_bufferoffset = 0;
12816 rsurface.batchelement3s = NULL;
12817 rsurface.batchelement3s_indexbuffer = NULL;
12818 rsurface.batchelement3s_bufferoffset = 0;
12819 rsurface.passcolor4f = NULL;
12820 rsurface.passcolor4f_vertexbuffer = NULL;
12821 rsurface.passcolor4f_bufferoffset = 0;
12823 if (rsurface.modelnumvertices && rsurface.modelelement3i)
12825 if ((wantnormals || wanttangents) && !normal3f)
12827 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12828 Mod_BuildNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modelelement3i, rsurface.modelnormal3f, r_smoothnormals_areaweighting.integer != 0);
12830 if (wanttangents && !svector3f)
12832 rsurface.modelsvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12833 rsurface.modeltvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
12834 Mod_BuildTextureVectorsFromNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modeltexcoordtexture2f, rsurface.modelnormal3f, rsurface.modelelement3i, rsurface.modelsvector3f, rsurface.modeltvector3f, r_smoothnormals_areaweighting.integer != 0);
12839 float RSurf_FogPoint(const float *v)
12841 // this code is identical to the USEFOGINSIDE/USEFOGOUTSIDE code in the shader
12842 float FogPlaneViewDist = r_refdef.fogplaneviewdist;
12843 float FogPlaneVertexDist = DotProduct(r_refdef.fogplane, v) + r_refdef.fogplane[3];
12844 float FogHeightFade = r_refdef.fogheightfade;
12846 unsigned int fogmasktableindex;
12847 if (r_refdef.fogplaneviewabove)
12848 fogfrac = min(0.0f, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0f, min(0.0f, FogPlaneVertexDist) * FogHeightFade);
12850 fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0f, FogPlaneVertexDist)) * min(1.0f, (min(0.0f, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);
12851 fogmasktableindex = (unsigned int)(VectorDistance(r_refdef.view.origin, v) * fogfrac * r_refdef.fogmasktabledistmultiplier);
12852 return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
12855 float RSurf_FogVertex(const float *v)
12857 // this code is identical to the USEFOGINSIDE/USEFOGOUTSIDE code in the shader
12858 float FogPlaneViewDist = rsurface.fogplaneviewdist;
12859 float FogPlaneVertexDist = DotProduct(rsurface.fogplane, v) + rsurface.fogplane[3];
12860 float FogHeightFade = rsurface.fogheightfade;
12862 unsigned int fogmasktableindex;
12863 if (r_refdef.fogplaneviewabove)
12864 fogfrac = min(0.0f, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0f, min(0.0f, FogPlaneVertexDist) * FogHeightFade);
12866 fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0f, FogPlaneVertexDist)) * min(1.0f, (min(0.0f, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);
12867 fogmasktableindex = (unsigned int)(VectorDistance(rsurface.localvieworigin, v) * fogfrac * rsurface.fogmasktabledistmultiplier);
12868 return r_refdef.fogmasktable[min(fogmasktableindex, FOGMASKTABLEWIDTH - 1)];
12871 void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, int numelements, int adjust)
12874 for (i = 0;i < numelements;i++)
12875 outelement3i[i] = inelement3i[i] + adjust;
12878 static const int quadedges[6][2] = {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
12879 extern cvar_t gl_vbo;
12880 void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const msurface_t **texturesurfacelist)
12888 int surfacefirsttriangle;
12889 int surfacenumtriangles;
12890 int surfacefirstvertex;
12891 int surfaceendvertex;
12892 int surfacenumvertices;
12893 int batchnumvertices;
12894 int batchnumtriangles;
12898 qboolean dynamicvertex;
12902 float center[3], forward[3], right[3], up[3], v[3], newforward[3], newright[3], newup[3];
12903 float waveparms[4];
12904 q3shaderinfo_deform_t *deform;
12905 const msurface_t *surface, *firstsurface;
12906 r_vertexmesh_t *vertexmesh;
12907 if (!texturenumsurfaces)
12909 // find vertex range of this surface batch
12911 firstsurface = texturesurfacelist[0];
12912 firsttriangle = firstsurface->num_firsttriangle;
12913 batchnumvertices = 0;
12914 batchnumtriangles = 0;
12915 firstvertex = endvertex = firstsurface->num_firstvertex;
12916 for (i = 0;i < texturenumsurfaces;i++)
12918 surface = texturesurfacelist[i];
12919 if (surface != firstsurface + i)
12921 surfacefirstvertex = surface->num_firstvertex;
12922 surfaceendvertex = surfacefirstvertex + surface->num_vertices;
12923 surfacenumvertices = surface->num_vertices;
12924 surfacenumtriangles = surface->num_triangles;
12925 if (firstvertex > surfacefirstvertex)
12926 firstvertex = surfacefirstvertex;
12927 if (endvertex < surfaceendvertex)
12928 endvertex = surfaceendvertex;
12929 batchnumvertices += surfacenumvertices;
12930 batchnumtriangles += surfacenumtriangles;
12933 // we now know the vertex range used, and if there are any gaps in it
12934 rsurface.batchfirstvertex = firstvertex;
12935 rsurface.batchnumvertices = endvertex - firstvertex;
12936 rsurface.batchfirsttriangle = firsttriangle;
12937 rsurface.batchnumtriangles = batchnumtriangles;
12939 // this variable holds flags for which properties have been updated that
12940 // may require regenerating vertexmesh array...
12943 // check if any dynamic vertex processing must occur
12944 dynamicvertex = false;
12946 // if there is a chance of animated vertex colors, it's a dynamic batch
12947 if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_ARRAY_VERTEXCOLOR)) && texturesurfacelist[0]->lightmapinfo)
12949 dynamicvertex = true;
12950 batchneed |= BATCHNEED_NOGAPS;
12951 needsupdate |= BATCHNEED_VERTEXMESH_VERTEXCOLOR;
12954 for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
12956 switch (deform->deform)
12959 case Q3DEFORM_PROJECTIONSHADOW:
12960 case Q3DEFORM_TEXT0:
12961 case Q3DEFORM_TEXT1:
12962 case Q3DEFORM_TEXT2:
12963 case Q3DEFORM_TEXT3:
12964 case Q3DEFORM_TEXT4:
12965 case Q3DEFORM_TEXT5:
12966 case Q3DEFORM_TEXT6:
12967 case Q3DEFORM_TEXT7:
12968 case Q3DEFORM_NONE:
12970 case Q3DEFORM_AUTOSPRITE:
12971 dynamicvertex = true;
12972 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12973 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12975 case Q3DEFORM_AUTOSPRITE2:
12976 dynamicvertex = true;
12977 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12978 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12980 case Q3DEFORM_NORMAL:
12981 dynamicvertex = true;
12982 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12983 needsupdate |= BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12985 case Q3DEFORM_WAVE:
12986 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
12987 break; // if wavefunc is a nop, ignore this transform
12988 dynamicvertex = true;
12989 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12990 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12992 case Q3DEFORM_BULGE:
12993 dynamicvertex = true;
12994 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
12995 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
12997 case Q3DEFORM_MOVE:
12998 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
12999 break; // if wavefunc is a nop, ignore this transform
13000 dynamicvertex = true;
13001 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
13002 needsupdate |= BATCHNEED_VERTEXMESH_VERTEX;
13006 switch(rsurface.texture->tcgen.tcgen)
13009 case Q3TCGEN_TEXTURE:
13011 case Q3TCGEN_LIGHTMAP:
13012 dynamicvertex = true;
13013 batchneed |= BATCHNEED_ARRAY_LIGHTMAP | BATCHNEED_NOGAPS;
13014 needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
13016 case Q3TCGEN_VECTOR:
13017 dynamicvertex = true;
13018 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
13019 needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
13021 case Q3TCGEN_ENVIRONMENT:
13022 dynamicvertex = true;
13023 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS;
13024 needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
13027 if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
13029 dynamicvertex = true;
13030 batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
13031 needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
13034 if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
13036 dynamicvertex = true;
13037 batchneed |= BATCHNEED_NOGAPS;
13038 needsupdate |= (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP));
13041 if (dynamicvertex || gaps || rsurface.batchfirstvertex)
13043 // when copying, we need to consider the regeneration of vertexmesh, any dependencies it may have must be set...
13044 if (batchneed & BATCHNEED_VERTEXMESH_VERTEX) batchneed |= BATCHNEED_ARRAY_VERTEX;
13045 if (batchneed & BATCHNEED_VERTEXMESH_NORMAL) batchneed |= BATCHNEED_ARRAY_NORMAL;
13046 if (batchneed & BATCHNEED_VERTEXMESH_VECTOR) batchneed |= BATCHNEED_ARRAY_VECTOR;
13047 if (batchneed & BATCHNEED_VERTEXMESH_VERTEXCOLOR) batchneed |= BATCHNEED_ARRAY_VERTEXCOLOR;
13048 if (batchneed & BATCHNEED_VERTEXMESH_TEXCOORD) batchneed |= BATCHNEED_ARRAY_TEXCOORD;
13049 if (batchneed & BATCHNEED_VERTEXMESH_LIGHTMAP) batchneed |= BATCHNEED_ARRAY_LIGHTMAP;
13052 // when the model data has no vertex buffer (dynamic mesh), we need to
13054 if (vid.useinterleavedarrays ? !rsurface.modelvertexmeshbuffer : !rsurface.modelvertex3f_vertexbuffer)
13055 batchneed |= BATCHNEED_NOGAPS;
13057 // if needsupdate, we have to do a dynamic vertex batch for sure
13058 if (needsupdate & batchneed)
13059 dynamicvertex = true;
13061 // see if we need to build vertexmesh from arrays
13062 if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
13063 dynamicvertex = true;
13065 // if gaps are unacceptable, and there are gaps, it's a dynamic batch...
13066 // also some drivers strongly dislike firstvertex
13067 if ((batchneed & BATCHNEED_NOGAPS) && (gaps || firstvertex))
13068 dynamicvertex = true;
13070 rsurface.batchvertex3f = rsurface.modelvertex3f;
13071 rsurface.batchvertex3f_vertexbuffer = rsurface.modelvertex3f_vertexbuffer;
13072 rsurface.batchvertex3f_bufferoffset = rsurface.modelvertex3f_bufferoffset;
13073 rsurface.batchsvector3f = rsurface.modelsvector3f;
13074 rsurface.batchsvector3f_vertexbuffer = rsurface.modelsvector3f_vertexbuffer;
13075 rsurface.batchsvector3f_bufferoffset = rsurface.modelsvector3f_bufferoffset;
13076 rsurface.batchtvector3f = rsurface.modeltvector3f;
13077 rsurface.batchtvector3f_vertexbuffer = rsurface.modeltvector3f_vertexbuffer;
13078 rsurface.batchtvector3f_bufferoffset = rsurface.modeltvector3f_bufferoffset;
13079 rsurface.batchnormal3f = rsurface.modelnormal3f;
13080 rsurface.batchnormal3f_vertexbuffer = rsurface.modelnormal3f_vertexbuffer;
13081 rsurface.batchnormal3f_bufferoffset = rsurface.modelnormal3f_bufferoffset;
13082 rsurface.batchlightmapcolor4f = rsurface.modellightmapcolor4f;
13083 rsurface.batchlightmapcolor4f_vertexbuffer = rsurface.modellightmapcolor4f_vertexbuffer;
13084 rsurface.batchlightmapcolor4f_bufferoffset = rsurface.modellightmapcolor4f_bufferoffset;
13085 rsurface.batchtexcoordtexture2f = rsurface.modeltexcoordtexture2f;
13086 rsurface.batchtexcoordtexture2f_vertexbuffer = rsurface.modeltexcoordtexture2f_vertexbuffer;
13087 rsurface.batchtexcoordtexture2f_bufferoffset = rsurface.modeltexcoordtexture2f_bufferoffset;
13088 rsurface.batchtexcoordlightmap2f = rsurface.modeltexcoordlightmap2f;
13089 rsurface.batchtexcoordlightmap2f_vertexbuffer = rsurface.modeltexcoordlightmap2f_vertexbuffer;
13090 rsurface.batchtexcoordlightmap2f_bufferoffset = rsurface.modeltexcoordlightmap2f_bufferoffset;
13091 rsurface.batchvertex3fbuffer = rsurface.modelvertex3fbuffer;
13092 rsurface.batchvertexmesh = rsurface.modelvertexmesh;
13093 rsurface.batchvertexmeshbuffer = rsurface.modelvertexmeshbuffer;
13094 rsurface.batchelement3i = rsurface.modelelement3i;
13095 rsurface.batchelement3i_indexbuffer = rsurface.modelelement3i_indexbuffer;
13096 rsurface.batchelement3i_bufferoffset = rsurface.modelelement3i_bufferoffset;
13097 rsurface.batchelement3s = rsurface.modelelement3s;
13098 rsurface.batchelement3s_indexbuffer = rsurface.modelelement3s_indexbuffer;
13099 rsurface.batchelement3s_bufferoffset = rsurface.modelelement3s_bufferoffset;
13101 // if any dynamic vertex processing has to occur in software, we copy the
13102 // entire surface list together before processing to rebase the vertices
13103 // to start at 0 (otherwise we waste a lot of room in a vertex buffer).
13105 // if any gaps exist and we do not have a static vertex buffer, we have to
13106 // copy the surface list together to avoid wasting upload bandwidth on the
13107 // vertices in the gaps.
13109 // if gaps exist and we have a static vertex buffer, we still have to
13110 // combine the index buffer ranges into one dynamic index buffer.
13112 // in all cases we end up with data that can be drawn in one call.
13114 if (!dynamicvertex)
13116 // static vertex data, just set pointers...
13117 rsurface.batchgeneratedvertex = false;
13118 // if there are gaps, we want to build a combined index buffer,
13119 // otherwise use the original static buffer with an appropriate offset
13122 // build a new triangle elements array for this batch
13123 rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
13124 rsurface.batchfirsttriangle = 0;
13126 for (i = 0;i < texturenumsurfaces;i++)
13128 surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
13129 surfacenumtriangles = texturesurfacelist[i]->num_triangles;
13130 memcpy(rsurface.batchelement3i + 3*numtriangles, rsurface.modelelement3i + 3*surfacefirsttriangle, surfacenumtriangles*sizeof(int[3]));
13131 numtriangles += surfacenumtriangles;
13133 rsurface.batchelement3i_indexbuffer = NULL;
13134 rsurface.batchelement3i_bufferoffset = 0;
13135 rsurface.batchelement3s = NULL;
13136 rsurface.batchelement3s_indexbuffer = NULL;
13137 rsurface.batchelement3s_bufferoffset = 0;
13138 if (endvertex <= 65536)
13140 // make a 16bit (unsigned short) index array if possible
13141 rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
13142 for (i = 0;i < numtriangles*3;i++)
13143 rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
13149 // something needs software processing, do it for real...
13150 // we only directly handle separate array data in this case and then
13151 // generate interleaved data if needed...
13152 rsurface.batchgeneratedvertex = true;
13154 // now copy the vertex data into a combined array and make an index array
13155 // (this is what Quake3 does all the time)
13156 //if (gaps || rsurface.batchfirstvertex)
13158 rsurface.batchvertex3fbuffer = NULL;
13159 rsurface.batchvertexmesh = NULL;
13160 rsurface.batchvertexmeshbuffer = NULL;
13161 rsurface.batchvertex3f = NULL;
13162 rsurface.batchvertex3f_vertexbuffer = NULL;
13163 rsurface.batchvertex3f_bufferoffset = 0;
13164 rsurface.batchsvector3f = NULL;
13165 rsurface.batchsvector3f_vertexbuffer = NULL;
13166 rsurface.batchsvector3f_bufferoffset = 0;
13167 rsurface.batchtvector3f = NULL;
13168 rsurface.batchtvector3f_vertexbuffer = NULL;
13169 rsurface.batchtvector3f_bufferoffset = 0;
13170 rsurface.batchnormal3f = NULL;
13171 rsurface.batchnormal3f_vertexbuffer = NULL;
13172 rsurface.batchnormal3f_bufferoffset = 0;
13173 rsurface.batchlightmapcolor4f = NULL;
13174 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
13175 rsurface.batchlightmapcolor4f_bufferoffset = 0;
13176 rsurface.batchtexcoordtexture2f = NULL;
13177 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13178 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13179 rsurface.batchtexcoordlightmap2f = NULL;
13180 rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
13181 rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
13182 rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
13183 rsurface.batchelement3i_indexbuffer = NULL;
13184 rsurface.batchelement3i_bufferoffset = 0;
13185 rsurface.batchelement3s = NULL;
13186 rsurface.batchelement3s_indexbuffer = NULL;
13187 rsurface.batchelement3s_bufferoffset = 0;
13188 // we'll only be setting up certain arrays as needed
13189 if (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP))
13190 rsurface.batchvertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(batchnumvertices * sizeof(r_vertexmesh_t));
13191 if (batchneed & BATCHNEED_ARRAY_VERTEX)
13192 rsurface.batchvertex3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13193 if (batchneed & BATCHNEED_ARRAY_NORMAL)
13194 rsurface.batchnormal3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13195 if (batchneed & BATCHNEED_ARRAY_VECTOR)
13197 rsurface.batchsvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13198 rsurface.batchtvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13200 if (batchneed & BATCHNEED_ARRAY_VERTEXCOLOR)
13201 rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
13202 if (batchneed & BATCHNEED_ARRAY_TEXCOORD)
13203 rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13204 if (batchneed & BATCHNEED_ARRAY_LIGHTMAP)
13205 rsurface.batchtexcoordlightmap2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13208 for (i = 0;i < texturenumsurfaces;i++)
13210 surfacefirstvertex = texturesurfacelist[i]->num_firstvertex;
13211 surfacenumvertices = texturesurfacelist[i]->num_vertices;
13212 surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
13213 surfacenumtriangles = texturesurfacelist[i]->num_triangles;
13214 // copy only the data requested
13215 if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)) && rsurface.modelvertexmesh)
13216 memcpy(rsurface.batchvertexmesh + numvertices, rsurface.modelvertexmesh + surfacefirstvertex, surfacenumvertices * sizeof(rsurface.batchvertexmesh[0]));
13217 if (batchneed & (BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_ARRAY_LIGHTMAP))
13219 if (batchneed & BATCHNEED_ARRAY_VERTEX)
13220 memcpy(rsurface.batchvertex3f + 3*numvertices, rsurface.modelvertex3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13221 if ((batchneed & BATCHNEED_ARRAY_NORMAL) && rsurface.modelnormal3f)
13222 memcpy(rsurface.batchnormal3f + 3*numvertices, rsurface.modelnormal3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13223 if ((batchneed & BATCHNEED_ARRAY_VECTOR) && rsurface.modelsvector3f)
13225 memcpy(rsurface.batchsvector3f + 3*numvertices, rsurface.modelsvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13226 memcpy(rsurface.batchtvector3f + 3*numvertices, rsurface.modeltvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
13228 if ((batchneed & BATCHNEED_ARRAY_VERTEXCOLOR) && rsurface.modellightmapcolor4f)
13229 memcpy(rsurface.batchlightmapcolor4f + 4*numvertices, rsurface.modellightmapcolor4f + 4*surfacefirstvertex, surfacenumvertices * sizeof(float[4]));
13230 if ((batchneed & BATCHNEED_ARRAY_TEXCOORD) && rsurface.modeltexcoordtexture2f)
13231 memcpy(rsurface.batchtexcoordtexture2f + 2*numvertices, rsurface.modeltexcoordtexture2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
13232 if ((batchneed & BATCHNEED_ARRAY_LIGHTMAP) && rsurface.modeltexcoordlightmap2f)
13233 memcpy(rsurface.batchtexcoordlightmap2f + 2*numvertices, rsurface.modeltexcoordlightmap2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
13235 RSurf_RenumberElements(rsurface.modelelement3i + 3*surfacefirsttriangle, rsurface.batchelement3i + 3*numtriangles, 3*surfacenumtriangles, numvertices - surfacefirstvertex);
13236 numvertices += surfacenumvertices;
13237 numtriangles += surfacenumtriangles;
13240 // generate a 16bit index array as well if possible
13241 // (in general, dynamic batches fit)
13242 if (numvertices <= 65536)
13244 rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
13245 for (i = 0;i < numtriangles*3;i++)
13246 rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
13249 // since we've copied everything, the batch now starts at 0
13250 rsurface.batchfirstvertex = 0;
13251 rsurface.batchnumvertices = batchnumvertices;
13252 rsurface.batchfirsttriangle = 0;
13253 rsurface.batchnumtriangles = batchnumtriangles;
13256 // q1bsp surfaces rendered in vertex color mode have to have colors
13257 // calculated based on lightstyles
13258 if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_ARRAY_VERTEXCOLOR)) && texturesurfacelist[0]->lightmapinfo)
13260 // generate color arrays for the surfaces in this list
13264 const int *offsets;
13265 const unsigned char *lm;
13266 rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
13267 rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
13268 rsurface.batchlightmapcolor4f_bufferoffset = 0;
13270 for (i = 0;i < texturenumsurfaces;i++)
13272 surface = texturesurfacelist[i];
13273 offsets = rsurface.modellightmapoffsets + surface->num_firstvertex;
13274 surfacenumvertices = surface->num_vertices;
13275 if (surface->lightmapinfo->samples)
13277 for (j = 0;j < surfacenumvertices;j++)
13279 lm = surface->lightmapinfo->samples + offsets[j];
13280 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[0]];
13281 VectorScale(lm, scale, c);
13282 if (surface->lightmapinfo->styles[1] != 255)
13284 size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
13286 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[1]];
13287 VectorMA(c, scale, lm, c);
13288 if (surface->lightmapinfo->styles[2] != 255)
13291 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[2]];
13292 VectorMA(c, scale, lm, c);
13293 if (surface->lightmapinfo->styles[3] != 255)
13296 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[3]];
13297 VectorMA(c, scale, lm, c);
13304 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);
13310 for (j = 0;j < surfacenumvertices;j++)
13312 Vector4Set(rsurface.batchlightmapcolor4f + 4*numvertices, 0, 0, 0, 1);
13319 // if vertices are deformed (sprite flares and things in maps, possibly
13320 // water waves, bulges and other deformations), modify the copied vertices
13322 for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
13324 switch (deform->deform)
13327 case Q3DEFORM_PROJECTIONSHADOW:
13328 case Q3DEFORM_TEXT0:
13329 case Q3DEFORM_TEXT1:
13330 case Q3DEFORM_TEXT2:
13331 case Q3DEFORM_TEXT3:
13332 case Q3DEFORM_TEXT4:
13333 case Q3DEFORM_TEXT5:
13334 case Q3DEFORM_TEXT6:
13335 case Q3DEFORM_TEXT7:
13336 case Q3DEFORM_NONE:
13338 case Q3DEFORM_AUTOSPRITE:
13339 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, newforward);
13340 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.right, newright);
13341 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.up, newup);
13342 VectorNormalize(newforward);
13343 VectorNormalize(newright);
13344 VectorNormalize(newup);
13345 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13346 // rsurface.batchvertex3f_vertexbuffer = NULL;
13347 // rsurface.batchvertex3f_bufferoffset = 0;
13348 // rsurface.batchsvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f);
13349 // rsurface.batchsvector3f_vertexbuffer = NULL;
13350 // rsurface.batchsvector3f_bufferoffset = 0;
13351 // rsurface.batchtvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f);
13352 // rsurface.batchtvector3f_vertexbuffer = NULL;
13353 // rsurface.batchtvector3f_bufferoffset = 0;
13354 // rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13355 // rsurface.batchnormal3f_vertexbuffer = NULL;
13356 // rsurface.batchnormal3f_bufferoffset = 0;
13357 // a single autosprite surface can contain multiple sprites...
13358 for (j = 0;j < batchnumvertices - 3;j += 4)
13360 VectorClear(center);
13361 for (i = 0;i < 4;i++)
13362 VectorAdd(center, rsurface.batchvertex3f + 3*(j+i), center);
13363 VectorScale(center, 0.25f, center);
13364 VectorCopy(rsurface.batchnormal3f + 3*j, forward);
13365 VectorCopy(rsurface.batchsvector3f + 3*j, right);
13366 VectorCopy(rsurface.batchtvector3f + 3*j, up);
13367 for (i = 0;i < 4;i++)
13369 VectorSubtract(rsurface.batchvertex3f + 3*(j+i), center, v);
13370 VectorMAMAMAM(1, center, DotProduct(forward, v), newforward, DotProduct(right, v), newright, DotProduct(up, v), newup, rsurface.batchvertex3f + 3*(j+i));
13373 // if we get here, BATCHNEED_ARRAY_NORMAL and BATCHNEED_ARRAY_VECTOR are in batchneed, so no need to check
13374 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13375 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);
13377 case Q3DEFORM_AUTOSPRITE2:
13378 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, newforward);
13379 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.right, newright);
13380 Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.up, newup);
13381 VectorNormalize(newforward);
13382 VectorNormalize(newright);
13383 VectorNormalize(newup);
13384 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13385 // rsurface.batchvertex3f_vertexbuffer = NULL;
13386 // rsurface.batchvertex3f_bufferoffset = 0;
13388 const float *v1, *v2;
13398 memset(shortest, 0, sizeof(shortest));
13399 // a single autosprite surface can contain multiple sprites...
13400 for (j = 0;j < batchnumvertices - 3;j += 4)
13402 VectorClear(center);
13403 for (i = 0;i < 4;i++)
13404 VectorAdd(center, rsurface.batchvertex3f + 3*(j+i), center);
13405 VectorScale(center, 0.25f, center);
13406 // find the two shortest edges, then use them to define the
13407 // axis vectors for rotating around the central axis
13408 for (i = 0;i < 6;i++)
13410 v1 = rsurface.batchvertex3f + 3*(j+quadedges[i][0]);
13411 v2 = rsurface.batchvertex3f + 3*(j+quadedges[i][1]);
13412 l = VectorDistance2(v1, v2);
13413 // this length bias tries to make sense of square polygons, assuming they are meant to be upright
13414 if (v1[2] != v2[2])
13415 l += (1.0f / 1024.0f);
13416 if (shortest[0].length2 > l || i == 0)
13418 shortest[1] = shortest[0];
13419 shortest[0].length2 = l;
13420 shortest[0].v1 = v1;
13421 shortest[0].v2 = v2;
13423 else if (shortest[1].length2 > l || i == 1)
13425 shortest[1].length2 = l;
13426 shortest[1].v1 = v1;
13427 shortest[1].v2 = v2;
13430 VectorLerp(shortest[0].v1, 0.5f, shortest[0].v2, start);
13431 VectorLerp(shortest[1].v1, 0.5f, shortest[1].v2, end);
13432 // this calculates the right vector from the shortest edge
13433 // and the up vector from the edge midpoints
13434 VectorSubtract(shortest[0].v1, shortest[0].v2, right);
13435 VectorNormalize(right);
13436 VectorSubtract(end, start, up);
13437 VectorNormalize(up);
13438 // calculate a forward vector to use instead of the original plane normal (this is how we get a new right vector)
13439 VectorSubtract(rsurface.localvieworigin, center, forward);
13440 //Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, forward);
13441 VectorNegate(forward, forward);
13442 VectorReflect(forward, 0, up, forward);
13443 VectorNormalize(forward);
13444 CrossProduct(up, forward, newright);
13445 VectorNormalize(newright);
13446 // rotate the quad around the up axis vector, this is made
13447 // especially easy by the fact we know the quad is flat,
13448 // so we only have to subtract the center position and
13449 // measure distance along the right vector, and then
13450 // multiply that by the newright vector and add back the
13452 // we also need to subtract the old position to undo the
13453 // displacement from the center, which we do with a
13454 // DotProduct, the subtraction/addition of center is also
13455 // optimized into DotProducts here
13456 l = DotProduct(right, center);
13457 for (i = 0;i < 4;i++)
13459 v1 = rsurface.batchvertex3f + 3*(j+i);
13460 f = DotProduct(right, v1) - l;
13461 VectorMAMAM(1, v1, -f, right, f, newright, rsurface.batchvertex3f + 3*(j+i));
13465 if(batchneed & (BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR)) // otherwise these can stay NULL
13467 // rsurface.batchnormal3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13468 // rsurface.batchnormal3f_vertexbuffer = NULL;
13469 // rsurface.batchnormal3f_bufferoffset = 0;
13470 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13472 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13474 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13475 // rsurface.batchsvector3f_vertexbuffer = NULL;
13476 // rsurface.batchsvector3f_bufferoffset = 0;
13477 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13478 // rsurface.batchtvector3f_vertexbuffer = NULL;
13479 // rsurface.batchtvector3f_bufferoffset = 0;
13480 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);
13483 case Q3DEFORM_NORMAL:
13484 // deform the normals to make reflections wavey
13485 rsurface.batchnormal3f = (float *)R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13486 rsurface.batchnormal3f_vertexbuffer = NULL;
13487 rsurface.batchnormal3f_bufferoffset = 0;
13488 for (j = 0;j < batchnumvertices;j++)
13491 float *normal = rsurface.batchnormal3f + 3*j;
13492 VectorScale(rsurface.batchvertex3f + 3*j, 0.98f, vertex);
13493 normal[0] = rsurface.batchnormal3f[j*3+0] + deform->parms[0] * noise4f( vertex[0], vertex[1], vertex[2], r_refdef.scene.time * deform->parms[1]);
13494 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]);
13495 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]);
13496 VectorNormalize(normal);
13498 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13500 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13501 // rsurface.batchsvector3f_vertexbuffer = NULL;
13502 // rsurface.batchsvector3f_bufferoffset = 0;
13503 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13504 // rsurface.batchtvector3f_vertexbuffer = NULL;
13505 // rsurface.batchtvector3f_bufferoffset = 0;
13506 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);
13509 case Q3DEFORM_WAVE:
13510 // deform vertex array to make wavey water and flags and such
13511 waveparms[0] = deform->waveparms[0];
13512 waveparms[1] = deform->waveparms[1];
13513 waveparms[2] = deform->waveparms[2];
13514 waveparms[3] = deform->waveparms[3];
13515 if(!R_TestQ3WaveFunc(deform->wavefunc, waveparms))
13516 break; // if wavefunc is a nop, don't make a dynamic vertex array
13517 // this is how a divisor of vertex influence on deformation
13518 animpos = deform->parms[0] ? 1.0f / deform->parms[0] : 100.0f;
13519 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
13520 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13521 // rsurface.batchvertex3f_vertexbuffer = NULL;
13522 // rsurface.batchvertex3f_bufferoffset = 0;
13523 // rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13524 // rsurface.batchnormal3f_vertexbuffer = NULL;
13525 // rsurface.batchnormal3f_bufferoffset = 0;
13526 for (j = 0;j < batchnumvertices;j++)
13528 // if the wavefunc depends on time, evaluate it per-vertex
13531 waveparms[2] = deform->waveparms[2] + (rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+1] + rsurface.batchvertex3f[j*3+2]) * animpos;
13532 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
13534 VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.batchvertex3f + 3*j);
13536 // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
13537 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13538 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13540 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13541 // rsurface.batchsvector3f_vertexbuffer = NULL;
13542 // rsurface.batchsvector3f_bufferoffset = 0;
13543 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13544 // rsurface.batchtvector3f_vertexbuffer = NULL;
13545 // rsurface.batchtvector3f_bufferoffset = 0;
13546 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);
13549 case Q3DEFORM_BULGE:
13550 // deform vertex array to make the surface have moving bulges
13551 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13552 // rsurface.batchvertex3f_vertexbuffer = NULL;
13553 // rsurface.batchvertex3f_bufferoffset = 0;
13554 // rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
13555 // rsurface.batchnormal3f_vertexbuffer = NULL;
13556 // rsurface.batchnormal3f_bufferoffset = 0;
13557 for (j = 0;j < batchnumvertices;j++)
13559 scale = sin(rsurface.batchtexcoordtexture2f[j*2+0] * deform->parms[0] + r_refdef.scene.time * deform->parms[2]) * deform->parms[1];
13560 VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.batchvertex3f + 3*j);
13562 // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
13563 Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
13564 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
13566 // rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13567 // rsurface.batchsvector3f_vertexbuffer = NULL;
13568 // rsurface.batchsvector3f_bufferoffset = 0;
13569 // rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
13570 // rsurface.batchtvector3f_vertexbuffer = NULL;
13571 // rsurface.batchtvector3f_bufferoffset = 0;
13572 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);
13575 case Q3DEFORM_MOVE:
13576 // deform vertex array
13577 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
13578 break; // if wavefunc is a nop, don't make a dynamic vertex array
13579 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, deform->waveparms);
13580 VectorScale(deform->parms, scale, waveparms);
13581 // rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
13582 // rsurface.batchvertex3f_vertexbuffer = NULL;
13583 // rsurface.batchvertex3f_bufferoffset = 0;
13584 for (j = 0;j < batchnumvertices;j++)
13585 VectorAdd(rsurface.batchvertex3f + 3*j, waveparms, rsurface.batchvertex3f + 3*j);
13590 // generate texcoords based on the chosen texcoord source
13591 switch(rsurface.texture->tcgen.tcgen)
13594 case Q3TCGEN_TEXTURE:
13596 case Q3TCGEN_LIGHTMAP:
13597 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13598 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13599 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13600 if (rsurface.batchtexcoordlightmap2f)
13601 memcpy(rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordtexture2f, batchnumvertices * sizeof(float[2]));
13603 case Q3TCGEN_VECTOR:
13604 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13605 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13606 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13607 for (j = 0;j < batchnumvertices;j++)
13609 rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
13610 rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
13613 case Q3TCGEN_ENVIRONMENT:
13614 // make environment reflections using a spheremap
13615 rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13616 rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13617 rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13618 for (j = 0;j < batchnumvertices;j++)
13620 // identical to Q3A's method, but executed in worldspace so
13621 // carried models can be shiny too
13623 float viewer[3], d, reflected[3], worldreflected[3];
13625 VectorSubtract(rsurface.localvieworigin, rsurface.batchvertex3f + 3*j, viewer);
13626 // VectorNormalize(viewer);
13628 d = DotProduct(rsurface.batchnormal3f + 3*j, viewer);
13630 reflected[0] = rsurface.batchnormal3f[j*3+0]*2*d - viewer[0];
13631 reflected[1] = rsurface.batchnormal3f[j*3+1]*2*d - viewer[1];
13632 reflected[2] = rsurface.batchnormal3f[j*3+2]*2*d - viewer[2];
13633 // note: this is proportinal to viewer, so we can normalize later
13635 Matrix4x4_Transform3x3(&rsurface.matrix, reflected, worldreflected);
13636 VectorNormalize(worldreflected);
13638 // note: this sphere map only uses world x and z!
13639 // so positive and negative y will LOOK THE SAME.
13640 rsurface.batchtexcoordtexture2f[j*2+0] = 0.5 + 0.5 * worldreflected[1];
13641 rsurface.batchtexcoordtexture2f[j*2+1] = 0.5 - 0.5 * worldreflected[2];
13645 // the only tcmod that needs software vertex processing is turbulent, so
13646 // check for it here and apply the changes if needed
13647 // and we only support that as the first one
13648 // (handling a mixture of turbulent and other tcmods would be problematic
13649 // without punting it entirely to a software path)
13650 if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
13652 amplitude = rsurface.texture->tcmods[0].parms[1];
13653 animpos = rsurface.texture->tcmods[0].parms[2] + r_refdef.scene.time * rsurface.texture->tcmods[0].parms[3];
13654 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
13655 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
13656 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
13657 for (j = 0;j < batchnumvertices;j++)
13659 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);
13660 rsurface.batchtexcoordtexture2f[j*2+1] += amplitude * sin(((rsurface.batchvertex3f[j*3+1] ) * 1.0 / 1024.0f + animpos) * M_PI * 2);
13664 if (needsupdate & batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP))
13666 // convert the modified arrays to vertex structs
13667 // rsurface.batchvertexmesh = R_FrameData_Alloc(batchnumvertices * sizeof(r_vertexmesh_t));
13668 // rsurface.batchvertexmeshbuffer = NULL;
13669 if (batchneed & BATCHNEED_VERTEXMESH_VERTEX)
13670 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13671 VectorCopy(rsurface.batchvertex3f + 3*j, vertexmesh->vertex3f);
13672 if (batchneed & BATCHNEED_VERTEXMESH_NORMAL)
13673 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13674 VectorCopy(rsurface.batchnormal3f + 3*j, vertexmesh->normal3f);
13675 if (batchneed & BATCHNEED_VERTEXMESH_VECTOR)
13677 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13679 VectorCopy(rsurface.batchsvector3f + 3*j, vertexmesh->svector3f);
13680 VectorCopy(rsurface.batchtvector3f + 3*j, vertexmesh->tvector3f);
13683 if ((batchneed & BATCHNEED_VERTEXMESH_VERTEXCOLOR) && rsurface.batchlightmapcolor4f)
13684 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13685 Vector4Scale(rsurface.batchlightmapcolor4f + 4*j, 255.0f, vertexmesh->color4ub);
13686 if (batchneed & BATCHNEED_VERTEXMESH_TEXCOORD)
13687 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13688 Vector2Copy(rsurface.batchtexcoordtexture2f + 2*j, vertexmesh->texcoordtexture2f);
13689 if ((batchneed & BATCHNEED_VERTEXMESH_LIGHTMAP) && rsurface.batchtexcoordlightmap2f)
13690 for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
13691 Vector2Copy(rsurface.batchtexcoordlightmap2f + 2*j, vertexmesh->texcoordlightmap2f);
13695 void RSurf_DrawBatch(void)
13697 // sometimes a zero triangle surface (usually a degenerate patch) makes it
13698 // through the pipeline, killing it earlier in the pipeline would have
13699 // per-surface overhead rather than per-batch overhead, so it's best to
13700 // reject it here, before it hits glDraw.
13701 if (rsurface.batchnumtriangles == 0)
13704 // batch debugging code
13705 if (r_test.integer && rsurface.entity == r_refdef.scene.worldentity && rsurface.batchvertex3f == r_refdef.scene.worldentity->model->surfmesh.data_vertex3f)
13711 e = rsurface.batchelement3i + rsurface.batchfirsttriangle*3;
13712 for (i = 0;i < rsurface.batchnumtriangles*3;i++)
13715 for (j = 0;j < rsurface.entity->model->num_surfaces;j++)
13717 if (c >= rsurface.modelsurfaces[j].num_firstvertex && c < (rsurface.modelsurfaces[j].num_firstvertex + rsurface.modelsurfaces[j].num_vertices))
13719 if (rsurface.modelsurfaces[j].texture != rsurface.texture)
13720 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);
13727 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);
13730 static int RSurf_FindWaterPlaneForSurface(const msurface_t *surface)
13732 // pick the closest matching water plane
13733 int planeindex, vertexindex, bestplaneindex = -1;
13737 r_waterstate_waterplane_t *p;
13738 qboolean prepared = false;
13740 for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
13742 if(p->camera_entity != rsurface.texture->camera_entity)
13747 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, 1, &surface);
13749 if(rsurface.batchnumvertices == 0)
13752 for (vertexindex = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3;vertexindex < rsurface.batchnumvertices;vertexindex++, v += 3)
13754 Matrix4x4_Transform(&rsurface.matrix, v, vert);
13755 d += fabs(PlaneDiff(vert, &p->plane));
13757 if (bestd > d || bestplaneindex < 0)
13760 bestplaneindex = planeindex;
13763 return bestplaneindex;
13764 // NOTE: this MAY return a totally unrelated water plane; we can ignore
13765 // this situation though, as it might be better to render single larger
13766 // batches with useless stuff (backface culled for example) than to
13767 // render multiple smaller batches
13770 static void RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray(void)
13773 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13774 rsurface.passcolor4f_vertexbuffer = 0;
13775 rsurface.passcolor4f_bufferoffset = 0;
13776 for (i = 0;i < rsurface.batchnumvertices;i++)
13777 Vector4Set(rsurface.passcolor4f + 4*i, 0.5f, 0.5f, 0.5f, 1.0f);
13780 static void RSurf_DrawBatch_GL11_ApplyFog(void)
13787 if (rsurface.passcolor4f)
13789 // generate color arrays
13790 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13791 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13792 rsurface.passcolor4f_vertexbuffer = 0;
13793 rsurface.passcolor4f_bufferoffset = 0;
13794 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)
13796 f = RSurf_FogVertex(v);
13805 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13806 rsurface.passcolor4f_vertexbuffer = 0;
13807 rsurface.passcolor4f_bufferoffset = 0;
13808 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c2 += 4)
13810 f = RSurf_FogVertex(v);
13819 static void RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors(void)
13826 if (!rsurface.passcolor4f)
13828 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13829 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13830 rsurface.passcolor4f_vertexbuffer = 0;
13831 rsurface.passcolor4f_bufferoffset = 0;
13832 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)
13834 f = RSurf_FogVertex(v);
13835 c2[0] = c[0] * f + r_refdef.fogcolor[0] * (1 - f);
13836 c2[1] = c[1] * f + r_refdef.fogcolor[1] * (1 - f);
13837 c2[2] = c[2] * f + r_refdef.fogcolor[2] * (1 - f);
13842 static void RSurf_DrawBatch_GL11_ApplyColor(float r, float g, float b, float a)
13847 if (!rsurface.passcolor4f)
13849 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13850 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13851 rsurface.passcolor4f_vertexbuffer = 0;
13852 rsurface.passcolor4f_bufferoffset = 0;
13853 for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
13862 static void RSurf_DrawBatch_GL11_ApplyAmbient(void)
13867 if (!rsurface.passcolor4f)
13869 c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
13870 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13871 rsurface.passcolor4f_vertexbuffer = 0;
13872 rsurface.passcolor4f_bufferoffset = 0;
13873 for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
13875 c2[0] = c[0] + r_refdef.scene.ambient;
13876 c2[1] = c[1] + r_refdef.scene.ambient;
13877 c2[2] = c[2] + r_refdef.scene.ambient;
13882 static void RSurf_DrawBatch_GL11_Lightmap(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13885 rsurface.passcolor4f = NULL;
13886 rsurface.passcolor4f_vertexbuffer = 0;
13887 rsurface.passcolor4f_bufferoffset = 0;
13888 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
13889 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
13890 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
13891 GL_Color(r, g, b, a);
13892 R_Mesh_TexBind(0, rsurface.lightmaptexture);
13896 static void RSurf_DrawBatch_GL11_Unlit(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13898 // TODO: optimize applyfog && applycolor case
13899 // just apply fog if necessary, and tint the fog color array if necessary
13900 rsurface.passcolor4f = NULL;
13901 rsurface.passcolor4f_vertexbuffer = 0;
13902 rsurface.passcolor4f_bufferoffset = 0;
13903 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
13904 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
13905 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
13906 GL_Color(r, g, b, a);
13910 static void RSurf_DrawBatch_GL11_VertexColor(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13913 rsurface.passcolor4f = rsurface.batchlightmapcolor4f;
13914 rsurface.passcolor4f_vertexbuffer = rsurface.batchlightmapcolor4f_vertexbuffer;
13915 rsurface.passcolor4f_bufferoffset = rsurface.batchlightmapcolor4f_bufferoffset;
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_ClampColor(void)
13928 if (!rsurface.passcolor4f)
13930 for (i = 0, c1 = rsurface.passcolor4f + 4*rsurface.batchfirstvertex, c2 = rsurface.passcolor4f + 4*rsurface.batchfirstvertex;i < rsurface.batchnumvertices;i++, c1 += 4, c2 += 4)
13932 c2[0] = bound(0.0f, c1[0], 1.0f);
13933 c2[1] = bound(0.0f, c1[1], 1.0f);
13934 c2[2] = bound(0.0f, c1[2], 1.0f);
13935 c2[3] = bound(0.0f, c1[3], 1.0f);
13939 static void RSurf_DrawBatch_GL11_ApplyFakeLight(void)
13949 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13950 rsurface.passcolor4f_vertexbuffer = 0;
13951 rsurface.passcolor4f_bufferoffset = 0;
13952 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)
13954 f = -DotProduct(r_refdef.view.forward, n);
13956 f = f * 0.85 + 0.15; // work around so stuff won't get black
13957 f *= r_refdef.lightmapintensity;
13958 Vector4Set(c, f, f, f, 1);
13962 static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
13964 RSurf_DrawBatch_GL11_ApplyFakeLight();
13965 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
13966 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
13967 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
13968 GL_Color(r, g, b, a);
13972 static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor)
13980 vec3_t ambientcolor;
13981 vec3_t diffusecolor;
13985 VectorCopy(rsurface.modellight_lightdir, lightdir);
13986 f = 0.5f * r_refdef.lightmapintensity;
13987 ambientcolor[0] = rsurface.modellight_ambient[0] * *r * f;
13988 ambientcolor[1] = rsurface.modellight_ambient[1] * *g * f;
13989 ambientcolor[2] = rsurface.modellight_ambient[2] * *b * f;
13990 diffusecolor[0] = rsurface.modellight_diffuse[0] * *r * f;
13991 diffusecolor[1] = rsurface.modellight_diffuse[1] * *g * f;
13992 diffusecolor[2] = rsurface.modellight_diffuse[2] * *b * f;
13994 if (VectorLength2(diffusecolor) > 0)
13996 // q3-style directional shading
13997 rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
13998 rsurface.passcolor4f_vertexbuffer = 0;
13999 rsurface.passcolor4f_bufferoffset = 0;
14000 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)
14002 if ((f = DotProduct(n, lightdir)) > 0)
14003 VectorMA(ambientcolor, f, diffusecolor, c);
14005 VectorCopy(ambientcolor, c);
14012 *applycolor = false;
14016 *r = ambientcolor[0];
14017 *g = ambientcolor[1];
14018 *b = ambientcolor[2];
14019 rsurface.passcolor4f = NULL;
14020 rsurface.passcolor4f_vertexbuffer = 0;
14021 rsurface.passcolor4f_bufferoffset = 0;
14025 static void RSurf_DrawBatch_GL11_VertexShade(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
14027 RSurf_DrawBatch_GL11_ApplyVertexShade(&r, &g, &b, &a, &applycolor);
14028 if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
14029 if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
14030 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
14031 GL_Color(r, g, b, a);
14035 static void RSurf_DrawBatch_GL11_MakeFogColor(float r, float g, float b, float a)
14041 for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4)
14043 f = 1 - RSurf_FogVertex(v);
14051 void RSurf_SetupDepthAndCulling(void)
14053 // submodels are biased to avoid z-fighting with world surfaces that they
14054 // may be exactly overlapping (avoids z-fighting artifacts on certain
14055 // doors and things in Quake maps)
14056 GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
14057 GL_PolygonOffset(rsurface.basepolygonfactor + rsurface.texture->biaspolygonfactor, rsurface.basepolygonoffset + rsurface.texture->biaspolygonoffset);
14058 GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
14059 GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_refdef.view.cullface_back);
14062 static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist)
14064 // transparent sky would be ridiculous
14065 if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
14067 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14068 skyrenderlater = true;
14069 RSurf_SetupDepthAndCulling();
14070 GL_DepthMask(true);
14071 // LordHavoc: HalfLife maps have freaky skypolys so don't use
14072 // skymasking on them, and Quake3 never did sky masking (unlike
14073 // software Quake and software Quake2), so disable the sky masking
14074 // in Quake3 maps as it causes problems with q3map2 sky tricks,
14075 // and skymasking also looks very bad when noclipping outside the
14076 // level, so don't use it then either.
14077 if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis)
14079 R_Mesh_ResetTextureState();
14080 if (skyrendermasked)
14082 R_SetupShader_DepthOrShadow();
14083 // depth-only (masking)
14084 GL_ColorMask(0,0,0,0);
14085 // just to make sure that braindead drivers don't draw
14086 // anything despite that colormask...
14087 GL_BlendFunc(GL_ZERO, GL_ONE);
14088 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14089 if (rsurface.batchvertex3fbuffer)
14090 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
14092 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
14096 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14098 GL_BlendFunc(GL_ONE, GL_ZERO);
14099 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14100 GL_Color(r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], 1);
14101 R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
14104 if (skyrendermasked)
14105 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
14107 R_Mesh_ResetTextureState();
14108 GL_Color(1, 1, 1, 1);
14111 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
14112 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
14113 static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
14115 if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA)))
14119 // render screenspace normalmap to texture
14120 GL_DepthMask(true);
14121 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL);
14126 // bind lightmap texture
14128 // water/refraction/reflection/camera surfaces have to be handled specially
14129 if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA | MATERIALFLAG_REFLECTION)))
14131 int start, end, startplaneindex;
14132 for (start = 0;start < texturenumsurfaces;start = end)
14134 startplaneindex = RSurf_FindWaterPlaneForSurface(texturesurfacelist[start]);
14135 if(startplaneindex < 0)
14137 // this happens if the plane e.g. got backface culled and thus didn't get a water plane. We can just ignore this.
14138 // Con_Printf("No matching water plane for surface with material flags 0x%08x - PLEASE DEBUG THIS\n", rsurface.texture->currentmaterialflags);
14142 for (end = start + 1;end < texturenumsurfaces && startplaneindex == RSurf_FindWaterPlaneForSurface(texturesurfacelist[end]);end++)
14144 // now that we have a batch using the same planeindex, render it
14145 if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)))
14147 // render water or distortion background
14148 GL_DepthMask(true);
14149 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));
14151 // blend surface on top
14152 GL_DepthMask(false);
14153 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL);
14156 else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION))
14158 // render surface with reflection texture as input
14159 GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
14160 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));
14167 // render surface batch normally
14168 GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
14169 R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL);
14173 static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)
14175 // OpenGL 1.3 path - anything not completely ancient
14176 qboolean applycolor;
14179 const texturelayer_t *layer;
14180 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);
14181 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
14183 for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++)
14186 int layertexrgbscale;
14187 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14189 if (layerindex == 0)
14190 GL_AlphaTest(true);
14193 GL_AlphaTest(false);
14194 GL_DepthFunc(GL_EQUAL);
14197 GL_DepthMask(layer->depthmask && writedepth);
14198 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
14199 if (layer->color[0] > 2 || layer->color[1] > 2 || layer->color[2] > 2)
14201 layertexrgbscale = 4;
14202 VectorScale(layer->color, 0.25f, layercolor);
14204 else if (layer->color[0] > 1 || layer->color[1] > 1 || layer->color[2] > 1)
14206 layertexrgbscale = 2;
14207 VectorScale(layer->color, 0.5f, layercolor);
14211 layertexrgbscale = 1;
14212 VectorScale(layer->color, 1.0f, layercolor);
14214 layercolor[3] = layer->color[3];
14215 applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1;
14216 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, 0, 0);
14217 applyfog = r_refdef.fogenabled && (rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED);
14218 switch (layer->type)
14220 case TEXTURELAYERTYPE_LITTEXTURE:
14221 // single-pass lightmapped texture with 2x rgbscale
14222 R_Mesh_TexBind(0, r_texture_white);
14223 R_Mesh_TexMatrix(0, NULL);
14224 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14225 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
14226 R_Mesh_TexBind(1, layer->texture);
14227 R_Mesh_TexMatrix(1, &layer->texmatrix);
14228 R_Mesh_TexCombine(1, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
14229 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14230 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14231 RSurf_DrawBatch_GL11_VertexShade(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14232 else if (FAKELIGHT_ENABLED)
14233 RSurf_DrawBatch_GL11_FakeLight(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14234 else if (rsurface.uselightmaptexture)
14235 RSurf_DrawBatch_GL11_Lightmap(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14237 RSurf_DrawBatch_GL11_VertexColor(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14239 case TEXTURELAYERTYPE_TEXTURE:
14240 // singletexture unlit texture with transparency support
14241 R_Mesh_TexBind(0, layer->texture);
14242 R_Mesh_TexMatrix(0, &layer->texmatrix);
14243 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
14244 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14245 R_Mesh_TexBind(1, 0);
14246 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14247 RSurf_DrawBatch_GL11_Unlit(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
14249 case TEXTURELAYERTYPE_FOG:
14250 // singletexture fogging
14251 if (layer->texture)
14253 R_Mesh_TexBind(0, layer->texture);
14254 R_Mesh_TexMatrix(0, &layer->texmatrix);
14255 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, layertexrgbscale, 1);
14256 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14260 R_Mesh_TexBind(0, 0);
14261 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14263 R_Mesh_TexBind(1, 0);
14264 R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14265 // generate a color array for the fog pass
14266 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
14267 RSurf_DrawBatch_GL11_MakeFogColor(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
14271 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
14274 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14276 GL_DepthFunc(GL_LEQUAL);
14277 GL_AlphaTest(false);
14281 static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)
14283 // OpenGL 1.1 - crusty old voodoo path
14286 const texturelayer_t *layer;
14287 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);
14288 R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
14290 for (layerindex = 0, layer = rsurface.texture->currentlayers;layerindex < rsurface.texture->currentnumlayers;layerindex++, layer++)
14292 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14294 if (layerindex == 0)
14295 GL_AlphaTest(true);
14298 GL_AlphaTest(false);
14299 GL_DepthFunc(GL_EQUAL);
14302 GL_DepthMask(layer->depthmask && writedepth);
14303 GL_BlendFunc(layer->blendfunc1, layer->blendfunc2);
14304 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, 0, 0);
14305 applyfog = r_refdef.fogenabled && (rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED);
14306 switch (layer->type)
14308 case TEXTURELAYERTYPE_LITTEXTURE:
14309 if (layer->blendfunc1 == GL_ONE && layer->blendfunc2 == GL_ZERO)
14311 // two-pass lit texture with 2x rgbscale
14312 // first the lightmap pass
14313 R_Mesh_TexBind(0, r_texture_white);
14314 R_Mesh_TexMatrix(0, NULL);
14315 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14316 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
14317 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14318 RSurf_DrawBatch_GL11_VertexShade(1, 1, 1, 1, false, false);
14319 else if (FAKELIGHT_ENABLED)
14320 RSurf_DrawBatch_GL11_FakeLight(1, 1, 1, 1, false, false);
14321 else if (rsurface.uselightmaptexture)
14322 RSurf_DrawBatch_GL11_Lightmap(1, 1, 1, 1, false, false);
14324 RSurf_DrawBatch_GL11_VertexColor(1, 1, 1, 1, false, false);
14325 // then apply the texture to it
14326 GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
14327 R_Mesh_TexBind(0, layer->texture);
14328 R_Mesh_TexMatrix(0, &layer->texmatrix);
14329 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14330 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14331 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);
14335 // single pass vertex-lighting-only texture with 1x rgbscale and transparency support
14336 R_Mesh_TexBind(0, layer->texture);
14337 R_Mesh_TexMatrix(0, &layer->texmatrix);
14338 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14339 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14340 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14341 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);
14343 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);
14346 case TEXTURELAYERTYPE_TEXTURE:
14347 // singletexture unlit texture with transparency support
14348 R_Mesh_TexBind(0, layer->texture);
14349 R_Mesh_TexMatrix(0, &layer->texmatrix);
14350 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14351 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14352 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);
14354 case TEXTURELAYERTYPE_FOG:
14355 // singletexture fogging
14356 if (layer->texture)
14358 R_Mesh_TexBind(0, layer->texture);
14359 R_Mesh_TexMatrix(0, &layer->texmatrix);
14360 R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
14361 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
14365 R_Mesh_TexBind(0, 0);
14366 R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
14368 // generate a color array for the fog pass
14369 R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
14370 RSurf_DrawBatch_GL11_MakeFogColor(layer->color[0], layer->color[1], layer->color[2], layer->color[3]);
14374 Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
14377 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14379 GL_DepthFunc(GL_LEQUAL);
14380 GL_AlphaTest(false);
14384 static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)
14388 r_vertexgeneric_t *batchvertex;
14391 GL_AlphaTest(false);
14392 // R_Mesh_ResetTextureState();
14393 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14395 if(rsurface.texture && rsurface.texture->currentskinframe)
14397 memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c));
14398 c[3] *= rsurface.texture->currentalpha;
14408 if (rsurface.texture->pantstexture || rsurface.texture->shirttexture)
14410 c[0] = 0.5 * (rsurface.colormap_pantscolor[0] * 0.3 + rsurface.colormap_shirtcolor[0] * 0.7);
14411 c[1] = 0.5 * (rsurface.colormap_pantscolor[1] * 0.3 + rsurface.colormap_shirtcolor[1] * 0.7);
14412 c[2] = 0.5 * (rsurface.colormap_pantscolor[2] * 0.3 + rsurface.colormap_shirtcolor[2] * 0.7);
14415 // brighten it up (as texture value 127 means "unlit")
14416 c[0] *= 2 * r_refdef.view.colorscale;
14417 c[1] *= 2 * r_refdef.view.colorscale;
14418 c[2] *= 2 * r_refdef.view.colorscale;
14420 if(rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA)
14421 c[3] *= r_wateralpha.value;
14423 if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1)
14425 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
14426 GL_DepthMask(false);
14428 else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
14430 GL_BlendFunc(GL_ONE, GL_ONE);
14431 GL_DepthMask(false);
14433 else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
14435 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // can't do alpha test without texture, so let's blend instead
14436 GL_DepthMask(false);
14438 else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
14440 GL_BlendFunc(rsurface.texture->customblendfunc[0], rsurface.texture->customblendfunc[1]);
14441 GL_DepthMask(false);
14445 GL_BlendFunc(GL_ONE, GL_ZERO);
14446 GL_DepthMask(writedepth);
14449 if (r_showsurfaces.integer == 3)
14451 rsurface.passcolor4f = NULL;
14453 if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
14455 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14457 rsurface.passcolor4f = NULL;
14458 rsurface.passcolor4f_vertexbuffer = 0;
14459 rsurface.passcolor4f_bufferoffset = 0;
14461 else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
14463 qboolean applycolor = true;
14466 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14468 r_refdef.lightmapintensity = 1;
14469 RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor);
14470 r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
14472 else if (FAKELIGHT_ENABLED)
14474 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14476 r_refdef.lightmapintensity = r_fakelight_intensity.value;
14477 RSurf_DrawBatch_GL11_ApplyFakeLight();
14478 r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
14482 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14484 rsurface.passcolor4f = rsurface.batchlightmapcolor4f;
14485 rsurface.passcolor4f_vertexbuffer = rsurface.batchlightmapcolor4f_vertexbuffer;
14486 rsurface.passcolor4f_bufferoffset = rsurface.batchlightmapcolor4f_bufferoffset;
14489 if(!rsurface.passcolor4f)
14490 RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray();
14492 RSurf_DrawBatch_GL11_ApplyAmbient();
14493 RSurf_DrawBatch_GL11_ApplyColor(c[0], c[1], c[2], c[3]);
14494 if(r_refdef.fogenabled)
14495 RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors();
14496 RSurf_DrawBatch_GL11_ClampColor();
14498 R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.passcolor4f, NULL);
14499 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
14502 else if (!r_refdef.view.showdebug)
14504 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14505 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchnumvertices);
14506 for (j = 0, vi = rsurface.batchfirstvertex;j < rsurface.batchnumvertices;j++, vi++)
14508 VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
14509 Vector4Set(batchvertex[vi].color4ub, 0, 0, 0, 255);
14511 R_Mesh_PrepareVertices_Generic_Unlock();
14514 else if (r_showsurfaces.integer == 4)
14516 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14517 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchnumvertices);
14518 for (j = 0, vi = rsurface.batchfirstvertex;j < rsurface.batchnumvertices;j++, vi++)
14520 unsigned char c = vi << 3;
14521 VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
14522 Vector4Set(batchvertex[vi].color4ub, c, c, c, 255);
14524 R_Mesh_PrepareVertices_Generic_Unlock();
14527 else if (r_showsurfaces.integer == 2)
14530 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14531 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(3*rsurface.batchnumtriangles);
14532 for (j = 0, e = rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle;j < rsurface.batchnumtriangles;j++, e += 3)
14534 unsigned char c = (j + rsurface.batchfirsttriangle) << 3;
14535 VectorCopy(rsurface.batchvertex3f + 3*e[0], batchvertex[j*3+0].vertex3f);
14536 VectorCopy(rsurface.batchvertex3f + 3*e[1], batchvertex[j*3+1].vertex3f);
14537 VectorCopy(rsurface.batchvertex3f + 3*e[2], batchvertex[j*3+2].vertex3f);
14538 Vector4Set(batchvertex[j*3+0].color4ub, c, c, c, 255);
14539 Vector4Set(batchvertex[j*3+1].color4ub, c, c, c, 255);
14540 Vector4Set(batchvertex[j*3+2].color4ub, c, c, c, 255);
14542 R_Mesh_PrepareVertices_Generic_Unlock();
14543 R_Mesh_Draw(0, rsurface.batchnumtriangles*3, 0, rsurface.batchnumtriangles, NULL, NULL, 0, NULL, NULL, 0);
14547 int texturesurfaceindex;
14549 const msurface_t *surface;
14550 unsigned char surfacecolor4ub[4];
14551 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
14552 batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchfirstvertex + rsurface.batchnumvertices);
14554 for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
14556 surface = texturesurfacelist[texturesurfaceindex];
14557 k = (int)(((size_t)surface) / sizeof(msurface_t));
14558 Vector4Set(surfacecolor4ub, (k & 0xF) << 4, (k & 0xF0), (k & 0xF00) >> 4, 255);
14559 for (j = 0;j < surface->num_vertices;j++)
14561 VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
14562 Vector4Copy(surfacecolor4ub, batchvertex[vi].color4ub);
14566 R_Mesh_PrepareVertices_Generic_Unlock();
14571 static void R_DrawWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
14574 RSurf_SetupDepthAndCulling();
14575 if (r_showsurfaces.integer)
14577 R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist, writedepth);
14580 switch (vid.renderpath)
14582 case RENDERPATH_GL20:
14583 case RENDERPATH_CGGL:
14584 case RENDERPATH_D3D9:
14585 case RENDERPATH_D3D10:
14586 case RENDERPATH_D3D11:
14587 case RENDERPATH_SOFT:
14588 case RENDERPATH_GLES2:
14589 R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14591 case RENDERPATH_GL13:
14592 R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth);
14594 case RENDERPATH_GL11:
14595 R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist, writedepth);
14601 static void R_DrawModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass)
14604 RSurf_SetupDepthAndCulling();
14605 if (r_showsurfaces.integer)
14607 R_DrawTextureSurfaceList_ShowSurfaces(texturenumsurfaces, texturesurfacelist, writedepth);
14610 switch (vid.renderpath)
14612 case RENDERPATH_GL20:
14613 case RENDERPATH_CGGL:
14614 case RENDERPATH_D3D9:
14615 case RENDERPATH_D3D10:
14616 case RENDERPATH_D3D11:
14617 case RENDERPATH_SOFT:
14618 case RENDERPATH_GLES2:
14619 R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14621 case RENDERPATH_GL13:
14622 R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth);
14624 case RENDERPATH_GL11:
14625 R_DrawTextureSurfaceList_GL11(texturenumsurfaces, texturesurfacelist, writedepth);
14631 static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
14634 int texturenumsurfaces, endsurface;
14635 texture_t *texture;
14636 const msurface_t *surface;
14637 #define MAXBATCH_TRANSPARENTSURFACES 256
14638 const msurface_t *texturesurfacelist[MAXBATCH_TRANSPARENTSURFACES];
14640 // if the model is static it doesn't matter what value we give for
14641 // wantnormals and wanttangents, so this logic uses only rules applicable
14642 // to a model, knowing that they are meaningless otherwise
14643 if (ent == r_refdef.scene.worldentity)
14644 RSurf_ActiveWorldEntity();
14645 else if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
14646 RSurf_ActiveModelEntity(ent, false, false, false);
14649 switch (vid.renderpath)
14651 case RENDERPATH_GL20:
14652 case RENDERPATH_CGGL:
14653 case RENDERPATH_D3D9:
14654 case RENDERPATH_D3D10:
14655 case RENDERPATH_D3D11:
14656 case RENDERPATH_SOFT:
14657 case RENDERPATH_GLES2:
14658 RSurf_ActiveModelEntity(ent, true, true, false);
14660 case RENDERPATH_GL13:
14661 case RENDERPATH_GL11:
14662 RSurf_ActiveModelEntity(ent, true, false, false);
14667 if (r_transparentdepthmasking.integer)
14669 qboolean setup = false;
14670 for (i = 0;i < numsurfaces;i = j)
14673 surface = rsurface.modelsurfaces + surfacelist[i];
14674 texture = surface->texture;
14675 rsurface.texture = R_GetCurrentTexture(texture);
14676 rsurface.lightmaptexture = NULL;
14677 rsurface.deluxemaptexture = NULL;
14678 rsurface.uselightmaptexture = false;
14679 // scan ahead until we find a different texture
14680 endsurface = min(i + 1024, numsurfaces);
14681 texturenumsurfaces = 0;
14682 texturesurfacelist[texturenumsurfaces++] = surface;
14683 for (;j < endsurface;j++)
14685 surface = rsurface.modelsurfaces + surfacelist[j];
14686 if (texture != surface->texture)
14688 texturesurfacelist[texturenumsurfaces++] = surface;
14690 if (!(rsurface.texture->currentmaterialflags & MATERIALFLAG_TRANSDEPTH))
14692 // render the range of surfaces as depth
14696 GL_ColorMask(0,0,0,0);
14698 GL_DepthTest(true);
14699 GL_BlendFunc(GL_ONE, GL_ZERO);
14700 GL_DepthMask(true);
14701 GL_AlphaTest(false);
14702 // R_Mesh_ResetTextureState();
14703 R_SetupShader_DepthOrShadow();
14705 RSurf_SetupDepthAndCulling();
14706 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
14707 if (rsurface.batchvertex3fbuffer)
14708 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
14710 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
14714 GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
14717 for (i = 0;i < numsurfaces;i = j)
14720 surface = rsurface.modelsurfaces + surfacelist[i];
14721 texture = surface->texture;
14722 rsurface.texture = R_GetCurrentTexture(texture);
14723 // scan ahead until we find a different texture
14724 endsurface = min(i + MAXBATCH_TRANSPARENTSURFACES, numsurfaces);
14725 texturenumsurfaces = 0;
14726 texturesurfacelist[texturenumsurfaces++] = surface;
14727 if(FAKELIGHT_ENABLED)
14729 rsurface.lightmaptexture = NULL;
14730 rsurface.deluxemaptexture = NULL;
14731 rsurface.uselightmaptexture = false;
14732 for (;j < endsurface;j++)
14734 surface = rsurface.modelsurfaces + surfacelist[j];
14735 if (texture != surface->texture)
14737 texturesurfacelist[texturenumsurfaces++] = surface;
14742 rsurface.lightmaptexture = surface->lightmaptexture;
14743 rsurface.deluxemaptexture = surface->deluxemaptexture;
14744 rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
14745 for (;j < endsurface;j++)
14747 surface = rsurface.modelsurfaces + surfacelist[j];
14748 if (texture != surface->texture || rsurface.lightmaptexture != surface->lightmaptexture)
14750 texturesurfacelist[texturenumsurfaces++] = surface;
14753 // render the range of surfaces
14754 if (ent == r_refdef.scene.worldentity)
14755 R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
14757 R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
14759 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
14760 GL_AlphaTest(false);
14763 static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, const entity_render_t *queueentity)
14765 // transparent surfaces get pushed off into the transparent queue
14766 int surfacelistindex;
14767 const msurface_t *surface;
14768 vec3_t tempcenter, center;
14769 for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++)
14771 surface = texturesurfacelist[surfacelistindex];
14772 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
14773 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
14774 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
14775 Matrix4x4_Transform(&rsurface.matrix, tempcenter, center);
14776 if (queueentity->transparent_offset) // transparent offset
14778 center[0] += r_refdef.view.forward[0]*queueentity->transparent_offset;
14779 center[1] += r_refdef.view.forward[1]*queueentity->transparent_offset;
14780 center[2] += r_refdef.view.forward[2]*queueentity->transparent_offset;
14782 R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight);
14786 static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msurface_t **texturesurfacelist)
14788 if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHATEST)))
14790 if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION)))
14792 RSurf_SetupDepthAndCulling();
14793 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
14794 if (rsurface.batchvertex3fbuffer)
14795 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
14797 R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
14801 static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass)
14803 const entity_render_t *queueentity = r_refdef.scene.worldentity;
14806 R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist);
14809 if (!rsurface.texture->currentnumlayers)
14811 if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
14812 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14814 R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14816 else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer)
14817 R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
14818 else if (!rsurface.texture->currentnumlayers)
14820 else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
14822 // in the deferred case, transparent surfaces were queued during prepass
14823 if (!r_shadow_usingdeferredprepass)
14824 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14828 // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier
14829 R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST), prepass);
14834 void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
14837 texture_t *texture;
14838 R_FrameData_SetMark();
14839 // break the surface list down into batches by texture and use of lightmapping
14840 for (i = 0;i < numsurfaces;i = j)
14843 // texture is the base texture pointer, rsurface.texture is the
14844 // current frame/skin the texture is directing us to use (for example
14845 // if a model has 2 skins and it is on skin 1, then skin 0 tells us to
14846 // use skin 1 instead)
14847 texture = surfacelist[i]->texture;
14848 rsurface.texture = R_GetCurrentTexture(texture);
14849 if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
14851 // if this texture is not the kind we want, skip ahead to the next one
14852 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14856 if(FAKELIGHT_ENABLED || depthonly || prepass)
14858 rsurface.lightmaptexture = NULL;
14859 rsurface.deluxemaptexture = NULL;
14860 rsurface.uselightmaptexture = false;
14861 // simply scan ahead until we find a different texture or lightmap state
14862 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14867 rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
14868 rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
14869 rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL;
14870 // simply scan ahead until we find a different texture or lightmap state
14871 for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
14874 // render the range of surfaces
14875 R_ProcessWorldTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass);
14877 R_FrameData_ReturnToMark();
14880 static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, const entity_render_t *queueentity, qboolean prepass)
14884 R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist);
14887 if (!rsurface.texture->currentnumlayers)
14889 if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
14890 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14892 R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
14894 else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer)
14895 R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
14896 else if (!rsurface.texture->currentnumlayers)
14898 else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity)
14900 // in the deferred case, transparent surfaces were queued during prepass
14901 if (!r_shadow_usingdeferredprepass)
14902 R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity);
14906 // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier
14907 R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth || (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST), prepass);
14912 void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qboolean writedepth, qboolean depthonly, qboolean prepass)
14915 texture_t *texture;
14916 R_FrameData_SetMark();
14917 // break the surface list down into batches by texture and use of lightmapping
14918 for (i = 0;i < numsurfaces;i = j)
14921 // texture is the base texture pointer, rsurface.texture is the
14922 // current frame/skin the texture is directing us to use (for example
14923 // if a model has 2 skins and it is on skin 1, then skin 0 tells us to
14924 // use skin 1 instead)
14925 texture = surfacelist[i]->texture;
14926 rsurface.texture = R_GetCurrentTexture(texture);
14927 if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
14929 // if this texture is not the kind we want, skip ahead to the next one
14930 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14934 if(FAKELIGHT_ENABLED || depthonly || prepass)
14936 rsurface.lightmaptexture = NULL;
14937 rsurface.deluxemaptexture = NULL;
14938 rsurface.uselightmaptexture = false;
14939 // simply scan ahead until we find a different texture or lightmap state
14940 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
14945 rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
14946 rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
14947 rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL;
14948 // simply scan ahead until we find a different texture or lightmap state
14949 for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
14952 // render the range of surfaces
14953 R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, ent, prepass);
14955 R_FrameData_ReturnToMark();
14958 float locboxvertex3f[6*4*3] =
14960 1,0,1, 1,0,0, 1,1,0, 1,1,1,
14961 0,1,1, 0,1,0, 0,0,0, 0,0,1,
14962 1,1,1, 1,1,0, 0,1,0, 0,1,1,
14963 0,0,1, 0,0,0, 1,0,0, 1,0,1,
14964 0,0,1, 1,0,1, 1,1,1, 0,1,1,
14965 1,0,0, 0,0,0, 0,1,0, 1,1,0
14968 unsigned short locboxelements[6*2*3] =
14973 12,13,14, 12,14,15,
14974 16,17,18, 16,18,19,
14978 void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
14981 cl_locnode_t *loc = (cl_locnode_t *)ent;
14983 float vertex3f[6*4*3];
14985 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
14986 GL_DepthMask(false);
14987 GL_DepthRange(0, 1);
14988 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
14989 GL_DepthTest(true);
14990 GL_CullFace(GL_NONE);
14991 R_EntityMatrix(&identitymatrix);
14993 // R_Mesh_ResetTextureState();
14995 i = surfacelist[0];
14996 GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_refdef.view.colorscale,
14997 ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_refdef.view.colorscale,
14998 ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_refdef.view.colorscale,
14999 surfacelist[0] < 0 ? 0.5f : 0.125f);
15001 if (VectorCompare(loc->mins, loc->maxs))
15003 VectorSet(size, 2, 2, 2);
15004 VectorMA(loc->mins, -0.5f, size, mins);
15008 VectorCopy(loc->mins, mins);
15009 VectorSubtract(loc->maxs, loc->mins, size);
15012 for (i = 0;i < 6*4*3;)
15013 for (j = 0;j < 3;j++, i++)
15014 vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i];
15016 R_Mesh_PrepareVertices_Generic_Arrays(6*4, vertex3f, NULL, NULL);
15017 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
15018 R_Mesh_Draw(0, 6*4, 0, 6*2, NULL, NULL, 0, locboxelements, NULL, 0);
15021 void R_DrawLocs(void)
15024 cl_locnode_t *loc, *nearestloc;
15026 nearestloc = CL_Locs_FindNearest(cl.movement_origin);
15027 for (loc = cl.locnodes, index = 0;loc;loc = loc->next, index++)
15029 VectorLerp(loc->mins, 0.5f, loc->maxs, center);
15030 R_MeshQueue_AddTransparent(center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL);
15034 void R_DecalSystem_Reset(decalsystem_t *decalsystem)
15036 if (decalsystem->decals)
15037 Mem_Free(decalsystem->decals);
15038 memset(decalsystem, 0, sizeof(*decalsystem));
15041 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)
15044 tridecal_t *decals;
15047 // expand or initialize the system
15048 if (decalsystem->maxdecals <= decalsystem->numdecals)
15050 decalsystem_t old = *decalsystem;
15051 qboolean useshortelements;
15052 decalsystem->maxdecals = max(16, decalsystem->maxdecals * 2);
15053 useshortelements = decalsystem->maxdecals * 3 <= 65536;
15054 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)));
15055 decalsystem->color4f = (float *)(decalsystem->decals + decalsystem->maxdecals);
15056 decalsystem->texcoord2f = (float *)(decalsystem->color4f + decalsystem->maxdecals*12);
15057 decalsystem->vertex3f = (float *)(decalsystem->texcoord2f + decalsystem->maxdecals*6);
15058 decalsystem->element3i = (int *)(decalsystem->vertex3f + decalsystem->maxdecals*9);
15059 decalsystem->element3s = (useshortelements ? ((unsigned short *)(decalsystem->element3i + decalsystem->maxdecals*3)) : NULL);
15060 if (decalsystem->numdecals)
15061 memcpy(decalsystem->decals, old.decals, decalsystem->numdecals * sizeof(tridecal_t));
15063 Mem_Free(old.decals);
15064 for (i = 0;i < decalsystem->maxdecals*3;i++)
15065 decalsystem->element3i[i] = i;
15066 if (useshortelements)
15067 for (i = 0;i < decalsystem->maxdecals*3;i++)
15068 decalsystem->element3s[i] = i;
15071 // grab a decal and search for another free slot for the next one
15072 decals = decalsystem->decals;
15073 decal = decalsystem->decals + (i = decalsystem->freedecal++);
15074 for (i = decalsystem->freedecal;i < decalsystem->numdecals && decals[i].color4ub[0][3];i++)
15076 decalsystem->freedecal = i;
15077 if (decalsystem->numdecals <= i)
15078 decalsystem->numdecals = i + 1;
15080 // initialize the decal
15082 decal->triangleindex = triangleindex;
15083 decal->surfaceindex = surfaceindex;
15084 decal->decalsequence = decalsequence;
15085 decal->color4ub[0][0] = (unsigned char)(c0[0]*255.0f);
15086 decal->color4ub[0][1] = (unsigned char)(c0[1]*255.0f);
15087 decal->color4ub[0][2] = (unsigned char)(c0[2]*255.0f);
15088 decal->color4ub[0][3] = 255;
15089 decal->color4ub[1][0] = (unsigned char)(c1[0]*255.0f);
15090 decal->color4ub[1][1] = (unsigned char)(c1[1]*255.0f);
15091 decal->color4ub[1][2] = (unsigned char)(c1[2]*255.0f);
15092 decal->color4ub[1][3] = 255;
15093 decal->color4ub[2][0] = (unsigned char)(c2[0]*255.0f);
15094 decal->color4ub[2][1] = (unsigned char)(c2[1]*255.0f);
15095 decal->color4ub[2][2] = (unsigned char)(c2[2]*255.0f);
15096 decal->color4ub[2][3] = 255;
15097 decal->vertex3f[0][0] = v0[0];
15098 decal->vertex3f[0][1] = v0[1];
15099 decal->vertex3f[0][2] = v0[2];
15100 decal->vertex3f[1][0] = v1[0];
15101 decal->vertex3f[1][1] = v1[1];
15102 decal->vertex3f[1][2] = v1[2];
15103 decal->vertex3f[2][0] = v2[0];
15104 decal->vertex3f[2][1] = v2[1];
15105 decal->vertex3f[2][2] = v2[2];
15106 decal->texcoord2f[0][0] = t0[0];
15107 decal->texcoord2f[0][1] = t0[1];
15108 decal->texcoord2f[1][0] = t1[0];
15109 decal->texcoord2f[1][1] = t1[1];
15110 decal->texcoord2f[2][0] = t2[0];
15111 decal->texcoord2f[2][1] = t2[1];
15114 extern cvar_t cl_decals_bias;
15115 extern cvar_t cl_decals_models;
15116 extern cvar_t cl_decals_newsystem_intensitymultiplier;
15117 // baseparms, parms, temps
15118 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)
15123 const float *vertex3f;
15125 float points[2][9][3];
15132 e = rsurface.modelelement3i + 3*triangleindex;
15134 vertex3f = rsurface.modelvertex3f;
15136 for (cornerindex = 0;cornerindex < 3;cornerindex++)
15138 index = 3*e[cornerindex];
15139 VectorCopy(vertex3f + index, v[cornerindex]);
15142 //TriangleNormal(v[0], v[1], v[2], normal);
15143 //if (DotProduct(normal, localnormal) < 0.0f)
15145 // clip by each of the box planes formed from the projection matrix
15146 // if anything survives, we emit the decal
15147 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]);
15150 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]);
15153 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]);
15156 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]);
15159 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]);
15162 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]);
15165 // some part of the triangle survived, so we have to accept it...
15168 // dynamic always uses the original triangle
15170 for (cornerindex = 0;cornerindex < 3;cornerindex++)
15172 index = 3*e[cornerindex];
15173 VectorCopy(vertex3f + index, v[cornerindex]);
15176 for (cornerindex = 0;cornerindex < numpoints;cornerindex++)
15178 // convert vertex positions to texcoords
15179 Matrix4x4_Transform(projection, v[cornerindex], temp);
15180 tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
15181 tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
15182 // calculate distance fade from the projection origin
15183 f = a * (1.0f-fabs(temp[0])) * cl_decals_newsystem_intensitymultiplier.value;
15184 f = bound(0.0f, f, 1.0f);
15185 c[cornerindex][0] = r * f;
15186 c[cornerindex][1] = g * f;
15187 c[cornerindex][2] = b * f;
15188 c[cornerindex][3] = 1.0f;
15189 //VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
15192 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);
15194 for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
15195 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);
15197 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)
15199 matrix4x4_t projection;
15200 decalsystem_t *decalsystem;
15203 const msurface_t *surface;
15204 const msurface_t *surfaces;
15205 const int *surfacelist;
15206 const texture_t *texture;
15208 int numsurfacelist;
15209 int surfacelistindex;
15212 float localorigin[3];
15213 float localnormal[3];
15214 float localmins[3];
15215 float localmaxs[3];
15218 float planes[6][4];
15221 int bih_triangles_count;
15222 int bih_triangles[256];
15223 int bih_surfaces[256];
15225 decalsystem = &ent->decalsystem;
15226 model = ent->model;
15227 if (!model || !ent->allowdecals || ent->alpha < 1 || (ent->flags & (RENDER_ADDITIVE | RENDER_NODEPTHTEST)))
15229 R_DecalSystem_Reset(&ent->decalsystem);
15233 if (!model->brush.data_leafs && !cl_decals_models.integer)
15235 if (decalsystem->model)
15236 R_DecalSystem_Reset(decalsystem);
15240 if (decalsystem->model != model)
15241 R_DecalSystem_Reset(decalsystem);
15242 decalsystem->model = model;
15244 RSurf_ActiveModelEntity(ent, false, false, false);
15246 Matrix4x4_Transform(&rsurface.inversematrix, worldorigin, localorigin);
15247 Matrix4x4_Transform3x3(&rsurface.inversematrix, worldnormal, localnormal);
15248 VectorNormalize(localnormal);
15249 localsize = worldsize*rsurface.inversematrixscale;
15250 localmins[0] = localorigin[0] - localsize;
15251 localmins[1] = localorigin[1] - localsize;
15252 localmins[2] = localorigin[2] - localsize;
15253 localmaxs[0] = localorigin[0] + localsize;
15254 localmaxs[1] = localorigin[1] + localsize;
15255 localmaxs[2] = localorigin[2] + localsize;
15257 //VectorCopy(localnormal, planes[4]);
15258 //VectorVectors(planes[4], planes[2], planes[0]);
15259 AnglesFromVectors(angles, localnormal, NULL, false);
15260 AngleVectors(angles, planes[0], planes[2], planes[4]);
15261 VectorNegate(planes[0], planes[1]);
15262 VectorNegate(planes[2], planes[3]);
15263 VectorNegate(planes[4], planes[5]);
15264 planes[0][3] = DotProduct(planes[0], localorigin) - localsize;
15265 planes[1][3] = DotProduct(planes[1], localorigin) - localsize;
15266 planes[2][3] = DotProduct(planes[2], localorigin) - localsize;
15267 planes[3][3] = DotProduct(planes[3], localorigin) - localsize;
15268 planes[4][3] = DotProduct(planes[4], localorigin) - localsize;
15269 planes[5][3] = DotProduct(planes[5], localorigin) - localsize;
15274 matrix4x4_t forwardprojection;
15275 Matrix4x4_CreateFromQuakeEntity(&forwardprojection, localorigin[0], localorigin[1], localorigin[2], angles[0], angles[1], angles[2], localsize);
15276 Matrix4x4_Invert_Simple(&projection, &forwardprojection);
15281 float projectionvector[4][3];
15282 VectorScale(planes[0], ilocalsize, projectionvector[0]);
15283 VectorScale(planes[2], ilocalsize, projectionvector[1]);
15284 VectorScale(planes[4], ilocalsize, projectionvector[2]);
15285 projectionvector[0][0] = planes[0][0] * ilocalsize;
15286 projectionvector[0][1] = planes[1][0] * ilocalsize;
15287 projectionvector[0][2] = planes[2][0] * ilocalsize;
15288 projectionvector[1][0] = planes[0][1] * ilocalsize;
15289 projectionvector[1][1] = planes[1][1] * ilocalsize;
15290 projectionvector[1][2] = planes[2][1] * ilocalsize;
15291 projectionvector[2][0] = planes[0][2] * ilocalsize;
15292 projectionvector[2][1] = planes[1][2] * ilocalsize;
15293 projectionvector[2][2] = planes[2][2] * ilocalsize;
15294 projectionvector[3][0] = -(localorigin[0]*projectionvector[0][0]+localorigin[1]*projectionvector[1][0]+localorigin[2]*projectionvector[2][0]);
15295 projectionvector[3][1] = -(localorigin[0]*projectionvector[0][1]+localorigin[1]*projectionvector[1][1]+localorigin[2]*projectionvector[2][1]);
15296 projectionvector[3][2] = -(localorigin[0]*projectionvector[0][2]+localorigin[1]*projectionvector[1][2]+localorigin[2]*projectionvector[2][2]);
15297 Matrix4x4_FromVectors(&projection, projectionvector[0], projectionvector[1], projectionvector[2], projectionvector[3]);
15301 dynamic = model->surfmesh.isanimated;
15302 numsurfacelist = model->nummodelsurfaces;
15303 surfacelist = model->sortedmodelsurfaces;
15304 surfaces = model->data_surfaces;
15307 bih_triangles_count = -1;
15310 if(model->render_bih.numleafs)
15311 bih = &model->render_bih;
15312 else if(model->collision_bih.numleafs)
15313 bih = &model->collision_bih;
15316 bih_triangles_count = BIH_GetTriangleListForBox(bih, sizeof(bih_triangles) / sizeof(*bih_triangles), bih_triangles, bih_surfaces, localmins, localmaxs);
15317 if(bih_triangles_count == 0)
15319 if(bih_triangles_count > (int) (sizeof(bih_triangles) / sizeof(*bih_triangles))) // hit too many, likely bad anyway
15321 if(bih_triangles_count > 0)
15323 for (triangleindex = 0; triangleindex < bih_triangles_count; ++triangleindex)
15325 surfaceindex = bih_surfaces[triangleindex];
15326 surface = surfaces + surfaceindex;
15327 texture = surface->texture;
15328 if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
15330 if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
15332 R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, bih_triangles[triangleindex], surfaceindex);
15337 for (surfacelistindex = 0;surfacelistindex < numsurfacelist;surfacelistindex++)
15339 surfaceindex = surfacelist[surfacelistindex];
15340 surface = surfaces + surfaceindex;
15341 // check cull box first because it rejects more than any other check
15342 if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
15344 // skip transparent surfaces
15345 texture = surface->texture;
15346 if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
15348 if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
15350 numtriangles = surface->num_triangles;
15351 for (triangleindex = 0; triangleindex < numtriangles; triangleindex++)
15352 R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, triangleindex + surface->num_firsttriangle, surfaceindex);
15357 // do not call this outside of rendering code - use R_DecalSystem_SplatEntities instead
15358 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)
15360 int renderentityindex;
15361 float worldmins[3];
15362 float worldmaxs[3];
15363 entity_render_t *ent;
15365 if (!cl_decals_newsystem.integer)
15368 worldmins[0] = worldorigin[0] - worldsize;
15369 worldmins[1] = worldorigin[1] - worldsize;
15370 worldmins[2] = worldorigin[2] - worldsize;
15371 worldmaxs[0] = worldorigin[0] + worldsize;
15372 worldmaxs[1] = worldorigin[1] + worldsize;
15373 worldmaxs[2] = worldorigin[2] + worldsize;
15375 R_DecalSystem_SplatEntity(r_refdef.scene.worldentity, worldorigin, worldnormal, r, g, b, a, s1, t1, s2, t2, worldsize, decalsequence);
15377 for (renderentityindex = 0;renderentityindex < r_refdef.scene.numentities;renderentityindex++)
15379 ent = r_refdef.scene.entities[renderentityindex];
15380 if (!BoxesOverlap(ent->mins, ent->maxs, worldmins, worldmaxs))
15383 R_DecalSystem_SplatEntity(ent, worldorigin, worldnormal, r, g, b, a, s1, t1, s2, t2, worldsize, decalsequence);
15387 typedef struct r_decalsystem_splatqueue_s
15389 vec3_t worldorigin;
15390 vec3_t worldnormal;
15396 r_decalsystem_splatqueue_t;
15398 int r_decalsystem_numqueued = 0;
15399 r_decalsystem_splatqueue_t r_decalsystem_queue[MAX_DECALSYSTEM_QUEUE];
15401 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)
15403 r_decalsystem_splatqueue_t *queue;
15405 if (!cl_decals_newsystem.integer || r_decalsystem_numqueued == MAX_DECALSYSTEM_QUEUE)
15408 queue = &r_decalsystem_queue[r_decalsystem_numqueued++];
15409 VectorCopy(worldorigin, queue->worldorigin);
15410 VectorCopy(worldnormal, queue->worldnormal);
15411 Vector4Set(queue->color, r, g, b, a);
15412 Vector4Set(queue->tcrange, s1, t1, s2, t2);
15413 queue->worldsize = worldsize;
15414 queue->decalsequence = cl.decalsequence++;
15417 static void R_DecalSystem_ApplySplatEntitiesQueue(void)
15420 r_decalsystem_splatqueue_t *queue;
15422 for (i = 0, queue = r_decalsystem_queue;i < r_decalsystem_numqueued;i++, queue++)
15423 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);
15424 r_decalsystem_numqueued = 0;
15427 extern cvar_t cl_decals_max;
15428 static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
15431 decalsystem_t *decalsystem = &ent->decalsystem;
15438 if (!decalsystem->numdecals)
15441 if (r_showsurfaces.integer)
15444 if (ent->model != decalsystem->model || ent->alpha < 1 || (ent->flags & RENDER_ADDITIVE))
15446 R_DecalSystem_Reset(decalsystem);
15450 killsequence = cl.decalsequence - max(1, cl_decals_max.integer);
15451 lifetime = cl_decals_time.value + cl_decals_fadetime.value;
15453 if (decalsystem->lastupdatetime)
15454 frametime = (cl.time - decalsystem->lastupdatetime);
15457 decalsystem->lastupdatetime = cl.time;
15458 decal = decalsystem->decals;
15459 numdecals = decalsystem->numdecals;
15461 for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
15463 if (decal->color4ub[0][3])
15465 decal->lived += frametime;
15466 if (killsequence - decal->decalsequence > 0 || decal->lived >= lifetime)
15468 memset(decal, 0, sizeof(*decal));
15469 if (decalsystem->freedecal > i)
15470 decalsystem->freedecal = i;
15474 decal = decalsystem->decals;
15475 while (numdecals > 0 && !decal[numdecals-1].color4ub[0][3])
15478 // collapse the array by shuffling the tail decals into the gaps
15481 while (decalsystem->freedecal < numdecals && decal[decalsystem->freedecal].color4ub[0][3])
15482 decalsystem->freedecal++;
15483 if (decalsystem->freedecal == numdecals)
15485 decal[decalsystem->freedecal] = decal[--numdecals];
15488 decalsystem->numdecals = numdecals;
15490 if (numdecals <= 0)
15492 // if there are no decals left, reset decalsystem
15493 R_DecalSystem_Reset(decalsystem);
15497 extern skinframe_t *decalskinframe;
15498 static void R_DrawModelDecals_Entity(entity_render_t *ent)
15501 decalsystem_t *decalsystem = &ent->decalsystem;
15510 const unsigned char *surfacevisible = ent == r_refdef.scene.worldentity ? r_refdef.viewcache.world_surfacevisible : NULL;
15513 numdecals = decalsystem->numdecals;
15517 if (r_showsurfaces.integer)
15520 if (ent->model != decalsystem->model || ent->alpha < 1 || (ent->flags & RENDER_ADDITIVE))
15522 R_DecalSystem_Reset(decalsystem);
15526 // if the model is static it doesn't matter what value we give for
15527 // wantnormals and wanttangents, so this logic uses only rules applicable
15528 // to a model, knowing that they are meaningless otherwise
15529 if (ent == r_refdef.scene.worldentity)
15530 RSurf_ActiveWorldEntity();
15532 RSurf_ActiveModelEntity(ent, false, false, false);
15534 decalsystem->lastupdatetime = cl.time;
15535 decal = decalsystem->decals;
15537 faderate = 1.0f / max(0.001f, cl_decals_fadetime.value);
15539 // update vertex positions for animated models
15540 v3f = decalsystem->vertex3f;
15541 c4f = decalsystem->color4f;
15542 t2f = decalsystem->texcoord2f;
15543 for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
15545 if (!decal->color4ub[0][3])
15548 if (surfacevisible && !surfacevisible[decal->surfaceindex])
15551 // update color values for fading decals
15552 if (decal->lived >= cl_decals_time.value)
15554 alpha = 1 - faderate * (decal->lived - cl_decals_time.value);
15555 alpha *= (1.0f/255.0f);
15558 alpha = 1.0f/255.0f;
15560 c4f[ 0] = decal->color4ub[0][0] * alpha;
15561 c4f[ 1] = decal->color4ub[0][1] * alpha;
15562 c4f[ 2] = decal->color4ub[0][2] * alpha;
15564 c4f[ 4] = decal->color4ub[1][0] * alpha;
15565 c4f[ 5] = decal->color4ub[1][1] * alpha;
15566 c4f[ 6] = decal->color4ub[1][2] * alpha;
15568 c4f[ 8] = decal->color4ub[2][0] * alpha;
15569 c4f[ 9] = decal->color4ub[2][1] * alpha;
15570 c4f[10] = decal->color4ub[2][2] * alpha;
15573 t2f[0] = decal->texcoord2f[0][0];
15574 t2f[1] = decal->texcoord2f[0][1];
15575 t2f[2] = decal->texcoord2f[1][0];
15576 t2f[3] = decal->texcoord2f[1][1];
15577 t2f[4] = decal->texcoord2f[2][0];
15578 t2f[5] = decal->texcoord2f[2][1];
15580 // update vertex positions for animated models
15581 if (decal->triangleindex >= 0 && decal->triangleindex < rsurface.modelnumtriangles)
15583 e = rsurface.modelelement3i + 3*decal->triangleindex;
15584 VectorCopy(rsurface.modelvertex3f + 3*e[0], v3f);
15585 VectorCopy(rsurface.modelvertex3f + 3*e[1], v3f + 3);
15586 VectorCopy(rsurface.modelvertex3f + 3*e[2], v3f + 6);
15590 VectorCopy(decal->vertex3f[0], v3f);
15591 VectorCopy(decal->vertex3f[1], v3f + 3);
15592 VectorCopy(decal->vertex3f[2], v3f + 6);
15595 if (r_refdef.fogenabled)
15597 alpha = RSurf_FogVertex(v3f);
15598 VectorScale(c4f, alpha, c4f);
15599 alpha = RSurf_FogVertex(v3f + 3);
15600 VectorScale(c4f + 4, alpha, c4f + 4);
15601 alpha = RSurf_FogVertex(v3f + 6);
15602 VectorScale(c4f + 8, alpha, c4f + 8);
15613 r_refdef.stats.drawndecals += numtris;
15615 // now render the decals all at once
15616 // (this assumes they all use one particle font texture!)
15617 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);
15618 // R_Mesh_ResetTextureState();
15619 R_Mesh_PrepareVertices_Generic_Arrays(numtris * 3, decalsystem->vertex3f, decalsystem->color4f, decalsystem->texcoord2f);
15620 GL_DepthMask(false);
15621 GL_DepthRange(0, 1);
15622 GL_PolygonOffset(rsurface.basepolygonfactor + r_polygonoffset_decals_factor.value, rsurface.basepolygonoffset + r_polygonoffset_decals_offset.value);
15623 GL_DepthTest(true);
15624 GL_CullFace(GL_NONE);
15625 GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
15626 R_SetupShader_Generic(decalskinframe->base, NULL, GL_MODULATE, 1);
15627 R_Mesh_Draw(0, numtris * 3, 0, numtris, decalsystem->element3i, NULL, 0, decalsystem->element3s, NULL, 0);
15631 static void R_DrawModelDecals(void)
15635 // fade faster when there are too many decals
15636 numdecals = r_refdef.scene.worldentity->decalsystem.numdecals;
15637 for (i = 0;i < r_refdef.scene.numentities;i++)
15638 numdecals += r_refdef.scene.entities[i]->decalsystem.numdecals;
15640 R_DrawModelDecals_FadeEntity(r_refdef.scene.worldentity);
15641 for (i = 0;i < r_refdef.scene.numentities;i++)
15642 if (r_refdef.scene.entities[i]->decalsystem.numdecals)
15643 R_DrawModelDecals_FadeEntity(r_refdef.scene.entities[i]);
15645 R_DecalSystem_ApplySplatEntitiesQueue();
15647 numdecals = r_refdef.scene.worldentity->decalsystem.numdecals;
15648 for (i = 0;i < r_refdef.scene.numentities;i++)
15649 numdecals += r_refdef.scene.entities[i]->decalsystem.numdecals;
15651 r_refdef.stats.totaldecals += numdecals;
15653 if (r_showsurfaces.integer)
15656 R_DrawModelDecals_Entity(r_refdef.scene.worldentity);
15658 for (i = 0;i < r_refdef.scene.numentities;i++)
15660 if (!r_refdef.viewcache.entityvisible[i])
15662 if (r_refdef.scene.entities[i]->decalsystem.numdecals)
15663 R_DrawModelDecals_Entity(r_refdef.scene.entities[i]);
15667 extern cvar_t mod_collision_bih;
15668 void R_DrawDebugModel(void)
15670 entity_render_t *ent = rsurface.entity;
15671 int i, j, k, l, flagsmask;
15672 const msurface_t *surface;
15673 dp_model_t *model = ent->model;
15676 switch(vid.renderpath)
15678 case RENDERPATH_GL11:
15679 case RENDERPATH_GL13:
15680 case RENDERPATH_GL20:
15681 case RENDERPATH_CGGL:
15683 case RENDERPATH_D3D9:
15684 //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15686 case RENDERPATH_D3D10:
15687 Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15689 case RENDERPATH_D3D11:
15690 Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15692 case RENDERPATH_SOFT:
15693 //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15695 case RENDERPATH_GLES2:
15696 //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
15700 flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL;
15702 // R_Mesh_ResetTextureState();
15703 R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
15704 GL_DepthRange(0, 1);
15705 GL_DepthTest(!r_showdisabledepthtest.integer);
15706 GL_DepthMask(false);
15707 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
15709 if (r_showcollisionbrushes.value > 0 && model->collision_bih.numleafs)
15713 qboolean cullbox = ent == r_refdef.scene.worldentity;
15714 const q3mbrush_t *brush;
15715 const bih_t *bih = &model->collision_bih;
15716 const bih_leaf_t *bihleaf;
15717 float vertex3f[3][3];
15718 GL_PolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);
15720 for (bihleafindex = 0, bihleaf = bih->leafs;bihleafindex < bih->numleafs;bihleafindex++, bihleaf++)
15722 if (cullbox && R_CullBox(bihleaf->mins, bihleaf->maxs))
15724 switch (bihleaf->type)
15727 brush = model->brush.data_brushes + bihleaf->itemindex;
15728 if (brush->colbrushf && brush->colbrushf->numtriangles)
15730 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);
15731 R_Mesh_PrepareVertices_Generic_Arrays(brush->colbrushf->numpoints, brush->colbrushf->points->v, NULL, NULL);
15732 R_Mesh_Draw(0, brush->colbrushf->numpoints, 0, brush->colbrushf->numtriangles, brush->colbrushf->elements, NULL, 0, NULL, NULL, 0);
15735 case BIH_COLLISIONTRIANGLE:
15736 triangleindex = bihleaf->itemindex;
15737 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+0], vertex3f[0]);
15738 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+1], vertex3f[1]);
15739 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+2], vertex3f[2]);
15740 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);
15741 R_Mesh_PrepareVertices_Generic_Arrays(3, vertex3f[0], NULL, NULL);
15742 R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
15744 case BIH_RENDERTRIANGLE:
15745 triangleindex = bihleaf->itemindex;
15746 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+0], vertex3f[0]);
15747 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+1], vertex3f[1]);
15748 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+2], vertex3f[2]);
15749 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);
15750 R_Mesh_PrepareVertices_Generic_Arrays(3, vertex3f[0], NULL, NULL);
15751 R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
15757 GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
15759 if (r_showtris.integer || (r_shownormals.value != 0))
15761 if (r_showdisabledepthtest.integer)
15763 GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
15764 GL_DepthMask(false);
15768 GL_BlendFunc(GL_ONE, GL_ZERO);
15769 GL_DepthMask(true);
15771 for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
15773 if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
15775 rsurface.texture = R_GetCurrentTexture(surface->texture);
15776 if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
15778 RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_NOGAPS, 1, &surface);
15779 if (r_showtris.value > 0)
15781 if (!rsurface.texture->currentlayers->depthmask)
15782 GL_Color(r_refdef.view.colorscale, 0, 0, r_showtris.value);
15783 else if (ent == r_refdef.scene.worldentity)
15784 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, r_showtris.value);
15786 GL_Color(0, r_refdef.view.colorscale, 0, r_showtris.value);
15787 R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
15788 qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
15790 qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
15793 if (r_shownormals.value < 0)
15795 qglBegin(GL_LINES);
15796 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15798 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15799 GL_Color(0, 0, r_refdef.view.colorscale, 1);
15800 qglVertex3f(v[0], v[1], v[2]);
15801 VectorMA(v, -r_shownormals.value, rsurface.batchnormal3f + l * 3, v);
15802 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15803 qglVertex3f(v[0], v[1], v[2]);
15808 if (r_shownormals.value > 0 && rsurface.batchsvector3f)
15810 qglBegin(GL_LINES);
15811 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15813 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15814 GL_Color(r_refdef.view.colorscale, 0, 0, 1);
15815 qglVertex3f(v[0], v[1], v[2]);
15816 VectorMA(v, r_shownormals.value, rsurface.batchsvector3f + l * 3, v);
15817 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15818 qglVertex3f(v[0], v[1], v[2]);
15822 qglBegin(GL_LINES);
15823 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15825 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15826 GL_Color(0, r_refdef.view.colorscale, 0, 1);
15827 qglVertex3f(v[0], v[1], v[2]);
15828 VectorMA(v, r_shownormals.value, rsurface.batchtvector3f + l * 3, v);
15829 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15830 qglVertex3f(v[0], v[1], v[2]);
15834 qglBegin(GL_LINES);
15835 for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
15837 VectorCopy(rsurface.batchvertex3f + l * 3, v);
15838 GL_Color(0, 0, r_refdef.view.colorscale, 1);
15839 qglVertex3f(v[0], v[1], v[2]);
15840 VectorMA(v, r_shownormals.value, rsurface.batchnormal3f + l * 3, v);
15841 GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
15842 qglVertex3f(v[0], v[1], v[2]);
15849 rsurface.texture = NULL;
15853 extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface);
15854 int r_maxsurfacelist = 0;
15855 const msurface_t **r_surfacelist = NULL;
15856 void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
15858 int i, j, endj, flagsmask;
15859 dp_model_t *model = r_refdef.scene.worldmodel;
15860 msurface_t *surfaces;
15861 unsigned char *update;
15862 int numsurfacelist = 0;
15866 if (r_maxsurfacelist < model->num_surfaces)
15868 r_maxsurfacelist = model->num_surfaces;
15870 Mem_Free((msurface_t**)r_surfacelist);
15871 r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist));
15874 RSurf_ActiveWorldEntity();
15876 surfaces = model->data_surfaces;
15877 update = model->brushq1.lightmapupdateflags;
15879 // update light styles on this submodel
15880 if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
15882 model_brush_lightstyleinfo_t *style;
15883 for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
15885 if (style->value != r_refdef.scene.lightstylevalue[style->style])
15887 int *list = style->surfacelist;
15888 style->value = r_refdef.scene.lightstylevalue[style->style];
15889 for (j = 0;j < style->numsurfaces;j++)
15890 update[list[j]] = true;
15895 flagsmask = skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL;
15899 R_DrawDebugModel();
15900 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
15904 rsurface.lightmaptexture = NULL;
15905 rsurface.deluxemaptexture = NULL;
15906 rsurface.uselightmaptexture = false;
15907 rsurface.texture = NULL;
15908 rsurface.rtlight = NULL;
15909 numsurfacelist = 0;
15910 // add visible surfaces to draw list
15911 for (i = 0;i < model->nummodelsurfaces;i++)
15913 j = model->sortedmodelsurfaces[i];
15914 if (r_refdef.viewcache.world_surfacevisible[j])
15915 r_surfacelist[numsurfacelist++] = surfaces + j;
15917 // update lightmaps if needed
15918 if (model->brushq1.firstrender)
15920 model->brushq1.firstrender = false;
15921 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
15923 R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j);
15927 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
15928 if (r_refdef.viewcache.world_surfacevisible[j])
15930 R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j);
15932 // don't do anything if there were no surfaces
15933 if (!numsurfacelist)
15935 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
15938 R_QueueWorldSurfaceList(numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
15939 GL_AlphaTest(false);
15941 // add to stats if desired
15942 if (r_speeds.integer && !skysurfaces && !depthonly)
15944 r_refdef.stats.world_surfaces += numsurfacelist;
15945 for (j = 0;j < numsurfacelist;j++)
15946 r_refdef.stats.world_triangles += r_surfacelist[j]->num_triangles;
15949 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
15952 void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass)
15954 int i, j, endj, flagsmask;
15955 dp_model_t *model = ent->model;
15956 msurface_t *surfaces;
15957 unsigned char *update;
15958 int numsurfacelist = 0;
15962 if (r_maxsurfacelist < model->num_surfaces)
15964 r_maxsurfacelist = model->num_surfaces;
15966 Mem_Free((msurface_t **)r_surfacelist);
15967 r_surfacelist = (const msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist));
15970 // if the model is static it doesn't matter what value we give for
15971 // wantnormals and wanttangents, so this logic uses only rules applicable
15972 // to a model, knowing that they are meaningless otherwise
15973 if (ent == r_refdef.scene.worldentity)
15974 RSurf_ActiveWorldEntity();
15975 else if (r_showsurfaces.integer && r_showsurfaces.integer != 3)
15976 RSurf_ActiveModelEntity(ent, false, false, false);
15978 RSurf_ActiveModelEntity(ent, true, true, true);
15979 else if (depthonly)
15981 switch (vid.renderpath)
15983 case RENDERPATH_GL20:
15984 case RENDERPATH_CGGL:
15985 case RENDERPATH_D3D9:
15986 case RENDERPATH_D3D10:
15987 case RENDERPATH_D3D11:
15988 case RENDERPATH_SOFT:
15989 case RENDERPATH_GLES2:
15990 RSurf_ActiveModelEntity(ent, model->wantnormals, model->wanttangents, false);
15992 case RENDERPATH_GL13:
15993 case RENDERPATH_GL11:
15994 RSurf_ActiveModelEntity(ent, model->wantnormals, false, false);
16000 switch (vid.renderpath)
16002 case RENDERPATH_GL20:
16003 case RENDERPATH_CGGL:
16004 case RENDERPATH_D3D9:
16005 case RENDERPATH_D3D10:
16006 case RENDERPATH_D3D11:
16007 case RENDERPATH_SOFT:
16008 case RENDERPATH_GLES2:
16009 RSurf_ActiveModelEntity(ent, true, true, false);
16011 case RENDERPATH_GL13:
16012 case RENDERPATH_GL11:
16013 RSurf_ActiveModelEntity(ent, true, false, false);
16018 surfaces = model->data_surfaces;
16019 update = model->brushq1.lightmapupdateflags;
16021 // update light styles
16022 if (!skysurfaces && !depthonly && !prepass && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0)
16024 model_brush_lightstyleinfo_t *style;
16025 for (i = 0, style = model->brushq1.data_lightstyleinfo;i < model->brushq1.num_lightstyles;i++, style++)
16027 if (style->value != r_refdef.scene.lightstylevalue[style->style])
16029 int *list = style->surfacelist;
16030 style->value = r_refdef.scene.lightstylevalue[style->style];
16031 for (j = 0;j < style->numsurfaces;j++)
16032 update[list[j]] = true;
16037 flagsmask = skysurfaces ? MATERIALFLAG_SKY : MATERIALFLAG_WALL;
16041 R_DrawDebugModel();
16042 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
16046 rsurface.lightmaptexture = NULL;
16047 rsurface.deluxemaptexture = NULL;
16048 rsurface.uselightmaptexture = false;
16049 rsurface.texture = NULL;
16050 rsurface.rtlight = NULL;
16051 numsurfacelist = 0;
16052 // add visible surfaces to draw list
16053 for (i = 0;i < model->nummodelsurfaces;i++)
16054 r_surfacelist[numsurfacelist++] = surfaces + model->sortedmodelsurfaces[i];
16055 // don't do anything if there were no surfaces
16056 if (!numsurfacelist)
16058 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
16061 // update lightmaps if needed
16065 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
16070 R_BuildLightMap(ent, surfaces + j);
16075 for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)
16077 R_BuildLightMap(ent, surfaces + j);
16078 R_QueueModelSurfaceList(ent, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
16079 GL_AlphaTest(false);
16081 // add to stats if desired
16082 if (r_speeds.integer && !skysurfaces && !depthonly)
16084 r_refdef.stats.entities_surfaces += numsurfacelist;
16085 for (j = 0;j < numsurfacelist;j++)
16086 r_refdef.stats.entities_triangles += r_surfacelist[j]->num_triangles;
16089 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
16092 void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass)
16094 static texture_t texture;
16095 static msurface_t surface;
16096 const msurface_t *surfacelist = &surface;
16098 // fake enough texture and surface state to render this geometry
16100 texture.update_lastrenderframe = -1; // regenerate this texture
16101 texture.basematerialflags = materialflags | MATERIALFLAG_CUSTOMSURFACE | MATERIALFLAG_WALL;
16102 texture.currentskinframe = skinframe;
16103 texture.currenttexmatrix = *texmatrix; // requires MATERIALFLAG_CUSTOMSURFACE
16104 texture.offsetmapping = OFFSETMAPPING_OFF;
16105 texture.offsetscale = 1;
16106 texture.specularscalemod = 1;
16107 texture.specularpowermod = 1;
16109 surface.texture = &texture;
16110 surface.num_triangles = numtriangles;
16111 surface.num_firsttriangle = firsttriangle;
16112 surface.num_vertices = numvertices;
16113 surface.num_firstvertex = firstvertex;
16116 rsurface.texture = R_GetCurrentTexture(surface.texture);
16117 rsurface.lightmaptexture = NULL;
16118 rsurface.deluxemaptexture = NULL;
16119 rsurface.uselightmaptexture = false;
16120 R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);
16123 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)
16125 static msurface_t surface;
16126 const msurface_t *surfacelist = &surface;
16128 // fake enough texture and surface state to render this geometry
16129 surface.texture = texture;
16130 surface.num_triangles = numtriangles;
16131 surface.num_firsttriangle = firsttriangle;
16132 surface.num_vertices = numvertices;
16133 surface.num_firstvertex = firstvertex;
16136 rsurface.texture = R_GetCurrentTexture(surface.texture);
16137 rsurface.lightmaptexture = NULL;
16138 rsurface.deluxemaptexture = NULL;
16139 rsurface.uselightmaptexture = false;
16140 R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass);