#include "ft2.h"
#include "csprogs.h"
#include "cl_video.h"
+#include "dpsoftrast.h"
+
+#ifdef SUPPORTD3D
+#include <d3d9.h>
+extern LPDIRECT3DDEVICE9 vid_d3d9dev;
+#endif
mempool_t *r_main_mempool;
rtexturepool_t *r_main_texturepool;
cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" };
+cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
+cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
+cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"};
+cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"};
cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"};
cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"};
cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
+cvar_t r_draw2d = {0, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
+
+cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"};
+cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"};
+#define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit))
+
cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
+cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
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"};
+cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
+cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
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)"};
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"};
-cvar_t r_texture_convertsRGB_2d = {0, "r_texture_convertsRGB_2d", "0", "load textures as sRGB and convert to linear for proper shading"};
-cvar_t r_texture_convertsRGB_skin = {0, "r_texture_convertsRGB_skin", "0", "load textures as sRGB and convert to linear for proper shading"};
-cvar_t r_texture_convertsRGB_cubemap = {0, "r_texture_convertsRGB_cubemap", "0", "load textures as sRGB and convert to linear for proper shading"};
-cvar_t r_texture_convertsRGB_skybox = {0, "r_texture_convertsRGB_skybox", "0", "load textures as sRGB and convert to linear for proper shading"};
-cvar_t r_texture_convertsRGB_particles = {0, "r_texture_convertsRGB_particles", "0", "load textures as sRGB and convert to linear for proper shading"};
-
cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"};
static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"};
static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"};
+cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"};
+cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"};
+cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
+cvar_t r_viewscale_fpsscaling_min = {CVAR_SAVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"};
+cvar_t r_viewscale_fpsscaling_multiply = {CVAR_SAVE, "r_viewscale_fpsscaling_multiply", "5", "adjust quality up or down by the frametime difference from 1.0/target, multiplied by this factor"};
+cvar_t r_viewscale_fpsscaling_stepsize = {CVAR_SAVE, "r_viewscale_fpsscaling_stepsize", "0.01", "smallest adjustment to hit the target framerate (this value prevents minute oscillations)"};
+cvar_t r_viewscale_fpsscaling_stepmax = {CVAR_SAVE, "r_viewscale_fpsscaling_stepmax", "1.00", "largest adjustment to hit the target framerate (this value prevents wild overshooting of the estimate)"};
+cvar_t r_viewscale_fpsscaling_target = {CVAR_SAVE, "r_viewscale_fpsscaling_target", "70", "desired framerate"};
+
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)"};
cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
+cvar_t r_glsl_offsetmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_steps", "2", "offset mapping steps (note: too high values may be not supported by your GPU)"};
cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
+cvar_t r_glsl_offsetmapping_reliefmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_steps", "10", "relief mapping steps (note: too high values may be not supported by your GPU)"};
+cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_refinesteps", "5", "relief mapping refine steps (these are a binary search executed as the last step as given by r_glsl_offsetmapping_reliefmapping_steps)"};
cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
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)"};
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)"};
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)"};
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)"};
+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)"};
+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)"};
+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)"};
+cvar_t r_glsl_postprocess_uservec4_enable = {CVAR_SAVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
cvar_t r_water = {CVAR_SAVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
cvar_t r_water_clippingplanebias = {CVAR_SAVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
cvar_t r_water_resolutionmultiplier = {CVAR_SAVE, "r_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"};
cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
+cvar_t r_water_scissormode = {0, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
+cvar_t r_water_lowquality = {0, "r_water_lowquality", "0", "special option to accelerate water rendering, 1 disables shadows and particles, 2 disables all dynamic lights"};
cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
cvar_t r_bloom_brighten = {CVAR_SAVE, "r_bloom_brighten", "2", "how bright the glow is, after subtract/power"};
cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
-cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exagerated the glow is"};
+cvar_t r_bloom_colorexponent = {CVAR_SAVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
cvar_t r_bloom_colorsubtract = {CVAR_SAVE, "r_bloom_colorsubtract", "0.125", "reduces bloom colors by a certain amount"};
cvar_t r_hdr = {CVAR_SAVE, "r_hdr", "0", "enables High Dynamic Range bloom effect (higher quality version of r_bloom)"};
cvar_t r_hdr_scenebrightness = {CVAR_SAVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
cvar_t r_hdr_glowintensity = {CVAR_SAVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
-cvar_t r_hdr_range = {CVAR_SAVE, "r_hdr_range", "4", "how much dynamic range to render bloom with (equivilant to multiplying r_bloom_brighten by this value and dividing r_bloom_colorscale by this value)"};
+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)"};
+cvar_t r_hdr_irisadaptation = {CVAR_SAVE, "r_hdr_irisadaptation", "0", "adjust scene brightness according to light intensity at player location"};
+cvar_t r_hdr_irisadaptation_multiplier = {CVAR_SAVE, "r_hdr_irisadaptation_multiplier", "2", "brightness at which value will be 1.0"};
+cvar_t r_hdr_irisadaptation_minvalue = {CVAR_SAVE, "r_hdr_irisadaptation_minvalue", "0.5", "minimum value that can result from multiplier / brightness"};
+cvar_t r_hdr_irisadaptation_maxvalue = {CVAR_SAVE, "r_hdr_irisadaptation_maxvalue", "4", "maximum value that can result from multiplier / brightness"};
+cvar_t r_hdr_irisadaptation_value = {0, "r_hdr_irisadaptation_value", "1", "current value as scenebrightness multiplier, changes continuously when irisadaptation is active"};
+cvar_t r_hdr_irisadaptation_fade = {CVAR_SAVE, "r_hdr_irisadaptation_fade", "1", "fade rate at which value adjusts"};
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"};
cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
-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"};
-cvar_t r_track_sprites_flags = {CVAR_SAVE, "r_track_sprites_flags", "1", "1: Rotate sprites accodringly, 2: Make it a continuous rotation"};
-cvar_t r_track_sprites_scalew = {CVAR_SAVE, "r_track_sprites_scalew", "1", "width scaling of tracked sprites"};
-cvar_t r_track_sprites_scaleh = {CVAR_SAVE, "r_track_sprites_scaleh", "1", "height scaling of tracked sprites"};
-cvar_t r_overheadsprites_perspective = {CVAR_SAVE, "r_overheadsprites_perspective", "0.15", "fake perspective effect for SPR_OVERHEAD sprites"};
-cvar_t r_overheadsprites_pushback = {CVAR_SAVE, "r_overheadsprites_pushback", "16", "how far to pull the SPR_OVERHEAD sprites toward the eye (used to avoid intersections with 3D models)"};
cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
+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"};
+
+cvar_t r_glsl_vertextextureblend_usebothalphas = {CVAR_SAVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer."};
-cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "1", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
+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)"};
extern cvar_t v_glslgamma;
int bloomwidth, bloomheight;
+ textype_t texturetype;
+ int viewfbo; // used to check if r_viewfbo cvar has changed
+
+ int fbo_framebuffer; // non-zero if r_viewfbo is enabled and working
+ rtexture_t *texture_framebuffercolor; // non-NULL if fbo_screen is non-zero
+ rtexture_t *texture_framebufferdepth; // non-NULL if fbo_screen is non-zero
+
int screentexturewidth, screentextureheight;
rtexture_t *texture_screen; /// \note also used for motion blur if enabled!
cubemapinfo_t;
int r_texture_numcubemaps;
-cubemapinfo_t r_texture_cubemaps[MAX_CUBEMAPS];
+cubemapinfo_t *r_texture_cubemaps[MAX_CUBEMAPS];
unsigned int r_queries[MAX_OCCLUSION_QUERIES];
unsigned int r_numqueries;
static int r_qwskincache_size;
/// vertex coordinates for a quad that covers the screen exactly
+extern const float r_screenvertex3f[12];
+extern const float r_d3dscreenvertex3f[12];
const float r_screenvertex3f[12] =
{
0, 0, 0,
1, 1, 0,
0, 1, 0
};
+const float r_d3dscreenvertex3f[12] =
+{
+ 0, 1, 0,
+ 1, 1, 0,
+ 1, 0, 0,
+ 0, 0, 0
+};
void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
{
data[1] = 128; // normal Y
data[0] = 255; // normal Z
data[3] = 128; // height
- r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
+ r_texture_blanknormalmap = R_LoadTexture2D(r_main_texturepool, "blankbump", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
data[0] = 255;
data[1] = 255;
data[2] = 255;
data[3] = 255;
- r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
+ r_texture_white = R_LoadTexture2D(r_main_texturepool, "blankwhite", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
data[0] = 128;
data[1] = 128;
data[2] = 128;
data[3] = 255;
- r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
+ r_texture_grey128 = R_LoadTexture2D(r_main_texturepool, "blankgrey128", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 255;
- r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, NULL);
+ r_texture_black = R_LoadTexture2D(r_main_texturepool, "blankblack", 1, 1, data, TEXTYPE_BGRA, TEXF_PERSISTENT, -1, NULL);
}
static void R_BuildNoTexture(void)
}
}
}
- r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, NULL);
+ r_texture_notexture = R_LoadTexture2D(r_main_texturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_BGRA, TEXF_MIPMAP | TEXF_PERSISTENT, -1, NULL);
}
static void R_BuildWhiteCube(void)
{
unsigned char data[6*1*1*4];
memset(data, 255, sizeof(data));
- r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, NULL);
+ r_texture_whitecube = R_LoadTextureCubeMap(r_main_texturepool, "whitecube", 1, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
}
static void R_BuildNormalizationCube(void)
vec_t s, t, intensity;
#define NORMSIZE 64
unsigned char *data;
- data = Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
+ data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
for (side = 0;side < 6;side++)
{
for (y = 0;y < NORMSIZE;y++)
}
}
}
- r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, NULL);
+ r_texture_normalizationcube = R_LoadTextureCubeMap(r_main_texturepool, "normalcube", NORMSIZE, data, TEXTYPE_BGRA, TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
Mem_Free(data);
}
}
if (r_texture_fogattenuation)
{
- R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, FOGWIDTH, 1);
- //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, FOGWIDTH, 1);
+ R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
+ //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, 0, FOGWIDTH, 1, 1);
}
else
{
- r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT | TEXF_ALLOWUPDATES, NULL);
- //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALLOWUPDATES, NULL);
+ r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
+ //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
}
}
inpixels = NULL;
strlcpy(r_refdef.fogheighttexturename, r_refdef.fog_height_texturename, sizeof(r_refdef.fogheighttexturename));
if (r_refdef.fogheighttexturename[0])
- inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false);
+ inpixels = loadimagepixelsbgra(r_refdef.fogheighttexturename, true, false, false, NULL);
if (!inpixels)
{
r_refdef.fog_height_tablesize = 0;
}
size = image_width;
r_refdef.fog_height_tablesize = size;
- r_refdef.fog_height_table1d = Mem_Alloc(r_main_mempool, size * 4);
- r_refdef.fog_height_table2d = Mem_Alloc(r_main_mempool, size * size * 4);
+ r_refdef.fog_height_table1d = (unsigned char *)Mem_Alloc(r_main_mempool, size * 4);
+ r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
memcpy(r_refdef.fog_height_table1d, inpixels, size * 4);
Mem_Free(inpixels);
// LordHavoc: now the magic - what is that table2d for? it is a cooked
r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
}
}
- r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, NULL);
+ r_texture_fogheighttexture = R_LoadTexture2D(r_main_texturepool, "fogheighttable", size, size, r_refdef.fog_height_table2d, TEXTYPE_BGRA, TEXF_ALPHA | TEXF_CLAMP, -1, NULL);
}
//=======================================================================================================================================================
static const char *builtinshaderstring =
-"// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
-"// written by Forest 'LordHavoc' Hale\n"
-"// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
-"\n"
-"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE) || defined(USEFOGHEIGHTTEXTURE)\n"
-"# define USEFOG\n"
-"#endif\n"
-"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"#define USELIGHTMAP\n"
-"#endif\n"
-"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n"
-"#define USEEYEVECTOR\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USEDEFERREDLIGHTMAP)\n"
-"# extension GL_ARB_texture_rectangle : enable\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAP2D\n"
-"# ifdef GL_EXT_gpu_shader4\n"
-"# extension GL_EXT_gpu_shader4 : enable\n"
-"# endif\n"
-"# ifdef GL_ARB_texture_gather\n"
-"# extension GL_ARB_texture_gather : enable\n"
-"# else\n"
-"# ifdef GL_AMD_texture_texture4\n"
-"# extension GL_AMD_texture_texture4 : enable\n"
-"# endif\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# extension GL_EXT_gpu_shader4 : enable\n"
-"#endif\n"
-"\n"
-"//#ifdef USESHADOWSAMPLER\n"
-"//# extension GL_ARB_shadow : enable\n"
-"//#endif\n"
-"\n"
-"//#ifdef __GLSL_CG_DATA_TYPES\n"
-"//# define myhalf half\n"
-"//# define myhalf2 half2\n"
-"//# define myhalf3 half3\n"
-"//# define myhalf4 half4\n"
-"//#else\n"
-"# define myhalf float\n"
-"# define myhalf2 vec2\n"
-"# define myhalf3 vec3\n"
-"# define myhalf4 vec4\n"
-"//#endif\n"
-"\n"
-"#ifdef VERTEX_SHADER\n"
-"uniform mat4 ModelViewProjectionMatrix;\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_DEPTH_OR_SHADOW\n"
-"#ifdef VERTEX_SHADER\n"
-"void main(void)\n"
-"{\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_DEPTH_ORSHADOW\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_SHOWDEPTH\n"
-"#ifdef VERTEX_SHADER\n"
-"void main(void)\n"
-"{\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-" gl_FrontColor = vec4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main(void)\n"
-"{\n"
-" gl_FragColor = gl_Color;\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_SHOWDEPTH\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_POSTPROCESS\n"
-"varying vec2 TexCoord1;\n"
-"varying vec2 TexCoord2;\n"
-"\n"
-"#ifdef VERTEX_SHADER\n"
-"void main(void)\n"
-"{\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-" TexCoord1 = gl_MultiTexCoord0.xy;\n"
-"#ifdef USEBLOOM\n"
-" TexCoord2 = gl_MultiTexCoord4.xy;\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"uniform sampler2D Texture_First;\n"
-"#ifdef USEBLOOM\n"
-"uniform sampler2D Texture_Second;\n"
-"#endif\n"
-"#ifdef USEGAMMARAMPS\n"
-"uniform sampler2D Texture_GammaRamps;\n"
-"#endif\n"
-"#ifdef USESATURATION\n"
-"uniform float Saturation;\n"
-"#endif\n"
-"#ifdef USEVIEWTINT\n"
-"uniform vec4 ViewTintColor;\n"
-"#endif\n"
-"//uncomment these if you want to use them:\n"
-"uniform vec4 UserVec1;\n"
-"uniform vec4 UserVec2;\n"
-"// uniform vec4 UserVec3;\n"
-"// uniform vec4 UserVec4;\n"
-"// uniform float ClientTime;\n"
-"uniform vec2 PixelSize;\n"
-"void main(void)\n"
-"{\n"
-" gl_FragColor = texture2D(Texture_First, TexCoord1);\n"
-"#ifdef USEBLOOM\n"
-" gl_FragColor += texture2D(Texture_Second, TexCoord2);\n"
-"#endif\n"
-"#ifdef USEVIEWTINT\n"
-" gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
-"#endif\n"
-"\n"
-"#ifdef USEPOSTPROCESSING\n"
-"// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
-"// 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"
-" float sobel = 1.0;\n"
-" // vec2 ts = textureSize(Texture_First, 0);\n"
-" // vec2 px = vec2(1/ts.x, 1/ts.y);\n"
-" vec2 px = PixelSize;\n"
-" vec3 x1 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n"
-" vec3 x2 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, 0.0)).rgb;\n"
-" vec3 x3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n"
-" vec3 x4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n"
-" vec3 x5 = texture2D(Texture_First, TexCoord1 + vec2( px.x, 0.0)).rgb;\n"
-" vec3 x6 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n"
-" vec3 y1 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n"
-" vec3 y2 = texture2D(Texture_First, TexCoord1 + vec2( 0.0,-px.y)).rgb;\n"
-" vec3 y3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n"
-" vec3 y4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n"
-" vec3 y5 = texture2D(Texture_First, TexCoord1 + vec2( 0.0, px.y)).rgb;\n"
-" vec3 y6 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n"
-" float px1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x1);\n"
-" float px2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), x2);\n"
-" float px3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x3);\n"
-" float px4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x4);\n"
-" float px5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), x5);\n"
-" float px6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x6);\n"
-" float py1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y1);\n"
-" float py2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), y2);\n"
-" float py3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y3);\n"
-" float py4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y4);\n"
-" float py5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), y5);\n"
-" float py6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y6);\n"
-" sobel = 0.25 * abs(px1 + px2 + px3 + px4 + px5 + px6) + 0.25 * abs(py1 + py2 + py3 + py4 + py5 + py6);\n"
-" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.707107, 0.707107)) * UserVec1.y;\n"
-" gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.453990, 0.891007)) * UserVec1.y;\n"
-" gl_FragColor /= (1.0 + 5.0 * UserVec1.y);\n"
-" gl_FragColor.rgb = gl_FragColor.rgb * (1.0 + UserVec2.x) + vec3(max(0.0, sobel - UserVec2.z))*UserVec2.y;\n"
-"#endif\n"
-"\n"
-"#ifdef USESATURATION\n"
-" //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
-" float y = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));\n"
-" //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
-" gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
-"#endif\n"
-"\n"
-"#ifdef USEGAMMARAMPS\n"
-" gl_FragColor.r = texture2D(Texture_GammaRamps, vec2(gl_FragColor.r, 0)).r;\n"
-" gl_FragColor.g = texture2D(Texture_GammaRamps, vec2(gl_FragColor.g, 0)).g;\n"
-" gl_FragColor.b = texture2D(Texture_GammaRamps, vec2(gl_FragColor.b, 0)).b;\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_POSTPROCESS\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_GENERIC\n"
-"#ifdef USEDIFFUSE\n"
-"varying vec2 TexCoord1;\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-"varying vec2 TexCoord2;\n"
-"#endif\n"
-"#ifdef VERTEX_SHADER\n"
-"void main(void)\n"
-"{\n"
-" gl_FrontColor = gl_Color;\n"
-"#ifdef USEDIFFUSE\n"
-" TexCoord1 = gl_MultiTexCoord0.xy;\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-" TexCoord2 = gl_MultiTexCoord1.xy;\n"
-"#endif\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"#ifdef USEDIFFUSE\n"
-"uniform sampler2D Texture_First;\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-"uniform sampler2D Texture_Second;\n"
-"#endif\n"
-"\n"
-"void main(void)\n"
-"{\n"
-" gl_FragColor = gl_Color;\n"
-"#ifdef USEDIFFUSE\n"
-" gl_FragColor *= texture2D(Texture_First, TexCoord1);\n"
-"#endif\n"
-"\n"
-"#ifdef USESPECULAR\n"
-" vec4 tex2 = texture2D(Texture_Second, TexCoord2);\n"
-"# ifdef USECOLORMAPPING\n"
-" gl_FragColor *= tex2;\n"
-"# endif\n"
-"# ifdef USEGLOW\n"
-" gl_FragColor += tex2;\n"
-"# endif\n"
-"# ifdef USEVERTEXTEXTUREBLEND\n"
-" gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
-"# endif\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_GENERIC\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_BLOOMBLUR\n"
-"varying TexCoord;\n"
-"#ifdef VERTEX_SHADER\n"
-"void main(void)\n"
-"{\n"
-" gl_FrontColor = gl_Color;\n"
-" TexCoord = gl_MultiTexCoord0.xy;\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"uniform sampler2D Texture_First;\n"
-"uniform vec4 BloomBlur_Parameters;\n"
-"\n"
-"void main(void)\n"
-"{\n"
-" int i;\n"
-" vec2 tc = TexCoord;\n"
-" vec3 color = texture2D(Texture_First, tc).rgb;\n"
-" tc += BloomBlur_Parameters.xy;\n"
-" for (i = 1;i < SAMPLES;i++)\n"
-" {\n"
-" color += texture2D(Texture_First, tc).rgb;\n"
-" tc += BloomBlur_Parameters.xy;\n"
-" }\n"
-" gl_FragColor = vec4(color * BloomBlur_Parameters.z + vec3(BloomBlur_Parameters.w), 1);\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_BLOOMBLUR\n"
-"#ifdef MODE_REFRACTION\n"
-"varying vec2 TexCoord;\n"
-"varying vec4 ModelViewProjectionPosition;\n"
-"uniform mat4 TexMatrix;\n"
-"#ifdef VERTEX_SHADER\n"
-"\n"
-"void main(void)\n"
-"{\n"
-" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-" ModelViewProjectionPosition = gl_Position;\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"uniform sampler2D Texture_Normal;\n"
-"uniform sampler2D Texture_Refraction;\n"
-"uniform sampler2D Texture_Reflection;\n"
-"\n"
-"uniform vec4 DistortScaleRefractReflect;\n"
-"uniform vec4 ScreenScaleRefractReflect;\n"
-"uniform vec4 ScreenCenterRefractReflect;\n"
-"uniform vec4 RefractColor;\n"
-"uniform vec4 ReflectColor;\n"
-"uniform float ReflectFactor;\n"
-"uniform float ReflectOffset;\n"
-"\n"
-"void main(void)\n"
-"{\n"
-" vec2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
-" //vec2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
-" vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
-" vec2 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
-" // FIXME temporary hack to detect the case that the reflection\n"
-" // gets blackened at edges due to leaving the area that contains actual\n"
-" // content.\n"
-" // Remove this 'ack once we have a better way to stop this thing from\n"
-" // 'appening.\n"
-" float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
-" gl_FragColor = texture2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_REFRACTION\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_WATER\n"
-"varying vec2 TexCoord;\n"
-"varying vec3 EyeVector;\n"
-"varying vec4 ModelViewProjectionPosition;\n"
-"#ifdef VERTEX_SHADER\n"
-"uniform vec3 EyePosition;\n"
-"uniform mat4 TexMatrix;\n"
-"\n"
-"void main(void)\n"
-"{\n"
-" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-" vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-" ModelViewProjectionPosition = gl_Position;\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"uniform sampler2D Texture_Normal;\n"
-"uniform sampler2D Texture_Refraction;\n"
-"uniform sampler2D Texture_Reflection;\n"
-"\n"
-"uniform vec4 DistortScaleRefractReflect;\n"
-"uniform vec4 ScreenScaleRefractReflect;\n"
-"uniform vec4 ScreenCenterRefractReflect;\n"
-"uniform vec4 RefractColor;\n"
-"uniform vec4 ReflectColor;\n"
-"uniform float ReflectFactor;\n"
-"uniform float ReflectOffset;\n"
-"\n"
-"void main(void)\n"
-"{\n"
-" vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
-" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
-" vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
-" //SafeScreenTexCoord = gl_FragCoord.xyxy * vec4(1.0 / 1920.0, 1.0 / 1200.0, 1.0 / 1920.0, 1.0 / 1200.0);\n"
-" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
-" // FIXME temporary hack to detect the case that the reflection\n"
-" // gets blackened at edges due to leaving the area that contains actual\n"
-" // content.\n"
-" // Remove this 'ack once we have a better way to stop this thing from\n"
-" // 'appening.\n"
-" float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
-" f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
-" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
-" gl_FragColor = mix(texture2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, texture2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_WATER\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"// common definitions between vertex shader and fragment shader:\n"
-"\n"
-"varying vec2 TexCoord;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"varying vec2 TexCoord2;\n"
-"#endif\n"
-"#ifdef USELIGHTMAP\n"
-"varying vec2 TexCoordLightmap;\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"varying vec3 CubeVector;\n"
-"#endif\n"
-"\n"
-"#if (defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)) && defined(USEDIFFUSE)\n"
-"varying vec3 LightVector;\n"
-"#endif\n"
-"\n"
-"#ifdef USEEYEVECTOR\n"
-"varying vec3 EyeVector;\n"
-"#endif\n"
-"#ifdef USEFOG\n"
-"varying vec4 EyeVectorModelSpaceFogPlaneVertexDist;\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n"
-"varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n"
-"varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n"
-"varying vec3 VectorR; // direction of R texcoord (surface normal)\n"
-"#endif\n"
-"\n"
-"#ifdef USEREFLECTION\n"
-"varying vec4 ModelViewProjectionPosition;\n"
-"#endif\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"uniform vec3 LightPosition;\n"
-"varying vec4 ModelViewPosition;\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform vec3 LightPosition;\n"
-"#endif\n"
-"uniform vec3 EyePosition;\n"
-"#ifdef MODE_LIGHTDIRECTION\n"
-"uniform vec3 LightDir;\n"
-"#endif\n"
-"uniform vec4 FogPlane;\n"
-"\n"
-"#ifdef USESHADOWMAPORTHO\n"
-"varying vec3 ShadowMapTC;\n"
-"#endif\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"// 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"
-"\n"
-"// fragment shader specific:\n"
-"#ifdef FRAGMENT_SHADER\n"
-"\n"
-"uniform sampler2D Texture_Normal;\n"
-"uniform sampler2D Texture_Color;\n"
-"uniform sampler2D Texture_Gloss;\n"
-"#ifdef USEGLOW\n"
-"uniform sampler2D Texture_Glow;\n"
-"#endif\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform sampler2D Texture_SecondaryNormal;\n"
-"uniform sampler2D Texture_SecondaryColor;\n"
-"uniform sampler2D Texture_SecondaryGloss;\n"
-"#ifdef USEGLOW\n"
-"uniform sampler2D Texture_SecondaryGlow;\n"
-"#endif\n"
-"#endif\n"
-"#ifdef USECOLORMAPPING\n"
-"uniform sampler2D Texture_Pants;\n"
-"uniform sampler2D Texture_Shirt;\n"
-"#endif\n"
-"#ifdef USEFOG\n"
-"#ifdef USEFOGHEIGHTTEXTURE\n"
-"uniform sampler2D Texture_FogHeightTexture;\n"
-"#endif\n"
-"uniform sampler2D Texture_FogMask;\n"
-"#endif\n"
-"#ifdef USELIGHTMAP\n"
-"uniform sampler2D Texture_Lightmap;\n"
-"#endif\n"
-"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"uniform sampler2D Texture_Deluxemap;\n"
-"#endif\n"
-"#ifdef USEREFLECTION\n"
-"uniform sampler2D Texture_Reflection;\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"uniform sampler2D Texture_ScreenDepth;\n"
-"uniform sampler2D Texture_ScreenNormalMap;\n"
-"#endif\n"
-"#ifdef USEDEFERREDLIGHTMAP\n"
-"uniform sampler2D Texture_ScreenDiffuse;\n"
-"uniform sampler2D Texture_ScreenSpecular;\n"
-"#endif\n"
-"\n"
-"uniform myhalf3 Color_Pants;\n"
-"uniform myhalf3 Color_Shirt;\n"
-"uniform myhalf3 FogColor;\n"
-"\n"
-"#ifdef USEFOG\n"
-"uniform float FogRangeRecip;\n"
-"uniform float FogPlaneViewDist;\n"
-"uniform float FogHeightFade;\n"
-"vec3 FogVertex(vec3 surfacecolor)\n"
-"{\n"
-" vec3 EyeVectorModelSpace = EyeVectorModelSpaceFogPlaneVertexDist.xyz;\n"
-" float FogPlaneVertexDist = EyeVectorModelSpaceFogPlaneVertexDist.w;\n"
-" float fogfrac;\n"
-"#ifdef USEFOGHEIGHTTEXTURE\n"
-" vec4 fogheightpixel = texture2D(Texture_FogHeightTexture, vec2(1,1) + vec2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n"
-" fogfrac = fogheightpixel.a;\n"
-" return mix(fogheightpixel.rgb * FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
-"#else\n"
-"# ifdef USEFOGOUTSIDE\n"
-" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
-"# else\n"
-" fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
-"# endif\n"
-" return mix(FogColor, surfacecolor, texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef USEOFFSETMAPPING\n"
-"uniform float OffsetMapping_Scale;\n"
-"vec2 OffsetMapping(vec2 TexCoord)\n"
-"{\n"
-"#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
-" // 14 sample relief mapping: linear search and then binary search\n"
-" // this basically steps forward a small amount repeatedly until it finds\n"
-" // itself inside solid, then jitters forward and back using decreasing\n"
-" // amounts to find the impact\n"
-" //vec3 OffsetVector = vec3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1), -1);\n"
-" //vec3 OffsetVector = vec3(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
-" vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1), -1);\n"
-" vec3 RT = vec3(TexCoord, 1);\n"
-" OffsetVector *= 0.1;\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n"
-" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n"
-" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n"
-" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n"
-" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
-" return RT.xy;\n"
-"#else\n"
-" // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
-" // this basically moves forward the full distance, and then backs up based\n"
-" // on height of samples\n"
-" //vec2 OffsetVector = vec2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * vec2(-1, 1));\n"
-" //vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1));\n"
-" vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1));\n"
-" TexCoord += OffsetVector;\n"
-" OffsetVector *= 0.333;\n"
-" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
-" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
-" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
-" return TexCoord;\n"
-"#endif\n"
-"}\n"
-"#endif // USEOFFSETMAPPING\n"
-"\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
-"uniform sampler2D Texture_Attenuation;\n"
-"uniform samplerCube Texture_Cube;\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
-"\n"
-"#ifdef USESHADOWMAPRECT\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform sampler2DRectShadow Texture_ShadowMapRect;\n"
-"# else\n"
-"uniform sampler2DRect Texture_ShadowMapRect;\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAP2D\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform sampler2DShadow Texture_ShadowMap2D;\n"
-"# else\n"
-"uniform sampler2D Texture_ShadowMap2D;\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-"uniform samplerCube Texture_CubeProjection;\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerCubeShadow Texture_ShadowMapCube;\n"
-"# else\n"
-"uniform samplerCube Texture_ShadowMapCube;\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
-"uniform vec2 ShadowMap_TextureScale;\n"
-"uniform vec4 ShadowMap_Parameters;\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
-"# ifdef USESHADOWMAPORTHO\n"
-"# define GetShadowMapTC2D(dir) (min(dir, ShadowMap_Parameters.xyz))\n"
-"# else\n"
-"# ifdef USESHADOWMAPVSDCT\n"
-"vec3 GetShadowMapTC2D(vec3 dir)\n"
-"{\n"
-" vec3 adir = abs(dir);\n"
-" vec2 aparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n"
-" vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
-" return vec3(mix(dir.xy, dir.zz, proj.xy) * aparams.x + proj.zw * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
-"}\n"
-"# else\n"
-"vec3 GetShadowMapTC2D(vec3 dir)\n"
-"{\n"
-" vec3 adir = abs(dir);\n"
-" float ma = adir.z;\n"
-" vec4 proj = vec4(dir, 2.5);\n"
-" if (adir.x > ma) { ma = adir.x; proj = vec4(dir.zyx, 0.5); }\n"
-" if (adir.y > ma) { ma = adir.y; proj = vec4(dir.xzy, 1.5); }\n"
-" vec2 aparams = ShadowMap_Parameters.xy / ma;\n"
-" 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"
-"}\n"
-"# endif\n"
-"# endif\n"
-"#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
-"\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"vec4 GetShadowMapTCCube(vec3 dir)\n"
-"{\n"
-" vec3 adir = abs(dir);\n"
-" return vec4(dir, ShadowMap_Parameters.w + ShadowMap_Parameters.y / max(max(adir.x, adir.y), adir.z));\n"
-"}\n"
-"#endif\n"
-"\n"
-"# ifdef USESHADOWMAPRECT\n"
-"float ShadowMapCompare(vec3 dir)\n"
-"{\n"
-" vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
-" float f;\n"
-"# ifdef USESHADOWSAMPLER\n"
-"\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + vec3(x, y, 0.0)).r\n"
-" 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"
-"# else\n"
-" f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
-"# endif\n"
-"\n"
-"# else\n"
-"\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# if USESHADOWMAPPCF > 1\n"
-"# define texval(x, y) texture2DRect(Texture_ShadowMapRect, center + vec2(x, y)).r\n"
-" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-" 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"
-" 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"
-" 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"
-" 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"
-" vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
-" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
-"# else\n"
-"# define texval(x, y) texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(x, y)).r\n"
-" vec2 offset = fract(shadowmaptc.xy);\n"
-" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-" vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
-" vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
-" vec3 cols = row2 + mix(row1, row3, offset.y);\n"
-" f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
-"# endif\n"
-"# else\n"
-" f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
-"# endif\n"
-"\n"
-"# endif\n"
-"# ifdef USESHADOWMAPORTHO\n"
-" return mix(ShadowMap_Parameters.w, 1.0, f);\n"
-"# else\n"
-" return f;\n"
-"# endif\n"
-"}\n"
-"# endif\n"
-"\n"
-"# ifdef USESHADOWMAP2D\n"
-"float ShadowMapCompare(vec3 dir)\n"
-"{\n"
-" vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
-" float f;\n"
-"\n"
-"# ifdef USESHADOWSAMPLER\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r \n"
-" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
-" 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"
-"# else\n"
-" f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
-"# endif\n"
-"# else\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
-"# ifdef GL_ARB_texture_gather\n"
-"# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec2(x, y))\n"
-"# else\n"
-"# define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale)\n"
-"# endif\n"
-" vec2 offset = fract(shadowmaptc.xy - 0.5), center = (shadowmaptc.xy - offset)*ShadowMap_TextureScale;\n"
-"# if USESHADOWMAPPCF > 1\n"
-" vec4 group1 = step(shadowmaptc.z, texval(-2.0, -2.0));\n"
-" vec4 group2 = step(shadowmaptc.z, texval( 0.0, -2.0));\n"
-" vec4 group3 = step(shadowmaptc.z, texval( 2.0, -2.0));\n"
-" vec4 group4 = step(shadowmaptc.z, texval(-2.0, 0.0));\n"
-" vec4 group5 = step(shadowmaptc.z, texval( 0.0, 0.0));\n"
-" vec4 group6 = step(shadowmaptc.z, texval( 2.0, 0.0));\n"
-" vec4 group7 = step(shadowmaptc.z, texval(-2.0, 2.0));\n"
-" vec4 group8 = step(shadowmaptc.z, texval( 0.0, 2.0));\n"
-" vec4 group9 = step(shadowmaptc.z, texval( 2.0, 2.0));\n"
-" vec4 locols = vec4(group1.ab, group3.ab);\n"
-" vec4 hicols = vec4(group7.rg, group9.rg);\n"
-" locols.yz += group2.ab;\n"
-" hicols.yz += group8.rg;\n"
-" vec4 midcols = vec4(group1.rg, group3.rg) + vec4(group7.ab, group9.ab) +\n"
-" vec4(group4.rg, group6.rg) + vec4(group4.ab, group6.ab) +\n"
-" mix(locols, hicols, offset.y);\n"
-" vec4 cols = group5 + vec4(group2.rg, group8.ab);\n"
-" cols.xyz += mix(midcols.xyz, midcols.yzw, offset.x);\n"
-" f = dot(cols, vec4(1.0/25.0));\n"
-"# else\n"
-" vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
-" vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
-" vec4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
-" vec4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
-" vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
-" mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
-" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
-"# endif\n"
-"# else\n"
-"# ifdef GL_EXT_gpu_shader4\n"
-"# define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n"
-"# else\n"
-"# define texval(x, y) texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r \n"
-"# endif\n"
-"# if USESHADOWMAPPCF > 1\n"
-" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-" center *= ShadowMap_TextureScale;\n"
-" 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"
-" 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"
-" 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"
-" 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"
-" vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
-" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
-"# else\n"
-" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
-" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-" vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
-" vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
-" vec3 cols = row2 + mix(row1, row3, offset.y);\n"
-" f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
-"# endif\n"
-"# endif\n"
-"# else\n"
-" f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
-"# endif\n"
-"# endif\n"
-"# ifdef USESHADOWMAPORTHO\n"
-" return mix(ShadowMap_Parameters.w, 1.0, f);\n"
-"# else\n"
-" return f;\n"
-"# endif\n"
-"}\n"
-"# endif\n"
-"\n"
-"# ifdef USESHADOWMAPCUBE\n"
-"float ShadowMapCompare(vec3 dir)\n"
-"{\n"
-" // apply depth texture cubemap as light filter\n"
-" vec4 shadowmaptc = GetShadowMapTCCube(dir);\n"
-" float f;\n"
-"# ifdef USESHADOWSAMPLER\n"
-" f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
-"# else\n"
-" f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
-"# endif\n"
-" return f;\n"
-"}\n"
-"# endif\n"
-"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
-"#endif // FRAGMENT_SHADER\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_DEFERREDGEOMETRY\n"
-"#ifdef VERTEX_SHADER\n"
-"uniform mat4 TexMatrix;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform mat4 BackgroundTexMatrix;\n"
-"#endif\n"
-"uniform mat4 ModelViewMatrix;\n"
-"void main(void)\n"
-"{\n"
-" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" gl_FrontColor = gl_Color;\n"
-" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
-"#endif\n"
-"\n"
-" // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEOFFSETMAPPING\n"
-" vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-" VectorS = (ModelViewMatrix * vec4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
-" VectorT = (ModelViewMatrix * vec4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
-" VectorR = (ModelViewMatrix * vec4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main(void)\n"
-"{\n"
-"#ifdef USEOFFSETMAPPING\n"
-" // apply offsetmapping\n"
-" vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
-"#define TexCoord TexCoordOffset\n"
-"#endif\n"
-"\n"
-"#ifdef USEALPHAKILL\n"
-" if (texture2D(Texture_Color, TexCoord).a < 0.5)\n"
-" discard;\n"
-"#endif\n"
-"\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" float alpha = texture2D(Texture_Color, TexCoord).a;\n"
-" float terrainblend = clamp(float(gl_Color.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
-" //float terrainblend = min(float(gl_Color.a) * alpha * 2.0, float(1.0));\n"
-" //float terrainblend = float(gl_Color.a) * alpha > 0.5;\n"
-"#endif\n"
-"\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(texture2D(Texture_Normal, TexCoord)), terrainblend) - vec3(0.5, 0.5, 0.5);\n"
-" float a = mix(texture2D(Texture_SecondaryGloss, TexCoord2).a, texture2D(Texture_Gloss, TexCoord).a, terrainblend);\n"
-"#else\n"
-" vec3 surfacenormal = vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5, 0.5, 0.5);\n"
-" float a = texture2D(Texture_Gloss, TexCoord).a;\n"
-"#endif\n"
-"\n"
-" gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), a);\n"
-"}\n"
-"#endif // FRAGMENT_SHADER\n"
-"#else // !MODE_DEFERREDGEOMETRY\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"#ifdef VERTEX_SHADER\n"
-"uniform mat4 ModelViewMatrix;\n"
-"void main(void)\n"
-"{\n"
-" ModelViewPosition = ModelViewMatrix * gl_Vertex;\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"uniform mat4 ViewToLight;\n"
-"// ScreenToDepth = vec2(Far / (Far - Near), Far * Near / (Near - Far));\n"
-"uniform vec2 ScreenToDepth;\n"
-"uniform myhalf3 DeferredColor_Ambient;\n"
-"uniform myhalf3 DeferredColor_Diffuse;\n"
-"#ifdef USESPECULAR\n"
-"uniform myhalf3 DeferredColor_Specular;\n"
-"uniform myhalf SpecularPower;\n"
-"#endif\n"
-"uniform myhalf2 PixelToScreenTexCoord;\n"
-"void main(void)\n"
-"{\n"
-" // calculate viewspace pixel position\n"
-" vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
-" vec3 position;\n"
-" position.z = ScreenToDepth.y / (texture2D(Texture_ScreenDepth, ScreenTexCoord).r + ScreenToDepth.x);\n"
-" position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
-" // decode viewspace pixel normal\n"
-" myhalf4 normalmap = texture2D(Texture_ScreenNormalMap, ScreenTexCoord);\n"
-" myhalf3 surfacenormal = normalize(normalmap.rgb - myhalf3(0.5,0.5,0.5));\n"
-" // surfacenormal = pixel normal in viewspace\n"
-" // LightVector = pixel to light in viewspace\n"
-" // CubeVector = position in lightspace\n"
-" // eyevector = pixel to view in viewspace\n"
-" vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n"
-" myhalf fade = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
-"#ifdef USEDIFFUSE\n"
-" // calculate diffuse shading\n"
-" myhalf3 lightnormal = myhalf3(normalize(LightPosition - position));\n"
-" myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-" // calculate directional shading\n"
-" vec3 eyevector = position * -1.0;\n"
-"# ifdef USEEXACTSPECULARMATH\n"
-" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a);\n"
-"# else\n"
-" myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(eyevector)));\n"
-" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a);\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
-" fade *= ShadowMapCompare(CubeVector);\n"
-"#endif\n"
-"\n"
-"#ifdef USEDIFFUSE\n"
-" gl_FragData[0] = vec4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
-"#else\n"
-" gl_FragData[0] = vec4(DeferredColor_Ambient * fade, 1.0);\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-" gl_FragData[1] = vec4(DeferredColor_Specular * (specular * fade), 1.0);\n"
-"#else\n"
-" gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0);\n"
-"#endif\n"
-"\n"
-"# ifdef USECUBEFILTER\n"
-" vec3 cubecolor = textureCube(Texture_Cube, CubeVector).rgb;\n"
-" gl_FragData[0].rgb *= cubecolor;\n"
-" gl_FragData[1].rgb *= cubecolor;\n"
-"# endif\n"
-"}\n"
-"#endif // FRAGMENT_SHADER\n"
-"#else // !MODE_DEFERREDLIGHTSOURCE\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef VERTEX_SHADER\n"
-"uniform mat4 TexMatrix;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform mat4 BackgroundTexMatrix;\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform mat4 ModelToLight;\n"
-"#endif\n"
-"#ifdef USESHADOWMAPORTHO\n"
-"uniform mat4 ShadowMapMatrix;\n"
-"#endif\n"
-"void main(void)\n"
-"{\n"
-"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
-" gl_FrontColor = gl_Color;\n"
-"#endif\n"
-" // copy the surface texcoord\n"
-" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
-"#endif\n"
-"#ifdef USELIGHTMAP\n"
-" TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-" // transform vertex position into light attenuation/cubemap space\n"
-" // (-1 to +1 across the light box)\n"
-" CubeVector = vec3(ModelToLight * gl_Vertex);\n"
-"\n"
-"# ifdef USEDIFFUSE\n"
-" // transform unnormalized light direction into tangent space\n"
-" // (we use unnormalized to ensure that it interpolates correctly and then\n"
-" // normalize it per pixel)\n"
-" vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
-" LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
-" LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
-" LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
-" LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
-" LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
-" LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-" // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEEYEVECTOR\n"
-" vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-"#ifdef USEFOG\n"
-" EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
-" EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(USEREFLECTCUBE)\n"
-" VectorS = gl_MultiTexCoord1.xyz;\n"
-" VectorT = gl_MultiTexCoord2.xyz;\n"
-" VectorR = gl_MultiTexCoord3.xyz;\n"
-"#endif\n"
-"\n"
-" // transform vertex to camera space, using ftransform to match non-VS rendering\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"\n"
-"#ifdef USESHADOWMAPORTHO\n"
-" ShadowMapTC = vec3(ShadowMapMatrix * gl_Position);\n"
-"#endif\n"
-"\n"
-"#ifdef USEREFLECTION\n"
-" ModelViewProjectionPosition = gl_Position;\n"
-"#endif\n"
-"}\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"#ifdef USEDEFERREDLIGHTMAP\n"
-"uniform myhalf2 PixelToScreenTexCoord;\n"
-"uniform myhalf3 DeferredMod_Diffuse;\n"
-"uniform myhalf3 DeferredMod_Specular;\n"
-"#endif\n"
-"uniform myhalf3 Color_Ambient;\n"
-"uniform myhalf3 Color_Diffuse;\n"
-"uniform myhalf3 Color_Specular;\n"
-"uniform myhalf SpecularPower;\n"
-"#ifdef USEGLOW\n"
-"uniform myhalf3 Color_Glow;\n"
-"#endif\n"
-"uniform myhalf Alpha;\n"
-"#ifdef USEREFLECTION\n"
-"uniform vec4 DistortScaleRefractReflect;\n"
-"uniform vec4 ScreenScaleRefractReflect;\n"
-"uniform vec4 ScreenCenterRefractReflect;\n"
-"uniform myhalf4 ReflectColor;\n"
-"#endif\n"
-"#ifdef USEREFLECTCUBE\n"
-"uniform mat4 ModelToReflectCube;\n"
-"uniform sampler2D Texture_ReflectMask;\n"
-"uniform samplerCube Texture_ReflectCube;\n"
-"#endif\n"
-"#ifdef MODE_LIGHTDIRECTION\n"
-"uniform myhalf3 LightColor;\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform myhalf3 LightColor;\n"
-"#endif\n"
-"void main(void)\n"
-"{\n"
-"#ifdef USEOFFSETMAPPING\n"
-" // apply offsetmapping\n"
-" vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
-"#define TexCoord TexCoordOffset\n"
-"#endif\n"
-"\n"
-" // combine the diffuse textures (base, pants, shirt)\n"
-" myhalf4 color = myhalf4(texture2D(Texture_Color, TexCoord));\n"
-"#ifdef USEALPHAKILL\n"
-" if (color.a < 0.5)\n"
-" discard;\n"
-"#endif\n"
-" color.a *= Alpha;\n"
-"#ifdef USECOLORMAPPING\n"
-" color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
-"#endif\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n"
-" //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n"
-" //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n"
-" color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord2)), color.rgb, terrainblend);\n"
-" color.a = 1.0;\n"
-" //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n"
-"#endif\n"
-"\n"
-" // get the surface normal\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n"
-"#else\n"
-" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n"
-"#endif\n"
-"\n"
-" // get the material colors\n"
-" myhalf3 diffusetex = color.rgb;\n"
-"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
-"# ifdef USEVERTEXTEXTUREBLEND\n"
-" myhalf4 glosstex = mix(myhalf4(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf4(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n"
-"# else\n"
-" myhalf4 glosstex = myhalf4(texture2D(Texture_Gloss, TexCoord));\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USEREFLECTCUBE\n"
-" vec3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n"
-" vec3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n"
-" vec3 ReflectCubeTexCoord = vec3(ModelToReflectCube * vec4(ModelReflectVector, 0));\n"
-" diffusetex += myhalf3(texture2D(Texture_ReflectMask, TexCoord)) * myhalf3(textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n"
-"#endif\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-" // light source\n"
-"#ifdef USEDIFFUSE\n"
-" myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
-" myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
-" color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
-"#ifdef USESPECULAR\n"
-"#ifdef USEEXACTSPECULARMATH\n"
-" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
-"#else\n"
-" myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
-" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
-"#endif\n"
-" color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
-"#endif\n"
-"#else\n"
-" color.rgb = diffusetex * Color_Ambient;\n"
-"#endif\n"
-" color.rgb *= LightColor;\n"
-" color.rgb *= myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
-" color.rgb *= ShadowMapCompare(CubeVector);\n"
-"#endif\n"
-"# ifdef USECUBEFILTER\n"
-" color.rgb *= myhalf3(textureCube(Texture_Cube, CubeVector));\n"
-"# endif\n"
-"#endif // MODE_LIGHTSOURCE\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_LIGHTDIRECTION\n"
-"#define SHADING\n"
-"#ifdef USEDIFFUSE\n"
-" myhalf3 lightnormal = myhalf3(normalize(LightVector));\n"
-"#endif\n"
-"#define lightcolor LightColor\n"
-"#endif // MODE_LIGHTDIRECTION\n"
-"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-"#define SHADING\n"
-" // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
-" myhalf3 lightnormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
-" myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
-" // convert modelspace light vector to tangentspace\n"
-" myhalf3 lightnormal;\n"
-" lightnormal.x = dot(lightnormal_modelspace, myhalf3(VectorS));\n"
-" lightnormal.y = dot(lightnormal_modelspace, myhalf3(VectorT));\n"
-" lightnormal.z = dot(lightnormal_modelspace, myhalf3(VectorR));\n"
-" // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
-" // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
-" // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
-" // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
-" // to map the luxels to coordinates on the draw surfaces), which also causes\n"
-" // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
-" // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
-" // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
-" // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
-" lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
-"#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-"#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
-"#define SHADING\n"
-" // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
-" myhalf3 lightnormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n"
-" myhalf3 lightcolor = myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap));\n"
-"#endif\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_LIGHTMAP\n"
-" color.rgb = diffusetex * (Color_Ambient + myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
-"#endif // MODE_LIGHTMAP\n"
-"#ifdef MODE_VERTEXCOLOR\n"
-" color.rgb = diffusetex * (Color_Ambient + myhalf3(gl_Color.rgb) * Color_Diffuse);\n"
-"#endif // MODE_VERTEXCOLOR\n"
-"#ifdef MODE_FLATCOLOR\n"
-" color.rgb = diffusetex * Color_Ambient;\n"
-"#endif // MODE_FLATCOLOR\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef SHADING\n"
-"# ifdef USEDIFFUSE\n"
-" myhalf diffuse = myhalf(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
-"# ifdef USESPECULAR\n"
-"# ifdef USEEXACTSPECULARMATH\n"
-" myhalf specular = pow(myhalf(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
-"# else\n"
-" myhalf3 specularnormal = normalize(lightnormal + myhalf3(normalize(EyeVector)));\n"
-" myhalf specular = pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
-"# endif\n"
-" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
-"# else\n"
-" color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
-"# endif\n"
-"# else\n"
-" color.rgb = diffusetex * Color_Ambient;\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPORTHO\n"
-" color.rgb *= ShadowMapCompare(ShadowMapTC);\n"
-"#endif\n"
-"\n"
-"#ifdef USEDEFERREDLIGHTMAP\n"
-" vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n"
-" color.rgb += diffusetex * myhalf3(texture2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n"
-" color.rgb += glosstex.rgb * myhalf3(texture2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n"
-"#endif\n"
-"\n"
-"#ifdef USEGLOW\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
-"#else\n"
-" color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
-"#endif\n"
-"#endif\n"
-"\n"
-"#ifdef USEFOG\n"
-" color.rgb = FogVertex(color.rgb);\n"
-"#endif\n"
-"\n"
-" // 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"
-"#ifdef USEREFLECTION\n"
-" vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
-" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
-" vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
-" vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
-" // FIXME temporary hack to detect the case that the reflection\n"
-" // gets blackened at edges due to leaving the area that contains actual\n"
-" // content.\n"
-" // Remove this 'ack once we have a better way to stop this thing from\n"
-" // 'appening.\n"
-" float f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord + vec2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
-" color.rgb = mix(color.rgb, myhalf3(texture2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
-"#endif\n"
-"\n"
-" gl_FragColor = vec4(color);\n"
-"}\n"
-"#endif // FRAGMENT_SHADER\n"
-"\n"
-"#endif // !MODE_DEFERREDLIGHTSOURCE\n"
-"#endif // !MODE_DEFERREDGEOMETRY\n"
-"#endif // !MODE_WATER\n"
-"#endif // !MODE_REFRACTION\n"
-"#endif // !MODE_BLOOMBLUR\n"
-"#endif // !MODE_GENERIC\n"
-"#endif // !MODE_POSTPROCESS\n"
-"#endif // !MODE_SHOWDEPTH\n"
-"#endif // !MODE_DEPTH_OR_SHADOW\n"
+#include "shader_glsl.h"
;
-/*
-=========================================================================================================================================================
-
-
-
-=========================================================================================================================================================
-
-
-
-=========================================================================================================================================================
-
-
-
-=========================================================================================================================================================
-
-
-
-=========================================================================================================================================================
-
-
-
-=========================================================================================================================================================
-
-
-
-=========================================================================================================================================================
-*/
-
-const char *builtincgshaderstring =
-"// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
-"// written by Forest 'LordHavoc' Hale\n"
-"// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
-"\n"
-"// FIXME: we need to get rid of ModelViewProjectionPosition to make room for the texcoord for this\n"
-"#if defined(USEREFLECTION)\n"
-"#undef USESHADOWMAPORTHO\n"
-"#endif\n"
-"\n"
-"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE) || defined(USEFOGHEIGHTTEXTURE)\n"
-"# define USEFOG\n"
-"#endif\n"
-"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"#define USELIGHTMAP\n"
-"#endif\n"
-"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n"
-"#define USEEYEVECTOR\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"#define texDepth2D(tex,texcoord) tex2D(tex,texcoord).r\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_DEPTH_OR_SHADOW\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"out float4 gl_Position : POSITION\n"
-")\n"
-"{\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_DEPTH_ORSHADOW\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_SHOWDEPTH\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"out float4 gl_Position : POSITION,\n"
-"out float4 gl_FrontColor : COLOR0\n"
-")\n"
-"{\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-" gl_FrontColor = float4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_FrontColor : COLOR0,\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" gl_FragColor = gl_FrontColor;\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_SHOWDEPTH\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_POSTPROCESS\n"
-"\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
-"float4 gl_MultiTexCoord1 : TEXCOORD4,\n"
-"out float4 gl_Position : POSITION,\n"
-"out float2 TexCoord1 : TEXCOORD0,\n"
-"out float2 TexCoord2 : TEXCOORD1\n"
-")\n"
-"{\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-" TexCoord1 = gl_MultiTexCoord0.xy;\n"
-"#ifdef USEBLOOM\n"
-" TexCoord2 = gl_MultiTexCoord1.xy;\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main\n"
-"(\n"
-"float2 TexCoord1 : TEXCOORD0,\n"
-"float2 TexCoord2 : TEXCOORD1,\n"
-"uniform sampler2D Texture_First,\n"
-"#ifdef USEBLOOM\n"
-"uniform sampler2D Texture_Second,\n"
-"#endif\n"
-"#ifdef USEGAMMARAMPS\n"
-"uniform sampler2D Texture_GammaRamps,\n"
-"#endif\n"
-"#ifdef USESATURATION\n"
-"uniform float Saturation,\n"
-"#endif\n"
-"#ifdef USEVIEWTINT\n"
-"uniform float4 ViewTintColor,\n"
-"#endif\n"
-"uniform float4 UserVec1,\n"
-"uniform float4 UserVec2,\n"
-"uniform float4 UserVec3,\n"
-"uniform float4 UserVec4,\n"
-"uniform float ClientTime,\n"
-"uniform float2 PixelSize,\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" gl_FragColor = tex2D(Texture_First, TexCoord1);\n"
-"#ifdef USEBLOOM\n"
-" gl_FragColor += tex2D(Texture_Second, TexCoord2);\n"
-"#endif\n"
-"#ifdef USEVIEWTINT\n"
-" gl_FragColor = lerp(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
-"#endif\n"
-"\n"
-"#ifdef USEPOSTPROCESSING\n"
-"// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
-"// 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"
-" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.987688, -0.156434)) * UserVec1.y;\n"
-" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.156434, -0.891007)) * UserVec1.y;\n"
-" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.891007, -0.453990)) * UserVec1.y;\n"
-" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.707107, 0.707107)) * UserVec1.y;\n"
-" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.453990, 0.891007)) * UserVec1.y;\n"
-" gl_FragColor /= (1 + 5 * UserVec1.y);\n"
-"#endif\n"
-"\n"
-"#ifdef USESATURATION\n"
-" //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
-" float y = dot(gl_FragColor.rgb, float3(0.299, 0.587, 0.114));\n"
-" //gl_FragColor = float3(y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
-" gl_FragColor.rgb = lerp(float3(y), gl_FragColor.rgb, Saturation);\n"
-"#endif\n"
-"\n"
-"#ifdef USEGAMMARAMPS\n"
-" gl_FragColor.r = tex2D(Texture_GammaRamps, float2(gl_FragColor.r, 0)).r;\n"
-" gl_FragColor.g = tex2D(Texture_GammaRamps, float2(gl_FragColor.g, 0)).g;\n"
-" gl_FragColor.b = tex2D(Texture_GammaRamps, float2(gl_FragColor.b, 0)).b;\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_POSTPROCESS\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_GENERIC\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"float4 gl_Color : COLOR0,\n"
-"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
-"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
-"out float4 gl_Position : POSITION,\n"
-"out float4 gl_FrontColor : COLOR,\n"
-"out float2 TexCoord1 : TEXCOORD0,\n"
-"out float2 TexCoord2 : TEXCOORD1\n"
-")\n"
-"{\n"
-" gl_FrontColor = gl_Color;\n"
-"#ifdef USEDIFFUSE\n"
-" TexCoord1 = gl_MultiTexCoord0.xy;\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-" TexCoord2 = gl_MultiTexCoord1.xy;\n"
-"#endif\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"\n"
-"void main\n"
-"(\n"
-"float4 gl_FrontColor : COLOR,\n"
-"float2 TexCoord1 : TEXCOORD0,\n"
-"float2 TexCoord2 : TEXCOORD1,\n"
-"#ifdef USEDIFFUSE\n"
-"uniform sampler2D Texture_First,\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-"uniform sampler2D Texture_Second,\n"
-"#endif\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" gl_FragColor = gl_FrontColor;\n"
-"#ifdef USEDIFFUSE\n"
-" gl_FragColor *= tex2D(Texture_First, TexCoord1);\n"
-"#endif\n"
-"\n"
-"#ifdef USESPECULAR\n"
-" float4 tex2 = tex2D(Texture_Second, TexCoord2);\n"
-"# ifdef USECOLORMAPPING\n"
-" gl_FragColor *= tex2;\n"
-"# endif\n"
-"# ifdef USEGLOW\n"
-" gl_FragColor += tex2;\n"
-"# endif\n"
-"# ifdef USEVERTEXTEXTUREBLEND\n"
-" gl_FragColor = lerp(gl_FragColor, tex2, tex2.a);\n"
-"# endif\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_GENERIC\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_BLOOMBLUR\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
-"out float4 gl_Position : POSITION,\n"
-"out float2 TexCoord : TEXCOORD0\n"
-")\n"
-"{\n"
-" TexCoord = gl_MultiTexCoord0.xy;\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"\n"
-"void main\n"
-"(\n"
-"float2 TexCoord : TEXCOORD0,\n"
-"uniform sampler2D Texture_First,\n"
-"uniform float4 BloomBlur_Parameters,\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" int i;\n"
-" float2 tc = TexCoord;\n"
-" float3 color = tex2D(Texture_First, tc).rgb;\n"
-" tc += BloomBlur_Parameters.xy;\n"
-" for (i = 1;i < SAMPLES;i++)\n"
-" {\n"
-" color += tex2D(Texture_First, tc).rgb;\n"
-" tc += BloomBlur_Parameters.xy;\n"
-" }\n"
-" gl_FragColor = float4(color * BloomBlur_Parameters.z + float3(BloomBlur_Parameters.w), 1);\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_BLOOMBLUR\n"
-"#ifdef MODE_REFRACTION\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
-"uniform float4x4 TexMatrix,\n"
-"uniform float3 EyePosition,\n"
-"out float4 gl_Position : POSITION,\n"
-"out float2 TexCoord : TEXCOORD0,\n"
-"out float3 EyeVector : TEXCOORD1,\n"
-"out float4 ModelViewProjectionPosition : TEXCOORD2\n"
-")\n"
-"{\n"
-" TexCoord = float2(mul(TexMatrix, gl_MultiTexCoord0));\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-" ModelViewProjectionPosition = gl_Position;\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main\n"
-"(\n"
-"float2 TexCoord : TEXCOORD0,\n"
-"float3 EyeVector : TEXCOORD1,\n"
-"float4 ModelViewProjectionPosition : TEXCOORD2,\n"
-"uniform sampler2D Texture_Normal,\n"
-"uniform sampler2D Texture_Refraction,\n"
-"uniform sampler2D Texture_Reflection,\n"
-"uniform float4 DistortScaleRefractReflect,\n"
-"uniform float4 ScreenScaleRefractReflect,\n"
-"uniform float4 ScreenCenterRefractReflect,\n"
-"uniform float4 RefractColor,\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" float2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
-" //float2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
-" float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
-" float2 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
-" // FIXME temporary hack to detect the case that the reflection\n"
-" // gets blackened at edges due to leaving the area that contains actual\n"
-" // content.\n"
-" // Remove this 'ack once we have a better way to stop this thing from\n"
-" // 'appening.\n"
-" float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord = lerp(SafeScreenTexCoord, ScreenTexCoord, f);\n"
-" gl_FragColor = tex2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_REFRACTION\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_WATER\n"
-"#ifdef VERTEX_SHADER\n"
-"\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
-"uniform float4x4 TexMatrix,\n"
-"uniform float3 EyePosition,\n"
-"out float4 gl_Position : POSITION,\n"
-"out float2 TexCoord : TEXCOORD0,\n"
-"out float3 EyeVector : TEXCOORD1,\n"
-"out float4 ModelViewProjectionPosition : TEXCOORD2\n"
-")\n"
-"{\n"
-" TexCoord = float2(mul(TexMatrix, gl_MultiTexCoord0));\n"
-" float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-" ModelViewProjectionPosition = gl_Position;\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main\n"
-"(\n"
-"float2 TexCoord : TEXCOORD0,\n"
-"float3 EyeVector : TEXCOORD1,\n"
-"float4 ModelViewProjectionPosition : TEXCOORD2,\n"
-"uniform sampler2D Texture_Normal,\n"
-"uniform sampler2D Texture_Refraction,\n"
-"uniform sampler2D Texture_Reflection,\n"
-"uniform float4 DistortScaleRefractReflect,\n"
-"uniform float4 ScreenScaleRefractReflect,\n"
-"uniform float4 ScreenCenterRefractReflect,\n"
-"uniform float4 RefractColor,\n"
-"uniform float4 ReflectColor,\n"
-"uniform float ReflectFactor,\n"
-"uniform float ReflectOffset,\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
-" //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
-" float4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
-" float4 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5))).xyxy * DistortScaleRefractReflect;\n"
-" // FIXME temporary hack to detect the case that the reflection\n"
-" // gets blackened at edges due to leaving the area that contains actual\n"
-" // content.\n"
-" // Remove this 'ack once we have a better way to stop this thing from\n"
-" // 'appening.\n"
-" float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord.xy = lerp(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
-" f = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord.zw = lerp(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
-" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
-" gl_FragColor = lerp(tex2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, tex2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
-"}\n"
-"#endif\n"
-"#else // !MODE_WATER\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"// 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"
-"\n"
-"// fragment shader specific:\n"
-"#ifdef FRAGMENT_SHADER\n"
-"\n"
-"#ifdef USEFOG\n"
-"float3 FogVertex(float3 surfacecolor, float3 FogColor, float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler2D Texture_FogMask, sampler2D Texture_FogHeightTexture)\n"
-"{\n"
-" float fogfrac;\n"
-"#ifdef USEFOGHEIGHTTEXTURE\n"
-" float4 fogheightpixel = tex2D(Texture_FogHeightTexture, float2(1,1) + float2(FogPlaneVertexDist, FogPlaneViewDist) * (-2.0 * FogHeightFade));\n"
-" fogfrac = fogheightpixel.a;\n"
-" return lerp(fogheightpixel.rgb * FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
-"#else\n"
-"# ifdef USEFOGOUTSIDE\n"
-" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
-"# else\n"
-" fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
-"# endif\n"
-" return lerp(FogColor, surfacecolor, tex2D(Texture_FogMask, float2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)).r);\n"
-"#endif\n"
-"}\n"
-"#endif\n"
-"\n"
-"#ifdef USEOFFSETMAPPING\n"
-"float2 OffsetMapping(float2 TexCoord, float OffsetMapping_Scale, float3 EyeVector, sampler2D Texture_Normal)\n"
-"{\n"
-"#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
-" // 14 sample relief mapping: linear search and then binary search\n"
-" // this basically steps forward a small amount repeatedly until it finds\n"
-" // itself inside solid, then jitters forward and back using decreasing\n"
-" // amounts to find the impact\n"
-" //float3 OffsetVector = float3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1), -1);\n"
-" //float3 OffsetVector = float3(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1), -1);\n"
-" float3 OffsetVector = float3(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1), -1);\n"
-" float3 RT = float3(TexCoord, 1);\n"
-" OffsetVector *= 0.1;\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
-" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n"
-" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n"
-" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n"
-" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n"
-" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
-" return RT.xy;\n"
-"#else\n"
-" // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
-" // this basically moves forward the full distance, and then backs up based\n"
-" // on height of samples\n"
-" //float2 OffsetVector = float2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1));\n"
-" //float2 OffsetVector = float2(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1));\n"
-" float2 OffsetVector = float2(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1));\n"
-" TexCoord += OffsetVector;\n"
-" OffsetVector *= 0.333;\n"
-" TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
-" TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
-" TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
-" return TexCoord;\n"
-"#endif\n"
-"}\n"
-"#endif // USEOFFSETMAPPING\n"
-"\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
-"# ifdef USESHADOWMAPORTHO\n"
-"# define GetShadowMapTC2D(dir, ShadowMap_Parameters) (min(dir, ShadowMap_Parameters.xyz))\n"
-"# else\n"
-"# ifdef USESHADOWMAPVSDCT\n"
-"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
-"{\n"
-" float3 adir = abs(dir);\n"
-" float2 aparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n"
-" float4 proj = texCUBE(Texture_CubeProjection, dir);\n"
-" return float3(lerp(dir.xy, dir.zz, proj.xy) * aparams.x + proj.zw * ShadowMap_Parameters.z, aparams.y + ShadowMap_Parameters.w);\n"
-"}\n"
-"# else\n"
-"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters)\n"
-"{\n"
-" float3 adir = abs(dir);\n"
-" float ma = adir.z;\n"
-" float4 proj = float4(dir, 2.5);\n"
-" if (adir.x > ma) { ma = adir.x; proj = float4(dir.zyx, 0.5); }\n"
-" if (adir.y > ma) { ma = adir.y; proj = float4(dir.xzy, 1.5); }\n"
-" float2 aparams = ShadowMap_Parameters.xy / ma;\n"
-" 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"
-"}\n"
-"# endif\n"
-"# endif\n"
-"#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
-"\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"float4 GetShadowMapTCCube(float3 dir, float4 ShadowMap_Parameters)\n"
-"{\n"
-" float3 adir = abs(dir);\n"
-" return float4(dir, ShadowMap_Parameters.w + ShadowMap_Parameters.y / max(max(adir.x, adir.y), adir.z));\n"
-"}\n"
-"#endif\n"
-"\n"
-"# ifdef USESHADOWMAPRECT\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-"float ShadowMapCompare(float3 dir, samplerRECT Texture_ShadowMapRect, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
-"#else\n"
-"float ShadowMapCompare(float3 dir, samplerRECT Texture_ShadowMapRect, float4 ShadowMap_Parameters)\n"
-"#endif\n"
-"{\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters, Texture_CubeProjection);\n"
-"#else\n"
-" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters);\n"
-"#endif\n"
-" float f;\n"
-"# ifdef USESHADOWSAMPLER\n"
-"\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + float3(x, y, 0.0)).r\n"
-" f = dot(float4(0.25), float4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
-"# else\n"
-" f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
-"# endif\n"
-"\n"
-"# else\n"
-"\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# if USESHADOWMAPPCF > 1\n"
-"# define texval(x, y) texRECT(Texture_ShadowMapRect, center + float2(x, y)).r\n"
-" float2 center = shadowmaptc.xy - 0.5, offset = frac(center);\n"
-" 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"
-" 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"
-" 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"
-" 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"
-" float4 cols = row2 + row3 + lerp(row1, row4, offset.y);\n"
-" f = dot(lerp(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
-"# else\n"
-"# define texval(x, y) texRECT(Texture_ShadowMapRect, shadowmaptc.xy + float2(x, y)).r\n"
-" float2 offset = frac(shadowmaptc.xy);\n"
-" float3 row1 = step(shadowmaptc.z, float3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-" float3 row2 = step(shadowmaptc.z, float3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
-" float3 row3 = step(shadowmaptc.z, float3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
-" float3 cols = row2 + lerp(row1, row3, offset.y);\n"
-" f = dot(lerp(cols.xy, cols.yz, offset.x), float2(0.25));\n"
-"# endif\n"
-"# else\n"
-" f = step(shadowmaptc.z, texRECT(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
-"# endif\n"
-"\n"
-"# endif\n"
-"# ifdef USESHADOWMAPORTHO\n"
-" return lerp(ShadowMap_Parameters.w, 1.0, f);\n"
-"# else\n"
-" return f;\n"
-"# endif\n"
-"}\n"
-"# endif\n"
-"\n"
-"# ifdef USESHADOWMAP2D\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-"float ShadowMapCompare(float3 dir, sampler2D Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale, samplerCUBE Texture_CubeProjection)\n"
-"#else\n"
-"float ShadowMapCompare(float3 dir, sampler2D Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale)\n"
-"#endif\n"
-"{\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters, Texture_CubeProjection);\n"
-"#else\n"
-" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters);\n"
-"#endif\n"
-" float f;\n"
-"\n"
-"# ifdef USESHADOWSAMPLER\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# define texval(x, y) shadow2D(Texture_ShadowMap2D, float3(center + float2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r \n"
-" float2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
-" f = dot(float4(0.25), float4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
-"# else\n"
-" f = shadow2D(Texture_ShadowMap2D, float3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
-"# endif\n"
-"# else\n"
-"# ifdef USESHADOWMAPPCF\n"
-"# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
-"# ifdef GL_ARB_texture_gather\n"
-"# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec(x, y))\n"
-"# else\n"
-"# define texval(x, y) texture4(Texture_ShadowMap2D, center + float2(x,y)*ShadowMap_TextureScale)\n"
-"# endif\n"
-" float2 center = shadowmaptc.xy - 0.5, offset = frac(center);\n"
-" center *= ShadowMap_TextureScale;\n"
-" float4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
-" float4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
-" float4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
-" float4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
-" float4 cols = float4(group1.rg, group2.rg) + float4(group3.ab, group4.ab) +\n"
-" lerp(float4(group1.ab, group2.ab), float4(group3.rg, group4.rg), offset.y);\n"
-" f = dot(lerp(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
-"# else\n"
-"# define texval(x, y) texDepth2D(Texture_ShadowMap2D, center + float2(x, y)*ShadowMap_TextureScale) \n"
-"# if USESHADOWMAPPCF > 1\n"
-" float2 center = shadowmaptc.xy - 0.5, offset = frac(center);\n"
-" center *= ShadowMap_TextureScale;\n"
-" 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"
-" 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"
-" 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"
-" 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"
-" float4 cols = row2 + row3 + lerp(row1, row4, offset.y);\n"
-" f = dot(lerp(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
-"# else\n"
-" float2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = frac(shadowmaptc.xy);\n"
-" float3 row1 = step(shadowmaptc.z, float3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-" float3 row2 = step(shadowmaptc.z, float3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
-" float3 row3 = step(shadowmaptc.z, float3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
-" float3 cols = row2 + lerp(row1, row3, offset.y);\n"
-" f = dot(lerp(cols.xy, cols.yz, offset.x), float2(0.25));\n"
-"# endif\n"
-"# endif\n"
-"# else\n"
-" f = step(shadowmaptc.z, tex2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
-"# endif\n"
-"# endif\n"
-"# ifdef USESHADOWMAPORTHO\n"
-" return lerp(ShadowMap_Parameters.w, 1.0, f);\n"
-"# else\n"
-" return f;\n"
-"# endif\n"
-"}\n"
-"# endif\n"
-"\n"
-"# ifdef USESHADOWMAPCUBE\n"
-"float ShadowMapCompare(float3 dir, samplerCUBE Texture_ShadowMapCube, float4 ShadowMap_Parameters)\n"
-"{\n"
-" // apply depth texture cubemap as light filter\n"
-" float4 shadowmaptc = GetShadowMapTCCube(dir, ShadowMap_Parameters);\n"
-" float f;\n"
-"# ifdef USESHADOWSAMPLER\n"
-" f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
-"# else\n"
-" f = step(shadowmaptc.w, texCUBE(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
-"# endif\n"
-" return f;\n"
-"}\n"
-"# endif\n"
-"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
-"#endif // FRAGMENT_SHADER\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_DEFERREDGEOMETRY\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"float4 gl_Color : COLOR0,\n"
-"#endif\n"
-"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
-"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
-"float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
-"float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
-"uniform float4x4 TexMatrix,\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform float4x4 BackgroundTexMatrix,\n"
-"#endif\n"
-"uniform float4x4 ModelViewMatrix,\n"
-"#ifdef USEOFFSETMAPPING\n"
-"uniform float3 EyePosition,\n"
-"#endif\n"
-"out float4 gl_Position : POSITION,\n"
-"out float4 gl_FrontColor : COLOR,\n"
-"out float4 TexCoordBoth : TEXCOORD0,\n"
-"#ifdef USEOFFSETMAPPING\n"
-"out float3 EyeVector : TEXCOORD2,\n"
-"#endif\n"
-"out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
-"out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
-"out float3 VectorR : TEXCOORD7 // direction of R texcoord (surface normal)\n"
-")\n"
-"{\n"
-" TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" gl_FrontColor = gl_Color;\n"
-" TexCoordBoth.zw = float2(Backgroundmul(TexMatrix, gl_MultiTexCoord0));\n"
-"#endif\n"
-"\n"
-" // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEOFFSETMAPPING\n"
-" float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-" VectorS = mul(ModelViewMatrix, float4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
-" VectorT = mul(ModelViewMatrix, float4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
-" VectorR = mul(ModelViewMatrix, float4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-"}\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main\n"
-"(\n"
-"float4 TexCoordBoth : TEXCOORD0,\n"
-"float3 EyeVector : TEXCOORD2,\n"
-"float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
-"float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
-"float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
-"uniform sampler2D Texture_Normal,\n"
-"#ifdef USEALPHAKILL\n"
-"uniform sampler2D Texture_Color,\n"
-"#endif\n"
-"uniform sampler2D Texture_Gloss,\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform sampler2D Texture_SecondaryNormal,\n"
-"uniform sampler2D Texture_SecondaryGloss,\n"
-"#endif\n"
-"#ifdef USEOFFSETMAPPING\n"
-"uniform float OffsetMapping_Scale,\n"
-"#endif\n"
-"uniform half SpecularPower,\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" float2 TexCoord = TexCoordBoth.xy;\n"
-"#ifdef USEOFFSETMAPPING\n"
-" // apply offsetmapping\n"
-" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
-"#define TexCoord TexCoordOffset\n"
-"#endif\n"
-"\n"
-"#ifdef USEALPHAKILL\n"
-" if (tex2D(Texture_Color, TexCoord).a < 0.5)\n"
-" discard;\n"
-"#endif\n"
-"\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" float alpha = tex2D(Texture_Color, TexCoord).a;\n"
-" float terrainblend = clamp(float(gl_FrontColor.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
-" //float terrainblend = min(float(gl_FrontColor.a) * alpha * 2.0, float(1.0));\n"
-" //float terrainblend = float(gl_FrontColor.a) * alpha > 0.5;\n"
-"#endif\n"
-"\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" float3 surfacenormal = lerp(float3(tex2D(Texture_SecondaryNormal, TexCoord2)), float3(tex2D(Texture_Normal, TexCoord)), terrainblend) - float3(0.5, 0.5, 0.5);\n"
-" float a = lerp(tex2D(Texture_SecondaryGloss, TexCoord2), tex2D(Texture_Gloss, TexCoord).a, terrainblend);\n"
-"#else\n"
-" float3 surfacenormal = float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5, 0.5, 0.5);\n"
-" float a = tex2D(Texture_Gloss, TexCoord).a;\n"
-"#endif\n"
-"\n"
-" gl_FragColor = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + float3(0.5, 0.5, 0.5), 1);\n"
-"}\n"
-"#endif // FRAGMENT_SHADER\n"
-"#else // !MODE_DEFERREDGEOMETRY\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"uniform float4x4 ModelViewMatrix,\n"
-"out float4 gl_Position : POSITION,\n"
-"out float4 ModelViewPosition : TEXCOORD0\n"
-")\n"
-"{\n"
-" ModelViewPosition = mul(ModelViewMatrix, gl_Vertex);\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-"}\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main\n"
-"(\n"
-"float2 Pixel : WPOS,\n"
-"float4 ModelViewPosition : TEXCOORD0,\n"
-"uniform float4x4 ViewToLight,\n"
-"uniform float2 ScreenToDepth, // ScreenToDepth = float2(Far / (Far - Near), Far * Near / (Near - Far));\n"
-"uniform float3 LightPosition,\n"
-"uniform half2 PixelToScreenTexCoord,\n"
-"uniform half3 DeferredColor_Ambient,\n"
-"uniform half3 DeferredColor_Diffuse,\n"
-"#ifdef USESPECULAR\n"
-"uniform half3 DeferredColor_Specular,\n"
-"uniform half SpecularPower,\n"
-"#endif\n"
-"uniform sampler2D Texture_Attenuation,\n"
-"uniform sampler2D Texture_ScreenDepth,\n"
-"uniform sampler2D Texture_ScreenNormalMap,\n"
-"\n"
-"#ifdef USECUBEFILTER\n"
-"uniform samplerCUBE Texture_Cube,\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPRECT\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerRECTShadow Texture_ShadowMapRect,\n"
-"# else\n"
-"uniform samplerRECT Texture_ShadowMapRect,\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAP2D\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform sampler2DShadow Texture_ShadowMap2D,\n"
-"# else\n"
-"uniform sampler2D Texture_ShadowMap2D,\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-"uniform samplerCUBE Texture_CubeProjection,\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerCUBEShadow Texture_ShadowMapCube,\n"
-"# else\n"
-"uniform samplerCUBE Texture_ShadowMapCube,\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
-"uniform float2 ShadowMap_TextureScale,\n"
-"uniform float4 ShadowMap_Parameters,\n"
-"#endif\n"
-"\n"
-"out float4 gl_FragData0 : COLOR0,\n"
-"out float4 gl_FragData1 : COLOR1\n"
-")\n"
-"{\n"
-" // calculate viewspace pixel position\n"
-" float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n"
-" //ScreenTexCoord.y = ScreenTexCoord.y * -1 + 1; // Cg is opposite?\n"
-" float3 position;\n"
-" position.z = ScreenToDepth.y / (texDepth2D(Texture_ScreenDepth, ScreenTexCoord) + ScreenToDepth.x);\n"
-" position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
-" // decode viewspace pixel normal\n"
-" half4 normalmap = tex2D(Texture_ScreenNormalMap, ScreenTexCoord);\n"
-" half3 surfacenormal = normalize(normalmap.rgb - half3(0.5,0.5,0.5));\n"
-" // surfacenormal = pixel normal in viewspace\n"
-" // LightVector = pixel to light in viewspace\n"
-" // CubeVector = position in lightspace\n"
-" // eyevector = pixel to view in viewspace\n"
-" float3 CubeVector = float3(mul(ViewToLight, float4(position,1)));\n"
-" half fade = half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)));\n"
-"#ifdef USEDIFFUSE\n"
-" // calculate diffuse shading\n"
-" half3 lightnormal = half3(normalize(LightPosition - position));\n"
-" half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-" // calculate directional shading\n"
-" float3 eyevector = position * -1.0;\n"
-"# ifdef USEEXACTSPECULARMATH\n"
-" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower * normalmap.a);\n"
-"# else\n"
-" half3 specularnormal = normalize(lightnormal + half3(normalize(eyevector)));\n"
-" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * normalmap.a);\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAP2D) || defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE)\n"
-" fade *= ShadowMapCompare(CubeVector,\n"
-"# if defined(USESHADOWMAP2D)\n"
-"Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
-"# endif\n"
-"# if defined(USESHADOWMAPRECT)\n"
-"Texture_ShadowMapRect, ShadowMap_Parameters\n"
-"# endif\n"
-"# if defined(USESHADOWMAPCUBE)\n"
-"Texture_ShadowMapCube, ShadowMap_Parameters\n"
-"# endif\n"
-"\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-", Texture_CubeProjection\n"
-"#endif\n"
-" );\n"
-"#endif\n"
-"\n"
-"#ifdef USEDIFFUSE\n"
-" gl_FragData0 = float4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
-"#else\n"
-" gl_FragData0 = float4(DeferredColor_Ambient * fade, 1.0);\n"
-"#endif\n"
-"#ifdef USESPECULAR\n"
-" gl_FragData1 = float4(DeferredColor_Specular * (specular * fade), 1.0);\n"
-"#else\n"
-" gl_FragData1 = float4(0.0, 0.0, 0.0, 1.0);\n"
-"#endif\n"
-"\n"
-"# ifdef USECUBEFILTER\n"
-" float3 cubecolor = texCUBE(Texture_Cube, CubeVector).rgb;\n"
-" gl_FragData0.rgb *= cubecolor;\n"
-" gl_FragData1.rgb *= cubecolor;\n"
-"# endif\n"
-"}\n"
-"#endif // FRAGMENT_SHADER\n"
-"#else // !MODE_DEFERREDLIGHTSOURCE\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef VERTEX_SHADER\n"
-"void main\n"
-"(\n"
-"float4 gl_Vertex : POSITION,\n"
-"uniform float4x4 ModelViewProjectionMatrix,\n"
-"#if defined(USEVERTEXTEXTUREBLEND) || defined(MODE_VERTEXCOLOR)\n"
-"float4 gl_Color : COLOR0,\n"
-"#endif\n"
-"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
-"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
-"float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
-"float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
-"float4 gl_MultiTexCoord4 : TEXCOORD4,\n"
-"\n"
-"uniform float3 EyePosition,\n"
-"uniform float4x4 TexMatrix,\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform float4x4 BackgroundTexMatrix,\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform float4x4 ModelToLight,\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform float3 LightPosition,\n"
-"#endif\n"
-"#ifdef MODE_LIGHTDIRECTION\n"
-"uniform float3 LightDir,\n"
-"#endif\n"
-"uniform float4 FogPlane,\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"uniform float3 LightPosition,\n"
-"#endif\n"
-"#ifdef USESHADOWMAPORTHO\n"
-"uniform float4x4 ShadowMapMatrix,\n"
-"#endif\n"
-"\n"
-"out float4 gl_FrontColor : COLOR,\n"
-"out float4 TexCoordBoth : TEXCOORD0,\n"
-"#ifdef USELIGHTMAP\n"
-"out float2 TexCoordLightmap : TEXCOORD1,\n"
-"#endif\n"
-"#ifdef USEEYEVECTOR\n"
-"out float3 EyeVector : TEXCOORD2,\n"
-"#endif\n"
-"#ifdef USEREFLECTION\n"
-"out float4 ModelViewProjectionPosition : TEXCOORD3,\n"
-"#endif\n"
-"#ifdef USEFOG\n"
-"out float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
-"#endif\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
-"out float3 LightVector : TEXCOORD1,\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"out float3 CubeVector : TEXCOORD3,\n"
-"#endif\n"
-"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n"
-"out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
-"out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
-"out float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
-"#endif\n"
-"#ifdef USESHADOWMAPORTHO\n"
-"out float3 ShadowMapTC : TEXCOORD3, // CONFLICTS WITH USEREFLECTION!\n"
-"#endif\n"
-"out float4 gl_Position : POSITION\n"
-")\n"
-"{\n"
-"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
-" gl_FrontColor = gl_Color;\n"
-"#endif\n"
-" // copy the surface texcoord\n"
-" TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" TexCoordBoth.zw = mul(BackgroundTexMatrix, gl_MultiTexCoord0).xy;\n"
-"#endif\n"
-"#ifdef USELIGHTMAP\n"
-" TexCoordLightmap = float2(gl_MultiTexCoord4);\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-" // transform vertex position into light attenuation/cubemap space\n"
-" // (-1 to +1 across the light box)\n"
-" CubeVector = float3(mul(ModelToLight, gl_Vertex));\n"
-"\n"
-"# ifdef USEDIFFUSE\n"
-" // transform unnormalized light direction into tangent space\n"
-" // (we use unnormalized to ensure that it interpolates correctly and then\n"
-" // normalize it per pixel)\n"
-" float3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
-" LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
-" LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
-" LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
-" LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
-" LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
-" LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-" // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEEYEVECTOR\n"
-" float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-"#ifdef USEFOG\n"
-" EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
-" EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-" VectorS = gl_MultiTexCoord1.xyz;\n"
-" VectorT = gl_MultiTexCoord2.xyz;\n"
-" VectorR = gl_MultiTexCoord3.xyz;\n"
-"#endif\n"
-"\n"
-" // transform vertex to camera space, using ftransform to match non-VS rendering\n"
-" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
-"\n"
-"#ifdef USESHADOWMAPORTHO\n"
-" ShadowMapTC = float3(mul(ShadowMapMatrix, gl_Position));\n"
-"#endif\n"
-"\n"
-"#ifdef USEREFLECTION\n"
-" ModelViewProjectionPosition = gl_Position;\n"
-"#endif\n"
-"}\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef FRAGMENT_SHADER\n"
-"void main\n"
-"(\n"
-"#ifdef USEDEFERREDLIGHTMAP\n"
-"float2 Pixel : WPOS,\n"
-"#endif\n"
-"float4 gl_FrontColor : COLOR,\n"
-"float4 TexCoordBoth : TEXCOORD0,\n"
-"#ifdef USELIGHTMAP\n"
-"float2 TexCoordLightmap : TEXCOORD1,\n"
-"#endif\n"
-"#ifdef USEEYEVECTOR\n"
-"float3 EyeVector : TEXCOORD2,\n"
-"#endif\n"
-"#ifdef USEREFLECTION\n"
-"float4 ModelViewProjectionPosition : TEXCOORD3,\n"
-"#endif\n"
-"#ifdef USEFOG\n"
-"float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
-"#endif\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
-"float3 LightVector : TEXCOORD1,\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"float3 CubeVector : TEXCOORD3,\n"
-"#endif\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"float4 ModelViewPosition : TEXCOORD0,\n"
-"#endif\n"
-"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY) || defined(USEREFLECTCUBE)\n"
-"float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
-"float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
-"float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
-"#endif\n"
-"#ifdef USESHADOWMAPORTHO\n"
-"float3 ShadowMapTC : TEXCOORD3, // CONFLICTS WITH USEREFLECTION!\n"
-"#endif\n"
-"\n"
-"uniform sampler2D Texture_Normal,\n"
-"uniform sampler2D Texture_Color,\n"
-"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
-"uniform sampler2D Texture_Gloss,\n"
-"#endif\n"
-"#ifdef USEGLOW\n"
-"uniform sampler2D Texture_Glow,\n"
-"#endif\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform sampler2D Texture_SecondaryNormal,\n"
-"uniform sampler2D Texture_SecondaryColor,\n"
-"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
-"uniform sampler2D Texture_SecondaryGloss,\n"
-"#endif\n"
-"#ifdef USEGLOW\n"
-"uniform sampler2D Texture_SecondaryGlow,\n"
-"#endif\n"
-"#endif\n"
-"#ifdef USECOLORMAPPING\n"
-"uniform sampler2D Texture_Pants,\n"
-"uniform sampler2D Texture_Shirt,\n"
-"#endif\n"
-"#ifdef USEFOG\n"
-"uniform sampler2D Texture_FogHeightTexture,\n"
-"uniform sampler2D Texture_FogMask,\n"
-"#endif\n"
-"#ifdef USELIGHTMAP\n"
-"uniform sampler2D Texture_Lightmap,\n"
-"#endif\n"
-"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"uniform sampler2D Texture_Deluxemap,\n"
-"#endif\n"
-"#ifdef USEREFLECTION\n"
-"uniform sampler2D Texture_Reflection,\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"uniform sampler2D Texture_ScreenDepth,\n"
-"uniform sampler2D Texture_ScreenNormalMap,\n"
-"#endif\n"
-"#ifdef USEDEFERREDLIGHTMAP\n"
-"uniform sampler2D Texture_ScreenDiffuse,\n"
-"uniform sampler2D Texture_ScreenSpecular,\n"
-"#endif\n"
-"\n"
-"#ifdef USECOLORMAPPING\n"
-"uniform half3 Color_Pants,\n"
-"uniform half3 Color_Shirt,\n"
-"#endif\n"
-"#ifdef USEFOG\n"
-"uniform float3 FogColor,\n"
-"uniform float FogRangeRecip,\n"
-"uniform float FogPlaneViewDist,\n"
-"uniform float FogHeightFade,\n"
-"#endif\n"
-"\n"
-"#ifdef USEOFFSETMAPPING\n"
-"uniform float OffsetMapping_Scale,\n"
-"#endif\n"
-"\n"
-"#ifdef USEDEFERREDLIGHTMAP\n"
-"uniform half2 PixelToScreenTexCoord,\n"
-"uniform half3 DeferredMod_Diffuse,\n"
-"uniform half3 DeferredMod_Specular,\n"
-"#endif\n"
-"uniform half3 Color_Ambient,\n"
-"uniform half3 Color_Diffuse,\n"
-"uniform half3 Color_Specular,\n"
-"uniform half SpecularPower,\n"
-"#ifdef USEGLOW\n"
-"uniform half3 Color_Glow,\n"
-"#endif\n"
-"uniform half Alpha,\n"
-"#ifdef USEREFLECTION\n"
-"uniform float4 DistortScaleRefractReflect,\n"
-"uniform float4 ScreenScaleRefractReflect,\n"
-"uniform float4 ScreenCenterRefractReflect,\n"
-"uniform half4 ReflectColor,\n"
-"#endif\n"
-"#ifdef USEREFLECTCUBE\n"
-"uniform float4x4 ModelToReflectCube,\n"
-"uniform sampler2D Texture_ReflectMask,\n"
-"uniform samplerCUBE Texture_ReflectCube,\n"
-"#endif\n"
-"#ifdef MODE_LIGHTDIRECTION\n"
-"uniform half3 LightColor,\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform half3 LightColor,\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
-"uniform sampler2D Texture_Attenuation,\n"
-"uniform samplerCUBE Texture_Cube,\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USESHADOWMAPORTHO)\n"
-"\n"
-"#ifdef USESHADOWMAPRECT\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerRECTShadow Texture_ShadowMapRect,\n"
-"# else\n"
-"uniform samplerRECT Texture_ShadowMapRect,\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAP2D\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform sampler2DShadow Texture_ShadowMap2D,\n"
-"# else\n"
-"uniform sampler2D Texture_ShadowMap2D,\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-"uniform samplerCUBE Texture_CubeProjection,\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# ifdef USESHADOWSAMPLER\n"
-"uniform samplerCUBEShadow Texture_ShadowMapCube,\n"
-"# else\n"
-"uniform samplerCUBE Texture_ShadowMapCube,\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
-"uniform float2 ShadowMap_TextureScale,\n"
-"uniform float4 ShadowMap_Parameters,\n"
-"#endif\n"
-"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE) && !defined(USESHADOWMAPORTHO)\n"
-"\n"
-"out float4 gl_FragColor : COLOR\n"
-")\n"
-"{\n"
-" float2 TexCoord = TexCoordBoth.xy;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" float2 TexCoord2 = TexCoordBoth.zw;\n"
-"#endif\n"
-"#ifdef USEOFFSETMAPPING\n"
-" // apply offsetmapping\n"
-" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
-"#define TexCoord TexCoordOffset\n"
-"#endif\n"
-"\n"
-" // combine the diffuse textures (base, pants, shirt)\n"
-" half4 color = half4(tex2D(Texture_Color, TexCoord));\n"
-"#ifdef USEALPHAKILL\n"
-" if (color.a < 0.5)\n"
-" discard;\n"
-"#endif\n"
-" color.a *= Alpha;\n"
-"#ifdef USECOLORMAPPING\n"
-" color.rgb += half3(tex2D(Texture_Pants, TexCoord)) * Color_Pants + half3(tex2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
-"#endif\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" float terrainblend = clamp(half(gl_FrontColor.a) * color.a * 2.0 - 0.5, half(0.0), half(1.0));\n"
-" //half terrainblend = min(half(gl_FrontColor.a) * color.a * 2.0, half(1.0));\n"
-" //half terrainblend = half(gl_FrontColor.a) * color.a > 0.5;\n"
-" color.rgb = half3(lerp(float3(tex2D(Texture_SecondaryColor, TexCoord2)), float3(color.rgb), terrainblend));\n"
-" color.a = 1.0;\n"
-" //color = lerp(half4(1, 0, 0, 1), color, terrainblend);\n"
-"#endif\n"
-"\n"
-" // get the surface normal\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" half3 surfacenormal = normalize(half3(lerp(float3(tex2D(Texture_SecondaryNormal, TexCoord2)), float3(tex2D(Texture_Normal, TexCoord)), terrainblend)) - half3(0.5, 0.5, 0.5));\n"
-"#else\n"
-" half3 surfacenormal = normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5, 0.5, 0.5));\n"
-"#endif\n"
-"\n"
-" // get the material colors\n"
-" half3 diffusetex = color.rgb;\n"
-"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
-"# ifdef USEVERTEXTEXTUREBLEND\n"
-" half4 glosstex = half4(lerp(float4(tex2D(Texture_SecondaryGloss, TexCoord2)), float4(tex2D(Texture_Gloss, TexCoord)), terrainblend));\n"
-"# else\n"
-" half4 glosstex = half4(tex2D(Texture_Gloss, TexCoord));\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USEREFLECTCUBE\n"
-" float3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n"
-" float3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n"
-" float3 ReflectCubeTexCoord = float3(mul(ModelToReflectCube, float4(ModelReflectVector, 0)));\n"
-" diffusetex += half3(tex2D(Texture_ReflectMask, TexCoord)) * half3(texCUBE(Texture_ReflectCube, ReflectCubeTexCoord));\n"
-"#endif\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-" // light source\n"
-"#ifdef USEDIFFUSE\n"
-" half3 lightnormal = half3(normalize(LightVector));\n"
-" half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
-" color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
-"#ifdef USESPECULAR\n"
-"#ifdef USEEXACTSPECULARMATH\n"
-" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
-"#else\n"
-" half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n"
-" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
-"#endif\n"
-" color.rgb += glosstex.rgb * (specular * Color_Specular);\n"
-"#endif\n"
-"#else\n"
-" color.rgb = diffusetex * Color_Ambient;\n"
-"#endif\n"
-" color.rgb *= LightColor;\n"
-" color.rgb *= half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)));\n"
-"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
-" color.rgb *= ShadowMapCompare(CubeVector,\n"
-"# if defined(USESHADOWMAP2D)\n"
-"Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
-"# endif\n"
-"# if defined(USESHADOWMAPRECT)\n"
-"Texture_ShadowMapRect, ShadowMap_Parameters\n"
-"# endif\n"
-"# if defined(USESHADOWMAPCUBE)\n"
-"Texture_ShadowMapCube, ShadowMap_Parameters\n"
-"# endif\n"
-"\n"
-"#ifdef USESHADOWMAPVSDCT\n"
-", Texture_CubeProjection\n"
-"#endif\n"
-" );\n"
-"\n"
-"#endif\n"
-"# ifdef USECUBEFILTER\n"
-" color.rgb *= half3(texCUBE(Texture_Cube, CubeVector));\n"
-"# endif\n"
-"#endif // MODE_LIGHTSOURCE\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_LIGHTDIRECTION\n"
-"#define SHADING\n"
-"#ifdef USEDIFFUSE\n"
-" half3 lightnormal = half3(normalize(LightVector));\n"
-"#endif\n"
-"#define lightcolor LightColor\n"
-"#endif // MODE_LIGHTDIRECTION\n"
-"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-"#define SHADING\n"
-" // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
-" half3 lightnormal_modelspace = half3(tex2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
-" half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap));\n"
-" // convert modelspace light vector to tangentspace\n"
-" half3 lightnormal;\n"
-" lightnormal.x = dot(lightnormal_modelspace, half3(VectorS));\n"
-" lightnormal.y = dot(lightnormal_modelspace, half3(VectorT));\n"
-" lightnormal.z = dot(lightnormal_modelspace, half3(VectorR));\n"
-" // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
-" // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
-" // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
-" // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
-" // to map the luxels to coordinates on the draw surfaces), which also causes\n"
-" // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
-" // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
-" // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
-" // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
-" lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
-"#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-"#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
-"#define SHADING\n"
-" // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
-" half3 lightnormal = half3(tex2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
-" half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap));\n"
-"#endif\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef MODE_LIGHTMAP\n"
-" color.rgb = diffusetex * (Color_Ambient + half3(tex2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
-"#endif // MODE_LIGHTMAP\n"
-"#ifdef MODE_VERTEXCOLOR\n"
-" color.rgb = diffusetex * (Color_Ambient + half3(gl_FrontColor.rgb) * Color_Diffuse);\n"
-"#endif // MODE_VERTEXCOLOR\n"
-"#ifdef MODE_FLATCOLOR\n"
-" color.rgb = diffusetex * Color_Ambient;\n"
-"#endif // MODE_FLATCOLOR\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"#ifdef SHADING\n"
-"# ifdef USEDIFFUSE\n"
-" half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
-"# ifdef USESPECULAR\n"
-"# ifdef USEEXACTSPECULARMATH\n"
-" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower * glosstex.a);\n"
-"# else\n"
-" half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n"
-" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower * glosstex.a);\n"
-"# endif\n"
-" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex.rgb * Color_Specular * specular) * lightcolor;\n"
-"# else\n"
-" color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
-"# endif\n"
-"# else\n"
-" color.rgb = diffusetex * Color_Ambient;\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAPORTHO\n"
-" color.rgb *= ShadowMapCompare(ShadowMapTC,\n"
-"# if defined(USESHADOWMAP2D)\n"
-"Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
-"# endif\n"
-"# if defined(USESHADOWMAPRECT)\n"
-"Texture_ShadowMapRect, ShadowMap_Parameters\n"
-"# endif\n"
-" );\n"
-"#endif\n"
-"\n"
-"#ifdef USEDEFERREDLIGHTMAP\n"
-" float2 ScreenTexCoord = Pixel * PixelToScreenTexCoord;\n"
-" color.rgb += diffusetex * half3(tex2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n"
-" color.rgb += glosstex.rgb * half3(tex2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n"
-"#endif\n"
-"\n"
-"#ifdef USEGLOW\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" color.rgb += lerp(half3(tex2D(Texture_SecondaryGlow, TexCoord2)), half3(tex2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
-"#else\n"
-" color.rgb += half3(tex2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
-"#endif\n"
-"#endif\n"
-"\n"
-"#ifdef USEFOG\n"
-" color.rgb = FogVertex(color.rgb, FogColor, EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask, Texture_FogHeightTexture);\n"
-"#endif\n"
-"\n"
-" // 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"
-"#ifdef USEREFLECTION\n"
-" float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
-" //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
-" float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
-" float2 ScreenTexCoord = SafeScreenTexCoord + float3(normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
-" // FIXME temporary hack to detect the case that the reflection\n"
-" // gets blackened at edges due to leaving the area that contains actual\n"
-" // content.\n"
-" // Remove this 'ack once we have a better way to stop this thing from\n"
-" // 'appening.\n"
-" float f = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
-" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
-" ScreenTexCoord = lerp(SafeScreenTexCoord, ScreenTexCoord, f);\n"
-" color.rgb = lerp(color.rgb, half3(tex2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
-"#endif\n"
-"\n"
-" gl_FragColor = float4(color);\n"
-"}\n"
-"#endif // FRAGMENT_SHADER\n"
-"\n"
-"#endif // !MODE_DEFERREDLIGHTSOURCE\n"
-"#endif // !MODE_DEFERREDGEOMETRY\n"
-"#endif // !MODE_WATER\n"
-"#endif // !MODE_REFRACTION\n"
-"#endif // !MODE_BLOOMBLUR\n"
-"#endif // !MODE_GENERIC\n"
-"#endif // !MODE_POSTPROCESS\n"
-"#endif // !MODE_SHOWDEPTH\n"
-"#endif // !MODE_DEPTH_OR_SHADOW\n"
+const char *builtinhlslshaderstring =
+#include "shader_hlsl.h"
;
char *glslshaderstring = NULL;
-char *cgshaderstring = NULL;
+char *hlslshaderstring = NULL;
//=======================================================================================================================================================
}
shadermodeinfo_t;
-typedef enum shaderpermutation_e
-{
- SHADERPERMUTATION_DIFFUSE = 1<<0, ///< (lightsource) whether to use directional shading
- SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, ///< indicates this is a two-layer material blend based on vertex alpha (q3bsp)
- SHADERPERMUTATION_VIEWTINT = 1<<2, ///< view tint (postprocessing only)
- SHADERPERMUTATION_COLORMAPPING = 1<<3, ///< indicates this is a colormapped skin
- SHADERPERMUTATION_SATURATION = 1<<4, ///< saturation (postprocessing only)
- SHADERPERMUTATION_FOGINSIDE = 1<<5, ///< tint the color by fog color or black if using additive blend mode
- SHADERPERMUTATION_FOGOUTSIDE = 1<<6, ///< tint the color by fog color or black if using additive blend mode
- SHADERPERMUTATION_FOGHEIGHTTEXTURE = 1<<7, ///< fog color and density determined by texture mapped on vertical axis
- SHADERPERMUTATION_GAMMARAMPS = 1<<8, ///< gamma (postprocessing only)
- SHADERPERMUTATION_CUBEFILTER = 1<<9, ///< (lightsource) use cubemap light filter
- SHADERPERMUTATION_GLOW = 1<<10, ///< (lightmap) blend in an additive glow texture
- SHADERPERMUTATION_BLOOM = 1<<11, ///< bloom (postprocessing only)
- SHADERPERMUTATION_SPECULAR = 1<<12, ///< (lightsource or deluxemapping) render specular effects
- SHADERPERMUTATION_POSTPROCESSING = 1<<13, ///< user defined postprocessing (postprocessing only)
- SHADERPERMUTATION_EXACTSPECULARMATH = 1<<14, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
- SHADERPERMUTATION_REFLECTION = 1<<15, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
- SHADERPERMUTATION_OFFSETMAPPING = 1<<16, ///< adjust texcoords to roughly simulate a displacement mapped surface
- SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<17, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
- SHADERPERMUTATION_SHADOWMAPRECT = 1<<18, ///< (lightsource) use shadowmap rectangle texture as light filter
- SHADERPERMUTATION_SHADOWMAPCUBE = 1<<19, ///< (lightsource) use shadowmap cubemap texture as light filter
- SHADERPERMUTATION_SHADOWMAP2D = 1<<20, ///< (lightsource) use shadowmap rectangle texture as light filter
- SHADERPERMUTATION_SHADOWMAPPCF = 1<<21, ///< (lightsource) use percentage closer filtering on shadowmap test results
- SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<22, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
- SHADERPERMUTATION_SHADOWSAMPLER = 1<<23, ///< (lightsource) use hardware shadowmap test
- SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<24, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
- SHADERPERMUTATION_SHADOWMAPORTHO = 1<<25, //< (lightsource) use orthographic shadowmap projection
- SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<26, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
- SHADERPERMUTATION_ALPHAKILL = 1<<27, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
- SHADERPERMUTATION_REFLECTCUBE = 1<<28, ///< fake reflections using global cubemap (not HDRI light probe)
- SHADERPERMUTATION_LIMIT = 1<<29, ///< size of permutations array
- SHADERPERMUTATION_COUNT = 29 ///< size of shaderpermutationinfo array
-}
-shaderpermutation_t;
-
// NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
{
{"#define USEFOGINSIDE\n", " foginside"},
{"#define USEFOGOUTSIDE\n", " fogoutside"},
{"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
+ {"#define USEFOGALPHAHACK\n", " fogalphahack"},
{"#define USEGAMMARAMPS\n", " gammaramps"},
{"#define USECUBEFILTER\n", " cubefilter"},
{"#define USEGLOW\n", " glow"},
{"#define USEBLOOM\n", " bloom"},
{"#define USESPECULAR\n", " specular"},
{"#define USEPOSTPROCESSING\n", " postprocessing"},
- {"#define USEEXACTSPECULARMATH\n", " exactspecularmath"},
{"#define USEREFLECTION\n", " reflection"},
{"#define USEOFFSETMAPPING\n", " offsetmapping"},
{"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
- {"#define USESHADOWMAPRECT\n", " shadowmaprect"},
- {"#define USESHADOWMAPCUBE\n", " shadowmapcube"},
{"#define USESHADOWMAP2D\n", " shadowmap2d"},
{"#define USESHADOWMAPPCF 1\n", " shadowmappcf"},
{"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"},
{"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
{"#define USEALPHAKILL\n", " alphakill"},
{"#define USEREFLECTCUBE\n", " reflectcube"},
+ {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
+ {"#define USEBOUNCEGRID\n", " bouncegrid"},
+ {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"},
+ {"#define USETRIPPY\n", " trippy"},
};
-/// this enum is multiplied by SHADERPERMUTATION_MODEBASE
-typedef enum shadermode_e
-{
- SHADERMODE_GENERIC, ///< (particles/HUD/etc) vertex color, optionally multiplied by one texture
- SHADERMODE_POSTPROCESS, ///< postprocessing shader (r_glsl_postprocess)
- SHADERMODE_DEPTH_OR_SHADOW, ///< (depthfirst/shadows) vertex shader only
- SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp)
- SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp)
- SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp)
- SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap)
- SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap)
- SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp)
- SHADERMODE_LIGHTSOURCE, ///< (lightsource) use directional pixel shading from light source (rtlight)
- SHADERMODE_REFRACTION, ///< refract background (the material is rendered normally after this pass)
- SHADERMODE_WATER, ///< refract background and reflection (the material is rendered normally after this pass)
- SHADERMODE_SHOWDEPTH, ///< (debugging) renders depth as color
- SHADERMODE_DEFERREDGEOMETRY, ///< (deferred) render material properties to screenspace geometry buffers
- SHADERMODE_DEFERREDLIGHTSOURCE, ///< (deferred) use directional pixel shading from light source (rtlight) on screenspace geometry buffers
- SHADERMODE_COUNT
-}
-shadermode_t;
-
// NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] =
{
{"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
{"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
{"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"},
+ {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"},
{"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
{"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
{"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
{"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
};
-#ifdef SUPPORTCG
-shadermodeinfo_t cgshadermodeinfo[SHADERMODE_COUNT] =
-{
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_GENERIC\n", " generic"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_POSTPROCESS\n", " postprocess"},
- {"cg/default.cg", NULL, NULL , "#define MODE_DEPTH_OR_SHADOW\n", " depth"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FLATCOLOR\n", " flatcolor"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTMAP\n", " lightmap"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTSOURCE\n", " lightsource"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_REFRACTION\n", " refraction"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_WATER\n", " water"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_SHOWDEPTH\n", " showdepth"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
- {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
+shadermodeinfo_t hlslshadermodeinfo[SHADERMODE_COUNT] =
+{
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_GENERIC\n", " generic"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_POSTPROCESS\n", " postprocess"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FLATCOLOR\n", " flatcolor"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTMAP\n", " lightmap"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_FAKELIGHT\n", " fakelight"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_LIGHTSOURCE\n", " lightsource"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_REFRACTION\n", " refraction"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_WATER\n", " water"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_SHOWDEPTH\n", " showdepth"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
+ {"hlsl/default.hlsl", NULL, "hlsl/default.hlsl", "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
};
-#endif
struct r_glsl_permutation_s;
typedef struct r_glsl_permutation_s
qboolean compiled;
/// 0 if compilation failed
int program;
+ // texture units assigned to each detected uniform
+ int tex_Texture_First;
+ int tex_Texture_Second;
+ int tex_Texture_GammaRamps;
+ int tex_Texture_Normal;
+ int tex_Texture_Color;
+ int tex_Texture_Gloss;
+ int tex_Texture_Glow;
+ int tex_Texture_SecondaryNormal;
+ int tex_Texture_SecondaryColor;
+ int tex_Texture_SecondaryGloss;
+ int tex_Texture_SecondaryGlow;
+ int tex_Texture_Pants;
+ int tex_Texture_Shirt;
+ int tex_Texture_FogHeightTexture;
+ int tex_Texture_FogMask;
+ int tex_Texture_Lightmap;
+ int tex_Texture_Deluxemap;
+ int tex_Texture_Attenuation;
+ int tex_Texture_Cube;
+ int tex_Texture_Refraction;
+ int tex_Texture_Reflection;
+ int tex_Texture_ShadowMap2D;
+ int tex_Texture_CubeProjection;
+ int tex_Texture_ScreenDepth;
+ int tex_Texture_ScreenNormalMap;
+ int tex_Texture_ScreenDiffuse;
+ int tex_Texture_ScreenSpecular;
+ int tex_Texture_ReflectMask;
+ int tex_Texture_ReflectCube;
+ int tex_Texture_BounceGrid;
/// locations of detected uniforms in program object, or -1 if not found
int loc_Texture_First;
int loc_Texture_Second;
int loc_Texture_Cube;
int loc_Texture_Refraction;
int loc_Texture_Reflection;
- int loc_Texture_ShadowMapRect;
- int loc_Texture_ShadowMapCube;
int loc_Texture_ShadowMap2D;
int loc_Texture_CubeProjection;
int loc_Texture_ScreenDepth;
int loc_Texture_ScreenSpecular;
int loc_Texture_ReflectMask;
int loc_Texture_ReflectCube;
+ int loc_Texture_BounceGrid;
int loc_Alpha;
int loc_BloomBlur_Parameters;
int loc_ClientTime;
int loc_LightColor;
int loc_LightDir;
int loc_LightPosition;
- int loc_OffsetMapping_Scale;
+ int loc_OffsetMapping_ScaleSteps;
int loc_PixelSize;
int loc_ReflectColor;
int loc_ReflectFactor;
int loc_ModelViewMatrix;
int loc_PixelToScreenTexCoord;
int loc_ModelToReflectCube;
- int loc_ShadowMapMatrix;
+ int loc_ShadowMapMatrix;
+ int loc_BloomColorSubtract;
+ int loc_NormalmapScrollBlend;
+ int loc_BounceGridMatrix;
+ int loc_BounceGridIntensity;
}
r_glsl_permutation_t;
#define SHADERPERMUTATION_HASHSIZE 256
+
+// non-degradable "lightweight" shader parameters to keep the permutations simpler
+// these can NOT degrade! only use for simple stuff
+enum
+{
+ SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0, ///< red compensation filter for saturation
+ SHADERSTATICPARM_EXACTSPECULARMATH = 1, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation
+ SHADERSTATICPARM_POSTPROCESS_USERVEC1 = 2, ///< postprocess uservec1 is enabled
+ SHADERSTATICPARM_POSTPROCESS_USERVEC2 = 3, ///< postprocess uservec2 is enabled
+ SHADERSTATICPARM_POSTPROCESS_USERVEC3 = 4, ///< postprocess uservec3 is enabled
+ SHADERSTATICPARM_POSTPROCESS_USERVEC4 = 5, ///< postprocess uservec4 is enabled
+ SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6 // use both alpha layers while blending materials, allows more advanced microblending
+};
+#define SHADERSTATICPARMS_COUNT 7
+
+static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
+static int shaderstaticparms_count = 0;
+
+static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
+#define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
+qboolean R_CompileShader_CheckStaticParms(void)
+{
+ static int r_compileshader_staticparms_save[1];
+ memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
+ memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
+
+ // detect all
+ if (r_glsl_saturation_redcompensate.integer)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
+ if (r_glsl_vertextextureblend_usebothalphas.integer)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS);
+ if (r_shadow_glossexact.integer)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_EXACTSPECULARMATH);
+ if (r_glsl_postprocess.integer)
+ {
+ if (r_glsl_postprocess_uservec1_enable.integer)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC1);
+ if (r_glsl_postprocess_uservec2_enable.integer)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC2);
+ if (r_glsl_postprocess_uservec3_enable.integer)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC3);
+ if (r_glsl_postprocess_uservec4_enable.integer)
+ R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
+ }
+ return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms)) != 0;
+}
+
+#define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
+ if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
+ shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
+ else \
+ shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
+void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
+{
+ shaderstaticparms_count = 0;
+
+ // emit all
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_EXACTSPECULARMATH, "USEEXACTSPECULARMATH");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC1, "USERVEC1");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC2, "USERVEC2");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC3, "USERVEC3");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_POSTPROCESS_USERVEC4, "USERVEC4");
+ R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS, "USEBOTHALPHAS");
+}
+
/// information about each possible shader permutation
r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
/// currently selected permutation
static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, unsigned int permutation)
{
int i;
+ int sampler;
shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
+ char *vertexstring, *geometrystring, *fragmentstring;
+ char permutationname[256];
int vertstrings_count = 0;
int geomstrings_count = 0;
int fragstrings_count = 0;
- char *vertexstring, *geometrystring, *fragmentstring;
- const char *vertstrings_list[32+3];
- const char *geomstrings_list[32+3];
- const char *fragstrings_list[32+3];
- char permutationname[256];
+ const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+ const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+ const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
if (p->compiled)
return;
strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
+ // if we can do #version 130, we should (this improves quality of offset/reliefmapping thanks to textureGrad)
+ if(vid.support.gl20shaders130)
+ {
+ vertstrings_list[vertstrings_count++] = "#version 130\n";
+ geomstrings_list[geomstrings_count++] = "#version 130\n";
+ fragstrings_list[fragstrings_count++] = "#version 130\n";
+ vertstrings_list[vertstrings_count++] = "#define GLSL130\n";
+ geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
+ fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
+ }
+
// the first pretext is which type of shader to compile as
// (later these will all be bound together as a program object)
vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
}
}
+ // add static parms
+ R_CompileShader_AddStaticParms(mode, permutation);
+ memcpy((char *)(vertstrings_list + vertstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+ vertstrings_count += shaderstaticparms_count;
+ memcpy((char *)(geomstrings_list + geomstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+ geomstrings_count += shaderstaticparms_count;
+ memcpy((char *)(fragstrings_list + fragstrings_count), shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+ fragstrings_count += shaderstaticparms_count;
+
// now append the shader text itself
vertstrings_list[vertstrings_count++] = vertexstring;
geomstrings_list[geomstrings_count++] = geometrystring;
if (p->program)
{
CHECKGLERROR
- qglUseProgramObjectARB(p->program);CHECKGLERROR
+ qglUseProgram(p->program);CHECKGLERROR
// look up all the uniform variable names we care about, so we don't
// have to look them up every time we set them
- p->loc_Texture_First = qglGetUniformLocationARB(p->program, "Texture_First");
- p->loc_Texture_Second = qglGetUniformLocationARB(p->program, "Texture_Second");
- p->loc_Texture_GammaRamps = qglGetUniformLocationARB(p->program, "Texture_GammaRamps");
- p->loc_Texture_Normal = qglGetUniformLocationARB(p->program, "Texture_Normal");
- p->loc_Texture_Color = qglGetUniformLocationARB(p->program, "Texture_Color");
- p->loc_Texture_Gloss = qglGetUniformLocationARB(p->program, "Texture_Gloss");
- p->loc_Texture_Glow = qglGetUniformLocationARB(p->program, "Texture_Glow");
- p->loc_Texture_SecondaryNormal = qglGetUniformLocationARB(p->program, "Texture_SecondaryNormal");
- p->loc_Texture_SecondaryColor = qglGetUniformLocationARB(p->program, "Texture_SecondaryColor");
- p->loc_Texture_SecondaryGloss = qglGetUniformLocationARB(p->program, "Texture_SecondaryGloss");
- p->loc_Texture_SecondaryGlow = qglGetUniformLocationARB(p->program, "Texture_SecondaryGlow");
- p->loc_Texture_Pants = qglGetUniformLocationARB(p->program, "Texture_Pants");
- p->loc_Texture_Shirt = qglGetUniformLocationARB(p->program, "Texture_Shirt");
- p->loc_Texture_FogHeightTexture = qglGetUniformLocationARB(p->program, "Texture_FogHeightTexture");
- p->loc_Texture_FogMask = qglGetUniformLocationARB(p->program, "Texture_FogMask");
- p->loc_Texture_Lightmap = qglGetUniformLocationARB(p->program, "Texture_Lightmap");
- p->loc_Texture_Deluxemap = qglGetUniformLocationARB(p->program, "Texture_Deluxemap");
- p->loc_Texture_Attenuation = qglGetUniformLocationARB(p->program, "Texture_Attenuation");
- p->loc_Texture_Cube = qglGetUniformLocationARB(p->program, "Texture_Cube");
- p->loc_Texture_Refraction = qglGetUniformLocationARB(p->program, "Texture_Refraction");
- p->loc_Texture_Reflection = qglGetUniformLocationARB(p->program, "Texture_Reflection");
- p->loc_Texture_ShadowMapRect = qglGetUniformLocationARB(p->program, "Texture_ShadowMapRect");
- p->loc_Texture_ShadowMapCube = qglGetUniformLocationARB(p->program, "Texture_ShadowMapCube");
- p->loc_Texture_ShadowMap2D = qglGetUniformLocationARB(p->program, "Texture_ShadowMap2D");
- p->loc_Texture_CubeProjection = qglGetUniformLocationARB(p->program, "Texture_CubeProjection");
- p->loc_Texture_ScreenDepth = qglGetUniformLocationARB(p->program, "Texture_ScreenDepth");
- p->loc_Texture_ScreenNormalMap = qglGetUniformLocationARB(p->program, "Texture_ScreenNormalMap");
- p->loc_Texture_ScreenDiffuse = qglGetUniformLocationARB(p->program, "Texture_ScreenDiffuse");
- p->loc_Texture_ScreenSpecular = qglGetUniformLocationARB(p->program, "Texture_ScreenSpecular");
- p->loc_Texture_ReflectMask = qglGetUniformLocationARB(p->program, "Texture_ReflectMask");
- p->loc_Texture_ReflectCube = qglGetUniformLocationARB(p->program, "Texture_ReflectCube");
- p->loc_Alpha = qglGetUniformLocationARB(p->program, "Alpha");
- p->loc_BloomBlur_Parameters = qglGetUniformLocationARB(p->program, "BloomBlur_Parameters");
- p->loc_ClientTime = qglGetUniformLocationARB(p->program, "ClientTime");
- p->loc_Color_Ambient = qglGetUniformLocationARB(p->program, "Color_Ambient");
- p->loc_Color_Diffuse = qglGetUniformLocationARB(p->program, "Color_Diffuse");
- p->loc_Color_Specular = qglGetUniformLocationARB(p->program, "Color_Specular");
- p->loc_Color_Glow = qglGetUniformLocationARB(p->program, "Color_Glow");
- p->loc_Color_Pants = qglGetUniformLocationARB(p->program, "Color_Pants");
- p->loc_Color_Shirt = qglGetUniformLocationARB(p->program, "Color_Shirt");
- p->loc_DeferredColor_Ambient = qglGetUniformLocationARB(p->program, "DeferredColor_Ambient");
- p->loc_DeferredColor_Diffuse = qglGetUniformLocationARB(p->program, "DeferredColor_Diffuse");
- p->loc_DeferredColor_Specular = qglGetUniformLocationARB(p->program, "DeferredColor_Specular");
- p->loc_DeferredMod_Diffuse = qglGetUniformLocationARB(p->program, "DeferredMod_Diffuse");
- p->loc_DeferredMod_Specular = qglGetUniformLocationARB(p->program, "DeferredMod_Specular");
- p->loc_DistortScaleRefractReflect = qglGetUniformLocationARB(p->program, "DistortScaleRefractReflect");
- p->loc_EyePosition = qglGetUniformLocationARB(p->program, "EyePosition");
- p->loc_FogColor = qglGetUniformLocationARB(p->program, "FogColor");
- p->loc_FogHeightFade = qglGetUniformLocationARB(p->program, "FogHeightFade");
- p->loc_FogPlane = qglGetUniformLocationARB(p->program, "FogPlane");
- p->loc_FogPlaneViewDist = qglGetUniformLocationARB(p->program, "FogPlaneViewDist");
- p->loc_FogRangeRecip = qglGetUniformLocationARB(p->program, "FogRangeRecip");
- p->loc_LightColor = qglGetUniformLocationARB(p->program, "LightColor");
- p->loc_LightDir = qglGetUniformLocationARB(p->program, "LightDir");
- p->loc_LightPosition = qglGetUniformLocationARB(p->program, "LightPosition");
- p->loc_OffsetMapping_Scale = qglGetUniformLocationARB(p->program, "OffsetMapping_Scale");
- p->loc_PixelSize = qglGetUniformLocationARB(p->program, "PixelSize");
- p->loc_ReflectColor = qglGetUniformLocationARB(p->program, "ReflectColor");
- p->loc_ReflectFactor = qglGetUniformLocationARB(p->program, "ReflectFactor");
- p->loc_ReflectOffset = qglGetUniformLocationARB(p->program, "ReflectOffset");
- p->loc_RefractColor = qglGetUniformLocationARB(p->program, "RefractColor");
- p->loc_Saturation = qglGetUniformLocationARB(p->program, "Saturation");
- p->loc_ScreenCenterRefractReflect = qglGetUniformLocationARB(p->program, "ScreenCenterRefractReflect");
- p->loc_ScreenScaleRefractReflect = qglGetUniformLocationARB(p->program, "ScreenScaleRefractReflect");
- p->loc_ScreenToDepth = qglGetUniformLocationARB(p->program, "ScreenToDepth");
- p->loc_ShadowMap_Parameters = qglGetUniformLocationARB(p->program, "ShadowMap_Parameters");
- p->loc_ShadowMap_TextureScale = qglGetUniformLocationARB(p->program, "ShadowMap_TextureScale");
- p->loc_SpecularPower = qglGetUniformLocationARB(p->program, "SpecularPower");
- p->loc_UserVec1 = qglGetUniformLocationARB(p->program, "UserVec1");
- p->loc_UserVec2 = qglGetUniformLocationARB(p->program, "UserVec2");
- p->loc_UserVec3 = qglGetUniformLocationARB(p->program, "UserVec3");
- p->loc_UserVec4 = qglGetUniformLocationARB(p->program, "UserVec4");
- p->loc_ViewTintColor = qglGetUniformLocationARB(p->program, "ViewTintColor");
- p->loc_ViewToLight = qglGetUniformLocationARB(p->program, "ViewToLight");
- p->loc_ModelToLight = qglGetUniformLocationARB(p->program, "ModelToLight");
- p->loc_TexMatrix = qglGetUniformLocationARB(p->program, "TexMatrix");
- p->loc_BackgroundTexMatrix = qglGetUniformLocationARB(p->program, "BackgroundTexMatrix");
- p->loc_ModelViewMatrix = qglGetUniformLocationARB(p->program, "ModelViewMatrix");
- p->loc_ModelViewProjectionMatrix = qglGetUniformLocationARB(p->program, "ModelViewProjectionMatrix");
- p->loc_PixelToScreenTexCoord = qglGetUniformLocationARB(p->program, "PixelToScreenTexCoord");
- p->loc_ModelToReflectCube = qglGetUniformLocationARB(p->program, "ModelToReflectCube");
- p->loc_ShadowMapMatrix = qglGetUniformLocationARB(p->program, "ShadowMapMatrix");
+ p->loc_Texture_First = qglGetUniformLocation(p->program, "Texture_First");
+ p->loc_Texture_Second = qglGetUniformLocation(p->program, "Texture_Second");
+ p->loc_Texture_GammaRamps = qglGetUniformLocation(p->program, "Texture_GammaRamps");
+ p->loc_Texture_Normal = qglGetUniformLocation(p->program, "Texture_Normal");
+ p->loc_Texture_Color = qglGetUniformLocation(p->program, "Texture_Color");
+ p->loc_Texture_Gloss = qglGetUniformLocation(p->program, "Texture_Gloss");
+ p->loc_Texture_Glow = qglGetUniformLocation(p->program, "Texture_Glow");
+ p->loc_Texture_SecondaryNormal = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
+ p->loc_Texture_SecondaryColor = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
+ p->loc_Texture_SecondaryGloss = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
+ p->loc_Texture_SecondaryGlow = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
+ p->loc_Texture_Pants = qglGetUniformLocation(p->program, "Texture_Pants");
+ p->loc_Texture_Shirt = qglGetUniformLocation(p->program, "Texture_Shirt");
+ p->loc_Texture_FogHeightTexture = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
+ p->loc_Texture_FogMask = qglGetUniformLocation(p->program, "Texture_FogMask");
+ p->loc_Texture_Lightmap = qglGetUniformLocation(p->program, "Texture_Lightmap");
+ p->loc_Texture_Deluxemap = qglGetUniformLocation(p->program, "Texture_Deluxemap");
+ p->loc_Texture_Attenuation = qglGetUniformLocation(p->program, "Texture_Attenuation");
+ p->loc_Texture_Cube = qglGetUniformLocation(p->program, "Texture_Cube");
+ p->loc_Texture_Refraction = qglGetUniformLocation(p->program, "Texture_Refraction");
+ p->loc_Texture_Reflection = qglGetUniformLocation(p->program, "Texture_Reflection");
+ p->loc_Texture_ShadowMap2D = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
+ p->loc_Texture_CubeProjection = qglGetUniformLocation(p->program, "Texture_CubeProjection");
+ p->loc_Texture_ScreenDepth = qglGetUniformLocation(p->program, "Texture_ScreenDepth");
+ p->loc_Texture_ScreenNormalMap = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
+ p->loc_Texture_ScreenDiffuse = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
+ p->loc_Texture_ScreenSpecular = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
+ p->loc_Texture_ReflectMask = qglGetUniformLocation(p->program, "Texture_ReflectMask");
+ p->loc_Texture_ReflectCube = qglGetUniformLocation(p->program, "Texture_ReflectCube");
+ p->loc_Texture_BounceGrid = qglGetUniformLocation(p->program, "Texture_BounceGrid");
+ p->loc_Alpha = qglGetUniformLocation(p->program, "Alpha");
+ p->loc_BloomBlur_Parameters = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
+ p->loc_ClientTime = qglGetUniformLocation(p->program, "ClientTime");
+ p->loc_Color_Ambient = qglGetUniformLocation(p->program, "Color_Ambient");
+ p->loc_Color_Diffuse = qglGetUniformLocation(p->program, "Color_Diffuse");
+ p->loc_Color_Specular = qglGetUniformLocation(p->program, "Color_Specular");
+ p->loc_Color_Glow = qglGetUniformLocation(p->program, "Color_Glow");
+ p->loc_Color_Pants = qglGetUniformLocation(p->program, "Color_Pants");
+ p->loc_Color_Shirt = qglGetUniformLocation(p->program, "Color_Shirt");
+ p->loc_DeferredColor_Ambient = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
+ p->loc_DeferredColor_Diffuse = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
+ p->loc_DeferredColor_Specular = qglGetUniformLocation(p->program, "DeferredColor_Specular");
+ p->loc_DeferredMod_Diffuse = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
+ p->loc_DeferredMod_Specular = qglGetUniformLocation(p->program, "DeferredMod_Specular");
+ p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
+ p->loc_EyePosition = qglGetUniformLocation(p->program, "EyePosition");
+ p->loc_FogColor = qglGetUniformLocation(p->program, "FogColor");
+ p->loc_FogHeightFade = qglGetUniformLocation(p->program, "FogHeightFade");
+ p->loc_FogPlane = qglGetUniformLocation(p->program, "FogPlane");
+ p->loc_FogPlaneViewDist = qglGetUniformLocation(p->program, "FogPlaneViewDist");
+ p->loc_FogRangeRecip = qglGetUniformLocation(p->program, "FogRangeRecip");
+ p->loc_LightColor = qglGetUniformLocation(p->program, "LightColor");
+ p->loc_LightDir = qglGetUniformLocation(p->program, "LightDir");
+ p->loc_LightPosition = qglGetUniformLocation(p->program, "LightPosition");
+ p->loc_OffsetMapping_ScaleSteps = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
+ p->loc_PixelSize = qglGetUniformLocation(p->program, "PixelSize");
+ p->loc_ReflectColor = qglGetUniformLocation(p->program, "ReflectColor");
+ p->loc_ReflectFactor = qglGetUniformLocation(p->program, "ReflectFactor");
+ p->loc_ReflectOffset = qglGetUniformLocation(p->program, "ReflectOffset");
+ p->loc_RefractColor = qglGetUniformLocation(p->program, "RefractColor");
+ p->loc_Saturation = qglGetUniformLocation(p->program, "Saturation");
+ p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
+ p->loc_ScreenScaleRefractReflect = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
+ p->loc_ScreenToDepth = qglGetUniformLocation(p->program, "ScreenToDepth");
+ p->loc_ShadowMap_Parameters = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
+ p->loc_ShadowMap_TextureScale = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
+ p->loc_SpecularPower = qglGetUniformLocation(p->program, "SpecularPower");
+ p->loc_UserVec1 = qglGetUniformLocation(p->program, "UserVec1");
+ p->loc_UserVec2 = qglGetUniformLocation(p->program, "UserVec2");
+ p->loc_UserVec3 = qglGetUniformLocation(p->program, "UserVec3");
+ p->loc_UserVec4 = qglGetUniformLocation(p->program, "UserVec4");
+ p->loc_ViewTintColor = qglGetUniformLocation(p->program, "ViewTintColor");
+ p->loc_ViewToLight = qglGetUniformLocation(p->program, "ViewToLight");
+ p->loc_ModelToLight = qglGetUniformLocation(p->program, "ModelToLight");
+ p->loc_TexMatrix = qglGetUniformLocation(p->program, "TexMatrix");
+ p->loc_BackgroundTexMatrix = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
+ p->loc_ModelViewMatrix = qglGetUniformLocation(p->program, "ModelViewMatrix");
+ p->loc_ModelViewProjectionMatrix = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
+ p->loc_PixelToScreenTexCoord = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
+ p->loc_ModelToReflectCube = qglGetUniformLocation(p->program, "ModelToReflectCube");
+ p->loc_ShadowMapMatrix = qglGetUniformLocation(p->program, "ShadowMapMatrix");
+ p->loc_BloomColorSubtract = qglGetUniformLocation(p->program, "BloomColorSubtract");
+ p->loc_NormalmapScrollBlend = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
+ p->loc_BounceGridMatrix = qglGetUniformLocation(p->program, "BounceGridMatrix");
+ p->loc_BounceGridIntensity = qglGetUniformLocation(p->program, "BounceGridIntensity");
// initialize the samplers to refer to the texture units we use
- if (p->loc_Texture_First >= 0) qglUniform1iARB(p->loc_Texture_First , GL20TU_FIRST);
- if (p->loc_Texture_Second >= 0) qglUniform1iARB(p->loc_Texture_Second , GL20TU_SECOND);
- if (p->loc_Texture_GammaRamps >= 0) qglUniform1iARB(p->loc_Texture_GammaRamps , GL20TU_GAMMARAMPS);
- if (p->loc_Texture_Normal >= 0) qglUniform1iARB(p->loc_Texture_Normal , GL20TU_NORMAL);
- if (p->loc_Texture_Color >= 0) qglUniform1iARB(p->loc_Texture_Color , GL20TU_COLOR);
- if (p->loc_Texture_Gloss >= 0) qglUniform1iARB(p->loc_Texture_Gloss , GL20TU_GLOSS);
- if (p->loc_Texture_Glow >= 0) qglUniform1iARB(p->loc_Texture_Glow , GL20TU_GLOW);
- if (p->loc_Texture_SecondaryNormal >= 0) qglUniform1iARB(p->loc_Texture_SecondaryNormal, GL20TU_SECONDARY_NORMAL);
- if (p->loc_Texture_SecondaryColor >= 0) qglUniform1iARB(p->loc_Texture_SecondaryColor , GL20TU_SECONDARY_COLOR);
- if (p->loc_Texture_SecondaryGloss >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGloss , GL20TU_SECONDARY_GLOSS);
- if (p->loc_Texture_SecondaryGlow >= 0) qglUniform1iARB(p->loc_Texture_SecondaryGlow , GL20TU_SECONDARY_GLOW);
- if (p->loc_Texture_Pants >= 0) qglUniform1iARB(p->loc_Texture_Pants , GL20TU_PANTS);
- if (p->loc_Texture_Shirt >= 0) qglUniform1iARB(p->loc_Texture_Shirt , GL20TU_SHIRT);
- if (p->loc_Texture_FogHeightTexture>= 0) qglUniform1iARB(p->loc_Texture_FogHeightTexture, GL20TU_FOGHEIGHTTEXTURE);
- if (p->loc_Texture_FogMask >= 0) qglUniform1iARB(p->loc_Texture_FogMask , GL20TU_FOGMASK);
- if (p->loc_Texture_Lightmap >= 0) qglUniform1iARB(p->loc_Texture_Lightmap , GL20TU_LIGHTMAP);
- if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap , GL20TU_DELUXEMAP);
- if (p->loc_Texture_Attenuation >= 0) qglUniform1iARB(p->loc_Texture_Attenuation , GL20TU_ATTENUATION);
- if (p->loc_Texture_Cube >= 0) qglUniform1iARB(p->loc_Texture_Cube , GL20TU_CUBE);
- if (p->loc_Texture_Refraction >= 0) qglUniform1iARB(p->loc_Texture_Refraction , GL20TU_REFRACTION);
- if (p->loc_Texture_Reflection >= 0) qglUniform1iARB(p->loc_Texture_Reflection , GL20TU_REFLECTION);
- if (p->loc_Texture_ShadowMapRect >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapRect , permutation & SHADERPERMUTATION_SHADOWMAPORTHO ? GL20TU_SHADOWMAPORTHORECT : GL20TU_SHADOWMAPRECT);
- if (p->loc_Texture_ShadowMapCube >= 0) qglUniform1iARB(p->loc_Texture_ShadowMapCube , GL20TU_SHADOWMAPCUBE);
- if (p->loc_Texture_ShadowMap2D >= 0) qglUniform1iARB(p->loc_Texture_ShadowMap2D , permutation & SHADERPERMUTATION_SHADOWMAPORTHO ? GL20TU_SHADOWMAPORTHO2D : GL20TU_SHADOWMAP2D);
- if (p->loc_Texture_CubeProjection >= 0) qglUniform1iARB(p->loc_Texture_CubeProjection , GL20TU_CUBEPROJECTION);
- if (p->loc_Texture_ScreenDepth >= 0) qglUniform1iARB(p->loc_Texture_ScreenDepth , GL20TU_SCREENDEPTH);
- if (p->loc_Texture_ScreenNormalMap >= 0) qglUniform1iARB(p->loc_Texture_ScreenNormalMap, GL20TU_SCREENNORMALMAP);
- if (p->loc_Texture_ScreenDiffuse >= 0) qglUniform1iARB(p->loc_Texture_ScreenDiffuse , GL20TU_SCREENDIFFUSE);
- if (p->loc_Texture_ScreenSpecular >= 0) qglUniform1iARB(p->loc_Texture_ScreenSpecular , GL20TU_SCREENSPECULAR);
- if (p->loc_Texture_ReflectMask >= 0) qglUniform1iARB(p->loc_Texture_ReflectMask , GL20TU_REFLECTMASK);
- if (p->loc_Texture_ReflectCube >= 0) qglUniform1iARB(p->loc_Texture_ReflectCube , GL20TU_REFLECTCUBE);
+ p->tex_Texture_First = -1;
+ p->tex_Texture_Second = -1;
+ p->tex_Texture_GammaRamps = -1;
+ p->tex_Texture_Normal = -1;
+ p->tex_Texture_Color = -1;
+ p->tex_Texture_Gloss = -1;
+ p->tex_Texture_Glow = -1;
+ p->tex_Texture_SecondaryNormal = -1;
+ p->tex_Texture_SecondaryColor = -1;
+ p->tex_Texture_SecondaryGloss = -1;
+ p->tex_Texture_SecondaryGlow = -1;
+ p->tex_Texture_Pants = -1;
+ p->tex_Texture_Shirt = -1;
+ p->tex_Texture_FogHeightTexture = -1;
+ p->tex_Texture_FogMask = -1;
+ p->tex_Texture_Lightmap = -1;
+ p->tex_Texture_Deluxemap = -1;
+ p->tex_Texture_Attenuation = -1;
+ p->tex_Texture_Cube = -1;
+ p->tex_Texture_Refraction = -1;
+ p->tex_Texture_Reflection = -1;
+ p->tex_Texture_ShadowMap2D = -1;
+ p->tex_Texture_CubeProjection = -1;
+ p->tex_Texture_ScreenDepth = -1;
+ p->tex_Texture_ScreenNormalMap = -1;
+ p->tex_Texture_ScreenDiffuse = -1;
+ p->tex_Texture_ScreenSpecular = -1;
+ p->tex_Texture_ReflectMask = -1;
+ p->tex_Texture_ReflectCube = -1;
+ p->tex_Texture_BounceGrid = -1;
+ sampler = 0;
+ if (p->loc_Texture_First >= 0) {p->tex_Texture_First = sampler;qglUniform1i(p->loc_Texture_First , sampler);sampler++;}
+ if (p->loc_Texture_Second >= 0) {p->tex_Texture_Second = sampler;qglUniform1i(p->loc_Texture_Second , sampler);sampler++;}
+ if (p->loc_Texture_GammaRamps >= 0) {p->tex_Texture_GammaRamps = sampler;qglUniform1i(p->loc_Texture_GammaRamps , sampler);sampler++;}
+ if (p->loc_Texture_Normal >= 0) {p->tex_Texture_Normal = sampler;qglUniform1i(p->loc_Texture_Normal , sampler);sampler++;}
+ if (p->loc_Texture_Color >= 0) {p->tex_Texture_Color = sampler;qglUniform1i(p->loc_Texture_Color , sampler);sampler++;}
+ if (p->loc_Texture_Gloss >= 0) {p->tex_Texture_Gloss = sampler;qglUniform1i(p->loc_Texture_Gloss , sampler);sampler++;}
+ if (p->loc_Texture_Glow >= 0) {p->tex_Texture_Glow = sampler;qglUniform1i(p->loc_Texture_Glow , sampler);sampler++;}
+ if (p->loc_Texture_SecondaryNormal >= 0) {p->tex_Texture_SecondaryNormal = sampler;qglUniform1i(p->loc_Texture_SecondaryNormal , sampler);sampler++;}
+ if (p->loc_Texture_SecondaryColor >= 0) {p->tex_Texture_SecondaryColor = sampler;qglUniform1i(p->loc_Texture_SecondaryColor , sampler);sampler++;}
+ if (p->loc_Texture_SecondaryGloss >= 0) {p->tex_Texture_SecondaryGloss = sampler;qglUniform1i(p->loc_Texture_SecondaryGloss , sampler);sampler++;}
+ if (p->loc_Texture_SecondaryGlow >= 0) {p->tex_Texture_SecondaryGlow = sampler;qglUniform1i(p->loc_Texture_SecondaryGlow , sampler);sampler++;}
+ if (p->loc_Texture_Pants >= 0) {p->tex_Texture_Pants = sampler;qglUniform1i(p->loc_Texture_Pants , sampler);sampler++;}
+ if (p->loc_Texture_Shirt >= 0) {p->tex_Texture_Shirt = sampler;qglUniform1i(p->loc_Texture_Shirt , sampler);sampler++;}
+ if (p->loc_Texture_FogHeightTexture>= 0) {p->tex_Texture_FogHeightTexture = sampler;qglUniform1i(p->loc_Texture_FogHeightTexture, sampler);sampler++;}
+ if (p->loc_Texture_FogMask >= 0) {p->tex_Texture_FogMask = sampler;qglUniform1i(p->loc_Texture_FogMask , sampler);sampler++;}
+ if (p->loc_Texture_Lightmap >= 0) {p->tex_Texture_Lightmap = sampler;qglUniform1i(p->loc_Texture_Lightmap , sampler);sampler++;}
+ if (p->loc_Texture_Deluxemap >= 0) {p->tex_Texture_Deluxemap = sampler;qglUniform1i(p->loc_Texture_Deluxemap , sampler);sampler++;}
+ if (p->loc_Texture_Attenuation >= 0) {p->tex_Texture_Attenuation = sampler;qglUniform1i(p->loc_Texture_Attenuation , sampler);sampler++;}
+ if (p->loc_Texture_Cube >= 0) {p->tex_Texture_Cube = sampler;qglUniform1i(p->loc_Texture_Cube , sampler);sampler++;}
+ if (p->loc_Texture_Refraction >= 0) {p->tex_Texture_Refraction = sampler;qglUniform1i(p->loc_Texture_Refraction , sampler);sampler++;}
+ if (p->loc_Texture_Reflection >= 0) {p->tex_Texture_Reflection = sampler;qglUniform1i(p->loc_Texture_Reflection , sampler);sampler++;}
+ if (p->loc_Texture_ShadowMap2D >= 0) {p->tex_Texture_ShadowMap2D = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D , sampler);sampler++;}
+ if (p->loc_Texture_CubeProjection >= 0) {p->tex_Texture_CubeProjection = sampler;qglUniform1i(p->loc_Texture_CubeProjection , sampler);sampler++;}
+ if (p->loc_Texture_ScreenDepth >= 0) {p->tex_Texture_ScreenDepth = sampler;qglUniform1i(p->loc_Texture_ScreenDepth , sampler);sampler++;}
+ if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;}
+ if (p->loc_Texture_ScreenDiffuse >= 0) {p->tex_Texture_ScreenDiffuse = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse , sampler);sampler++;}
+ if (p->loc_Texture_ScreenSpecular >= 0) {p->tex_Texture_ScreenSpecular = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular , sampler);sampler++;}
+ if (p->loc_Texture_ReflectMask >= 0) {p->tex_Texture_ReflectMask = sampler;qglUniform1i(p->loc_Texture_ReflectMask , sampler);sampler++;}
+ if (p->loc_Texture_ReflectCube >= 0) {p->tex_Texture_ReflectCube = sampler;qglUniform1i(p->loc_Texture_ReflectCube , sampler);sampler++;}
+ if (p->loc_Texture_BounceGrid >= 0) {p->tex_Texture_BounceGrid = sampler;qglUniform1i(p->loc_Texture_BounceGrid , sampler);sampler++;}
CHECKGLERROR
- Con_DPrintf("^5GLSL shader %s compiled.\n", permutationname);
+ Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
}
else
Con_Printf("^1GLSL shader %s failed! some features may not work properly.\n", permutationname);
{
//Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
r_glsl_permutation = R_GLSL_FindPermutation(mode, permutation);
- qglUseProgramObjectARB(0);CHECKGLERROR
+ qglUseProgram(0);CHECKGLERROR
return; // no bit left to clear, entire mode is broken
}
}
}
CHECKGLERROR
- qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
+ qglUseProgram(r_glsl_permutation->program);CHECKGLERROR
}
- if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
- if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
- if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1fARB(r_glsl_permutation->loc_ClientTime, cl.time);
+ if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
+ if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
+ if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1f(r_glsl_permutation->loc_ClientTime, cl.time);
}
-#ifdef SUPPORTCG
-#include <Cg/cgGL.h>
-struct r_cg_permutation_s;
-typedef struct r_cg_permutation_s
+#ifdef SUPPORTD3D
+
+#ifdef SUPPORTD3D
+#include <d3d9.h>
+extern LPDIRECT3DDEVICE9 vid_d3d9dev;
+extern D3DCAPS9 vid_d3d9caps;
+#endif
+
+struct r_hlsl_permutation_s;
+typedef struct r_hlsl_permutation_s
{
/// hash lookup data
- struct r_cg_permutation_s *hashnext;
+ struct r_hlsl_permutation_s *hashnext;
unsigned int mode;
unsigned int permutation;
/// indicates if we have tried compiling this permutation already
qboolean compiled;
- /// 0 if compilation failed
- CGprogram vprogram;
- CGprogram fprogram;
- /// locations of detected parameters in programs, or NULL if not found
- CGparameter vp_EyePosition;
- CGparameter vp_FogPlane;
- CGparameter vp_LightDir;
- CGparameter vp_LightPosition;
- CGparameter vp_ModelToLight;
- CGparameter vp_TexMatrix;
- CGparameter vp_BackgroundTexMatrix;
- CGparameter vp_ModelViewProjectionMatrix;
- CGparameter vp_ModelViewMatrix;
- CGparameter vp_ShadowMapMatrix;
-
- CGparameter fp_Texture_First;
- CGparameter fp_Texture_Second;
- CGparameter fp_Texture_GammaRamps;
- CGparameter fp_Texture_Normal;
- CGparameter fp_Texture_Color;
- CGparameter fp_Texture_Gloss;
- CGparameter fp_Texture_Glow;
- CGparameter fp_Texture_SecondaryNormal;
- CGparameter fp_Texture_SecondaryColor;
- CGparameter fp_Texture_SecondaryGloss;
- CGparameter fp_Texture_SecondaryGlow;
- CGparameter fp_Texture_Pants;
- CGparameter fp_Texture_Shirt;
- CGparameter fp_Texture_FogHeightTexture;
- CGparameter fp_Texture_FogMask;
- CGparameter fp_Texture_Lightmap;
- CGparameter fp_Texture_Deluxemap;
- CGparameter fp_Texture_Attenuation;
- CGparameter fp_Texture_Cube;
- CGparameter fp_Texture_Refraction;
- CGparameter fp_Texture_Reflection;
- CGparameter fp_Texture_ShadowMapRect;
- CGparameter fp_Texture_ShadowMapCube;
- CGparameter fp_Texture_ShadowMap2D;
- CGparameter fp_Texture_CubeProjection;
- CGparameter fp_Texture_ScreenDepth;
- CGparameter fp_Texture_ScreenNormalMap;
- CGparameter fp_Texture_ScreenDiffuse;
- CGparameter fp_Texture_ScreenSpecular;
- CGparameter fp_Texture_ReflectMask;
- CGparameter fp_Texture_ReflectCube;
- CGparameter fp_Alpha;
- CGparameter fp_BloomBlur_Parameters;
- CGparameter fp_ClientTime;
- CGparameter fp_Color_Ambient;
- CGparameter fp_Color_Diffuse;
- CGparameter fp_Color_Specular;
- CGparameter fp_Color_Glow;
- CGparameter fp_Color_Pants;
- CGparameter fp_Color_Shirt;
- CGparameter fp_DeferredColor_Ambient;
- CGparameter fp_DeferredColor_Diffuse;
- CGparameter fp_DeferredColor_Specular;
- CGparameter fp_DeferredMod_Diffuse;
- CGparameter fp_DeferredMod_Specular;
- CGparameter fp_DistortScaleRefractReflect;
- CGparameter fp_EyePosition;
- CGparameter fp_FogColor;
- CGparameter fp_FogHeightFade;
- CGparameter fp_FogPlane;
- CGparameter fp_FogPlaneViewDist;
- CGparameter fp_FogRangeRecip;
- CGparameter fp_LightColor;
- CGparameter fp_LightDir;
- CGparameter fp_LightPosition;
- CGparameter fp_OffsetMapping_Scale;
- CGparameter fp_PixelSize;
- CGparameter fp_ReflectColor;
- CGparameter fp_ReflectFactor;
- CGparameter fp_ReflectOffset;
- CGparameter fp_RefractColor;
- CGparameter fp_Saturation;
- CGparameter fp_ScreenCenterRefractReflect;
- CGparameter fp_ScreenScaleRefractReflect;
- CGparameter fp_ScreenToDepth;
- CGparameter fp_ShadowMap_Parameters;
- CGparameter fp_ShadowMap_TextureScale;
- CGparameter fp_SpecularPower;
- CGparameter fp_UserVec1;
- CGparameter fp_UserVec2;
- CGparameter fp_UserVec3;
- CGparameter fp_UserVec4;
- CGparameter fp_ViewTintColor;
- CGparameter fp_ViewToLight;
- CGparameter fp_PixelToScreenTexCoord;
- CGparameter fp_ModelToReflectCube;
-}
-r_cg_permutation_t;
+ /// NULL if compilation failed
+ IDirect3DVertexShader9 *vertexshader;
+ IDirect3DPixelShader9 *pixelshader;
+}
+r_hlsl_permutation_t;
+
+typedef enum D3DVSREGISTER_e
+{
+ D3DVSREGISTER_TexMatrix = 0, // float4x4
+ D3DVSREGISTER_BackgroundTexMatrix = 4, // float4x4
+ D3DVSREGISTER_ModelViewProjectionMatrix = 8, // float4x4
+ D3DVSREGISTER_ModelViewMatrix = 12, // float4x4
+ D3DVSREGISTER_ShadowMapMatrix = 16, // float4x4
+ D3DVSREGISTER_ModelToLight = 20, // float4x4
+ D3DVSREGISTER_EyePosition = 24,
+ D3DVSREGISTER_FogPlane = 25,
+ D3DVSREGISTER_LightDir = 26,
+ D3DVSREGISTER_LightPosition = 27,
+}
+D3DVSREGISTER_t;
+
+typedef enum D3DPSREGISTER_e
+{
+ D3DPSREGISTER_Alpha = 0,
+ D3DPSREGISTER_BloomBlur_Parameters = 1,
+ D3DPSREGISTER_ClientTime = 2,
+ D3DPSREGISTER_Color_Ambient = 3,
+ D3DPSREGISTER_Color_Diffuse = 4,
+ D3DPSREGISTER_Color_Specular = 5,
+ D3DPSREGISTER_Color_Glow = 6,
+ D3DPSREGISTER_Color_Pants = 7,
+ D3DPSREGISTER_Color_Shirt = 8,
+ D3DPSREGISTER_DeferredColor_Ambient = 9,
+ D3DPSREGISTER_DeferredColor_Diffuse = 10,
+ D3DPSREGISTER_DeferredColor_Specular = 11,
+ D3DPSREGISTER_DeferredMod_Diffuse = 12,
+ D3DPSREGISTER_DeferredMod_Specular = 13,
+ D3DPSREGISTER_DistortScaleRefractReflect = 14,
+ D3DPSREGISTER_EyePosition = 15, // unused
+ D3DPSREGISTER_FogColor = 16,
+ D3DPSREGISTER_FogHeightFade = 17,
+ D3DPSREGISTER_FogPlane = 18,
+ D3DPSREGISTER_FogPlaneViewDist = 19,
+ D3DPSREGISTER_FogRangeRecip = 20,
+ D3DPSREGISTER_LightColor = 21,
+ D3DPSREGISTER_LightDir = 22, // unused
+ D3DPSREGISTER_LightPosition = 23,
+ D3DPSREGISTER_OffsetMapping_ScaleSteps = 24,
+ D3DPSREGISTER_PixelSize = 25,
+ D3DPSREGISTER_ReflectColor = 26,
+ D3DPSREGISTER_ReflectFactor = 27,
+ D3DPSREGISTER_ReflectOffset = 28,
+ D3DPSREGISTER_RefractColor = 29,
+ D3DPSREGISTER_Saturation = 30,
+ D3DPSREGISTER_ScreenCenterRefractReflect = 31,
+ D3DPSREGISTER_ScreenScaleRefractReflect = 32,
+ D3DPSREGISTER_ScreenToDepth = 33,
+ D3DPSREGISTER_ShadowMap_Parameters = 34,
+ D3DPSREGISTER_ShadowMap_TextureScale = 35,
+ D3DPSREGISTER_SpecularPower = 36,
+ D3DPSREGISTER_UserVec1 = 37,
+ D3DPSREGISTER_UserVec2 = 38,
+ D3DPSREGISTER_UserVec3 = 39,
+ D3DPSREGISTER_UserVec4 = 40,
+ D3DPSREGISTER_ViewTintColor = 41,
+ D3DPSREGISTER_PixelToScreenTexCoord = 42,
+ D3DPSREGISTER_BloomColorSubtract = 43,
+ D3DPSREGISTER_ViewToLight = 44, // float4x4
+ D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
+ D3DPSREGISTER_NormalmapScrollBlend = 52,
+ // next at 53
+}
+D3DPSREGISTER_t;
/// information about each possible shader permutation
-r_cg_permutation_t *r_cg_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
+r_hlsl_permutation_t *r_hlsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
/// currently selected permutation
-r_cg_permutation_t *r_cg_permutation;
+r_hlsl_permutation_t *r_hlsl_permutation;
/// storage for permutations linked in the hash table
-memexpandablearray_t r_cg_permutationarray;
+memexpandablearray_t r_hlsl_permutationarray;
-#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));}}
-
-static r_cg_permutation_t *R_CG_FindPermutation(unsigned int mode, unsigned int permutation)
+static r_hlsl_permutation_t *R_HLSL_FindPermutation(unsigned int mode, unsigned int permutation)
{
//unsigned int hashdepth = 0;
unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
- r_cg_permutation_t *p;
- for (p = r_cg_permutationhash[mode][hashindex];p;p = p->hashnext)
+ r_hlsl_permutation_t *p;
+ for (p = r_hlsl_permutationhash[mode][hashindex];p;p = p->hashnext)
{
if (p->mode == mode && p->permutation == permutation)
{
//if (hashdepth > 10)
- // Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
+ // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
return p;
}
//hashdepth++;
}
- p = (r_cg_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_cg_permutationarray);
+ p = (r_hlsl_permutation_t*)Mem_ExpandableArray_AllocRecord(&r_hlsl_permutationarray);
p->mode = mode;
p->permutation = permutation;
- p->hashnext = r_cg_permutationhash[mode][hashindex];
- r_cg_permutationhash[mode][hashindex] = p;
+ p->hashnext = r_hlsl_permutationhash[mode][hashindex];
+ r_hlsl_permutationhash[mode][hashindex] = p;
//if (hashdepth > 10)
- // Con_Printf("R_CG_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
+ // Con_Printf("R_HLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
return p;
}
-static char *R_CG_GetText(const char *filename, qboolean printfromdisknotice)
+static char *R_HLSL_GetText(const char *filename, qboolean printfromdisknotice)
{
char *shaderstring;
if (!filename || !filename[0])
return NULL;
- if (!strcmp(filename, "cg/default.cg"))
+ if (!strcmp(filename, "hlsl/default.hlsl"))
{
- if (!cgshaderstring)
+ if (!hlslshaderstring)
{
- cgshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
- if (cgshaderstring)
+ hlslshaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
+ if (hlslshaderstring)
Con_DPrintf("Loading shaders from file %s...\n", filename);
else
- cgshaderstring = (char *)builtincgshaderstring;
+ hlslshaderstring = (char *)builtinhlslshaderstring;
}
- shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(cgshaderstring) + 1);
- memcpy(shaderstring, cgshaderstring, strlen(cgshaderstring) + 1);
+ shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(hlslshaderstring) + 1);
+ memcpy(shaderstring, hlslshaderstring, strlen(hlslshaderstring) + 1);
return shaderstring;
}
shaderstring = (char *)FS_LoadFile(filename, r_main_mempool, false, NULL);
return shaderstring;
}
-static void R_CG_CacheShader(r_cg_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
-{
- // TODO: load or create .fp and .vp shader files
+#include <d3dx9.h>
+//#include <d3dx9shader.h>
+//#include <d3dx9mesh.h>
+
+static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
+{
+ DWORD *vsbin = NULL;
+ DWORD *psbin = NULL;
+ fs_offset_t vsbinsize;
+ fs_offset_t psbinsize;
+// IDirect3DVertexShader9 *vs = NULL;
+// IDirect3DPixelShader9 *ps = NULL;
+ ID3DXBuffer *vslog = NULL;
+ ID3DXBuffer *vsbuffer = NULL;
+ ID3DXConstantTable *vsconstanttable = NULL;
+ ID3DXBuffer *pslog = NULL;
+ ID3DXBuffer *psbuffer = NULL;
+ ID3DXConstantTable *psconstanttable = NULL;
+ int vsresult = 0;
+ int psresult = 0;
+ char temp[MAX_INPUTLINE];
+ const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
+ qboolean debugshader = gl_paranoid.integer != 0;
+ if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
+ if (p->permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) {vsversion = "vs_3_0";psversion = "ps_3_0";}
+ if (!debugshader)
+ {
+ vsbin = (DWORD *)FS_LoadFile(va("%s.vsbin", cachename), r_main_mempool, true, &vsbinsize);
+ psbin = (DWORD *)FS_LoadFile(va("%s.psbin", cachename), r_main_mempool, true, &psbinsize);
+ }
+ if ((!vsbin && vertstring) || (!psbin && fragstring))
+ {
+ const char* dllnames_d3dx9 [] =
+ {
+ "d3dx9_43.dll",
+ "d3dx9_42.dll",
+ "d3dx9_41.dll",
+ "d3dx9_40.dll",
+ "d3dx9_39.dll",
+ "d3dx9_38.dll",
+ "d3dx9_37.dll",
+ "d3dx9_36.dll",
+ "d3dx9_35.dll",
+ "d3dx9_34.dll",
+ "d3dx9_33.dll",
+ "d3dx9_32.dll",
+ "d3dx9_31.dll",
+ "d3dx9_30.dll",
+ "d3dx9_29.dll",
+ "d3dx9_28.dll",
+ "d3dx9_27.dll",
+ "d3dx9_26.dll",
+ "d3dx9_25.dll",
+ "d3dx9_24.dll",
+ NULL
+ };
+ dllhandle_t d3dx9_dll = NULL;
+ HRESULT (WINAPI *qD3DXCompileShaderFromFileA)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
+ HRESULT (WINAPI *qD3DXPreprocessShader)(LPCSTR pSrcData, UINT SrcDataSize, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs);
+ HRESULT (WINAPI *qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
+ dllfunction_t d3dx9_dllfuncs[] =
+ {
+ {"D3DXCompileShaderFromFileA", (void **) &qD3DXCompileShaderFromFileA},
+ {"D3DXPreprocessShader", (void **) &qD3DXPreprocessShader},
+ {"D3DXCompileShader", (void **) &qD3DXCompileShader},
+ {NULL, NULL}
+ };
+ if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
+ {
+ DWORD shaderflags = 0;
+ if (debugshader)
+ shaderflags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
+ vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
+ psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
+ if (vertstring && vertstring[0])
+ {
+ if (debugshader)
+ {
+// vsresult = qD3DXPreprocessShader(vertstring, strlen(vertstring), NULL, NULL, &vsbuffer, &vslog);
+// FS_WriteFile(va("%s_vs.fx", cachename), vsbuffer->GetBufferPointer(), vsbuffer->GetBufferSize());
+ FS_WriteFile(va("%s_vs.fx", cachename), vertstring, strlen(vertstring));
+ vsresult = qD3DXCompileShaderFromFileA(va("%s/%s_vs.fx", fs_gamedir, cachename), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
+ }
+ else
+ vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, shaderflags, &vsbuffer, &vslog, &vsconstanttable);
+ if (vsbuffer)
+ {
+ vsbinsize = vsbuffer->GetBufferSize();
+ vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
+ memcpy(vsbin, vsbuffer->GetBufferPointer(), vsbinsize);
+ vsbuffer->Release();
+ }
+ if (vslog)
+ {
+ strlcpy(temp, (const char *)vslog->GetBufferPointer(), min(sizeof(temp), vslog->GetBufferSize()));
+ Con_Printf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
+ vslog->Release();
+ }
+ }
+ if (fragstring && fragstring[0])
+ {
+ if (debugshader)
+ {
+// psresult = qD3DXPreprocessShader(fragstring, strlen(fragstring), NULL, NULL, &psbuffer, &pslog);
+// FS_WriteFile(va("%s_ps.fx", cachename), psbuffer->GetBufferPointer(), psbuffer->GetBufferSize());
+ FS_WriteFile(va("%s_ps.fx", cachename), fragstring, strlen(fragstring));
+ psresult = qD3DXCompileShaderFromFileA(va("%s/%s_ps.fx", fs_gamedir, cachename), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
+ }
+ else
+ psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, shaderflags, &psbuffer, &pslog, &psconstanttable);
+ if (psbuffer)
+ {
+ psbinsize = psbuffer->GetBufferSize();
+ psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
+ memcpy(psbin, psbuffer->GetBufferPointer(), psbinsize);
+ psbuffer->Release();
+ }
+ if (pslog)
+ {
+ strlcpy(temp, (const char *)pslog->GetBufferPointer(), min(sizeof(temp), pslog->GetBufferSize()));
+ Con_Printf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
+ pslog->Release();
+ }
+ }
+ Sys_UnloadLibrary(&d3dx9_dll);
+ }
+ else
+ Con_Printf("Unable to compile shader - D3DXCompileShader function not found\n");
+ }
+ if (vsbin && psbin)
+ {
+ vsresult = IDirect3DDevice9_CreateVertexShader(vid_d3d9dev, vsbin, &p->vertexshader);
+ if (FAILED(vsresult))
+ Con_Printf("HLSL CreateVertexShader failed for %s (hresult = %8x)\n", cachename, vsresult);
+ psresult = IDirect3DDevice9_CreatePixelShader(vid_d3d9dev, psbin, &p->pixelshader);
+ if (FAILED(psresult))
+ Con_Printf("HLSL CreatePixelShader failed for %s (hresult = %8x)\n", cachename, psresult);
+ }
+ // free the shader data
+ vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
+ psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
}
-static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, unsigned int permutation)
+static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode, unsigned int permutation)
{
int i;
- shadermodeinfo_t *modeinfo = cgshadermodeinfo + mode;
- int vertstrings_count = 0, vertstring_length = 0;
- int geomstrings_count = 0, geomstring_length = 0;
- int fragstrings_count = 0, fragstring_length = 0;
+ shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
+ int vertstring_length = 0;
+ int geomstring_length = 0;
+ int fragstring_length = 0;
char *t;
char *vertexstring, *geometrystring, *fragmentstring;
char *vertstring, *geomstring, *fragstring;
- const char *vertstrings_list[32+3];
- const char *geomstrings_list[32+3];
- const char *fragstrings_list[32+3];
char permutationname[256];
char cachename[256];
- CGprofile vertexProfile;
- CGprofile fragmentProfile;
+ int vertstrings_count = 0;
+ int geomstrings_count = 0;
+ int fragstrings_count = 0;
+ const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+ const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+ const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
if (p->compiled)
return;
p->compiled = true;
- p->vprogram = NULL;
- p->fprogram = NULL;
+ p->vertexshader = NULL;
+ p->pixelshader = NULL;
permutationname[0] = 0;
cachename[0] = 0;
- vertexstring = R_CG_GetText(modeinfo->vertexfilename, true);
- geometrystring = R_CG_GetText(modeinfo->geometryfilename, false);
- fragmentstring = R_CG_GetText(modeinfo->fragmentfilename, false);
+ vertexstring = R_HLSL_GetText(modeinfo->vertexfilename, true);
+ geometrystring = R_HLSL_GetText(modeinfo->geometryfilename, false);
+ fragmentstring = R_HLSL_GetText(modeinfo->fragmentfilename, false);
strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname));
- strlcat(cachename, "cg/", sizeof(cachename));
+ strlcat(cachename, "hlsl/", sizeof(cachename));
+
+ // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
+ vertstrings_count = 0;
+ geomstrings_count = 0;
+ fragstrings_count = 0;
+ vertstrings_list[vertstrings_count++] = "#define HLSL\n";
+ geomstrings_list[geomstrings_count++] = "#define HLSL\n";
+ fragstrings_list[fragstrings_count++] = "#define HLSL\n";
// the first pretext is which type of shader to compile as
// (later these will all be bound together as a program object)
}
}
+ // add static parms
+ R_CompileShader_AddStaticParms(mode, permutation);
+ memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+ vertstrings_count += shaderstaticparms_count;
+ memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+ geomstrings_count += shaderstaticparms_count;
+ memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+ fragstrings_count += shaderstaticparms_count;
+
// replace spaces in the cachename with _ characters
for (i = 0;cachename[i];i++)
if (cachename[i] == ' ')
vertstring_length = 0;
for (i = 0;i < vertstrings_count;i++)
vertstring_length += strlen(vertstrings_list[i]);
- vertstring = t = Mem_Alloc(tempmempool, vertstring_length + 1);
+ vertstring = t = (char *)Mem_Alloc(tempmempool, vertstring_length + 1);
for (i = 0;i < vertstrings_count;t += strlen(vertstrings_list[i]), i++)
memcpy(t, vertstrings_list[i], strlen(vertstrings_list[i]));
geomstring_length = 0;
for (i = 0;i < geomstrings_count;i++)
geomstring_length += strlen(geomstrings_list[i]);
- geomstring = t = Mem_Alloc(tempmempool, geomstring_length + 1);
+ geomstring = t = (char *)Mem_Alloc(tempmempool, geomstring_length + 1);
for (i = 0;i < geomstrings_count;t += strlen(geomstrings_list[i]), i++)
memcpy(t, geomstrings_list[i], strlen(geomstrings_list[i]));
fragstring_length = 0;
for (i = 0;i < fragstrings_count;i++)
fragstring_length += strlen(fragstrings_list[i]);
- fragstring = t = Mem_Alloc(tempmempool, fragstring_length + 1);
+ fragstring = t = (char *)Mem_Alloc(tempmempool, fragstring_length + 1);
for (i = 0;i < fragstrings_count;t += strlen(fragstrings_list[i]), i++)
memcpy(t, fragstrings_list[i], strlen(fragstrings_list[i]));
- CHECKGLERROR
- CHECKCGERROR
- //vertexProfile = CG_PROFILE_ARBVP1;
- //fragmentProfile = CG_PROFILE_ARBFP1;
- vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);CHECKCGERROR
- fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);CHECKCGERROR
- //cgGLSetOptimalOptions(vertexProfile);CHECKCGERROR
- //cgGLSetOptimalOptions(fragmentProfile);CHECKCGERROR
- //cgSetAutoCompile(vid.cgcontext, CG_COMPILE_MANUAL);CHECKCGERROR
- CHECKGLERROR
-
// try to load the cached shader, or generate one
- R_CG_CacheShader(p, cachename, vertstring, fragstring);
-
- // if caching failed, do a dynamic compile for now
- CHECKCGERROR
- if (vertstring[0] && !p->vprogram)
- p->vprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, vertstring, vertexProfile, NULL, NULL);
- CHECKCGERROR
- if (fragstring[0] && !p->fprogram)
- p->fprogram = cgCreateProgram(vid.cgcontext, CG_SOURCE, fragstring, fragmentProfile, NULL, NULL);
- CHECKCGERROR
-
- // look up all the uniform variable names we care about, so we don't
- // have to look them up every time we set them
- if (p->vprogram)
- {
- CHECKCGERROR
- cgGLLoadProgram(p->vprogram);CHECKCGERROR CHECKGLERROR
- cgGLEnableProfile(vertexProfile);CHECKCGERROR CHECKGLERROR
- p->vp_EyePosition = cgGetNamedParameter(p->vprogram, "EyePosition");
- p->vp_FogPlane = cgGetNamedParameter(p->vprogram, "FogPlane");
- p->vp_LightDir = cgGetNamedParameter(p->vprogram, "LightDir");
- p->vp_LightPosition = cgGetNamedParameter(p->vprogram, "LightPosition");
- p->vp_ModelToLight = cgGetNamedParameter(p->vprogram, "ModelToLight");
- p->vp_TexMatrix = cgGetNamedParameter(p->vprogram, "TexMatrix");
- p->vp_BackgroundTexMatrix = cgGetNamedParameter(p->vprogram, "BackgroundTexMatrix");
- p->vp_ModelViewProjectionMatrix = cgGetNamedParameter(p->vprogram, "ModelViewProjectionMatrix");
- p->vp_ModelViewMatrix = cgGetNamedParameter(p->vprogram, "ModelViewMatrix");
- p->vp_ShadowMapMatrix = cgGetNamedParameter(p->vprogram, "ShadowMapMatrix");
- CHECKCGERROR
- }
- if (p->fprogram)
- {
- CHECKCGERROR
- cgGLLoadProgram(p->fprogram);CHECKCGERROR CHECKGLERROR
- cgGLEnableProfile(fragmentProfile);CHECKCGERROR CHECKGLERROR
- p->fp_Texture_First = cgGetNamedParameter(p->fprogram, "Texture_First");
- p->fp_Texture_Second = cgGetNamedParameter(p->fprogram, "Texture_Second");
- p->fp_Texture_GammaRamps = cgGetNamedParameter(p->fprogram, "Texture_GammaRamps");
- p->fp_Texture_Normal = cgGetNamedParameter(p->fprogram, "Texture_Normal");
- p->fp_Texture_Color = cgGetNamedParameter(p->fprogram, "Texture_Color");
- p->fp_Texture_Gloss = cgGetNamedParameter(p->fprogram, "Texture_Gloss");
- p->fp_Texture_Glow = cgGetNamedParameter(p->fprogram, "Texture_Glow");
- p->fp_Texture_SecondaryNormal = cgGetNamedParameter(p->fprogram, "Texture_SecondaryNormal");
- p->fp_Texture_SecondaryColor = cgGetNamedParameter(p->fprogram, "Texture_SecondaryColor");
- p->fp_Texture_SecondaryGloss = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGloss");
- p->fp_Texture_SecondaryGlow = cgGetNamedParameter(p->fprogram, "Texture_SecondaryGlow");
- p->fp_Texture_Pants = cgGetNamedParameter(p->fprogram, "Texture_Pants");
- p->fp_Texture_Shirt = cgGetNamedParameter(p->fprogram, "Texture_Shirt");
- p->fp_Texture_FogHeightTexture = cgGetNamedParameter(p->fprogram, "Texture_FogHeightTexture");
- p->fp_Texture_FogMask = cgGetNamedParameter(p->fprogram, "Texture_FogMask");
- p->fp_Texture_Lightmap = cgGetNamedParameter(p->fprogram, "Texture_Lightmap");
- p->fp_Texture_Deluxemap = cgGetNamedParameter(p->fprogram, "Texture_Deluxemap");
- p->fp_Texture_Attenuation = cgGetNamedParameter(p->fprogram, "Texture_Attenuation");
- p->fp_Texture_Cube = cgGetNamedParameter(p->fprogram, "Texture_Cube");
- p->fp_Texture_Refraction = cgGetNamedParameter(p->fprogram, "Texture_Refraction");
- p->fp_Texture_Reflection = cgGetNamedParameter(p->fprogram, "Texture_Reflection");
- p->fp_Texture_ShadowMapRect = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapRect");
- p->fp_Texture_ShadowMapCube = cgGetNamedParameter(p->fprogram, "Texture_ShadowMapCube");
- p->fp_Texture_ShadowMap2D = cgGetNamedParameter(p->fprogram, "Texture_ShadowMap2D");
- p->fp_Texture_CubeProjection = cgGetNamedParameter(p->fprogram, "Texture_CubeProjection");
- p->fp_Texture_ScreenDepth = cgGetNamedParameter(p->fprogram, "Texture_ScreenDepth");
- p->fp_Texture_ScreenNormalMap = cgGetNamedParameter(p->fprogram, "Texture_ScreenNormalMap");
- p->fp_Texture_ScreenDiffuse = cgGetNamedParameter(p->fprogram, "Texture_ScreenDiffuse");
- p->fp_Texture_ScreenSpecular = cgGetNamedParameter(p->fprogram, "Texture_ScreenSpecular");
- p->fp_Texture_ReflectMask = cgGetNamedParameter(p->fprogram, "Texture_ReflectMask");
- p->fp_Texture_ReflectCube = cgGetNamedParameter(p->fprogram, "Texture_ReflectCube");
- p->fp_Alpha = cgGetNamedParameter(p->fprogram, "Alpha");
- p->fp_BloomBlur_Parameters = cgGetNamedParameter(p->fprogram, "BloomBlur_Parameters");
- p->fp_ClientTime = cgGetNamedParameter(p->fprogram, "ClientTime");
- p->fp_Color_Ambient = cgGetNamedParameter(p->fprogram, "Color_Ambient");
- p->fp_Color_Diffuse = cgGetNamedParameter(p->fprogram, "Color_Diffuse");
- p->fp_Color_Specular = cgGetNamedParameter(p->fprogram, "Color_Specular");
- p->fp_Color_Glow = cgGetNamedParameter(p->fprogram, "Color_Glow");
- p->fp_Color_Pants = cgGetNamedParameter(p->fprogram, "Color_Pants");
- p->fp_Color_Shirt = cgGetNamedParameter(p->fprogram, "Color_Shirt");
- p->fp_DeferredColor_Ambient = cgGetNamedParameter(p->fprogram, "DeferredColor_Ambient");
- p->fp_DeferredColor_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredColor_Diffuse");
- p->fp_DeferredColor_Specular = cgGetNamedParameter(p->fprogram, "DeferredColor_Specular");
- p->fp_DeferredMod_Diffuse = cgGetNamedParameter(p->fprogram, "DeferredMod_Diffuse");
- p->fp_DeferredMod_Specular = cgGetNamedParameter(p->fprogram, "DeferredMod_Specular");
- p->fp_DistortScaleRefractReflect = cgGetNamedParameter(p->fprogram, "DistortScaleRefractReflect");
- p->fp_EyePosition = cgGetNamedParameter(p->fprogram, "EyePosition");
- p->fp_FogColor = cgGetNamedParameter(p->fprogram, "FogColor");
- p->fp_FogHeightFade = cgGetNamedParameter(p->fprogram, "FogHeightFade");
- p->fp_FogPlane = cgGetNamedParameter(p->fprogram, "FogPlane");
- p->fp_FogPlaneViewDist = cgGetNamedParameter(p->fprogram, "FogPlaneViewDist");
- p->fp_FogRangeRecip = cgGetNamedParameter(p->fprogram, "FogRangeRecip");
- p->fp_LightColor = cgGetNamedParameter(p->fprogram, "LightColor");
- p->fp_LightDir = cgGetNamedParameter(p->fprogram, "LightDir");
- p->fp_LightPosition = cgGetNamedParameter(p->fprogram, "LightPosition");
- p->fp_OffsetMapping_Scale = cgGetNamedParameter(p->fprogram, "OffsetMapping_Scale");
- p->fp_PixelSize = cgGetNamedParameter(p->fprogram, "PixelSize");
- p->fp_ReflectColor = cgGetNamedParameter(p->fprogram, "ReflectColor");
- p->fp_ReflectFactor = cgGetNamedParameter(p->fprogram, "ReflectFactor");
- p->fp_ReflectOffset = cgGetNamedParameter(p->fprogram, "ReflectOffset");
- p->fp_RefractColor = cgGetNamedParameter(p->fprogram, "RefractColor");
- p->fp_Saturation = cgGetNamedParameter(p->fprogram, "Saturation");
- p->fp_ScreenCenterRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenCenterRefractReflect");
- p->fp_ScreenScaleRefractReflect = cgGetNamedParameter(p->fprogram, "ScreenScaleRefractReflect");
- p->fp_ScreenToDepth = cgGetNamedParameter(p->fprogram, "ScreenToDepth");
- p->fp_ShadowMap_Parameters = cgGetNamedParameter(p->fprogram, "ShadowMap_Parameters");
- p->fp_ShadowMap_TextureScale = cgGetNamedParameter(p->fprogram, "ShadowMap_TextureScale");
- p->fp_SpecularPower = cgGetNamedParameter(p->fprogram, "SpecularPower");
- p->fp_UserVec1 = cgGetNamedParameter(p->fprogram, "UserVec1");
- p->fp_UserVec2 = cgGetNamedParameter(p->fprogram, "UserVec2");
- p->fp_UserVec3 = cgGetNamedParameter(p->fprogram, "UserVec3");
- p->fp_UserVec4 = cgGetNamedParameter(p->fprogram, "UserVec4");
- p->fp_ViewTintColor = cgGetNamedParameter(p->fprogram, "ViewTintColor");
- p->fp_ViewToLight = cgGetNamedParameter(p->fprogram, "ViewToLight");
- p->fp_PixelToScreenTexCoord = cgGetNamedParameter(p->fprogram, "PixelToScreenTexCoord");
- p->fp_ModelToReflectCube = cgGetNamedParameter(p->fprogram, "ModelToReflectCube");
- CHECKCGERROR
- }
-
- if ((p->vprogram || !vertstring[0]) && (p->fprogram || !fragstring[0]))
- Con_DPrintf("^5CG shader %s compiled.\n", permutationname);
+ R_HLSL_CacheShader(p, cachename, vertstring, fragstring);
+
+ if ((p->vertexshader || !vertstring[0]) && (p->pixelshader || !fragstring[0]))
+ Con_DPrintf("^5HLSL shader %s compiled.\n", permutationname);
else
- Con_Printf("^1CG shader %s failed! some features may not work properly.\n", permutationname);
+ Con_Printf("^1HLSL shader %s failed! some features may not work properly.\n", permutationname);
// free the strings
if (vertstring)
Mem_Free(fragmentstring);
}
-void R_SetupShader_SetPermutationCG(unsigned int mode, unsigned int permutation)
+static inline void hlslVSSetParameter16f(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 4);}
+static inline void hlslVSSetParameter4fv(D3DVSREGISTER_t r, const float *a) {IDirect3DDevice9_SetVertexShaderConstantF(vid_d3d9dev, r, a, 1);}
+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);}
+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);}
+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);}
+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);}
+
+static inline void hlslPSSetParameter16f(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 4);}
+static inline void hlslPSSetParameter4fv(D3DPSREGISTER_t r, const float *a) {IDirect3DDevice9_SetPixelShaderConstantF(vid_d3d9dev, r, a, 1);}
+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);}
+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);}
+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);}
+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);}
+
+void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutation)
{
- r_cg_permutation_t *perm = R_CG_FindPermutation(mode, permutation);
- CHECKGLERROR
- CHECKCGERROR
- if (r_cg_permutation != perm)
+ r_hlsl_permutation_t *perm = R_HLSL_FindPermutation(mode, permutation);
+ if (r_hlsl_permutation != perm)
{
- r_cg_permutation = perm;
- if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
+ r_hlsl_permutation = perm;
+ if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
{
- if (!r_cg_permutation->compiled)
- R_CG_CompilePermutation(perm, mode, permutation);
- if (!r_cg_permutation->vprogram && !r_cg_permutation->fprogram)
+ if (!r_hlsl_permutation->compiled)
+ R_HLSL_CompilePermutation(perm, mode, permutation);
+ if (!r_hlsl_permutation->vertexshader && !r_hlsl_permutation->pixelshader)
{
// remove features until we find a valid permutation
int i;
if (!(permutation & j))
continue;
permutation -= j;
- r_cg_permutation = R_CG_FindPermutation(mode, permutation);
- if (!r_cg_permutation->compiled)
- R_CG_CompilePermutation(perm, mode, permutation);
- if (r_cg_permutation->vprogram || r_cg_permutation->fprogram)
+ r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
+ if (!r_hlsl_permutation->compiled)
+ R_HLSL_CompilePermutation(perm, mode, permutation);
+ if (r_hlsl_permutation->vertexshader || r_hlsl_permutation->pixelshader)
break;
}
if (i >= SHADERPERMUTATION_COUNT)
{
- //Con_Printf("Could not find a working Cg shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
- r_cg_permutation = R_CG_FindPermutation(mode, permutation);
+ //Con_Printf("Could not find a working HLSL shader for permutation %s %s\n", shadermodeinfo[mode].vertexfilename, shadermodeinfo[mode].pretext);
+ r_hlsl_permutation = R_HLSL_FindPermutation(mode, permutation);
return; // no bit left to clear, entire mode is broken
}
}
}
- CHECKGLERROR
- CHECKCGERROR
- if (r_cg_permutation->vprogram)
- {
- cgGLLoadProgram(r_cg_permutation->vprogram);CHECKCGERROR CHECKGLERROR
- cgGLBindProgram(r_cg_permutation->vprogram);CHECKCGERROR CHECKGLERROR
- cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
- }
- else
- {
- cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
- cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
- }
- if (r_cg_permutation->fprogram)
- {
- cgGLLoadProgram(r_cg_permutation->fprogram);CHECKCGERROR CHECKGLERROR
- cgGLBindProgram(r_cg_permutation->fprogram);CHECKCGERROR CHECKGLERROR
- cgGLEnableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- }
- else
- {
- cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- }
+ IDirect3DDevice9_SetVertexShader(vid_d3d9dev, r_hlsl_permutation->vertexshader);
+ IDirect3DDevice9_SetPixelShader(vid_d3d9dev, r_hlsl_permutation->pixelshader);
}
- CHECKCGERROR
- if (r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR
- if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR
- if (r_cg_permutation->fp_ClientTime) cgGLSetParameter1f(r_cg_permutation->fp_ClientTime, cl.time);CHECKCGERROR
+ hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
+ hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
+ hlslPSSetParameter1f(D3DPSREGISTER_ClientTime, cl.time);
}
+#endif
-void CG_BindTexture(CGparameter param, rtexture_t *tex)
+void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
{
- cgGLSetTextureParameter(param, R_GetTexture(tex));
- cgGLEnableTextureParameter(param);
+ DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer);
+ DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
+ DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
}
-#endif
void R_GLSL_Restart_f(void)
{
if (glslshaderstring && glslshaderstring != builtinshaderstring)
Mem_Free(glslshaderstring);
glslshaderstring = NULL;
- if (cgshaderstring && cgshaderstring != builtincgshaderstring)
- Mem_Free(cgshaderstring);
- cgshaderstring = NULL;
+ if (hlslshaderstring && hlslshaderstring != builtinhlslshaderstring)
+ Mem_Free(hlslshaderstring);
+ hlslshaderstring = NULL;
switch(vid.renderpath)
{
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ {
+ r_hlsl_permutation_t *p;
+ r_hlsl_permutation = NULL;
+ limit = Mem_ExpandableArray_IndexRange(&r_hlsl_permutationarray);
+ for (i = 0;i < limit;i++)
+ {
+ if ((p = (r_hlsl_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_hlsl_permutationarray, i)))
+ {
+ if (p->vertexshader)
+ IDirect3DVertexShader9_Release(p->vertexshader);
+ if (p->pixelshader)
+ IDirect3DPixelShader9_Release(p->pixelshader);
+ Mem_ExpandableArray_FreeRecord(&r_hlsl_permutationarray, (void*)p);
+ }
+ }
+ memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
+ }
+#endif
+ break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
{
r_glsl_permutation_t *p;
r_glsl_permutation = NULL;
memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
}
break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- {
- r_cg_permutation_t *p;
- r_cg_permutation = NULL;
- cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
- cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_VERTEX));CHECKCGERROR CHECKGLERROR
- cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- cgGLUnbindProgram(cgGLGetLatestProfile(CG_GL_FRAGMENT));CHECKCGERROR CHECKGLERROR
- limit = Mem_ExpandableArray_IndexRange(&r_cg_permutationarray);
- for (i = 0;i < limit;i++)
- {
- if ((p = (r_cg_permutation_t*)Mem_ExpandableArray_RecordAtIndex(&r_cg_permutationarray, i)))
- {
- if (p->vprogram)
- cgDestroyProgram(p->vprogram);
- if (p->fprogram)
- cgDestroyProgram(p->fprogram);
- Mem_ExpandableArray_FreeRecord(&r_cg_permutationarray, (void*)p);
- }
- }
- memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
- }
- break;
-#endif
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
+ break;
+ case RENDERPATH_SOFT:
break;
}
}
else
Con_Printf("failed to write to glsl/default.glsl\n");
-#ifdef SUPPORTCG
- file = FS_OpenRealFile("cg/default.cg", "w", false);
+ file = FS_OpenRealFile("hlsl/default.hlsl", "w", false);
if (file)
{
FS_Print(file, "/* The engine may define the following macros:\n");
FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
for (i = 0;i < SHADERMODE_COUNT;i++)
- FS_Print(file, cgshadermodeinfo[i].pretext);
+ FS_Print(file, hlslshadermodeinfo[i].pretext);
for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
FS_Print(file, shaderpermutationinfo[i].pretext);
FS_Print(file, "*/\n");
- FS_Print(file, builtincgshaderstring);
+ FS_Print(file, builtinhlslshaderstring);
FS_Close(file);
- Con_Printf("cg/default.cg written\n");
+ Con_Printf("hlsl/default.hlsl written\n");
}
else
- Con_Printf("failed to write to cg/default.cg\n");
-#endif
+ Con_Printf("failed to write to hlsl/default.hlsl\n");
}
-void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale)
+void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean notrippy)
{
+ unsigned int permutation = 0;
+ if (r_trippy.integer && !notrippy)
+ permutation |= SHADERPERMUTATION_TRIPPY;
+ permutation |= SHADERPERMUTATION_VIEWTINT;
+ if (first)
+ permutation |= SHADERPERMUTATION_DIFFUSE;
+ if (second)
+ permutation |= SHADERPERMUTATION_SPECULAR;
+ if (texturemode == GL_MODULATE)
+ permutation |= SHADERPERMUTATION_COLORMAPPING;
+ else if (texturemode == GL_ADD)
+ permutation |= SHADERPERMUTATION_GLOW;
+ else if (texturemode == GL_DECAL)
+ permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
if (!second)
texturemode = GL_MODULATE;
+ if (vid.allowalphatocoverage)
+ GL_AlphaToCoverage(false);
switch (vid.renderpath)
{
- case RENDERPATH_GL20:
- R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
- if (r_glsl_permutation->loc_Texture_First ) R_Mesh_TexBind(GL20TU_FIRST , first );
- if (r_glsl_permutation->loc_Texture_Second) R_Mesh_TexBind(GL20TU_SECOND, second);
- break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- CHECKCGERROR
- R_SetupShader_SetPermutationCG(SHADERMODE_GENERIC, (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (r_shadow_glossexact.integer ? SHADERPERMUTATION_EXACTSPECULARMATH : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
- if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , first );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Second) CG_BindTexture(r_cg_permutation->fp_Texture_Second, second);CHECKCGERROR
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, permutation);
+ R_Mesh_TexBind(GL20TU_FIRST , first );
+ R_Mesh_TexBind(GL20TU_SECOND, second);
#endif
break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, permutation);
+ R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , first );
+ R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second);
+ break;
case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
R_Mesh_TexBind(0, first );
R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1);
R_Mesh_TexBind(1, second);
case RENDERPATH_GL11:
R_Mesh_TexBind(0, first );
break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, permutation);
+ R_Mesh_TexBind(GL20TU_FIRST , first );
+ R_Mesh_TexBind(GL20TU_SECOND, second);
+ break;
}
}
-void R_SetupShader_DepthOrShadow(void)
+void R_SetupShader_DepthOrShadow(qboolean notrippy)
{
+ unsigned int permutation = 0;
+ if (r_trippy.integer && !notrippy)
+ permutation |= SHADERPERMUTATION_TRIPPY;
+ if (vid.allowalphatocoverage)
+ GL_AlphaToCoverage(false);
switch (vid.renderpath)
{
- case RENDERPATH_GL20:
- R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, 0);
- break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- R_SetupShader_SetPermutationCG(SHADERMODE_DEPTH_OR_SHADOW, 0);
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ R_SetupShader_SetPermutationHLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
#endif
break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, permutation);
+ break;
case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
R_Mesh_TexBind(0, 0);
R_Mesh_TexBind(1, 0);
break;
case RENDERPATH_GL11:
R_Mesh_TexBind(0, 0);
break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, permutation);
+ break;
}
}
-void R_SetupShader_ShowDepth(void)
+void R_SetupShader_ShowDepth(qboolean notrippy)
{
+ int permutation = 0;
+ if (r_trippy.integer && !notrippy)
+ permutation |= SHADERPERMUTATION_TRIPPY;
+ if (r_trippy.integer)
+ permutation |= SHADERPERMUTATION_TRIPPY;
+ if (vid.allowalphatocoverage)
+ GL_AlphaToCoverage(false);
switch (vid.renderpath)
{
- case RENDERPATH_GL20:
- R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, 0);
- break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- R_SetupShader_SetPermutationCG(SHADERMODE_SHOWDEPTH, 0);
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTHLSL
+ R_SetupShader_SetPermutationHLSL(SHADERMODE_SHOWDEPTH, permutation);
#endif
break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, permutation);
+ break;
case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
break;
case RENDERPATH_GL11:
break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationSoft(SHADERMODE_SHOWDEPTH, permutation);
+ break;
}
}
extern rtexture_t *r_shadow_attenuationgradienttexture;
extern rtexture_t *r_shadow_attenuation2dtexture;
extern rtexture_t *r_shadow_attenuation3dtexture;
-extern qboolean r_shadow_usingshadowmaprect;
-extern qboolean r_shadow_usingshadowmapcube;
extern qboolean r_shadow_usingshadowmap2d;
extern qboolean r_shadow_usingshadowmaportho;
extern float r_shadow_shadowmap_texturescale[2];
extern qboolean r_shadow_shadowmapvsdct;
extern qboolean r_shadow_shadowmapsampler;
extern int r_shadow_shadowmappcf;
-extern rtexture_t *r_shadow_shadowmaprectangletexture;
extern rtexture_t *r_shadow_shadowmap2dtexture;
-extern rtexture_t *r_shadow_shadowmapcubetexture[R_SHADOW_SHADOWMAP_NUMCUBEMAPS];
+extern rtexture_t *r_shadow_shadowmap2dcolortexture;
extern rtexture_t *r_shadow_shadowmapvsdcttexture;
extern matrix4x4_t r_shadow_shadowmapmatrix;
extern int r_shadow_shadowmaplod; // changes for each light based on distance
extern int r_shadow_prepass_height;
extern rtexture_t *r_shadow_prepassgeometrydepthtexture;
extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
+extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
extern rtexture_t *r_shadow_prepasslightingspeculartexture;
-extern cvar_t gl_mesh_separatearrays;
-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)
+
+#define BLENDFUNC_ALLOWS_COLORMOD 1
+#define BLENDFUNC_ALLOWS_FOG 2
+#define BLENDFUNC_ALLOWS_FOG_HACK0 4
+#define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
+#define BLENDFUNC_ALLOWS_ANYFOG (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
+static int R_BlendFuncFlags(int src, int dst)
+{
+ int r = 0;
+
+ // a blendfunc allows colormod if:
+ // a) it can never keep the destination pixel invariant, or
+ // b) it can keep the destination pixel invariant, and still can do so if colormodded
+ // this is to prevent unintended side effects from colormod
+
+ // a blendfunc allows fog if:
+ // blend(fog(src), fog(dst)) == fog(blend(src, dst))
+ // this is to prevent unintended side effects from fog
+
+ // these checks are the output of fogeval.pl
+
+ r |= BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_DST_ALPHA && dst == GL_ONE_MINUS_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_DST_COLOR && dst == GL_SRC_ALPHA) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_DST_COLOR && dst == GL_ZERO) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG_HACKALPHA;
+ if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_DST_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_DST_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_ONE_MINUS_DST_COLOR && dst == GL_SRC_COLOR) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ONE_MINUS_SRC_ALPHA && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_ONE_MINUS_SRC_COLOR && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+ if(src == GL_SRC_ALPHA && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
+ if(src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
+ if(src == GL_ZERO && dst == GL_SRC_COLOR) r &= ~BLENDFUNC_ALLOWS_COLORMOD;
+
+ return r;
+}
+
+void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qboolean notrippy)
{
// select a permutation of the lighting shader appropriate to this
// combination of texture, entity, light source, and fogging, only use the
// fragment shader on features that are not being used
unsigned int permutation = 0;
unsigned int mode = 0;
+ int blendfuncflags;
+ static float dummy_colormod[3] = {1, 1, 1};
+ float *colormod = rsurface.colormod;
float m16f[16];
+ matrix4x4_t tempmatrix;
+ r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
+ if (r_trippy.integer && !notrippy)
+ permutation |= SHADERPERMUTATION_TRIPPY;
+ if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
+ permutation |= SHADERPERMUTATION_ALPHAKILL;
+ if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
+ permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
if (rsurfacepass == RSURFPASS_BACKGROUND)
{
// distorted background
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
+ {
mode = SHADERMODE_WATER;
+ if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA))
+ {
+ // this is the right thing to do for wateralpha
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
+ }
+ else
+ {
+ // this is the right thing to do for entity alpha
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ }
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFRACTION)
+ {
mode = SHADERMODE_REFRACTION;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
else
{
mode = SHADERMODE_GENERIC;
permutation |= SHADERPERMUTATION_DIFFUSE;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
}
- GL_AlphaTest(false);
- GL_BlendFunc(GL_ONE, GL_ZERO);
+ if (vid.allowalphatocoverage)
+ GL_AlphaToCoverage(false);
}
else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
{
if (r_glsl_offsetmapping.integer)
{
- if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
- else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
+ switch(rsurface.texture->offsetmapping)
{
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_glsl_offsetmapping_reliefmapping.integer)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
+ case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_OFF: break;
}
}
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
- permutation |= SHADERPERMUTATION_ALPHAKILL;
// normalmap (deferred prepass), may use alpha test on diffuse
mode = SHADERMODE_DEFERREDGEOMETRY;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
- permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
- GL_AlphaTest(false);
GL_BlendFunc(GL_ONE, GL_ZERO);
+ blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO);
+ if (vid.allowalphatocoverage)
+ GL_AlphaToCoverage(false);
}
else if (rsurfacepass == RSURFPASS_RTLIGHT)
{
if (r_glsl_offsetmapping.integer)
{
- if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
- else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
+ switch(rsurface.texture->offsetmapping)
{
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_glsl_offsetmapping_reliefmapping.integer)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
+ case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_OFF: break;
}
}
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
// light source
mode = SHADERMODE_LIGHTSOURCE;
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
- permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
permutation |= SHADERPERMUTATION_CUBEFILTER;
if (diffusescale > 0)
permutation |= SHADERPERMUTATION_DIFFUSE;
if (specularscale > 0)
- {
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
- if (r_shadow_glossexact.integer)
- permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
- }
if (r_refdef.fogenabled)
permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
if (rsurface.texture->colormapping)
permutation |= SHADERPERMUTATION_COLORMAPPING;
- if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
- {
- if (r_shadow_usingshadowmaprect)
- permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
- if (r_shadow_usingshadowmap2d)
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
- if (r_shadow_usingshadowmapcube)
- permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
- else if(r_shadow_shadowmapvsdct)
+ if (r_shadow_usingshadowmap2d)
+ {
+ permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+ if(r_shadow_shadowmapvsdct)
permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
if (r_shadow_shadowmapsampler)
}
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ blendfuncflags = R_BlendFuncFlags(GL_SRC_ALPHA, GL_ONE);
+ if (vid.allowalphatocoverage)
+ GL_AlphaToCoverage(false);
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
{
if (r_glsl_offsetmapping.integer)
{
- if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
- else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
+ switch(rsurface.texture->offsetmapping)
{
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_glsl_offsetmapping_reliefmapping.integer)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
+ case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_OFF: break;
}
}
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
- if (r_shadow_usingshadowmaprect)
- permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
- if (r_shadow_usingshadowmap2d)
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+ permutation |= SHADERPERMUTATION_SHADOWMAP2D;
if (r_shadow_shadowmapsampler)
permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
permutation |= SHADERPERMUTATION_REFLECTION;
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ // when using alphatocoverage, we don't need alphakill
+ if (vid.allowalphatocoverage)
+ {
+ if (r_transparent_alphatocoverage.integer)
+ {
+ GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ permutation &= ~SHADERPERMUTATION_ALPHAKILL;
+ }
+ else
+ GL_AlphaToCoverage(false);
+ }
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
{
if (r_glsl_offsetmapping.integer)
{
- if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
- else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
+ switch(rsurface.texture->offsetmapping)
{
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_glsl_offsetmapping_reliefmapping.integer)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
+ case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_OFF: break;
}
}
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
permutation |= SHADERPERMUTATION_GLOW;
permutation |= SHADERPERMUTATION_DIFFUSE;
if (specularscale > 0)
- {
permutation |= SHADERPERMUTATION_SPECULAR;
- if (r_shadow_glossexact.integer)
- permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
- }
if (r_refdef.fogenabled)
permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE);
if (rsurface.texture->colormapping)
if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
- if (r_shadow_usingshadowmaprect)
- permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
- if (r_shadow_usingshadowmap2d)
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+ permutation |= SHADERPERMUTATION_SHADOWMAP2D;
if (r_shadow_shadowmapsampler)
permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ if (r_shadow_bouncegridtexture)
+ {
+ permutation |= SHADERPERMUTATION_BOUNCEGRID;
+ if (r_shadow_bouncegriddirectional)
+ permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
+ }
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ // when using alphatocoverage, we don't need alphakill
+ if (vid.allowalphatocoverage)
+ {
+ if (r_transparent_alphatocoverage.integer)
+ {
+ GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ permutation &= ~SHADERPERMUTATION_ALPHAKILL;
+ }
+ else
+ GL_AlphaToCoverage(false);
+ }
}
else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
{
if (r_glsl_offsetmapping.integer)
{
- if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
- else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
+ switch(rsurface.texture->offsetmapping)
{
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_glsl_offsetmapping_reliefmapping.integer)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
+ case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_OFF: break;
}
}
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
- if (r_shadow_usingshadowmaprect)
- permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
- if (r_shadow_usingshadowmap2d)
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+ permutation |= SHADERPERMUTATION_SHADOWMAP2D;
if (r_shadow_shadowmapsampler)
permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ if (r_shadow_bouncegridtexture)
+ {
+ permutation |= SHADERPERMUTATION_BOUNCEGRID;
+ if (r_shadow_bouncegriddirectional)
+ permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
+ }
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ // when using alphatocoverage, we don't need alphakill
+ if (vid.allowalphatocoverage)
+ {
+ if (r_transparent_alphatocoverage.integer)
+ {
+ GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ permutation &= ~SHADERPERMUTATION_ALPHAKILL;
+ }
+ else
+ GL_AlphaToCoverage(false);
+ }
}
else
{
if (r_glsl_offsetmapping.integer)
{
- if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
- else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF)
+ switch(rsurface.texture->offsetmapping)
{
- permutation |= SHADERPERMUTATION_OFFSETMAPPING;
- if (r_glsl_offsetmapping_reliefmapping.integer)
- permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;
+ case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
+ case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break;
+ case OFFSETMAPPING_OFF: break;
}
}
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)
if (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))
{
permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
- if (r_shadow_usingshadowmaprect)
- permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
- if (r_shadow_usingshadowmap2d)
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+ permutation |= SHADERPERMUTATION_SHADOWMAP2D;
if (r_shadow_shadowmapsampler)
permutation |= SHADERPERMUTATION_SHADOWSAMPLER;
permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP;
if (rsurface.texture->reflectmasktexture)
permutation |= SHADERPERMUTATION_REFLECTCUBE;
- if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
+ if (FAKELIGHT_ENABLED)
+ {
+ // fake lightmapping (q1bsp, q3bsp, fullbright map)
+ mode = SHADERMODE_FAKELIGHT;
+ permutation |= SHADERPERMUTATION_DIFFUSE;
+ if (specularscale > 0)
+ permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
+ }
+ else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping)
{
// deluxemapping (light direction texture)
if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace)
mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
permutation |= SHADERPERMUTATION_DIFFUSE;
if (specularscale > 0)
- {
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
- if (r_shadow_glossexact.integer)
- permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
- }
}
- else if (r_glsl_deluxemapping.integer >= 2)
+ else if (r_glsl_deluxemapping.integer >= 2 && rsurface.uselightmaptexture)
{
// fake deluxemapping (uniform light direction in tangentspace)
mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE;
permutation |= SHADERPERMUTATION_DIFFUSE;
if (specularscale > 0)
- {
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
- if (r_shadow_glossexact.integer)
- permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
- }
}
else if (rsurface.uselightmaptexture)
{
// ordinary vertex coloring (q3bsp)
mode = SHADERMODE_VERTEXCOLOR;
}
- GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ if (r_shadow_bouncegridtexture)
+ {
+ permutation |= SHADERPERMUTATION_BOUNCEGRID;
+ if (r_shadow_bouncegriddirectional)
+ permutation |= SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL;
+ }
GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ blendfuncflags = R_BlendFuncFlags(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+ // when using alphatocoverage, we don't need alphakill
+ if (vid.allowalphatocoverage)
+ {
+ if (r_transparent_alphatocoverage.integer)
+ {
+ GL_AlphaToCoverage((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
+ permutation &= ~SHADERPERMUTATION_ALPHAKILL;
+ }
+ else
+ GL_AlphaToCoverage(false);
+ }
}
+ if(!(blendfuncflags & BLENDFUNC_ALLOWS_COLORMOD))
+ colormod = dummy_colormod;
+ if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG))
+ permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE);
+ if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA)
+ permutation |= SHADERPERMUTATION_FOGALPHAHACK;
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
- if (gl_mesh_separatearrays.integer)
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ 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);
+ R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
+ R_SetupShader_SetPermutationHLSL(mode, permutation);
+ Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);hlslPSSetParameter16f(D3DPSREGISTER_ModelToReflectCube, m16f);
+ if (mode == SHADERMODE_LIGHTSOURCE)
{
- 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);
- R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
- R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
- R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
- R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
- R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
- R_Mesh_TexCoordPointer(3, 4, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
- R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
+ Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ModelToLight, m16f);
+ hlslVSSetParameter3f(D3DVSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
}
else
{
- 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);
- R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
+ if (mode == SHADERMODE_LIGHTDIRECTION)
+ {
+ hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ }
}
- R_SetupShader_SetPermutationGLSL(mode, permutation);
- if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
+ Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_TexMatrix, m16f);
+ Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_BackgroundTexMatrix, m16f);
+ Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);hlslVSSetParameter16f(D3DVSREGISTER_ShadowMapMatrix, m16f);
+ hlslVSSetParameter3f(D3DVSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
+ hlslVSSetParameter4f(D3DVSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
+
if (mode == SHADERMODE_LIGHTSOURCE)
{
- if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
- if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
- if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);
- if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);
- if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
-
+ hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
+
// additive passes are only darkened by fog, not tinted
- if (r_glsl_permutation->loc_FogColor >= 0)
- qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
+ hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
}
else
{
if (mode == SHADERMODE_FLATCOLOR)
{
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
}
else if (mode == SHADERMODE_LIGHTDIRECTION)
{
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);
- if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * rsurface.colormod[0], r_refdef.lightmapintensity * rsurface.colormod[1], r_refdef.lightmapintensity * rsurface.colormod[2]);
- if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);
- if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
- if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
- if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+ hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
}
else
{
- if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);
- if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
- if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
- if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
- if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
}
// additive passes are only darkened by fog, not tinted
- if (r_glsl_permutation->loc_FogColor >= 0)
- {
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
- qglUniform3fARB(r_glsl_permutation->loc_FogColor, 0, 0, 0);
- else
- qglUniform3fARB(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
- }
- if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
- if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
- if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
- if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
- if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
- if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
- if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
- }
- if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
- if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
- if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
- if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2fARB(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4fARB(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
-
- if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
- if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1fARB(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3]);
- if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
- if (r_glsl_permutation->loc_Color_Pants >= 0)
- {
- if (rsurface.texture->pantstexture)
- qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
+ hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
else
- qglUniform3fARB(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
+ hlslPSSetParameter3f(D3DPSREGISTER_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
+ hlslPSSetParameter4f(D3DPSREGISTER_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
+ hlslPSSetParameter4f(D3DPSREGISTER_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
+ hlslPSSetParameter4f(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ hlslPSSetParameter1f(D3DPSREGISTER_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
+ hlslPSSetParameter1f(D3DPSREGISTER_ReflectOffset, rsurface.texture->reflectmin);
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ if (mode == SHADERMODE_WATER)
+ hlslPSSetParameter2f(D3DPSREGISTER_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
+ }
+ hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
+ hlslPSSetParameter1f(D3DPSREGISTER_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
+ hlslPSSetParameter3f(D3DPSREGISTER_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
+ if (rsurface.texture->pantstexture)
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ else
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Pants, 0, 0, 0);
+ if (rsurface.texture->shirttexture)
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
+ else
+ hlslPSSetParameter3f(D3DPSREGISTER_Color_Shirt, 0, 0, 0);
+ hlslPSSetParameter4f(D3DPSREGISTER_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
+ hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist);
+ hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip);
+ hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade);
+ hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps,
+ r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
+ max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
+ 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
+ max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
+ );
+ hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
+
+ R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
+ R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
+ R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
+ R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
+ if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
+ if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
+ R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
+ R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
+ if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
+ if (rsurfacepass == RSURFPASS_BACKGROUND)
+ {
+ R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
+ if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
+ R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
}
- if (r_glsl_permutation->loc_Color_Shirt >= 0)
+ else
{
- if (rsurface.texture->shirttexture)
- qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
- else
- qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
- }
- if (r_glsl_permutation->loc_FogPlane >= 0) qglUniform4fARB(r_glsl_permutation->loc_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
- if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
- if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
- if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
- if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale);
- if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2fARB(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
- if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2fARB(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
-
- // if (r_glsl_permutation->loc_Texture_First >= 0) R_Mesh_TexBind(GL20TU_FIRST , r_texture_white );
- // if (r_glsl_permutation->loc_Texture_Second >= 0) R_Mesh_TexBind(GL20TU_SECOND , r_texture_white );
- // if (r_glsl_permutation->loc_Texture_GammaRamps >= 0) R_Mesh_TexBind(GL20TU_GAMMARAMPS , r_texture_gammaramps );
- if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
- if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
- if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
- if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
- if (r_glsl_permutation->loc_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
- if (r_glsl_permutation->loc_Texture_SecondaryColor >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
- if (r_glsl_permutation->loc_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
- if (r_glsl_permutation->loc_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
- if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
- if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
- if (r_glsl_permutation->loc_Texture_ReflectMask >= 0) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
- if (r_glsl_permutation->loc_Texture_ReflectCube >= 0) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
- if (r_glsl_permutation->loc_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
- if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
- if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(GL20TU_LIGHTMAP , r_texture_white );
- if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(GL20TU_DELUXEMAP , r_texture_blanknormalmap );
- if (r_glsl_permutation->loc_Texture_Attenuation >= 0) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
- if (r_glsl_permutation->loc_Texture_Refraction >= 0) R_Mesh_TexBind(GL20TU_REFRACTION , r_texture_white );
- if (r_glsl_permutation->loc_Texture_Reflection >= 0) R_Mesh_TexBind(GL20TU_REFLECTION , r_texture_white );
- if (r_glsl_permutation->loc_Texture_ScreenDepth >= 0) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
- if (r_glsl_permutation->loc_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
- if (r_glsl_permutation->loc_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
- if (r_glsl_permutation->loc_Texture_ScreenSpecular >= 0) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
+ if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ }
+// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
+// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
+ if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
+ if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
{
- if (r_glsl_permutation->loc_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_shadow_usingshadowmaportho ? GL20TU_SHADOWMAPORTHO2D : GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dtexture );
- if (r_glsl_permutation->loc_Texture_ShadowMapRect >= 0) R_Mesh_TexBind(r_shadow_usingshadowmaportho ? GL20TU_SHADOWMAPORTHORECT : GL20TU_SHADOWMAPRECT, r_shadow_shadowmaprectangletexture );
+ R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
if (rsurface.rtlight)
{
- if (r_glsl_permutation->loc_Texture_Cube >= 0) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
- if (r_shadow_usingshadowmapcube)
- if (r_glsl_permutation->loc_Texture_ShadowMapCube >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPCUBE , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);
- if (r_glsl_permutation->loc_Texture_CubeProjection >= 0) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
+ if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
+ if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
}
}
- CHECKGLERROR
+#endif
+ break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- if (gl_mesh_separatearrays.integer)
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ if (!vid.useinterleavedarrays)
{
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);
R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
R_Mesh_TexCoordPointer(1, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchsvector3f, rsurface.batchsvector3f_vertexbuffer, rsurface.batchsvector3f_bufferoffset);
R_Mesh_TexCoordPointer(2, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchtvector3f, rsurface.batchtvector3f_vertexbuffer, rsurface.batchtvector3f_bufferoffset);
- R_Mesh_TexCoordPointer(3, 4, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
+ R_Mesh_TexCoordPointer(3, 3, GL_FLOAT, sizeof(float[3]), rsurface.batchnormal3f, rsurface.batchnormal3f_vertexbuffer, rsurface.batchnormal3f_bufferoffset);
R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
}
else
{
- 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);
- R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
+ 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);
+ R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
+ }
+ R_SetupShader_SetPermutationGLSL(mode, permutation);
+ if (r_glsl_permutation->loc_ModelToReflectCube >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToReflectCube, 1, false, m16f);}
+ if (mode == SHADERMODE_LIGHTSOURCE)
+ {
+ if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
+ if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
+ if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
+ if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
+ if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
+
+ // additive passes are only darkened by fog, not tinted
+ if (r_glsl_permutation->loc_FogColor >= 0)
+ qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ }
+ else
+ {
+ if (mode == SHADERMODE_FLATCOLOR)
+ {
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
+ }
+ else if (mode == SHADERMODE_LIGHTDIRECTION)
+ {
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
+ if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
+ if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
+ if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
+ 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);
+ if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
+ if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ }
+ else
+ {
+ if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
+ if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
+ if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
+ if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
+ 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);
+ }
+ // additive passes are only darkened by fog, not tinted
+ if (r_glsl_permutation->loc_FogColor >= 0)
+ {
+ if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
+ qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0);
+ else
+ qglUniform3f(r_glsl_permutation->loc_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
+ }
+ if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
+ if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4f(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
+ 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]);
+ if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4f(r_glsl_permutation->loc_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4f(r_glsl_permutation->loc_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
+ if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1f(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2f(r_glsl_permutation->loc_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
+ }
+ if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);}
+ if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);}
+ if (r_glsl_permutation->loc_ShadowMapMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_ShadowMapMatrix, 1, false, m16f);}
+ if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f(r_glsl_permutation->loc_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f(r_glsl_permutation->loc_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+
+ if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
+ if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
+ if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
+ if (r_glsl_permutation->loc_Color_Pants >= 0)
+ {
+ if (rsurface.texture->pantstexture)
+ qglUniform3f(r_glsl_permutation->loc_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ else
+ qglUniform3f(r_glsl_permutation->loc_Color_Pants, 0, 0, 0);
}
- R_SetupShader_SetPermutationCG(mode, permutation);
- if (r_cg_permutation->fp_ModelToReflectCube) {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->fp_ModelToReflectCube, m16f);}CHECKCGERROR
- if (mode == SHADERMODE_LIGHTSOURCE)
+ if (r_glsl_permutation->loc_Color_Shirt >= 0)
{
- if (r_cg_permutation->vp_ModelToLight) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelToLight, m16f);}CHECKCGERROR
- if (r_cg_permutation->vp_LightPosition) cgGLSetParameter3f(r_cg_permutation->vp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);CHECKCGERROR
+ if (rsurface.texture->shirttexture)
+ qglUniform3f(r_glsl_permutation->loc_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
+ else
+ qglUniform3f(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0);
+ }
+ 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]);
+ if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist);
+ if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip);
+ if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade);
+ if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps,
+ r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
+ max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
+ 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
+ max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
+ );
+ if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
+ if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);}
+ if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale);
+
+ if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white );
+ if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white );
+ if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps , r_texture_gammaramps );
+ if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , rsurface.texture->nmaptexture );
+ if (r_glsl_permutation->tex_Texture_Color >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Color , rsurface.texture->basetexture );
+ if (r_glsl_permutation->tex_Texture_Gloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Gloss , rsurface.texture->glosstexture );
+ if (r_glsl_permutation->tex_Texture_Glow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Glow , rsurface.texture->glowtexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryNormal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryNormal , rsurface.texture->backgroundnmaptexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryColor >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryGloss >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );
+ if (r_glsl_permutation->tex_Texture_SecondaryGlow >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );
+ if (r_glsl_permutation->tex_Texture_Pants >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Pants , rsurface.texture->pantstexture );
+ if (r_glsl_permutation->tex_Texture_Shirt >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Shirt , rsurface.texture->shirttexture );
+ if (r_glsl_permutation->tex_Texture_ReflectMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectMask , rsurface.texture->reflectmasktexture );
+ if (r_glsl_permutation->tex_Texture_ReflectCube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ReflectCube , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
+ if (r_glsl_permutation->tex_Texture_FogHeightTexture>= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogHeightTexture , r_texture_fogheighttexture );
+ if (r_glsl_permutation->tex_Texture_FogMask >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_FogMask , r_texture_fogattenuation );
+ if (r_glsl_permutation->tex_Texture_Lightmap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Lightmap , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
+ if (r_glsl_permutation->tex_Texture_Deluxemap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Deluxemap , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
+ if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
+ if (rsurfacepass == RSURFPASS_BACKGROUND)
+ {
+ 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);
+ 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);
+ 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);
}
else
{
- if (mode == SHADERMODE_LIGHTDIRECTION)
+ 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);
+ }
+ if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );
+ if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
+ if (r_glsl_permutation->tex_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );
+ if (r_glsl_permutation->tex_Texture_ScreenSpecular >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );
+ if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
+ {
+ if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2dtexture );
+ if (rsurface.rtlight)
{
- 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
+ if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
+ if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
}
}
- if (r_cg_permutation->vp_TexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_TexMatrix, m16f);}CHECKCGERROR
- if (r_cg_permutation->vp_BackgroundTexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_BackgroundTexMatrix, m16f);}CHECKCGERROR
- if (r_cg_permutation->vp_ShadowMapMatrix) {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_ShadowMapMatrix, m16f);}CHECKGLERROR
- if (r_cg_permutation->vp_EyePosition) cgGLSetParameter3f(r_cg_permutation->vp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
- 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
+ if (r_glsl_permutation->tex_Texture_BounceGrid >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture);
CHECKGLERROR
-
+ break;
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
+ break;
+ case RENDERPATH_SOFT:
+ 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);
+ R_Mesh_PrepareVertices_Mesh_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchsvector3f, rsurface.batchtvector3f, rsurface.batchnormal3f, rsurface.batchlightmapcolor4f, rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f);
+ R_SetupShader_SetPermutationSoft(mode, permutation);
+ {Matrix4x4_ToArrayFloatGL(&rsurface.matrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
if (mode == SHADERMODE_LIGHTSOURCE)
{
- if (r_cg_permutation->fp_LightPosition) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);CHECKCGERROR
- if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKCGERROR
- if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);CHECKCGERROR
- if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);CHECKCGERROR
- 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
-
+ {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
+
// additive passes are only darkened by fog, not tinted
- if (r_cg_permutation->fp_FogColor) cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);CHECKCGERROR
- if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));CHECKCGERROR
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
}
else
{
if (mode == SHADERMODE_FLATCOLOR)
{
- if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);CHECKCGERROR
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
}
else if (mode == SHADERMODE_LIGHTDIRECTION)
{
- 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) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);CHECKCGERROR
- if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, r_refdef.lightmapintensity * rsurface.colormod[0], r_refdef.lightmapintensity * rsurface.colormod[1], r_refdef.lightmapintensity * rsurface.colormod[2]);CHECKCGERROR
- 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
- if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);CHECKCGERROR
- 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
- 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
- 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
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity * r_refdef.scene.rtlightstylevalue[0]) * colormod[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightColor, rsurface.modellight_diffuse[0] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[1] * r_refdef.scene.rtlightstylevalue[0], rsurface.modellight_diffuse[2] * r_refdef.scene.rtlightstylevalue[0]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
}
else
{
- if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);CHECKCGERROR
- 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
- 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
- if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
- 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
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
}
// additive passes are only darkened by fog, not tinted
- if (r_cg_permutation->fp_FogColor)
- {
- if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
- cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);
- else
- cgGLSetParameter3f(r_cg_permutation->fp_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
- CHECKCGERROR
- }
- 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
- 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
- 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
- if (r_cg_permutation->fp_RefractColor) cgGLSetParameter4fv(r_cg_permutation->fp_RefractColor, rsurface.texture->refractcolor4f);CHECKCGERROR
- if (r_cg_permutation->fp_ReflectColor) cgGLSetParameter4fv(r_cg_permutation->fp_ReflectColor, rsurface.texture->reflectcolor4f);CHECKCGERROR
- if (r_cg_permutation->fp_ReflectFactor) cgGLSetParameter1f(r_cg_permutation->fp_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);CHECKCGERROR
- if (r_cg_permutation->fp_ReflectOffset) cgGLSetParameter1f(r_cg_permutation->fp_ReflectOffset, rsurface.texture->reflectmin);CHECKCGERROR
- if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));CHECKCGERROR
- }
- 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
- 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
- if (r_cg_permutation->fp_Color_Glow) cgGLSetParameter3f(r_cg_permutation->fp_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);CHECKCGERROR
- if (r_cg_permutation->fp_Alpha) cgGLSetParameter1f(r_cg_permutation->fp_Alpha, rsurface.texture->lightmapcolor[3]);CHECKCGERROR
- if (r_cg_permutation->fp_EyePosition) cgGLSetParameter3f(r_cg_permutation->fp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR
- if (r_cg_permutation->fp_Color_Pants)
+ if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0)
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
+ else
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
+ }
+ {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
+ {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
+ {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
+ if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
{
if (rsurface.texture->pantstexture)
- cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
else
- cgGLSetParameter3f(r_cg_permutation->fp_Color_Pants, 0, 0, 0);
- CHECKCGERROR
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
}
- if (r_cg_permutation->fp_Color_Shirt)
+ if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
{
if (rsurface.texture->shirttexture)
- cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
else
- cgGLSetParameter3f(r_cg_permutation->fp_Color_Shirt, 0, 0, 0);
- CHECKCGERROR
- }
- 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
- if (r_cg_permutation->fp_FogPlaneViewDist) cgGLSetParameter1f(r_cg_permutation->fp_FogPlaneViewDist, rsurface.fogplaneviewdist);CHECKCGERROR
- if (r_cg_permutation->fp_FogRangeRecip) cgGLSetParameter1f(r_cg_permutation->fp_FogRangeRecip, rsurface.fograngerecip);CHECKCGERROR
- if (r_cg_permutation->fp_FogHeightFade) cgGLSetParameter1f(r_cg_permutation->fp_FogHeightFade, rsurface.fogheightfade);CHECKCGERROR
- if (r_cg_permutation->fp_OffsetMapping_Scale) cgGLSetParameter1f(r_cg_permutation->fp_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);CHECKCGERROR
- 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
- if (r_cg_permutation->fp_PixelToScreenTexCoord) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
-
- // if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , r_texture_white );CHECKCGERROR
- // if (r_cg_permutation->fp_Texture_Second ) CG_BindTexture(r_cg_permutation->fp_Texture_Second , r_texture_white );CHECKCGERROR
- // if (r_cg_permutation->fp_Texture_GammaRamps ) CG_BindTexture(r_cg_permutation->fp_Texture_GammaRamps , r_texture_gammaramps );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Normal ) CG_BindTexture(r_cg_permutation->fp_Texture_Normal , rsurface.texture->nmaptexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Color ) CG_BindTexture(r_cg_permutation->fp_Texture_Color , rsurface.texture->basetexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Gloss ) CG_BindTexture(r_cg_permutation->fp_Texture_Gloss , rsurface.texture->glosstexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Glow ) CG_BindTexture(r_cg_permutation->fp_Texture_Glow , rsurface.texture->glowtexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_SecondaryNormal) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryNormal, rsurface.texture->backgroundnmaptexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_SecondaryColor ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryColor , rsurface.texture->backgroundbasetexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_SecondaryGloss ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryGloss , rsurface.texture->backgroundglosstexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_SecondaryGlow ) CG_BindTexture(r_cg_permutation->fp_Texture_SecondaryGlow , rsurface.texture->backgroundglowtexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Pants ) CG_BindTexture(r_cg_permutation->fp_Texture_Pants , rsurface.texture->pantstexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Shirt ) CG_BindTexture(r_cg_permutation->fp_Texture_Shirt , rsurface.texture->shirttexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ReflectMask ) CG_BindTexture(r_cg_permutation->fp_Texture_ReflectMask , rsurface.texture->reflectmasktexture );CHECKCGERROR
- 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
- if (r_cg_permutation->fp_Texture_FogHeightTexture) CG_BindTexture(r_cg_permutation->fp_Texture_FogHeightTexture, r_texture_fogheighttexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_FogMask ) CG_BindTexture(r_cg_permutation->fp_Texture_FogMask , r_texture_fogattenuation );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Lightmap ) CG_BindTexture(r_cg_permutation->fp_Texture_Lightmap , r_texture_white );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Deluxemap ) CG_BindTexture(r_cg_permutation->fp_Texture_Deluxemap , r_texture_blanknormalmap );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Attenuation ) CG_BindTexture(r_cg_permutation->fp_Texture_Attenuation , r_shadow_attenuationgradienttexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Refraction ) CG_BindTexture(r_cg_permutation->fp_Texture_Refraction , r_texture_white );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Reflection ) CG_BindTexture(r_cg_permutation->fp_Texture_Reflection , r_texture_white );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ScreenDepth ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ScreenNormalMap) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ScreenDiffuse ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ScreenSpecular ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture );CHECKCGERROR
+ DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
+ }
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps,
+ r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale,
+ max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
+ 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer),
+ max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer)
+ );
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
+
+ R_Mesh_TexBind(GL20TU_NORMAL , rsurface.texture->nmaptexture );
+ R_Mesh_TexBind(GL20TU_COLOR , rsurface.texture->basetexture );
+ R_Mesh_TexBind(GL20TU_GLOSS , rsurface.texture->glosstexture );
+ R_Mesh_TexBind(GL20TU_GLOW , rsurface.texture->glowtexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_NORMAL , rsurface.texture->backgroundnmaptexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_COLOR , rsurface.texture->backgroundbasetexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS , rsurface.texture->backgroundglosstexture );
+ if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) R_Mesh_TexBind(GL20TU_SECONDARY_GLOW , rsurface.texture->backgroundglowtexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_PANTS , rsurface.texture->pantstexture );
+ if (permutation & SHADERPERMUTATION_COLORMAPPING) R_Mesh_TexBind(GL20TU_SHIRT , rsurface.texture->shirttexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTMASK , rsurface.texture->reflectmasktexture );
+ if (permutation & SHADERPERMUTATION_REFLECTCUBE) R_Mesh_TexBind(GL20TU_REFLECTCUBE , rsurface.texture->reflectcubetexture ? rsurface.texture->reflectcubetexture : r_texture_whitecube);
+ if (permutation & SHADERPERMUTATION_FOGHEIGHTTEXTURE) R_Mesh_TexBind(GL20TU_FOGHEIGHTTEXTURE , r_texture_fogheighttexture );
+ if (permutation & (SHADERPERMUTATION_FOGINSIDE | SHADERPERMUTATION_FOGOUTSIDE)) R_Mesh_TexBind(GL20TU_FOGMASK , r_texture_fogattenuation );
+ R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture ? rsurface.lightmaptexture : r_texture_white);
+ R_Mesh_TexBind(GL20TU_DELUXEMAP , rsurface.deluxemaptexture ? rsurface.deluxemaptexture : r_texture_blanknormalmap);
+ if (rsurface.rtlight ) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
+ if (rsurfacepass == RSURFPASS_BACKGROUND)
+ {
+ R_Mesh_TexBind(GL20TU_REFRACTION , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
+ if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
+ R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ }
+ else
+ {
+ if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
+ }
+// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
+// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
+ if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture );
+ if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture );
if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW)))
{
- if (r_cg_permutation->fp_Texture_ShadowMap2D ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ShadowMapRect ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapRect , r_shadow_shadowmaprectangletexture );CHECKCGERROR
+ R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
if (rsurface.rtlight)
{
- if (r_cg_permutation->fp_Texture_Cube ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube , rsurface.rtlight->currentcubemap );CHECKCGERROR
- if (r_shadow_usingshadowmapcube)
- if (r_cg_permutation->fp_Texture_ShadowMapCube ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapCube , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);CHECKCGERROR
- if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );CHECKCGERROR
+ if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
+ if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
}
}
-
- CHECKGLERROR
-#endif
- break;
- case RENDERPATH_GL13:
- case RENDERPATH_GL11:
break;
}
}
permutation |= SHADERPERMUTATION_CUBEFILTER;
if (diffusescale > 0)
permutation |= SHADERPERMUTATION_DIFFUSE;
- if (specularscale > 0)
- {
+ if (specularscale > 0 && r_shadow_gloss.integer > 0)
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
- if (r_shadow_glossexact.integer)
- permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
- }
- if (r_shadow_usingshadowmaprect || r_shadow_usingshadowmap2d || r_shadow_usingshadowmapcube)
+ if (r_shadow_usingshadowmap2d)
{
- if (r_shadow_usingshadowmaprect)
- permutation |= SHADERPERMUTATION_SHADOWMAPRECT;
- if (r_shadow_usingshadowmap2d)
- permutation |= SHADERPERMUTATION_SHADOWMAP2D;
- if (r_shadow_usingshadowmapcube)
- permutation |= SHADERPERMUTATION_SHADOWMAPCUBE;
- else if(r_shadow_shadowmapvsdct)
+ permutation |= SHADERPERMUTATION_SHADOWMAP2D;
+ if (r_shadow_shadowmapvsdct)
permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
if (r_shadow_shadowmapsampler)
else if (r_shadow_shadowmappcf)
permutation |= SHADERPERMUTATION_SHADOWMAPPCF;
}
+ if (vid.allowalphatocoverage)
+ GL_AlphaToCoverage(false);
Matrix4x4_Transform(&r_refdef.view.viewport.viewmatrix, rtlight->shadoworigin, viewlightorigin);
Matrix4x4_Concat(&lighttoview, &r_refdef.view.viewport.viewmatrix, &rtlight->matrix_lighttoworld);
Matrix4x4_Invert_Simple(&viewtolight, &lighttoview);
Matrix4x4_ToArrayFloatGL(&viewtolight, viewtolight16f);
switch(vid.renderpath)
{
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ R_SetupShader_SetPermutationHLSL(mode, permutation);
+ hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
+ hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
+ hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
+ hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
+
+ R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
+ R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthcolortexture );
+ R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
+ R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
+ R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dcolortexture );
+ R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
+#endif
+ break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
R_SetupShader_SetPermutationGLSL(mode, permutation);
- if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB( r_glsl_permutation->loc_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
- if (r_glsl_permutation->loc_ViewToLight >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ViewToLight , 1, false, viewtolight16f);
- if (r_glsl_permutation->loc_DeferredColor_Ambient >= 0) qglUniform3fARB( r_glsl_permutation->loc_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
- if (r_glsl_permutation->loc_DeferredColor_Diffuse >= 0) qglUniform3fARB( r_glsl_permutation->loc_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
- if (r_glsl_permutation->loc_DeferredColor_Specular >= 0) qglUniform3fARB( r_glsl_permutation->loc_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
- if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2fARB( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
- if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4fARB( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
- if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB( r_glsl_permutation->loc_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
- if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2fARB( r_glsl_permutation->loc_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
- if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2fARB(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
-
- if (r_glsl_permutation->loc_Texture_Attenuation >= 0) R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
- if (r_glsl_permutation->loc_Texture_ScreenDepth >= 0) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
- if (r_glsl_permutation->loc_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
- if (r_glsl_permutation->loc_Texture_Cube >= 0) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
- if (r_glsl_permutation->loc_Texture_ShadowMapRect >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPRECT , r_shadow_shadowmaprectangletexture );
- if (r_shadow_usingshadowmapcube)
- if (r_glsl_permutation->loc_Texture_ShadowMapCube >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAPCUBE , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);
- if (r_glsl_permutation->loc_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dtexture );
- if (r_glsl_permutation->loc_Texture_CubeProjection >= 0) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
+ if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3f( r_glsl_permutation->loc_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
+ if (r_glsl_permutation->loc_ViewToLight >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ViewToLight , 1, false, viewtolight16f);
+ 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);
+ 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);
+ 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);
+ if (r_glsl_permutation->loc_ShadowMap_TextureScale >= 0) qglUniform2f( r_glsl_permutation->loc_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ if (r_glsl_permutation->loc_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));
+ if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f( r_glsl_permutation->loc_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height);
+
+ if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture );
+ if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );
+ if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture );
+ if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap );
+ if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );
+ if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );
break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- R_SetupShader_SetPermutationCG(mode, permutation);
- if (r_cg_permutation->fp_LightPosition ) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);CHECKCGERROR
- if (r_cg_permutation->fp_ViewToLight ) cgGLSetMatrixParameterfc(r_cg_permutation->fp_ViewToLight, viewtolight16f);CHECKCGERROR
- 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
- 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
- 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
- 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
- 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
- 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) * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));CHECKCGERROR
- 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
- if (r_cg_permutation->fp_PixelToScreenTexCoord ) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
-
- if (r_cg_permutation->fp_Texture_Attenuation ) CG_BindTexture(r_cg_permutation->fp_Texture_Attenuation , r_shadow_attenuationgradienttexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ScreenDepth ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ScreenNormalMap ) CG_BindTexture(r_cg_permutation->fp_Texture_ScreenNormalMap, r_shadow_prepassgeometrynormalmaptexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Cube ) CG_BindTexture(r_cg_permutation->fp_Texture_Cube , rsurface.rtlight->currentcubemap );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ShadowMapRect ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapRect , r_shadow_shadowmaprectangletexture );CHECKCGERROR
- if (r_shadow_usingshadowmapcube)
- if (r_cg_permutation->fp_Texture_ShadowMapCube ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMapCube , r_shadow_shadowmapcubetexture[r_shadow_shadowmaplod]);CHECKCGERROR
- if (r_cg_permutation->fp_Texture_ShadowMap2D ) CG_BindTexture(r_cg_permutation->fp_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_CubeProjection ) CG_BindTexture(r_cg_permutation->fp_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture );CHECKCGERROR
-#endif
- break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
+ break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationGLSL(mode, permutation);
+ DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
+ DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ViewToLightM1 , 1, false, viewtolight16f);
+ DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
+ DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
+ DPSOFTRAST_Uniform3f( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
+ DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ DPSOFTRAST_Uniform4f( DPSOFTRAST_UNIFORM_ShadowMap_Parameters , r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]);
+ DPSOFTRAST_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));
+ DPSOFTRAST_Uniform2f( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
+
+ R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture );
+ R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture );
+ R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture );
+ R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
+ R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dtexture );
+ R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
break;
}
}
skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \
}
+extern cvar_t gl_picmip;
skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain)
{
int j;
qboolean ddshasalpha = false;
float ddsavgcolor[4];
char basename[MAX_QPATH];
+ int miplevel = R_PicmipForFlags(textureflags);
+ int savemiplevel = miplevel;
+ int mymiplevel;
if (cls.state == ca_dedicated)
return NULL;
Image_StripImageExtension(name, basename, sizeof(basename));
// check for DDS texture file first
- if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor)))
+ if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor, miplevel)))
{
- basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer);
+ basepixels = loadimagepixelsbgra(name, complain, true, false, &miplevel);
if (basepixels == NULL)
return NULL;
}
+ // FIXME handle miplevel
+
if (developer_loading.integer)
Con_Printf("loading skin \"%s\"\n", name);
skinframe->hasalpha = ddshasalpha;
VectorCopy(ddsavgcolor, skinframe->avgcolor);
if (r_loadfog && skinframe->hasalpha)
- skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL);
+ skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, miplevel);
//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]);
}
else
{
basepixels_width = image_width;
basepixels_height = image_height;
- skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
if (textureflags & TEXF_ALPHA)
{
for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
pixels[j+2] = 255;
pixels[j+3] = basepixels[j+3];
}
- skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
Mem_Free(pixels);
}
}
R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
//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]);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->base)
- R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), r_texture_dds_save.integer < 2, skinframe->hasalpha);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog)
- R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
}
if (r_loaddds)
{
+ mymiplevel = savemiplevel;
if (r_loadnormalmap)
- skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL);
- skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL);
+ 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);
+ skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
if (r_loadgloss)
- skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL);
- skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL);
+ skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
+ skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_reflect.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
}
// _norm is the name used by tenebrae and has been adopted as standard
if (r_loadnormalmap && skinframe->nmap == NULL)
{
- if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false, false)) != NULL)
+ mymiplevel = savemiplevel;
+ if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
{
- skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ 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 && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
Mem_Free(pixels);
pixels = NULL;
}
- else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false, false)) != NULL)
+ else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va("%s_bump", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
{
pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value);
- skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ 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 && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
Mem_Free(pixels);
Mem_Free(bumppixels);
}
{
pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4);
Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value);
- skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ 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 && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
Mem_Free(pixels);
}
if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap)
- R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
}
// _luma is supported only for tenebrae compatibility
// _glow is the preferred name
- if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer))))
+ mymiplevel = savemiplevel;
+ if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, false, &mymiplevel))))
{
- skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
- R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
Mem_Free(pixels);pixels = NULL;
}
- if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer)))
+ mymiplevel = savemiplevel;
+ if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, false, &mymiplevel)))
{
- skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
- R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
Mem_Free(pixels);
pixels = NULL;
}
- if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer)))
+ mymiplevel = savemiplevel;
+ if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, false, &mymiplevel)))
{
- skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
- R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
Mem_Free(pixels);
pixels = NULL;
}
- if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer)))
+ mymiplevel = savemiplevel;
+ if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, false, &mymiplevel)))
{
- skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
- R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
Mem_Free(pixels);
pixels = NULL;
}
- if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer)))
+ mymiplevel = savemiplevel;
+ if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, false, &mymiplevel)))
{
- skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), NULL);
+ skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer && gl_texturecompression.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
- R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true);
+ R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
Mem_Free(pixels);
pixels = NULL;
}
}
// this is only used by .spr32 sprites, HL .spr files, HL .bsp files
-skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height)
+skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, qboolean sRGB)
{
int i;
unsigned char *temp1, *temp2;
temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
temp2 = temp1 + width * height * 4;
Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
- skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL);
+ 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);
Mem_Free(temp1);
}
- skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, skinframe->textureflags, NULL);
+ skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, sRGB ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags, -1, NULL);
if (textureflags & TEXF_ALPHA)
{
for (i = 3;i < width * height * 4;i += 4)
memcpy(fogpixels, skindata, width * height * 4);
for (i = 0;i < width * height * 4;i += 4)
fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
- skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, skinframe->textureflags, NULL);
+ skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, textureflags, -1, NULL);
Mem_Free(fogpixels);
}
}
Con_Printf("loading quake skin \"%s\"\n", name);
// 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)
- skinframe->qpixels = Mem_Alloc(r_main_mempool, width*height);
+ skinframe->qpixels = (unsigned char *)Mem_Alloc(r_main_mempool, width*height); // FIXME LEAK
memcpy(skinframe->qpixels, skindata, width*height);
skinframe->qwidth = width;
skinframe->qheight = height;
// use either a custom palette or the quake palette
Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
- skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, NULL);
+ 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);
Mem_Free(temp1);
}
if (skinframe->qgenerateglow)
{
skinframe->qgenerateglow = false;
- skinframe->glow = R_LoadTexture2D(r_main_texturepool, va("%s_glow", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette_bgra_onlyfullbrights); // glow
+ skinframe->glow = R_LoadTexture2D(r_main_texturepool, va("%s_glow", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_onlyfullbrights); // glow
}
if (colormapped)
{
skinframe->qgeneratebase = false;
- skinframe->base = R_LoadTexture2D(r_main_texturepool, va("%s_nospecial", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, skinframe->glow ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap);
- skinframe->pants = R_LoadTexture2D(r_main_texturepool, va("%s_pants", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette_bgra_pantsaswhite);
- skinframe->shirt = R_LoadTexture2D(r_main_texturepool, va("%s_shirt", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette_bgra_shirtaswhite);
+ skinframe->base = R_LoadTexture2D(r_main_texturepool, va("%s_nospecial", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nocolormapnofullbrights : palette_bgra_nocolormap);
+ skinframe->pants = R_LoadTexture2D(r_main_texturepool, va("%s_pants", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_pantsaswhite);
+ skinframe->shirt = R_LoadTexture2D(r_main_texturepool, va("%s_shirt", skinframe->basename), width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, palette_bgra_shirtaswhite);
}
else
{
skinframe->qgeneratemerged = false;
- skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete);
+ skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, vid.sRGB3D ? TEXTYPE_SRGB_PALETTE : TEXTYPE_PALETTE, skinframe->textureflags, -1, skinframe->glow ? palette_bgra_nofullbrights : palette_bgra_complete);
}
if (!skinframe->qgeneratemerged && !skinframe->qgeneratebase)
if (developer_loading.integer)
Con_Printf("loading embedded 8bit image \"%s\"\n", name);
- skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, palette);
+ skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, palette);
if (textureflags & TEXF_ALPHA)
{
for (i = 0;i < width * height;i++)
}
}
if (r_loadfog && skinframe->hasalpha)
- skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, alphapalette);
+ skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, alphapalette);
}
R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
//static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
typedef struct suffixinfo_s
{
- char *suffix;
+ const char *suffix;
qboolean flipx, flipy, flipdiagonal;
}
suffixinfo_t;
// generate an image name based on the base and and suffix
dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix);
// load it
- if ((image_buffer = loadimagepixelsbgra(name, false, false, r_texture_convertsRGB_cubemap.integer)))
+ if ((image_buffer = loadimagepixelsbgra(name, false, false, false, NULL)))
{
// an image loaded, make sure width and height are equal
if (image_width == image_height && (!cubemappixels || image_width == cubemapsize))
if (developer_loading.integer)
Con_Printf("loading cubemap \"%s\"\n", basename);
- cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR, NULL);
+ cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer && gl_texturecompression.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
Mem_Free(cubemappixels);
}
else
{
int i;
for (i = 0;i < r_texture_numcubemaps;i++)
- if (!strcasecmp(r_texture_cubemaps[i].basename, basename))
- return r_texture_cubemaps[i].texture ? r_texture_cubemaps[i].texture : r_texture_whitecube;
- if (i >= MAX_CUBEMAPS)
+ if (r_texture_cubemaps[i] != NULL)
+ if (!strcasecmp(r_texture_cubemaps[i]->basename, basename))
+ return r_texture_cubemaps[i]->texture ? r_texture_cubemaps[i]->texture : r_texture_whitecube;
+ if (i >= MAX_CUBEMAPS || !r_main_mempool)
return r_texture_whitecube;
r_texture_numcubemaps++;
- strlcpy(r_texture_cubemaps[i].basename, basename, sizeof(r_texture_cubemaps[i].basename));
- r_texture_cubemaps[i].texture = R_LoadCubemap(r_texture_cubemaps[i].basename);
- return r_texture_cubemaps[i].texture;
+ r_texture_cubemaps[i] = (cubemapinfo_t *)Mem_Alloc(r_main_mempool, sizeof(cubemapinfo_t));
+ strlcpy(r_texture_cubemaps[i]->basename, basename, sizeof(r_texture_cubemaps[i]->basename));
+ r_texture_cubemaps[i]->texture = R_LoadCubemap(r_texture_cubemaps[i]->basename);
+ return r_texture_cubemaps[i]->texture;
+}
+
+void R_FreeCubemap(const char *basename)
+{
+ int i;
+
+ for (i = 0;i < r_texture_numcubemaps;i++)
+ {
+ if (r_texture_cubemaps[i] != NULL)
+ {
+ if (r_texture_cubemaps[i]->texture)
+ {
+ if (developer_loading.integer)
+ Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i]->basename);
+ R_FreeTexture(r_texture_cubemaps[i]->texture);
+ Mem_Free(r_texture_cubemaps[i]);
+ r_texture_cubemaps[i] = NULL;
+ }
+ }
+ }
}
void R_FreeCubemaps(void)
for (i = 0;i < r_texture_numcubemaps;i++)
{
if (developer_loading.integer)
- Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i].basename);
- if (r_texture_cubemaps[i].texture)
- R_FreeTexture(r_texture_cubemaps[i].texture);
+ Con_DPrintf("unloading cubemap \"%s\"\n", r_texture_cubemaps[i]->basename);
+ if (r_texture_cubemaps[i] != NULL)
+ {
+ if (r_texture_cubemaps[i]->texture)
+ R_FreeTexture(r_texture_cubemaps[i]->texture);
+ Mem_Free(r_texture_cubemaps[i]);
+ }
}
r_texture_numcubemaps = 0;
}
r_refdef.viewcache.maxentities = numentities;
if (r_refdef.viewcache.entityvisible)
Mem_Free(r_refdef.viewcache.entityvisible);
- r_refdef.viewcache.entityvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
+ r_refdef.viewcache.entityvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.maxentities);
}
if (r_refdef.viewcache.world_numclusters != numclusters)
{
r_refdef.viewcache.world_numclusterbytes = numclusterbytes;
if (r_refdef.viewcache.world_pvsbits)
Mem_Free(r_refdef.viewcache.world_pvsbits);
- r_refdef.viewcache.world_pvsbits = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
+ r_refdef.viewcache.world_pvsbits = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numclusterbytes);
}
if (r_refdef.viewcache.world_numleafs != numleafs)
{
r_refdef.viewcache.world_numleafs = numleafs;
if (r_refdef.viewcache.world_leafvisible)
Mem_Free(r_refdef.viewcache.world_leafvisible);
- r_refdef.viewcache.world_leafvisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
+ r_refdef.viewcache.world_leafvisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numleafs);
}
if (r_refdef.viewcache.world_numsurfaces != numsurfaces)
{
r_refdef.viewcache.world_numsurfaces = numsurfaces;
if (r_refdef.viewcache.world_surfacevisible)
Mem_Free(r_refdef.viewcache.world_surfacevisible);
- r_refdef.viewcache.world_surfacevisible = Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
+ r_refdef.viewcache.world_surfacevisible = (unsigned char *)Mem_Alloc(r_main_mempool, r_refdef.viewcache.world_numsurfaces);
}
}
r_texture_gammaramps = NULL;
r_texture_numcubemaps = 0;
- r_loaddds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_load.integer;
+ r_loaddds = r_texture_dds_load.integer != 0;
r_savedds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_save.integer;
switch(vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
Cvar_SetValueQuick(&r_textureunits, vid.texunits);
Cvar_SetValueQuick(&gl_combine, 1);
Cvar_SetValueQuick(&r_glsl, 1);
r_loadfog = false;
break;
case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
Cvar_SetValueQuick(&r_textureunits, vid.texunits);
Cvar_SetValueQuick(&gl_combine, 1);
Cvar_SetValueQuick(&r_glsl, 0);
r_qwskincache = NULL;
r_qwskincache_size = 0;
+ // due to caching of texture_t references, the collision cache must be reset
+ Collision_Cache_Reset(true);
+
// set up r_skinframe loading system for textures
memset(&r_skinframe, 0, sizeof(r_skinframe));
r_skinframe.loadsequence = 1;
memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
Mem_ExpandableArray_NewArray(&r_glsl_permutationarray, r_main_mempool, sizeof(r_glsl_permutation_t), 256);
glslshaderstring = NULL;
-#ifdef SUPPORTCG
- r_cg_permutation = NULL;
- memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
- Mem_ExpandableArray_NewArray(&r_cg_permutationarray, r_main_mempool, sizeof(r_cg_permutation_t), 256);
- cgshaderstring = NULL;
+#ifdef SUPPORTD3D
+ r_hlsl_permutation = NULL;
+ memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
+ Mem_ExpandableArray_NewArray(&r_hlsl_permutationarray, r_main_mempool, sizeof(r_hlsl_permutation_t), 256);
#endif
+ hlslshaderstring = NULL;
memset(&r_svbsp, 0, sizeof (r_svbsp));
+ memset(r_texture_cubemaps, 0, sizeof(r_texture_cubemaps));
+ r_texture_numcubemaps = 0;
+
r_refdef.fogmasktable_density = 0;
}
R_Main_FreeViewCache();
- if (r_maxqueries)
- qglDeleteQueriesARB(r_maxqueries, r_queries);
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ if (r_maxqueries)
+ qglDeleteQueriesARB(r_maxqueries, r_queries);
+ break;
+ case RENDERPATH_D3D9:
+ //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_SOFT:
+ break;
+ }
r_numqueries = 0;
r_maxqueries = 0;
//r_texture_fogintensity = NULL;
memset(&r_bloomstate, 0, sizeof(r_bloomstate));
memset(&r_waterstate, 0, sizeof(r_waterstate));
+ R_GLSL_Restart_f();
+
r_glsl_permutation = NULL;
memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash));
+ Mem_ExpandableArray_FreeArray(&r_glsl_permutationarray);
glslshaderstring = NULL;
-#ifdef SUPPORTCG
- r_cg_permutation = NULL;
- memset(r_cg_permutationhash, 0, sizeof(r_cg_permutationhash));
- cgshaderstring = NULL;
+#ifdef SUPPORTD3D
+ r_hlsl_permutation = NULL;
+ memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
+ Mem_ExpandableArray_FreeArray(&r_hlsl_permutationarray);
#endif
- R_GLSL_Restart_f();
+ hlslshaderstring = NULL;
}
extern void CL_ParseEntityLump(char *entitystring);
Cvar_RegisterVariable(&r_farclip_base);
Cvar_RegisterVariable(&r_farclip_world);
Cvar_RegisterVariable(&r_nearclip);
+ Cvar_RegisterVariable(&r_deformvertexes);
+ Cvar_RegisterVariable(&r_transparent);
+ Cvar_RegisterVariable(&r_transparent_alphatocoverage);
+ Cvar_RegisterVariable(&r_showoverdraw);
Cvar_RegisterVariable(&r_showbboxes);
Cvar_RegisterVariable(&r_showsurfaces);
Cvar_RegisterVariable(&r_showtris);
Cvar_RegisterVariable(&r_showdisabledepthtest);
Cvar_RegisterVariable(&r_drawportals);
Cvar_RegisterVariable(&r_drawentities);
+ Cvar_RegisterVariable(&r_draw2d);
Cvar_RegisterVariable(&r_drawworld);
Cvar_RegisterVariable(&r_cullentities_trace);
Cvar_RegisterVariable(&r_cullentities_trace_samples);
Cvar_RegisterVariable(&r_fullbrights);
Cvar_RegisterVariable(&r_wateralpha);
Cvar_RegisterVariable(&r_dynamic);
+ Cvar_RegisterVariable(&r_fakelight);
+ Cvar_RegisterVariable(&r_fakelight_intensity);
Cvar_RegisterVariable(&r_fullbright);
Cvar_RegisterVariable(&r_shadows);
Cvar_RegisterVariable(&r_shadows_darken);
Cvar_RegisterVariable(&r_polygonoffset_decals_factor);
Cvar_RegisterVariable(&r_polygonoffset_decals_offset);
Cvar_RegisterVariable(&r_fog_exp2);
+ Cvar_RegisterVariable(&r_fog_clear);
Cvar_RegisterVariable(&r_drawfog);
Cvar_RegisterVariable(&r_transparentdepthmasking);
+ Cvar_RegisterVariable(&r_transparent_sortmaxdist);
+ Cvar_RegisterVariable(&r_transparent_sortarraysize);
Cvar_RegisterVariable(&r_texture_dds_load);
Cvar_RegisterVariable(&r_texture_dds_save);
- Cvar_RegisterVariable(&r_texture_convertsRGB_2d);
- Cvar_RegisterVariable(&r_texture_convertsRGB_skin);
- Cvar_RegisterVariable(&r_texture_convertsRGB_cubemap);
- Cvar_RegisterVariable(&r_texture_convertsRGB_skybox);
- Cvar_RegisterVariable(&r_texture_convertsRGB_particles);
Cvar_RegisterVariable(&r_textureunits);
Cvar_RegisterVariable(&gl_combine);
+ Cvar_RegisterVariable(&r_viewfbo);
+ Cvar_RegisterVariable(&r_viewscale);
+ Cvar_RegisterVariable(&r_viewscale_fpsscaling);
+ Cvar_RegisterVariable(&r_viewscale_fpsscaling_min);
+ Cvar_RegisterVariable(&r_viewscale_fpsscaling_multiply);
+ Cvar_RegisterVariable(&r_viewscale_fpsscaling_stepsize);
+ Cvar_RegisterVariable(&r_viewscale_fpsscaling_stepmax);
+ Cvar_RegisterVariable(&r_viewscale_fpsscaling_target);
Cvar_RegisterVariable(&r_glsl);
Cvar_RegisterVariable(&r_glsl_deluxemapping);
Cvar_RegisterVariable(&r_glsl_offsetmapping);
+ Cvar_RegisterVariable(&r_glsl_offsetmapping_steps);
Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping);
+ Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping_steps);
+ Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping_refinesteps);
Cvar_RegisterVariable(&r_glsl_offsetmapping_scale);
Cvar_RegisterVariable(&r_glsl_postprocess);
Cvar_RegisterVariable(&r_glsl_postprocess_uservec1);
Cvar_RegisterVariable(&r_glsl_postprocess_uservec2);
Cvar_RegisterVariable(&r_glsl_postprocess_uservec3);
Cvar_RegisterVariable(&r_glsl_postprocess_uservec4);
+ Cvar_RegisterVariable(&r_glsl_postprocess_uservec1_enable);
+ Cvar_RegisterVariable(&r_glsl_postprocess_uservec2_enable);
+ Cvar_RegisterVariable(&r_glsl_postprocess_uservec3_enable);
+ Cvar_RegisterVariable(&r_glsl_postprocess_uservec4_enable);
+
Cvar_RegisterVariable(&r_water);
Cvar_RegisterVariable(&r_water_resolutionmultiplier);
Cvar_RegisterVariable(&r_water_clippingplanebias);
Cvar_RegisterVariable(&r_water_refractdistort);
Cvar_RegisterVariable(&r_water_reflectdistort);
+ Cvar_RegisterVariable(&r_water_scissormode);
+ Cvar_RegisterVariable(&r_water_lowquality);
+
Cvar_RegisterVariable(&r_lerpsprites);
Cvar_RegisterVariable(&r_lerpmodels);
Cvar_RegisterVariable(&r_lerplightstyles);
Cvar_RegisterVariable(&r_hdr_scenebrightness);
Cvar_RegisterVariable(&r_hdr_glowintensity);
Cvar_RegisterVariable(&r_hdr_range);
+ Cvar_RegisterVariable(&r_hdr_irisadaptation);
+ Cvar_RegisterVariable(&r_hdr_irisadaptation_multiplier);
+ Cvar_RegisterVariable(&r_hdr_irisadaptation_minvalue);
+ Cvar_RegisterVariable(&r_hdr_irisadaptation_maxvalue);
+ Cvar_RegisterVariable(&r_hdr_irisadaptation_value);
+ Cvar_RegisterVariable(&r_hdr_irisadaptation_fade);
Cvar_RegisterVariable(&r_smoothnormals_areaweighting);
Cvar_RegisterVariable(&developer_texturelogging);
Cvar_RegisterVariable(&gl_lightmaps);
Cvar_RegisterVariable(&r_test);
Cvar_RegisterVariable(&r_glsl_saturation);
+ Cvar_RegisterVariable(&r_glsl_saturation_redcompensate);
+ Cvar_RegisterVariable(&r_glsl_vertextextureblend_usebothalphas);
Cvar_RegisterVariable(&r_framedatasize);
if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
Cvar_SetValue("r_fullbrights", 0);
- R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
-
- Cvar_RegisterVariable(&r_track_sprites);
- Cvar_RegisterVariable(&r_track_sprites_flags);
- Cvar_RegisterVariable(&r_track_sprites_scalew);
- Cvar_RegisterVariable(&r_track_sprites_scaleh);
- Cvar_RegisterVariable(&r_overheadsprites_perspective);
- Cvar_RegisterVariable(&r_overheadsprites_pushback);
+ R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap, NULL, NULL);
}
extern void R_Textures_Init(void);
Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
// clear to black (loading plaque will be seen over this)
- CHECKGLERROR
- qglClearColor(0,0,0,1);CHECKGLERROR
- qglClear(GL_COLOR_BUFFER_BIT);CHECKGLERROR
+ GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);
}
int R_CullBox(const vec3_t mins, const vec3_t maxs)
{
int i;
mplane_t *p;
+ if (r_trippy.integer)
+ return false;
for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
{
// skip nearclip plane, it often culls portals when you are very close, and is almost never useful
{
int i;
const mplane_t *p;
+ if (r_trippy.integer)
+ return false;
for (i = 0;i < numplanes;i++)
{
p = planes + i;
// LordHavoc: this stores temporary data used within the same frame
-qboolean r_framedata_failed;
-static size_t r_framedata_size;
-static size_t r_framedata_current;
-static void *r_framedata_base;
+typedef struct r_framedata_mem_s
+{
+ struct r_framedata_mem_s *purge; // older mem block to free on next frame
+ size_t size; // how much usable space
+ size_t current; // how much space in use
+ size_t mark; // last "mark" location, temporary memory can be freed by returning to this
+ size_t wantedsize; // how much space was allocated
+ unsigned char *data; // start of real data (16byte aligned)
+}
+r_framedata_mem_t;
+
+static r_framedata_mem_t *r_framedata_mem;
void R_FrameData_Reset(void)
{
- if (r_framedata_base)
- Mem_Free(r_framedata_base);
- r_framedata_base = NULL;
- r_framedata_size = 0;
- r_framedata_current = 0;
- r_framedata_failed = false;
+ while (r_framedata_mem)
+ {
+ r_framedata_mem_t *next = r_framedata_mem->purge;
+ Mem_Free(r_framedata_mem);
+ r_framedata_mem = next;
+ }
}
-void R_FrameData_NewFrame(void)
+void R_FrameData_Resize(void)
{
size_t wantedsize;
- if (r_framedata_failed)
- Cvar_SetValueQuick(&r_framedatasize, r_framedatasize.value + 1.0f);
wantedsize = (size_t)(r_framedatasize.value * 1024*1024);
- wantedsize = bound(65536, wantedsize, 128*1024*1024);
- if (r_framedata_size != wantedsize)
+ wantedsize = bound(65536, wantedsize, 1000*1024*1024);
+ if (!r_framedata_mem || r_framedata_mem->wantedsize != wantedsize)
+ {
+ r_framedata_mem_t *newmem = (r_framedata_mem_t *)Mem_Alloc(r_main_mempool, wantedsize);
+ newmem->wantedsize = wantedsize;
+ newmem->data = (unsigned char *)(((size_t)(newmem+1) + 15) & ~15);
+ newmem->size = (unsigned char *)newmem + wantedsize - newmem->data;
+ newmem->current = 0;
+ newmem->mark = 0;
+ newmem->purge = r_framedata_mem;
+ r_framedata_mem = newmem;
+ }
+}
+
+void R_FrameData_NewFrame(void)
+{
+ R_FrameData_Resize();
+ if (!r_framedata_mem)
+ return;
+ // if we ran out of space on the last frame, free the old memory now
+ while (r_framedata_mem->purge)
{
- r_framedata_size = wantedsize;
- if (r_framedata_base)
- Mem_Free(r_framedata_base);
- r_framedata_base = Mem_Alloc(r_main_mempool, r_framedata_size);
+ // repeatedly remove the second item in the list, leaving only head
+ r_framedata_mem_t *next = r_framedata_mem->purge->purge;
+ Mem_Free(r_framedata_mem->purge);
+ r_framedata_mem->purge = next;
}
- r_framedata_current = 0;
- r_framedata_failed = false;
+ // reset the current mem pointer
+ r_framedata_mem->current = 0;
+ r_framedata_mem->mark = 0;
}
void *R_FrameData_Alloc(size_t size)
{
void *data;
- // align to 16 byte boundary
+ // align to 16 byte boundary - the data pointer is already aligned, so we
+ // only need to ensure the size of every allocation is also aligned
size = (size + 15) & ~15;
- data = (void *)((unsigned char*)r_framedata_base + r_framedata_current);
- r_framedata_current += size;
- // check overflow
- if (r_framedata_current > r_framedata_size)
- r_framedata_failed = true;
+ while (!r_framedata_mem || r_framedata_mem->current + size > r_framedata_mem->size)
+ {
+ // emergency - we ran out of space, allocate more memory
+ Cvar_SetValueQuick(&r_framedatasize, bound(0.25f, r_framedatasize.value * 2.0f, 128.0f));
+ R_FrameData_Resize();
+ }
+
+ data = r_framedata_mem->data + r_framedata_mem->current;
+ r_framedata_mem->current += size;
- // return NULL on everything after a failure
- if (r_framedata_failed)
- return NULL;
+ // count the usage for stats
+ r_refdef.stats.framedatacurrent = max(r_refdef.stats.framedatacurrent, (int)r_framedata_mem->current);
+ r_refdef.stats.framedatasize = max(r_refdef.stats.framedatasize, (int)r_framedata_mem->size);
- return data;
+ return (void *)data;
}
void *R_FrameData_Store(size_t size, void *data)
{
void *d = R_FrameData_Alloc(size);
- if (d)
+ if (d && data)
memcpy(d, data, size);
return d;
}
+void R_FrameData_SetMark(void)
+{
+ if (!r_framedata_mem)
+ return;
+ r_framedata_mem->mark = r_framedata_mem->current;
+}
+
+void R_FrameData_ReturnToMark(void)
+{
+ if (!r_framedata_mem)
+ return;
+ r_framedata_mem->current = r_framedata_mem->mark;
+}
+
//==================================================================================
// LordHavoc: animcache originally written by Echon, rewritten since then
ent->animcache_normal3f = NULL;
ent->animcache_svector3f = NULL;
ent->animcache_tvector3f = NULL;
- ent->animcache_vertexposition = NULL;
ent->animcache_vertexmesh = NULL;
- ent->animcache_vertexpositionbuffer = NULL;
+ ent->animcache_vertex3fbuffer = NULL;
ent->animcache_vertexmeshbuffer = NULL;
}
}
void R_AnimCache_UpdateEntityMeshBuffers(entity_render_t *ent, int numvertices)
{
int i;
+
+ // check if we need the meshbuffers
+ if (!vid.useinterleavedarrays)
+ return;
+
if (!ent->animcache_vertexmesh && ent->animcache_normal3f)
- ent->animcache_vertexmesh = R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
- if (!ent->animcache_vertexposition)
- ent->animcache_vertexposition = R_FrameData_Alloc(sizeof(r_vertexposition_t)*numvertices);
- if (ent->animcache_vertexposition)
- {
- for (i = 0;i < numvertices;i++)
- VectorCopy(ent->animcache_vertex3f + 3*i, ent->animcache_vertexposition[i].vertex3f);
- // TODO: upload vertex buffer?
- }
+ ent->animcache_vertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
+ // TODO: upload vertex3f buffer?
if (ent->animcache_vertexmesh)
{
memcpy(ent->animcache_vertexmesh, ent->model->surfmesh.vertexmesh, sizeof(r_vertexmesh_t)*numvertices);
for (i = 0;i < numvertices;i++)
- VectorCopy(ent->animcache_vertex3f + 3*i, ent->animcache_vertexmesh[i].vertex3f);
+ memcpy(ent->animcache_vertexmesh[i].vertex3f, ent->animcache_vertex3f + 3*i, sizeof(float[3]));
if (ent->animcache_svector3f)
for (i = 0;i < numvertices;i++)
- VectorCopy(ent->animcache_svector3f + 3*i, ent->animcache_vertexmesh[i].svector3f);
+ memcpy(ent->animcache_vertexmesh[i].svector3f, ent->animcache_svector3f + 3*i, sizeof(float[3]));
if (ent->animcache_tvector3f)
for (i = 0;i < numvertices;i++)
- VectorCopy(ent->animcache_tvector3f + 3*i, ent->animcache_vertexmesh[i].tvector3f);
+ memcpy(ent->animcache_vertexmesh[i].tvector3f, ent->animcache_tvector3f + 3*i, sizeof(float[3]));
if (ent->animcache_normal3f)
for (i = 0;i < numvertices;i++)
- VectorCopy(ent->animcache_normal3f + 3*i, ent->animcache_vertexmesh[i].normal3f);
- // TODO: upload vertex buffer?
+ memcpy(ent->animcache_vertexmesh[i].normal3f, ent->animcache_normal3f + 3*i, sizeof(float[3]));
+ // TODO: upload vertexmeshbuffer?
}
}
{
numvertices = model->surfmesh.num_vertices;
if (wantnormals)
- ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
if (wanttangents)
{
- ent->animcache_svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
- ent->animcache_tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
- }
- if (!r_framedata_failed)
- {
- model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? ent->animcache_normal3f : NULL, wanttangents ? ent->animcache_svector3f : NULL, wanttangents ? ent->animcache_tvector3f : NULL);
- R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
+ ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
}
+ model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? ent->animcache_normal3f : NULL, wanttangents ? ent->animcache_svector3f : NULL, wanttangents ? ent->animcache_tvector3f : NULL);
+ R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
}
}
}
else
{
// see if this ent is worth caching
- if (!model || !model->Draw || !model->surfmesh.isanimated || !model->AnimateVertices || (ent->frameblend[0].lerp == 1 && ent->frameblend[0].subframe == 0 && !ent->skeleton))
+ if (!model || !model->Draw || !model->surfmesh.isanimated || !model->AnimateVertices)
return false;
// get some memory for this entity and generate mesh data
numvertices = model->surfmesh.num_vertices;
- ent->animcache_vertex3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_vertex3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
if (wantnormals)
- ent->animcache_normal3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
if (wanttangents)
{
- ent->animcache_svector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
- ent->animcache_tvector3f = R_FrameData_Alloc(sizeof(float[3])*numvertices);
- }
- if (!r_framedata_failed)
- {
- model->AnimateVertices(model, ent->frameblend, ent->skeleton, ent->animcache_vertex3f, ent->animcache_normal3f, ent->animcache_svector3f, ent->animcache_tvector3f);
- R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
+ ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
+ ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
}
+ model->AnimateVertices(model, ent->frameblend, ent->skeleton, ent->animcache_vertex3f, ent->animcache_normal3f, ent->animcache_svector3f, ent->animcache_tvector3f);
+ R_AnimCache_UpdateEntityMeshBuffers(ent, model->surfmesh.num_vertices);
}
- return !r_framedata_failed;
+ return true;
}
void R_AnimCache_CacheVisibleEntities(void)
switch(vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_GLES2:
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
wanttangents = false;
break;
+ case RENDERPATH_SOFT:
+ break;
}
if (r_shownormals.integer)
//==================================================================================
+extern cvar_t r_overheadsprites_pushback;
+
static void R_View_UpdateEntityLighting (void)
{
int i;
VectorClear(ent->modellight_ambient);
VectorClear(ent->modellight_diffuse);
VectorClear(tempdiffusenormal);
- if ((ent->flags & RENDER_LIGHT) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint)
+ if (ent->flags & RENDER_LIGHT)
{
vec3_t org;
Matrix4x4_OriginFromMatrix(&ent->matrix, org);
- r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
+
+ // complete lightning for lit sprites
+ // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
+ if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
+ {
+ if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
+ org[2] = org[2] + r_overheadsprites_pushback.value;
+ R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
+ }
+ else
+ R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP);
+
if(ent->flags & RENDER_EQUALIZE)
{
// first fix up ambient lighting...
if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
{
- VectorMA(ent->modellight_ambient, 0.25f, ent->modellight_diffuse, avg);
- f = 0.299f * avg[0] + 0.587f * avg[1] + 0.114f * avg[2];
+ fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
+ fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
+ f = fa + 0.25 * fd;
if(f > 0)
{
- f = pow(f / r_equalize_entities_to.value, -r_equalize_entities_by.value);
- VectorScale(ent->modellight_ambient, f, ent->modellight_ambient);
- VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
+ // adjust brightness and saturation to target
+ avg[0] = avg[1] = avg[2] = fa / f;
+ VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
+ avg[0] = avg[1] = avg[2] = fd / f;
+ VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
}
}
}
{
ent = r_refdef.scene.entities[i];
if (!(ent->flags & renderimask))
- if (!R_CullBox(ent->mins, ent->maxs) || (ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
+ 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)))
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))
r_refdef.viewcache.entityvisible[i] = true;
}
- if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane)
- // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling
- {
- for (i = 0;i < r_refdef.scene.numentities;i++)
- {
- ent = r_refdef.scene.entities[i];
- if(r_refdef.viewcache.entityvisible[i] && !(ent->flags & (RENDER_VIEWMODEL | RENDER_NOCULL | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
- {
- samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer;
- if (samples < 0)
- continue; // temp entities do pvs only
- if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
- ent->last_trace_visibility = realtime;
- if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
- r_refdef.viewcache.entityvisible[i] = 0;
- }
- }
- }
}
else
{
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));
}
}
+ if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane && !r_trippy.integer)
+ // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling
+ {
+ for (i = 0;i < r_refdef.scene.numentities;i++)
+ {
+ if (!r_refdef.viewcache.entityvisible[i])
+ continue;
+ ent = r_refdef.scene.entities[i];
+ if(!(ent->flags & (RENDER_VIEWMODEL | RENDER_NOCULL | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
+ {
+ samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer;
+ if (samples < 0)
+ continue; // temp entities do pvs only
+ if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
+ ent->last_trace_visibility = realtime;
+ if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
+ r_refdef.viewcache.entityvisible[i] = 0;
+ }
+ }
+ }
}
/// only used if skyrendermasked, and normally returns false
continue;
ent = r_refdef.scene.entities[i];
r_refdef.stats.entities++;
+ /*
+ if (ent->model && !strncmp(ent->model->name, "models/proto_", 13))
+ {
+ vec3_t f, l, u, o;
+ Matrix4x4_ToVectors(&ent->matrix, f, l, u, o);
+ Con_Printf("R_DrawModels\n");
+ Con_Printf("model %s O %f %f %f F %f %f %f L %f %f %f U %f %f %f\n", ent->model->name, o[0], o[1], o[2], f[0], f[1], f[2], l[0], l[1], l[2], u[0], u[1], u[2]);
+ Con_Printf("group: %i %f %i %f %i %f %i %f\n", ent->framegroupblend[0].frame, ent->framegroupblend[0].lerp, ent->framegroupblend[1].frame, ent->framegroupblend[1].lerp, ent->framegroupblend[2].frame, ent->framegroupblend[2].lerp, ent->framegroupblend[3].frame, ent->framegroupblend[3].lerp);
+ Con_Printf("blend: %i %f %i %f %i %f %i %f %i %f %i %f %i %f %i %f\n", ent->frameblend[0].subframe, ent->frameblend[0].lerp, ent->frameblend[1].subframe, ent->frameblend[1].lerp, ent->frameblend[2].subframe, ent->frameblend[2].lerp, ent->frameblend[3].subframe, ent->frameblend[3].lerp, ent->frameblend[4].subframe, ent->frameblend[4].lerp, ent->frameblend[5].subframe, ent->frameblend[5].lerp, ent->frameblend[6].subframe, ent->frameblend[6].lerp, ent->frameblend[7].subframe, ent->frameblend[7].lerp);
+ }
+ */
if (ent->model && ent->model->Draw != NULL)
ent->model->Draw(ent);
else
}
}
-static void R_View_SetFrustum(void)
+void R_HDR_UpdateIrisAdaptation(const vec3_t point)
+{
+ if (r_hdr_irisadaptation.integer)
+ {
+ vec3_t ambient;
+ vec3_t diffuse;
+ vec3_t diffusenormal;
+ vec_t brightness;
+ vec_t goal;
+ vec_t adjust;
+ vec_t current;
+ R_CompleteLightPoint(ambient, diffuse, diffusenormal, point, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
+ brightness = (ambient[0] + ambient[1] + ambient[2] + diffuse[0] + diffuse[1] + diffuse[2]) * (1.0f / 3.0f);
+ brightness = max(0.0000001f, brightness);
+ goal = r_hdr_irisadaptation_multiplier.value / brightness;
+ goal = bound(r_hdr_irisadaptation_minvalue.value, goal, r_hdr_irisadaptation_maxvalue.value);
+ adjust = r_hdr_irisadaptation_fade.value * cl.realframetime;
+ current = r_hdr_irisadaptation_value.value;
+ if (current < goal)
+ current = min(current + adjust, goal);
+ else if (current > goal)
+ current = max(current - adjust, goal);
+ if (fabs(r_hdr_irisadaptation_value.value - current) > 0.0001f)
+ Cvar_SetValueQuick(&r_hdr_irisadaptation_value, current);
+ }
+ else if (r_hdr_irisadaptation_value.value != 1.0f)
+ Cvar_SetValueQuick(&r_hdr_irisadaptation_value, 1.0f);
+}
+
+static void R_View_SetFrustum(const int *scissor)
{
int i;
- double slopex, slopey;
- vec3_t forward, left, up, origin;
+ double fpx = +1, fnx = -1, fpy = +1, fny = -1;
+ vec3_t forward, left, up, origin, v;
+
+ if(scissor)
+ {
+ // flipped x coordinates (because x points left here)
+ fpx = 1.0 - 2.0 * (scissor[0] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
+ fnx = 1.0 - 2.0 * (scissor[0] + scissor[2] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
+
+ // D3D Y coordinate is top to bottom, OpenGL is bottom to top, fix the D3D one
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ // non-flipped y coordinates
+ fny = -1.0 + 2.0 * (vid.height - scissor[1] - scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
+ fpy = -1.0 + 2.0 * (vid.height - scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
+ break;
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ // non-flipped y coordinates
+ fny = -1.0 + 2.0 * (scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
+ fpy = -1.0 + 2.0 * (scissor[1] + scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
+ break;
+ }
+ }
// we can't trust r_refdef.view.forward and friends in reflected scenes
Matrix4x4_ToVectors(&r_refdef.view.matrix, forward, left, up, origin);
if (r_refdef.view.useperspective)
{
- slopex = 1.0 / r_refdef.view.frustum_x;
- slopey = 1.0 / r_refdef.view.frustum_y;
- VectorMA(forward, -slopex, left, r_refdef.view.frustum[0].normal);
- VectorMA(forward, slopex, left, r_refdef.view.frustum[1].normal);
- VectorMA(forward, -slopey, up , r_refdef.view.frustum[2].normal);
- VectorMA(forward, slopey, up , r_refdef.view.frustum[3].normal);
- VectorCopy(forward, r_refdef.view.frustum[4].normal);
+ // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
+ 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]);
+ 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]);
+ 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]);
+ 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]);
+
+ // then the normals from the corners relative to origin
+ CrossProduct(r_refdef.view.frustumcorner[2], r_refdef.view.frustumcorner[0], r_refdef.view.frustum[0].normal);
+ CrossProduct(r_refdef.view.frustumcorner[1], r_refdef.view.frustumcorner[3], r_refdef.view.frustum[1].normal);
+ CrossProduct(r_refdef.view.frustumcorner[0], r_refdef.view.frustumcorner[1], r_refdef.view.frustum[2].normal);
+ CrossProduct(r_refdef.view.frustumcorner[3], r_refdef.view.frustumcorner[2], r_refdef.view.frustum[3].normal);
+
+ // in a NORMAL view, forward cross left == up
+ // in a REFLECTED view, forward cross left == down
+ // so our cross products above need to be adjusted for a left handed coordinate system
+ CrossProduct(forward, left, v);
+ if(DotProduct(v, up) < 0)
+ {
+ VectorNegate(r_refdef.view.frustum[0].normal, r_refdef.view.frustum[0].normal);
+ VectorNegate(r_refdef.view.frustum[1].normal, r_refdef.view.frustum[1].normal);
+ VectorNegate(r_refdef.view.frustum[2].normal, r_refdef.view.frustum[2].normal);
+ VectorNegate(r_refdef.view.frustum[3].normal, r_refdef.view.frustum[3].normal);
+ }
// Leaving those out was a mistake, those were in the old code, and they
// fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix
VectorNormalize(r_refdef.view.frustum[2].normal);
VectorNormalize(r_refdef.view.frustum[3].normal);
- // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, -1024 * r_refdef.view.frustum_x, left, -1024 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[0]);
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, 1024 * r_refdef.view.frustum_x, left, -1024 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[1]);
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, -1024 * r_refdef.view.frustum_x, left, 1024 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[2]);
- VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, 1024 * r_refdef.view.frustum_x, left, 1024 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[3]);
+ // make the corners absolute
+ VectorAdd(r_refdef.view.frustumcorner[0], r_refdef.view.origin, r_refdef.view.frustumcorner[0]);
+ VectorAdd(r_refdef.view.frustumcorner[1], r_refdef.view.origin, r_refdef.view.frustumcorner[1]);
+ VectorAdd(r_refdef.view.frustumcorner[2], r_refdef.view.origin, r_refdef.view.frustumcorner[2]);
+ VectorAdd(r_refdef.view.frustumcorner[3], r_refdef.view.origin, r_refdef.view.frustumcorner[3]);
+
+ // one more normal
+ VectorCopy(forward, r_refdef.view.frustum[4].normal);
r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal);
r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal);
//PlaneClassify(&frustum[4]);
}
+void R_View_UpdateWithScissor(const int *myscissor)
+{
+ R_Main_ResizeViewCache();
+ R_View_SetFrustum(myscissor);
+ R_View_WorldVisibility(r_refdef.view.useclipplane);
+ R_View_UpdateEntityVisible();
+ R_View_UpdateEntityLighting();
+}
+
void R_View_Update(void)
{
R_Main_ResizeViewCache();
- R_View_SetFrustum();
+ R_View_SetFrustum(NULL);
R_View_WorldVisibility(r_refdef.view.useclipplane);
R_View_UpdateEntityVisible();
R_View_UpdateEntityLighting();
}
+float viewscalefpsadjusted = 1.0f;
+
+void R_GetScaledViewSize(int width, int height, int *outwidth, int *outheight)
+{
+ float scale = r_viewscale.value * sqrt(viewscalefpsadjusted);
+ scale = bound(0.03125f, scale, 1.0f);
+ *outwidth = (int)ceil(width * scale);
+ *outheight = (int)ceil(height * scale);
+}
+
+void R_Mesh_SetMainRenderTargets(void)
+{
+ if (r_bloomstate.fbo_framebuffer)
+ R_Mesh_SetRenderTargets(r_bloomstate.fbo_framebuffer, r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL);
+ else
+ R_Mesh_ResetRenderTargets();
+}
+
void R_SetupView(qboolean allowwaterclippingplane)
{
const float *customclipplane = NULL;
float plane[4];
+ int scaledwidth, scaledheight;
if (r_refdef.view.useclipplane && allowwaterclippingplane)
{
// LordHavoc: couldn't figure out how to make this approach the
plane[0] = r_refdef.view.clipplane.normal[0];
plane[1] = r_refdef.view.clipplane.normal[1];
plane[2] = r_refdef.view.clipplane.normal[2];
- plane[3] = dist;
- customclipplane = plane;
+ plane[3] = -dist;
+ if(vid.renderpath != RENDERPATH_SOFT) customclipplane = plane;
}
+ R_GetScaledViewSize(r_refdef.view.width, r_refdef.view.height, &scaledwidth, &scaledheight);
if (!r_refdef.view.useperspective)
- 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);
+ R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, -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);
else if (vid.stencil && r_useinfinitefarclip.integer)
- 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);
+ R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane);
else
- 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);
+ R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane);
+ R_Mesh_SetMainRenderTargets();
R_SetViewport(&r_refdef.view.viewport);
+ if (r_refdef.view.useclipplane && allowwaterclippingplane && vid.renderpath == RENDERPATH_SOFT)
+ {
+ matrix4x4_t mvpmatrix, invmvpmatrix, invtransmvpmatrix;
+ float screenplane[4];
+ Matrix4x4_Concat(&mvpmatrix, &r_refdef.view.viewport.projectmatrix, &r_refdef.view.viewport.viewmatrix);
+ Matrix4x4_Invert_Full(&invmvpmatrix, &mvpmatrix);
+ Matrix4x4_Transpose(&invtransmvpmatrix, &invmvpmatrix);
+ Matrix4x4_Transform4(&invtransmvpmatrix, plane, screenplane);
+ DPSOFTRAST_ClipPlane(screenplane[0], screenplane[1], screenplane[2], screenplane[3]);
+ }
}
void R_EntityMatrix(const matrix4x4_t *matrix)
CHECKGLERROR
switch(vid.renderpath)
{
- case RENDERPATH_GL20:
- if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
- if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
- qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
- break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- CHECKCGERROR
- if (r_cg_permutation && r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR
- if (r_cg_permutation && r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR
- qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ hlslVSSetParameter16f(D3DVSREGISTER_ModelViewProjectionMatrix, gl_modelviewprojection16f);
+ hlslVSSetParameter16f(D3DVSREGISTER_ModelViewMatrix, gl_modelview16f);
#endif
break;
- case RENDERPATH_GL13:
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 shader %s:%i\n", __FILE__, __LINE__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 shader %s:%i\n", __FILE__, __LINE__);
+ break;
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
break;
+ case RENDERPATH_SOFT:
+ DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
+ DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
+ break;
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f);
+ if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fv(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f);
+ break;
}
}
}
// GL is weird because it's bottom to top, r_refdef.view.y is top to bottom
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);
+ R_Mesh_ResetRenderTargets();
R_SetViewport(&viewport);
GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
GL_Color(1, 1, 1, 1);
GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_AlphaTest(false);
GL_ScissorTest(false);
GL_DepthMask(false);
GL_DepthRange(0, 1);
GL_DepthTest(false);
+ GL_DepthFunc(GL_LEQUAL);
R_EntityMatrix(&identitymatrix);
R_Mesh_ResetTextureState();
GL_PolygonOffset(0, 0);
- qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
- qglDepthFunc(GL_LEQUAL);CHECKGLERROR
- qglDisable(GL_STENCIL_TEST);CHECKGLERROR
- qglStencilMask(~0);CHECKGLERROR
- qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
- qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
- GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
+ R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+ break;
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ break;
+ }
+ GL_CullFace(GL_NONE);
}
void R_ResetViewRendering3D(void)
GL_Color(1, 1, 1, 1);
GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1);
GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_AlphaTest(false);
GL_ScissorTest(true);
GL_DepthMask(true);
GL_DepthRange(0, 1);
GL_DepthTest(true);
+ GL_DepthFunc(GL_LEQUAL);
R_EntityMatrix(&identitymatrix);
R_Mesh_ResetTextureState();
GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
- qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
- qglDepthFunc(GL_LEQUAL);CHECKGLERROR
- qglDisable(GL_STENCIL_TEST);CHECKGLERROR
- qglStencilMask(~0);CHECKGLERROR
- qglStencilFunc(GL_ALWAYS, 128, ~0);CHECKGLERROR
- qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);CHECKGLERROR
+ R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255);
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR
+ break;
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ break;
+ }
GL_CullFace(r_refdef.view.cullface_back);
}
switch(vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
return;
}
// set waterwidth and waterheight to the water resolution that will be
// used (often less than the screen resolution for faster rendering)
- waterwidth = (int)bound(1, vid.width * r_water_resolutionmultiplier.value, vid.width);
- waterheight = (int)bound(1, vid.height * r_water_resolutionmultiplier.value, vid.height);
+ R_GetScaledViewSize(bound(1, vid.width * r_water_resolutionmultiplier.value, vid.width), bound(1, vid.height * r_water_resolutionmultiplier.value, vid.height), &waterwidth, &waterheight);
// calculate desired texture sizes
// can't use water if the card does not support the texture size
if (r_waterstate.texturewidth)
{
+ int scaledwidth, scaledheight;
+
r_waterstate.enabled = true;
// when doing a reduced render (HDR) we want to use a smaller area
r_waterstate.waterwidth = (int)bound(1, r_refdef.view.width * r_water_resolutionmultiplier.value, r_refdef.view.width);
r_waterstate.waterheight = (int)bound(1, r_refdef.view.height * r_water_resolutionmultiplier.value, r_refdef.view.height);
+ R_GetScaledViewSize(r_waterstate.waterwidth, r_waterstate.waterheight, &scaledwidth, &scaledheight);
// set up variables that will be used in shader setup
- r_waterstate.screenscale[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
- r_waterstate.screenscale[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
- r_waterstate.screencenter[0] = 0.5f * (float)r_waterstate.waterwidth / (float)r_waterstate.texturewidth;
- r_waterstate.screencenter[1] = 0.5f * (float)r_waterstate.waterheight / (float)r_waterstate.textureheight;
+ r_waterstate.screenscale[0] = 0.5f * (float)scaledwidth / (float)r_waterstate.texturewidth;
+ r_waterstate.screenscale[1] = 0.5f * (float)scaledheight / (float)r_waterstate.textureheight;
+ r_waterstate.screencenter[0] = 0.5f * (float)scaledwidth / (float)r_waterstate.texturewidth;
+ r_waterstate.screencenter[1] = 0.5f * (float)scaledheight / (float)r_waterstate.textureheight;
}
r_waterstate.maxwaterplanes = MAX_WATERPLANES;
r_waterstate.numwaterplanes = 0;
}
-void R_Water_AddWaterPlane(msurface_t *surface)
+void R_Water_AddWaterPlane(msurface_t *surface, int entno)
{
int triangleindex, planeindex;
const int *e;
vec3_t normal;
vec3_t center;
mplane_t plane;
- int cam_ent;
r_waterstate_waterplane_t *p;
texture_t *t = R_GetCurrentTexture(surface->texture);
- cam_ent = t->camera_entity;
- if(!(t->currentmaterialflags & MATERIALFLAG_CAMERA))
- cam_ent = 0;
// just use the first triangle with a valid normal for any decisions
VectorClear(normal);
p->materialflags = 0;
p->pvsvalid = false;
p->camera_entity = t->camera_entity;
+ VectorCopy(surface->mins, p->mins);
+ VectorCopy(surface->maxs, p->maxs);
+ }
+ else
+ {
+ // merge mins/maxs
+ p->mins[0] = min(p->mins[0], surface->mins[0]);
+ p->mins[1] = min(p->mins[1], surface->mins[1]);
+ p->mins[2] = min(p->mins[2], surface->mins[2]);
+ p->maxs[0] = max(p->maxs[0], surface->maxs[0]);
+ p->maxs[1] = max(p->maxs[1], surface->maxs[1]);
+ p->maxs[2] = max(p->maxs[2], surface->maxs[2]);
}
// merge this surface's materialflags into the waterplane
p->materialflags |= t->currentmaterialflags;
}
}
+extern cvar_t r_drawparticles;
+extern cvar_t r_drawdecals;
+
static void R_Water_ProcessPlanes(void)
{
+ int myscissor[4];
r_refdef_view_t originalview;
r_refdef_view_t myview;
- int planeindex;
+ int planeindex, qualityreduction = 0, old_r_dynamic = 0, old_r_shadows = 0, old_r_worldrtlight = 0, old_r_dlight = 0, old_r_particles = 0, old_r_decals = 0;
r_waterstate_waterplane_t *p;
vec3_t visorigin;
originalview = r_refdef.view;
+ // lowquality hack, temporarily shut down some cvars and restore afterwards
+ qualityreduction = r_water_lowquality.integer;
+ if (qualityreduction > 0)
+ {
+ if (qualityreduction >= 1)
+ {
+ old_r_shadows = r_shadows.integer;
+ old_r_worldrtlight = r_shadow_realtime_world.integer;
+ old_r_dlight = r_shadow_realtime_dlight.integer;
+ Cvar_SetValueQuick(&r_shadows, 0);
+ Cvar_SetValueQuick(&r_shadow_realtime_world, 0);
+ Cvar_SetValueQuick(&r_shadow_realtime_dlight, 0);
+ }
+ if (qualityreduction >= 2)
+ {
+ old_r_dynamic = r_dynamic.integer;
+ old_r_particles = r_drawparticles.integer;
+ old_r_decals = r_drawdecals.integer;
+ Cvar_SetValueQuick(&r_dynamic, 0);
+ Cvar_SetValueQuick(&r_drawparticles, 0);
+ Cvar_SetValueQuick(&r_drawdecals, 0);
+ }
+ }
+
// make sure enough textures are allocated
for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
{
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
{
if (!p->texture_refraction)
- p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_refraction", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
+ 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);
if (!p->texture_refraction)
goto error;
}
else if (p->materialflags & MATERIALFLAG_CAMERA)
{
if (!p->texture_camera)
- p->texture_camera = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_camera", planeindex), r_waterstate.camerawidth, r_waterstate.cameraheight, NULL, TEXTYPE_COLORBUFFER, TEXF_FORCELINEAR, NULL);
+ 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);
if (!p->texture_camera)
goto error;
}
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
{
if (!p->texture_reflection)
- p->texture_reflection = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_reflection", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
+ 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);
if (!p->texture_reflection)
goto error;
}
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
{
r_refdef.view = myview;
+ if(r_water_scissormode.integer)
+ {
+ R_SetupView(true);
+ if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
+ continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
+ }
+
// render reflected scene and copy into texture
Matrix4x4_Reflect(&r_refdef.view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2);
// update the r_refdef.view.origin because otherwise the sky renders at the wrong location (amongst other problems)
R_ResetViewRendering3D();
R_ClearScreen(r_refdef.fogenabled);
- R_View_Update();
+ if(r_water_scissormode.integer & 2)
+ R_View_UpdateWithScissor(myscissor);
+ else
+ R_View_Update();
+ if(r_water_scissormode.integer & 1)
+ GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
R_RenderScene();
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);
// (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)
if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
{
- r_waterstate.renderingrefraction = true;
r_refdef.view = myview;
+ if(r_water_scissormode.integer)
+ {
+ R_SetupView(true);
+ if(R_ScissorForBBox(p->mins, p->maxs, myscissor))
+ continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
+ }
+
+ r_waterstate.renderingrefraction = true;
r_refdef.view.clipplane = p->plane;
VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal);
r_waterstate.renderingrefraction = false; // we don't want to hide the player model from these ones
CL_VM_TransformView(p->camera_entity - MAX_EDICTS, &r_refdef.view.matrix, &r_refdef.view.clipplane, visorigin);
R_RenderView_UpdateViewVectors();
- 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);
+ if(r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
+ {
+ r_refdef.view.usecustompvs = true;
+ 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);
+ }
}
PlaneClassify(&r_refdef.view.clipplane);
R_ResetViewRendering3D();
R_ClearScreen(r_refdef.fogenabled);
- R_View_Update();
+ if(r_water_scissormode.integer & 2)
+ R_View_UpdateWithScissor(myscissor);
+ else
+ R_View_Update();
+ if(r_water_scissormode.integer & 1)
+ GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]);
R_RenderScene();
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);
CL_VM_TransformView(p->camera_entity - MAX_EDICTS, &r_refdef.view.matrix, &r_refdef.view.clipplane, visorigin);
}
+ // note: all of the view is used for displaying... so
+ // there is no use in scissoring
+
// reverse the cullface settings for this render
r_refdef.view.cullface_front = GL_FRONT;
r_refdef.view.cullface_back = GL_BACK;
// also reverse the view matrix
- Matrix4x4_ConcatScale3(&r_refdef.view.matrix, 1, -1, 1);
+ 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
R_RenderView_UpdateViewVectors();
- if(p->camera_entity)
+ if(p->camera_entity && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.FatPVS)
+ {
+ r_refdef.view.usecustompvs = true;
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);
+ }
// camera needs no clipplane
r_refdef.view.useclipplane = false;
}
}
+ if(vid.renderpath==RENDERPATH_SOFT) DPSOFTRAST_ClipPlane(0, 0, 0, 1);
r_waterstate.renderingscene = false;
r_refdef.view = originalview;
R_ResetViewRendering3D();
R_ClearScreen(r_refdef.fogenabled);
R_View_Update();
- return;
+ goto finish;
error:
r_refdef.view = originalview;
r_waterstate.renderingscene = false;
Cvar_SetValueQuick(&r_water, 0);
Con_Printf("R_Water_ProcessPlanes: Error: texture creation failed! Turned off r_water.\n");
- return;
+finish:
+ // lowquality hack, restore cvars
+ if (qualityreduction > 0)
+ {
+ if (qualityreduction >= 1)
+ {
+ Cvar_SetValueQuick(&r_shadows, old_r_shadows);
+ Cvar_SetValueQuick(&r_shadow_realtime_world, old_r_worldrtlight);
+ Cvar_SetValueQuick(&r_shadow_realtime_dlight, old_r_dlight);
+ }
+ if (qualityreduction >= 2)
+ {
+ Cvar_SetValueQuick(&r_dynamic, old_r_dynamic);
+ Cvar_SetValueQuick(&r_drawparticles, old_r_particles);
+ Cvar_SetValueQuick(&r_drawdecals, old_r_decals);
+ }
+ }
}
void R_Bloom_StartFrame(void)
{
int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight;
+ int viewwidth, viewheight;
+ textype_t textype;
+
+ if (r_viewscale_fpsscaling.integer)
+ {
+ double actualframetime;
+ double targetframetime;
+ double adjust;
+ actualframetime = r_refdef.lastdrawscreentime;
+ targetframetime = (1.0 / r_viewscale_fpsscaling_target.value);
+ adjust = (targetframetime - actualframetime) * r_viewscale_fpsscaling_multiply.value;
+ adjust = bound(-r_viewscale_fpsscaling_stepmax.value, adjust, r_viewscale_fpsscaling_stepmax.value);
+ if (r_viewscale_fpsscaling_stepsize.value > 0)
+ adjust = (int)(adjust / r_viewscale_fpsscaling_stepsize.value) * r_viewscale_fpsscaling_stepsize.value;
+ viewscalefpsadjusted += adjust;
+ viewscalefpsadjusted = bound(r_viewscale_fpsscaling_min.value, viewscalefpsadjusted, 1.0f);
+ }
+ else
+ viewscalefpsadjusted = 1.0f;
+
+ R_GetScaledViewSize(r_refdef.view.width, r_refdef.view.height, &viewwidth, &viewheight);
switch(vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
return;
}
// calculate desired texture sizes
if (vid.support.arb_texture_non_power_of_two)
{
- screentexturewidth = r_refdef.view.width;
- screentextureheight = r_refdef.view.height;
+ screentexturewidth = vid.width;
+ screentextureheight = vid.height;
bloomtexturewidth = r_bloomstate.bloomwidth;
bloomtextureheight = r_bloomstate.bloomheight;
}
Cvar_SetValueQuick(&r_damageblur, 0);
}
- 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)))
+ 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)) && r_viewfbo.integer < 1 && r_viewscale.value == 1.0f && !r_viewscale_fpsscaling.integer)
screentexturewidth = screentextureheight = 0;
if (!r_hdr.integer && !r_bloom.integer)
bloomtexturewidth = bloomtextureheight = 0;
+ textype = TEXTYPE_COLORBUFFER;
+ switch (vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ if (vid.support.ext_framebuffer_object)
+ {
+ if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F;
+ if (r_viewfbo.integer == 3) textype = TEXTYPE_COLORBUFFER32F;
+ }
+ break;
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ break;
+ }
+
// allocate textures as needed
- if (r_bloomstate.screentexturewidth != screentexturewidth || r_bloomstate.screentextureheight != screentextureheight)
+ if (r_bloomstate.screentexturewidth != screentexturewidth
+ || r_bloomstate.screentextureheight != screentextureheight
+ || r_bloomstate.bloomtexturewidth != bloomtexturewidth
+ || r_bloomstate.bloomtextureheight != bloomtextureheight
+ || r_bloomstate.texturetype != textype
+ || r_bloomstate.viewfbo != r_viewfbo.integer)
{
+ if (r_bloomstate.texture_bloom)
+ R_FreeTexture(r_bloomstate.texture_bloom);
+ r_bloomstate.texture_bloom = NULL;
if (r_bloomstate.texture_screen)
R_FreeTexture(r_bloomstate.texture_screen);
r_bloomstate.texture_screen = NULL;
+ if (r_bloomstate.fbo_framebuffer)
+ R_Mesh_DestroyFramebufferObject(r_bloomstate.fbo_framebuffer);
+ r_bloomstate.fbo_framebuffer = 0;
+ if (r_bloomstate.texture_framebuffercolor)
+ R_FreeTexture(r_bloomstate.texture_framebuffercolor);
+ r_bloomstate.texture_framebuffercolor = NULL;
+ if (r_bloomstate.texture_framebufferdepth)
+ R_FreeTexture(r_bloomstate.texture_framebufferdepth);
+ r_bloomstate.texture_framebufferdepth = NULL;
r_bloomstate.screentexturewidth = screentexturewidth;
r_bloomstate.screentextureheight = screentextureheight;
if (r_bloomstate.screentexturewidth && r_bloomstate.screentextureheight)
- r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_FORCENEAREST | TEXF_CLAMP, NULL);
- }
- if (r_bloomstate.bloomtexturewidth != bloomtexturewidth || r_bloomstate.bloomtextureheight != bloomtextureheight)
- {
- if (r_bloomstate.texture_bloom)
- R_FreeTexture(r_bloomstate.texture_bloom);
- r_bloomstate.texture_bloom = NULL;
+ r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
+ if (r_viewfbo.integer >= 1 && vid.support.ext_framebuffer_object)
+ {
+ // FIXME: choose depth bits based on a cvar
+ r_bloomstate.texture_framebufferdepth = R_LoadTextureShadowMap2D(r_main_texturepool, "framebufferdepth", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, 24, false);
+ r_bloomstate.texture_framebuffercolor = R_LoadTexture2D(r_main_texturepool, "framebuffercolor", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
+ r_bloomstate.fbo_framebuffer = R_Mesh_CreateFramebufferObject(r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL);
+ R_Mesh_SetRenderTargets(r_bloomstate.fbo_framebuffer, r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL);
+ // render depth into one texture and normalmap into the other
+ if (qglDrawBuffer)
+ {
+ int status;
+ qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR
+ qglReadBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR
+ status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+ Con_Printf("R_Bloom_StartFrame: glCheckFramebufferStatusEXT returned %i\n", status);
+ }
+ }
r_bloomstate.bloomtexturewidth = bloomtexturewidth;
r_bloomstate.bloomtextureheight = bloomtextureheight;
if (r_bloomstate.bloomtexturewidth && r_bloomstate.bloomtextureheight)
- r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
+ r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
+ r_bloomstate.viewfbo = r_viewfbo.integer;
+ r_bloomstate.texturetype = textype;
}
// when doing a reduced render (HDR) we want to use a smaller area
// set up a texcoord array for the full resolution screen image
// (we have to keep this around to copy back during final render)
r_bloomstate.screentexcoord2f[0] = 0;
- r_bloomstate.screentexcoord2f[1] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight;
- r_bloomstate.screentexcoord2f[2] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth;
- r_bloomstate.screentexcoord2f[3] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight;
- r_bloomstate.screentexcoord2f[4] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth;
+ r_bloomstate.screentexcoord2f[1] = (float)viewheight / (float)r_bloomstate.screentextureheight;
+ r_bloomstate.screentexcoord2f[2] = (float)viewwidth / (float)r_bloomstate.screentexturewidth;
+ r_bloomstate.screentexcoord2f[3] = (float)viewheight / (float)r_bloomstate.screentextureheight;
+ r_bloomstate.screentexcoord2f[4] = (float)viewwidth / (float)r_bloomstate.screentexturewidth;
r_bloomstate.screentexcoord2f[5] = 0;
r_bloomstate.screentexcoord2f[6] = 0;
r_bloomstate.screentexcoord2f[7] = 0;
r_bloomstate.bloomtexcoord2f[6] = 0;
r_bloomstate.bloomtexcoord2f[7] = 0;
- if (r_hdr.integer || r_bloom.integer)
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ break;
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ {
+ int i;
+ for (i = 0;i < 4;i++)
+ {
+ r_bloomstate.screentexcoord2f[i*2+0] += 0.5f / (float)r_bloomstate.screentexturewidth;
+ r_bloomstate.screentexcoord2f[i*2+1] += 0.5f / (float)r_bloomstate.screentextureheight;
+ r_bloomstate.bloomtexcoord2f[i*2+0] += 0.5f / (float)r_bloomstate.bloomtexturewidth;
+ r_bloomstate.bloomtexcoord2f[i*2+1] += 0.5f / (float)r_bloomstate.bloomtextureheight;
+ }
+ }
+ break;
+ }
+
+ if ((r_hdr.integer || r_bloom.integer) && r_bloomstate.bloomwidth)
{
r_bloomstate.enabled = true;
- r_bloomstate.hdr = r_hdr.integer != 0;
+ r_bloomstate.hdr = r_hdr.integer != 0 && !r_bloomstate.fbo_framebuffer;
}
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);
+
+ if (r_bloomstate.fbo_framebuffer)
+ r_refdef.view.clear = true;
}
void R_Bloom_CopyBloomTexture(float colorscale)
// scale down screen texture to the bloom texture size
CHECKGLERROR
+ R_Mesh_SetMainRenderTargets();
R_SetViewport(&r_bloomstate.viewport);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_Color(colorscale, colorscale, colorscale, 1);
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
+ // 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...
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ case RENDERPATH_SOFT:
+ R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
+ break;
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_bloomstate.screentexcoord2f);
+ break;
+ }
// TODO: do boxfilter scale-down in shader?
- R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1, true);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
GL_Color(r,r,r,1);
R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.bloomtexcoord2f);
- R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1, true);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
range = r_bloom_blur.integer * r_bloomstate.bloomwidth / 320;
brighten = r_bloom_brighten.value;
- if (r_hdr.integer)
+ if (r_bloomstate.hdr)
brighten *= r_hdr_range.value;
brighten = sqrt(brighten);
if(range >= 1)
brighten *= (3 * range) / (2 * range - 1); // compensate for the "dot particle"
- R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1, true);
for (dir = 0;dir < 2;dir++)
{
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);
r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
}
-
- // apply subtract last
- // (just like it would be in a GLSL shader)
- if (r_bloom_colorsubtract.value > 0 && vid.support.ext_blend_subtract)
- {
- GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_Color(1,1,1,1);
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.bloomtexcoord2f);
- R_SetupShader_Generic(r_bloomstate.texture_bloom, NULL, GL_MODULATE, 1);
- R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
- r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
-
- GL_BlendFunc(GL_ONE, GL_ONE);
- qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
- GL_Color(r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 1);
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.bloomtexcoord2f);
- R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
- r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
- qglBlendEquationEXT(GL_FUNC_ADD_EXT);
-
- // copy the darkened bloom view to a texture
- 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);
- r_refdef.stats.bloom_copypixels += r_bloomstate.viewport.width * r_bloomstate.viewport.height;
- }
}
void R_HDR_RenderBloomTexture(void)
{
int oldwidth, oldheight;
float oldcolorscale;
+ qboolean oldwaterstate;
+ oldwaterstate = r_waterstate.enabled;
oldcolorscale = r_refdef.view.colorscale;
oldwidth = r_refdef.view.width;
oldheight = r_refdef.view.height;
r_refdef.view.width = r_bloomstate.bloomwidth;
r_refdef.view.height = r_bloomstate.bloomheight;
+ if(r_hdr.integer < 2)
+ r_waterstate.enabled = false;
+
// TODO: support GL_EXT_framebuffer_object rather than reusing the framebuffer? it might improve SLI performance.
// TODO: add exposure compensation features
// TODO: add fp16 framebuffer support (using GL_EXT_framebuffer_object)
// only do secondary renders with HDR if r_hdr is 2 or higher
r_waterstate.numwaterplanes = 0;
- if (r_waterstate.enabled && r_hdr.integer >= 2)
+ if (r_waterstate.enabled)
R_RenderWaterPlanes();
r_refdef.view.showdebug = true;
R_Bloom_MakeTexture();
// restore the view settings
+ r_waterstate.enabled = oldwaterstate;
r_refdef.view.width = oldwidth;
r_refdef.view.height = oldheight;
r_refdef.view.colorscale = oldcolorscale;
switch (vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
permutation =
(r_bloomstate.texture_bloom ? SHADERPERMUTATION_BLOOM : 0)
| (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VIEWTINT : 0)
if (r_bloom_blur.value < 1) { Cvar_SetValueQuick(&r_bloom_blur, 1); }
R_ResetViewRendering2D();
+ R_Mesh_SetMainRenderTargets();
if(!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0))
{
{
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_Color(1, 1, 1, cl.motionbluralpha);
- R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
- R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1);
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ case RENDERPATH_SOFT:
+ R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
+ break;
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ R_Mesh_PrepareVertices_Generic_Arrays(4, r_d3dscreenvertex3f, NULL, r_bloomstate.screentexcoord2f);
+ break;
+ }
+ R_SetupShader_Generic(r_bloomstate.texture_screen, NULL, GL_MODULATE, 1, true);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
r_refdef.stats.bloom_drawpixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
}
R_ResetViewRendering2D();
GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, true);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
}
#define sscanf sscanf_s
#endif
memset(uservecs, 0, sizeof(uservecs));
- sscanf(r_glsl_postprocess_uservec1.string, "%f %f %f %f", &uservecs[0][0], &uservecs[0][1], &uservecs[0][2], &uservecs[0][3]);
- sscanf(r_glsl_postprocess_uservec2.string, "%f %f %f %f", &uservecs[1][0], &uservecs[1][1], &uservecs[1][2], &uservecs[1][3]);
- sscanf(r_glsl_postprocess_uservec3.string, "%f %f %f %f", &uservecs[2][0], &uservecs[2][1], &uservecs[2][2], &uservecs[2][3]);
- sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &uservecs[3][0], &uservecs[3][1], &uservecs[3][2], &uservecs[3][3]);
+ if (r_glsl_postprocess_uservec1_enable.integer)
+ sscanf(r_glsl_postprocess_uservec1.string, "%f %f %f %f", &uservecs[0][0], &uservecs[0][1], &uservecs[0][2], &uservecs[0][3]);
+ if (r_glsl_postprocess_uservec2_enable.integer)
+ sscanf(r_glsl_postprocess_uservec2.string, "%f %f %f %f", &uservecs[1][0], &uservecs[1][1], &uservecs[1][2], &uservecs[1][3]);
+ if (r_glsl_postprocess_uservec3_enable.integer)
+ sscanf(r_glsl_postprocess_uservec3.string, "%f %f %f %f", &uservecs[2][0], &uservecs[2][1], &uservecs[2][2], &uservecs[2][3]);
+ if (r_glsl_postprocess_uservec4_enable.integer)
+ sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &uservecs[3][0], &uservecs[3][1], &uservecs[3][2], &uservecs[3][3]);
R_ResetViewRendering2D();
GL_Color(1, 1, 1, 1);
- R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
GL_BlendFunc(GL_ONE, GL_ZERO);
switch(vid.renderpath)
{
case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
R_SetupShader_SetPermutationGLSL(SHADERMODE_POSTPROCESS, permutation);
- if (r_glsl_permutation->loc_Texture_First >= 0) R_Mesh_TexBind(GL20TU_FIRST , r_bloomstate.texture_screen);
- if (r_glsl_permutation->loc_Texture_Second >= 0) R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom );
- if (r_glsl_permutation->loc_Texture_GammaRamps >= 0) R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
- if (r_glsl_permutation->loc_ViewTintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
- if (r_glsl_permutation->loc_PixelSize >= 0) qglUniform2fARB(r_glsl_permutation->loc_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
- if (r_glsl_permutation->loc_UserVec1 >= 0) qglUniform4fARB(r_glsl_permutation->loc_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
- if (r_glsl_permutation->loc_UserVec2 >= 0) qglUniform4fARB(r_glsl_permutation->loc_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
- if (r_glsl_permutation->loc_UserVec3 >= 0) qglUniform4fARB(r_glsl_permutation->loc_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
- if (r_glsl_permutation->loc_UserVec4 >= 0) qglUniform4fARB(r_glsl_permutation->loc_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
- if (r_glsl_permutation->loc_Saturation >= 0) qglUniform1fARB(r_glsl_permutation->loc_Saturation , r_glsl_saturation.value);
- if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2fARB(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
+ if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_bloomstate.texture_screen);
+ if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_bloomstate.texture_bloom );
+ if (r_glsl_permutation->tex_Texture_GammaRamps >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_GammaRamps, r_texture_gammaramps );
+ 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]);
+ if (r_glsl_permutation->loc_PixelSize >= 0) qglUniform2f(r_glsl_permutation->loc_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
+ 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]);
+ 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]);
+ 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]);
+ 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]);
+ if (r_glsl_permutation->loc_Saturation >= 0) qglUniform1f(r_glsl_permutation->loc_Saturation , r_glsl_saturation.value);
+ if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
+ if (r_glsl_permutation->loc_BloomColorSubtract >= 0) qglUniform4f(r_glsl_permutation->loc_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
break;
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- R_SetupShader_SetPermutationCG(SHADERMODE_POSTPROCESS, permutation);
- if (r_cg_permutation->fp_Texture_First ) CG_BindTexture(r_cg_permutation->fp_Texture_First , r_bloomstate.texture_screen);CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Second ) CG_BindTexture(r_cg_permutation->fp_Texture_Second , r_bloomstate.texture_bloom );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_GammaRamps) CG_BindTexture(r_cg_permutation->fp_Texture_GammaRamps, r_texture_gammaramps );CHECKCGERROR
- 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
- if (r_cg_permutation->fp_PixelSize ) cgGLSetParameter2f( r_cg_permutation->fp_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);CHECKCGERROR
- 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
- 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
- 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
- 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
- if (r_cg_permutation->fp_Saturation ) cgGLSetParameter1f( r_cg_permutation->fp_Saturation , r_glsl_saturation.value);CHECKCGERROR
- if (r_cg_permutation->fp_PixelToScreenTexCoord) cgGLSetParameter2f(r_cg_permutation->fp_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);CHECKCGERROR
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ // 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...
+ R_Mesh_PrepareVertices_Mesh_Arrays(4, r_d3dscreenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
+ R_SetupShader_SetPermutationHLSL(SHADERMODE_POSTPROCESS, permutation);
+ R_Mesh_TexBind(GL20TU_FIRST , r_bloomstate.texture_screen);
+ R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom );
+ R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
+ hlslPSSetParameter4f(D3DPSREGISTER_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
+ hlslPSSetParameter2f(D3DPSREGISTER_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
+ hlslPSSetParameter4f(D3DPSREGISTER_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
+ hlslPSSetParameter4f(D3DPSREGISTER_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
+ hlslPSSetParameter1f(D3DPSREGISTER_Saturation , r_glsl_saturation.value);
+ hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height);
+ hlslPSSetParameter4f(D3DPSREGISTER_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
#endif
break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_SOFT:
+ R_Mesh_PrepareVertices_Mesh_Arrays(4, r_screenvertex3f, NULL, NULL, NULL, NULL, r_bloomstate.screentexcoord2f, r_bloomstate.bloomtexcoord2f);
+ R_SetupShader_SetPermutationSoft(SHADERMODE_POSTPROCESS, permutation);
+ R_Mesh_TexBind(GL20TU_FIRST , r_bloomstate.texture_screen);
+ R_Mesh_TexBind(GL20TU_SECOND , r_bloomstate.texture_bloom );
+ R_Mesh_TexBind(GL20TU_GAMMARAMPS, r_texture_gammaramps );
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
+ DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_Saturation , r_glsl_saturation.value);
+ DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
+ DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
+ break;
default:
break;
}
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
- r_refdef.stats.bloom_drawpixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height;
+ r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height;
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
{
// apply a color tint to the whole view
R_ResetViewRendering2D();
GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, true);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
}
r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0;
r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
- r_refdef.scene.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer;
+ r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+ if (FAKELIGHT_ENABLED)
+ {
+ r_refdef.lightmapintensity *= r_fakelight_intensity.value;
+ }
if (r_showsurfaces.integer)
{
r_refdef.scene.rtworld = false;
switch(vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
if(v_glslgamma.integer && !vid_gammatables_trivial)
{
if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial)
}
if (r_texture_gammaramps)
{
- R_UpdateTexture(r_texture_gammaramps, &rampbgr[0][0], 0, 0, RAMPWIDTH, 1);
+ R_UpdateTexture(r_texture_gammaramps, &rampbgr[0][0], 0, 0, 0, RAMPWIDTH, 1, 1);
}
else
{
- r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &rampbgr[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT | TEXF_ALLOWUPDATES, NULL);
+ r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &rampbgr[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, -1, NULL);
}
}
}
// remove GLSL gamma texture
}
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
break;
}
}
R_RenderView
================
*/
+int dpsoftrast_test;
+extern void R_Shadow_UpdateBounceGridTexture(void);
+extern cvar_t r_shadow_bouncegrid;
void R_RenderView(void)
{
+ matrix4x4_t originalmatrix = r_refdef.view.matrix, offsetmatrix;
+
+ dpsoftrast_test = r_test.integer;
+
if (r_timereport_active)
R_TimeReport("start");
r_textureframe++; // used only by R_GetCurrentTexture
rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
+ if(R_CompileShader_CheckStaticParms())
+ R_GLSL_Restart_f();
+
if (!r_drawentities.integer)
r_refdef.scene.numentities = 0;
R_AnimCache_ClearCache();
R_FrameData_NewFrame();
+ /* adjust for stereo display */
+ if(R_Stereo_Active())
+ {
+ 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);
+ Matrix4x4_Concat(&r_refdef.view.matrix, &originalmatrix, &offsetmatrix);
+ }
+
if (r_refdef.view.isoverlay)
{
// TODO: FIXME: move this into its own backend function maybe? [2/5/2008 Andreas]
- GL_Clear( GL_DEPTH_BUFFER_BIT );
+ GL_Clear(GL_DEPTH_BUFFER_BIT, NULL, 1.0f, 0);
R_TimeReport("depthclear");
r_refdef.view.showdebug = false;
R_RenderScene();
+ r_refdef.view.matrix = originalmatrix;
+
CHECKGLERROR
return;
}
if (!r_refdef.scene.entities || r_refdef.view.width * r_refdef.view.height == 0 || !r_renderview.integer || cl_videoplaying/* || !r_refdef.scene.worldmodel*/)
+ {
+ r_refdef.view.matrix = originalmatrix;
return; //Host_Error ("R_RenderView: NULL worldmodel");
+ }
- r_refdef.view.colorscale = r_hdr_scenebrightness.value;
+ r_refdef.view.colorscale = r_hdr_scenebrightness.value * r_hdr_irisadaptation_value.value;
R_RenderView_UpdateViewVectors();
r_refdef.view.clear = true;
// this produces a bloom texture to be used in R_BlendView() later
- if (r_hdr.integer && r_bloomstate.bloomwidth)
+ if (r_bloomstate.hdr)
{
R_HDR_RenderBloomTexture();
// we have to bump the texture frame again because r_refdef.view.colorscale is cached in the textures
if (r_timereport_active)
R_TimeReport("visibility");
+ R_Shadow_UpdateBounceGridTexture();
+ if (r_timereport_active && r_shadow_bouncegrid.integer)
+ R_TimeReport("bouncegrid");
+
r_waterstate.numwaterplanes = 0;
if (r_waterstate.enabled)
R_RenderWaterPlanes();
GL_Scissor(0, 0, vid.width, vid.height);
GL_ScissorTest(false);
+
+ r_refdef.view.matrix = originalmatrix;
+
CHECKGLERROR
}
}
}
- R_MeshQueue_RenderTransparent();
- if (r_timereport_active)
- R_TimeReport("drawtrans");
+ if (r_transparent.integer)
+ {
+ R_MeshQueue_RenderTransparent();
+ if (r_timereport_active)
+ R_TimeReport("drawtrans");
+ }
- 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))
+ 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 || r_showoverdraw.value > 0))
{
r_refdef.scene.worldmodel->DrawDebug(r_refdef.scene.worldentity);
if (r_timereport_active)
R_TimeReport("coronas");
}
+#if 0
+ {
+ GL_DepthTest(false);
+ qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ GL_Color(1, 1, 1, 1);
+ qglBegin(GL_POLYGON);
+ qglVertex3f(r_refdef.view.frustumcorner[0][0], r_refdef.view.frustumcorner[0][1], r_refdef.view.frustumcorner[0][2]);
+ qglVertex3f(r_refdef.view.frustumcorner[1][0], r_refdef.view.frustumcorner[1][1], r_refdef.view.frustumcorner[1][2]);
+ qglVertex3f(r_refdef.view.frustumcorner[3][0], r_refdef.view.frustumcorner[3][1], r_refdef.view.frustumcorner[3][2]);
+ qglVertex3f(r_refdef.view.frustumcorner[2][0], r_refdef.view.frustumcorner[2][1], r_refdef.view.frustumcorner[2][2]);
+ qglEnd();
+ qglBegin(GL_POLYGON);
+ 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]);
+ 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]);
+ 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]);
+ 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]);
+ qglEnd();
+ qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+#endif
+
// don't let sound skip if going slow
if (r_refdef.scene.extraupdate)
S_ExtraUpdate ();
GL_DepthMask(false);
GL_DepthRange(0, 1);
GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
- R_Mesh_ResetTextureState();
+// R_Mesh_ResetTextureState();
vertex3f[ 0] = mins[0];vertex3f[ 1] = mins[1];vertex3f[ 2] = mins[2]; //
vertex3f[ 3] = maxs[0];vertex3f[ 4] = mins[1];vertex3f[ 5] = mins[2];
}
R_Mesh_PrepareVertices_Generic_Arrays(8, vertex3f, color4f, NULL);
R_Mesh_ResetTextureState();
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
R_Mesh_Draw(0, 8, 0, 12, NULL, NULL, 0, bboxelements, NULL, 0);
}
return;
GL_CullFace(GL_NONE);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
prog = 0;
SV_VM_Begin();
for (i = 0;i < numsurfaces;i++)
{
edict = PRVM_EDICT_NUM(surfacelist[i]);
- switch ((int)edict->fields.server->solid)
+ switch ((int)PRVM_serveredictfloat(edict, solid))
{
case SOLID_NOT: Vector4Set(color, 1, 1, 1, 0.05);break;
case SOLID_TRIGGER: Vector4Set(color, 1, 0, 1, 0.10);break;
if (edict->priv.server->free)
continue;
// exclude the following for now, as they don't live in world coordinate space and can't be solid:
- if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.tag_entity)->edict != 0)
+ if(PRVM_serveredictedict(edict, tag_entity) != 0)
continue;
- if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.viewmodelforclient)->edict != 0)
+ if(PRVM_serveredictedict(edict, viewmodelforclient) != 0)
continue;
VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL);
GL_PolygonOffset(rsurface.basepolygonfactor, rsurface.basepolygonoffset);
GL_DepthTest(!(rsurface.ent_flags & RENDER_NODEPTHTEST));
GL_CullFace((rsurface.ent_flags & RENDER_DOUBLESIDED) ? GL_NONE : r_refdef.view.cullface_back);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
for (i = 0, c = color4f;i < 6;i++, c += 4)
{
c[2] = (c[2] * f1 + r_refdef.fogcolor[2] * f2);
}
}
- R_Mesh_ResetTextureState();
+// R_Mesh_ResetTextureState();
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
R_Mesh_PrepareVertices_Generic_Arrays(6, nomodelvertex3f, color4f, NULL);
R_Mesh_Draw(0, 6, 0, 8, nomodelelement3i, NULL, 0, nomodelelement3s, NULL, 0);
}
layer->color[3] = a;
}
+static qboolean R_TestQ3WaveFunc(q3wavefunc_t func, const float *parms)
+{
+ if(parms[0] == 0 && parms[1] == 0)
+ return false;
+ if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
+ if(rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)] == 0)
+ return false;
+ return true;
+}
+
static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms)
{
double index, f;
- index = parms[2] + r_refdef.scene.time * parms[3];
+ index = parms[2] + rsurface.shadertime * parms[3];
index -= floor(index);
- switch (func)
+ switch (func & ((1 << Q3WAVEFUNC_USER_SHIFT) - 1))
{
default:
case Q3WAVEFUNC_NONE:
index *= 4;
f = index - floor(index);
if (index < 1)
- f = f;
+ {
+ // f = f;
+ }
else if (index < 2)
f = 1 - f;
else if (index < 3)
f = -(1 - f);
break;
}
- return (float)(parms[0] + parms[1] * f);
+ f = parms[0] + parms[1] * f;
+ if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
+ f *= rsurface.userwavefunc_param[bound(0, (func >> Q3WAVEFUNC_USER_SHIFT) - 1, Q3WAVEFUNC_USER_COUNT)];
+ return (float) f;
}
void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags)
{
int w, h, idx;
- float f;
+ double f;
+ double offsetd[2];
float tcmat[12];
matrix4x4_t matrix, temp;
switch(tcmod->tcmod)
break;
case Q3TCMOD_ROTATE:
Matrix4x4_CreateTranslate(&matrix, 0.5, 0.5, 0);
- Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * r_refdef.scene.time, 0, 0, 1);
+ Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * rsurface.shadertime, 0, 0, 1);
Matrix4x4_ConcatTranslate(&matrix, -0.5, -0.5, 0);
break;
case Q3TCMOD_SCALE:
Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1);
break;
case Q3TCMOD_SCROLL:
- Matrix4x4_CreateTranslate(&matrix, tcmod->parms[0] * r_refdef.scene.time, tcmod->parms[1] * r_refdef.scene.time, 0);
+ // extra care is needed because of precision breakdown with large values of time
+ offsetd[0] = tcmod->parms[0] * rsurface.shadertime;
+ offsetd[1] = tcmod->parms[1] * rsurface.shadertime;
+ Matrix4x4_CreateTranslate(&matrix, offsetd[0] - floor(offsetd[0]), offsetd[1] - floor(offsetd[1]), 0);
break;
case Q3TCMOD_PAGE: // poor man's animmap (to store animations into a single file, useful for HTTP downloaded textures)
w = (int) tcmod->parms[0];
h = (int) tcmod->parms[1];
- f = r_refdef.scene.time / (tcmod->parms[2] * w * h);
+ f = rsurface.shadertime / (tcmod->parms[2] * w * h);
f = f - floor(f);
idx = (int) floor(f * w * h);
Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0);
void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
{
- int textureflags = (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP | TEXF_COMPRESS;
+ int textureflags = (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP;
char name[MAX_QPATH];
skinframe_t *skinframe;
unsigned char pixels[296*194];
if (model->skinscenes)
{
if (model->skinscenes[s].framecount > 1)
- s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.scene.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
+ s = model->skinscenes[s].firstframe + (unsigned int) (rsurface.shadertime * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
else
s = model->skinscenes[s].firstframe;
}
// use an alternate animation if the entity's frame is not 0,
// and only if the texture has an alternate animation
if (rsurface.ent_alttextures && t->anim_total[1])
- t = t->anim_frames[1][(t->anim_total[1] >= 2) ? ((int)(r_refdef.scene.time * 5.0f) % t->anim_total[1]) : 0];
+ t = t->anim_frames[1][(t->anim_total[1] >= 2) ? ((int)(rsurface.shadertime * 5.0f) % t->anim_total[1]) : 0];
else
- t = t->anim_frames[0][(t->anim_total[0] >= 2) ? ((int)(r_refdef.scene.time * 5.0f) % t->anim_total[0]) : 0];
+ t = t->anim_frames[0][(t->anim_total[0] >= 2) ? ((int)(rsurface.shadertime * 5.0f) % t->anim_total[0]) : 0];
}
texture->currentframe = t;
}
r_qwskincache_size = cl.maxclients;
if (r_qwskincache)
Mem_Free(r_qwskincache);
- r_qwskincache = Mem_Alloc(r_main_mempool, sizeof(*r_qwskincache) * r_qwskincache_size);
+ r_qwskincache = (r_qwskincache_t *)Mem_Alloc(r_main_mempool, sizeof(*r_qwskincache) * r_qwskincache_size);
}
if (strcmp(r_qwskincache[i].name, cl.scores[i].qw_skin))
R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin);
t->currentskinframe = r_qwskincache[i].skinframe;
if (t->currentskinframe == NULL)
- t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
+ t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)];
}
else if (t->numskinframes >= 2)
- t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
+ t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)];
if (t->backgroundnumskinframes >= 2)
- t->backgroundcurrentskinframe = t->backgroundskinframes[(int)(t->backgroundskinframerate * (cl.time - rsurface.ent_shadertime)) % t->backgroundnumskinframes];
+ t->backgroundcurrentskinframe = t->backgroundskinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundskinframerate, t->backgroundnumskinframes)];
t->currentmaterialflags = t->basematerialflags;
t->currentalpha = rsurface.colormod[3];
- if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer))
+ if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer || r_trippy.integer))
t->currentalpha *= r_wateralpha.value;
if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay)
- t->currentalpha *= t->r_water_wateralpha;
+ t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; // we apply wateralpha later
if(!r_waterstate.enabled || r_refdef.view.isoverlay)
t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA);
if (!(rsurface.ent_flags & RENDER_LIGHT))
t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
+ else if (FAKELIGHT_ENABLED)
+ {
+ // no modellight if using fakelight for the map
+ }
else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
{
// pick a model lighting mode
}
else
t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER | MATERIALFLAG_CAMERA);
+ if (vid.allowalphatocoverage && r_transparent_alphatocoverage.integer >= 2 && ((t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHA | MATERIALFLAG_ADD | MATERIALFLAG_CUSTOMBLEND)) == (MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHA)))
+ {
+ // promote alphablend to alphatocoverage (a type of alphatest) if antialiasing is on
+ t->currentmaterialflags = (t->currentmaterialflags & ~(MATERIALFLAG_BLENDED | MATERIALFLAG_ALPHA)) | MATERIALFLAG_ALPHATEST;
+ }
if ((t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)) == MATERIALFLAG_BLENDED && r_transparentdepthmasking.integer && !(t->basematerialflags & MATERIALFLAG_BLENDED))
t->currentmaterialflags |= MATERIALFLAG_TRANSDEPTH;
blendfunc1 = GL_ONE;
blendfunc2 = GL_ZERO;
}
+ // don't colormod evilblend textures
+ if(!R_BlendFuncFlags(blendfunc1, blendfunc2) & BLENDFUNC_ALLOWS_COLORMOD)
+ VectorSet(t->lightmapcolor, 1, 1, 1);
depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
{
rsurfacestate_t rsurface;
-void R_Mesh_ResizeArrays(int newvertices)
-{
- unsigned char *base;
- size_t size;
- if (rsurface.array_size >= newvertices)
- return;
- if (rsurface.array_base)
- Mem_Free(rsurface.array_base);
- rsurface.array_size = (newvertices + 1023) & ~1023;
- size = 0;
- size += rsurface.array_size * sizeof(*rsurface.array_modelvertexmesh);
- size += rsurface.array_size * sizeof(*rsurface.array_batchvertexmesh);
- size += rsurface.array_size * sizeof(*rsurface.array_modelvertexposition);
- size += rsurface.array_size * sizeof(*rsurface.array_batchvertexposition);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[3]);
- size += rsurface.array_size * sizeof(float[4]);
- size += rsurface.array_size * sizeof(float[2]);
- size += rsurface.array_size * sizeof(float[2]);
- size += rsurface.array_size * sizeof(float[4]);
- size += rsurface.array_size * sizeof(int[3]);
- size += rsurface.array_size * sizeof(unsigned short[3]);
- rsurface.array_base = base = (unsigned char *)Mem_Alloc(r_main_mempool, size);
- rsurface.array_modelvertexmesh = (r_vertexmesh_t *)base;base += rsurface.array_size * sizeof(*rsurface.array_modelvertexmesh);
- rsurface.array_batchvertexmesh = (r_vertexmesh_t *)base;base += rsurface.array_size * sizeof(*rsurface.array_batchvertexmesh);
- rsurface.array_modelvertexposition = (r_vertexposition_t *)base;base += rsurface.array_size * sizeof(*rsurface.array_modelvertexposition);
- rsurface.array_batchvertexposition = (r_vertexposition_t *)base;base += rsurface.array_size * sizeof(*rsurface.array_batchvertexposition);
- rsurface.array_modelvertex3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_modelsvector3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_modeltvector3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_modelnormal3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_batchvertex3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_batchsvector3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_batchtvector3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_batchnormal3f = (float *)base;base += rsurface.array_size * sizeof(float[3]);
- rsurface.array_batchlightmapcolor4f = (float *)base;base += rsurface.array_size * sizeof(float[4]);
- rsurface.array_batchtexcoordtexture2f = (float *)base;base += rsurface.array_size * sizeof(float[2]);
- rsurface.array_batchtexcoordlightmap2f = (float *)base;base += rsurface.array_size * sizeof(float[2]);
- rsurface.array_passcolor4f = (float *)base;base += rsurface.array_size * sizeof(float[4]);
- rsurface.array_batchelement3i = (int *)base;base += rsurface.array_size * sizeof(int[3]);
- rsurface.array_batchelement3s = (unsigned short *)base;base += rsurface.array_size * sizeof(unsigned short[3]);
-}
-
void RSurf_ActiveWorldEntity(void)
{
dp_model_t *model = r_refdef.scene.worldmodel;
// return;
rsurface.entity = r_refdef.scene.worldentity;
rsurface.skeleton = NULL;
+ memset(rsurface.userwavefunc_param, 0, sizeof(rsurface.userwavefunc_param));
rsurface.ent_skinnum = 0;
rsurface.ent_qwskin = -1;
- rsurface.ent_shadertime = 0;
rsurface.ent_flags = r_refdef.scene.worldentity->flags;
- if (rsurface.array_size < model->surfmesh.num_vertices)
- R_Mesh_ResizeArrays(model->surfmesh.num_vertices);
+ rsurface.shadertime = r_refdef.scene.time;
rsurface.matrix = identitymatrix;
rsurface.inversematrix = identitymatrix;
rsurface.matrixscale = 1;
rsurface.modelsurfaces = model->data_surfaces;
rsurface.modelvertexmesh = model->surfmesh.vertexmesh;
rsurface.modelvertexmeshbuffer = model->surfmesh.vertexmeshbuffer;
- rsurface.modelvertexposition = model->surfmesh.vertexposition;
- rsurface.modelvertexpositionbuffer = model->surfmesh.vertexpositionbuffer;
+ rsurface.modelvertex3fbuffer = model->surfmesh.vertex3fbuffer;
rsurface.modelgeneratedvertex = false;
rsurface.batchgeneratedvertex = false;
rsurface.batchfirstvertex = 0;
rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
rsurface.batchvertexmesh = NULL;
rsurface.batchvertexmeshbuffer = NULL;
- rsurface.batchvertexposition = NULL;
- rsurface.batchvertexpositionbuffer = NULL;
+ rsurface.batchvertex3fbuffer = NULL;
rsurface.batchelement3i = NULL;
rsurface.batchelement3i_indexbuffer = NULL;
rsurface.batchelement3i_bufferoffset = 0;
// return;
rsurface.entity = (entity_render_t *)ent;
rsurface.skeleton = ent->skeleton;
+ memcpy(rsurface.userwavefunc_param, ent->userwavefunc_param, sizeof(rsurface.userwavefunc_param));
rsurface.ent_skinnum = ent->skinnum;
rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1;
- rsurface.ent_shadertime = ent->shadertime;
rsurface.ent_flags = ent->flags;
- if (rsurface.array_size < model->surfmesh.num_vertices)
- R_Mesh_ResizeArrays(model->surfmesh.num_vertices);
+ rsurface.shadertime = r_refdef.scene.time - ent->shadertime;
rsurface.matrix = ent->matrix;
rsurface.inversematrix = ent->inversematrix;
rsurface.matrixscale = Matrix4x4_ScaleFromMatrix(&rsurface.matrix);
rsurface.basepolygonfactor += r_polygonoffset_submodel_factor.value;
rsurface.basepolygonoffset += r_polygonoffset_submodel_offset.value;
}
- if (model->surfmesh.isanimated && model->AnimateVertices && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].subframe != 0))
+ if (model->surfmesh.isanimated && model->AnimateVertices)
{
- if (ent->animcache_vertex3f && !r_framedata_failed)
+ if (ent->animcache_vertex3f)
{
rsurface.modelvertex3f = ent->animcache_vertex3f;
rsurface.modelsvector3f = wanttangents ? ent->animcache_svector3f : NULL;
rsurface.modelnormal3f = wantnormals ? ent->animcache_normal3f : NULL;
rsurface.modelvertexmesh = ent->animcache_vertexmesh;
rsurface.modelvertexmeshbuffer = ent->animcache_vertexmeshbuffer;
- rsurface.modelvertexposition = ent->animcache_vertexposition;
- rsurface.modelvertexpositionbuffer = ent->animcache_vertexpositionbuffer;
+ rsurface.modelvertex3fbuffer = ent->animcache_vertex3fbuffer;
}
else if (wanttangents)
{
- rsurface.modelvertex3f = rsurface.array_modelvertex3f;
- rsurface.modelsvector3f = rsurface.array_modelsvector3f;
- rsurface.modeltvector3f = rsurface.array_modeltvector3f;
- rsurface.modelnormal3f = rsurface.array_modelnormal3f;
- model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.array_modelvertex3f, rsurface.array_modelnormal3f, rsurface.array_modelsvector3f, rsurface.array_modeltvector3f);
+ rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
+ rsurface.modelsvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
+ rsurface.modeltvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
+ rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
+ model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, rsurface.modelnormal3f, rsurface.modelsvector3f, rsurface.modeltvector3f);
rsurface.modelvertexmesh = NULL;
rsurface.modelvertexmeshbuffer = NULL;
- rsurface.modelvertexposition = NULL;
- rsurface.modelvertexpositionbuffer = NULL;
+ rsurface.modelvertex3fbuffer = NULL;
}
else if (wantnormals)
{
- rsurface.modelvertex3f = rsurface.array_modelvertex3f;
+ rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
rsurface.modelsvector3f = NULL;
rsurface.modeltvector3f = NULL;
- rsurface.modelnormal3f = rsurface.array_modelnormal3f;
- model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.array_modelvertex3f, rsurface.array_modelnormal3f, NULL, NULL);
+ rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
+ model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, rsurface.modelnormal3f, NULL, NULL);
rsurface.modelvertexmesh = NULL;
rsurface.modelvertexmeshbuffer = NULL;
- rsurface.modelvertexposition = NULL;
- rsurface.modelvertexpositionbuffer = NULL;
+ rsurface.modelvertex3fbuffer = NULL;
}
else
{
- rsurface.modelvertex3f = rsurface.array_modelvertex3f;
+ rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
rsurface.modelsvector3f = NULL;
rsurface.modeltvector3f = NULL;
rsurface.modelnormal3f = NULL;
- model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.array_modelvertex3f, NULL, NULL, NULL);
+ model->AnimateVertices(model, rsurface.frameblend, rsurface.skeleton, rsurface.modelvertex3f, NULL, NULL, NULL);
rsurface.modelvertexmesh = NULL;
rsurface.modelvertexmeshbuffer = NULL;
- rsurface.modelvertexposition = NULL;
- rsurface.modelvertexpositionbuffer = NULL;
+ rsurface.modelvertex3fbuffer = NULL;
}
rsurface.modelvertex3f_vertexbuffer = 0;
rsurface.modelvertex3f_bufferoffset = 0;
rsurface.modelnormal3f_bufferoffset = model->surfmesh.vbooffset_normal3f;
rsurface.modelvertexmesh = model->surfmesh.vertexmesh;
rsurface.modelvertexmeshbuffer = model->surfmesh.vertexmeshbuffer;
- rsurface.modelvertexposition = model->surfmesh.vertexposition;
- rsurface.modelvertexpositionbuffer = model->surfmesh.vertexpositionbuffer;
+ rsurface.modelvertex3fbuffer = model->surfmesh.vertex3fbuffer;
rsurface.modelgeneratedvertex = false;
}
rsurface.modellightmapcolor4f = model->surfmesh.data_lightmapcolor4f;
rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
rsurface.batchvertexmesh = NULL;
rsurface.batchvertexmeshbuffer = NULL;
- rsurface.batchvertexposition = NULL;
- rsurface.batchvertexpositionbuffer = NULL;
+ rsurface.batchvertex3fbuffer = NULL;
rsurface.batchelement3i = NULL;
rsurface.batchelement3i_indexbuffer = NULL;
rsurface.batchelement3i_bufferoffset = 0;
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)
{
- int i;
-
rsurface.entity = r_refdef.scene.worldentity;
rsurface.skeleton = NULL;
rsurface.ent_skinnum = 0;
rsurface.ent_qwskin = -1;
- rsurface.ent_shadertime = shadertime;
rsurface.ent_flags = entflags;
+ rsurface.shadertime = r_refdef.scene.time - shadertime;
rsurface.modelnumvertices = numvertices;
rsurface.modelnumtriangles = numtriangles;
- if (rsurface.array_size < rsurface.modelnumvertices)
- R_Mesh_ResizeArrays(rsurface.modelnumvertices);
rsurface.matrix = *matrix;
rsurface.inversematrix = *inversematrix;
rsurface.matrixscale = Matrix4x4_ScaleFromMatrix(&rsurface.matrix);
rsurface.basepolygonoffset = r_refdef.polygonoffset;
if (wanttangents)
{
- rsurface.modelvertex3f = vertex3f;
- rsurface.modelsvector3f = svector3f ? svector3f : rsurface.array_modelsvector3f;
- rsurface.modeltvector3f = tvector3f ? tvector3f : rsurface.array_modeltvector3f;
- rsurface.modelnormal3f = normal3f ? normal3f : rsurface.array_modelnormal3f;
+ rsurface.modelvertex3f = (float *)vertex3f;
+ rsurface.modelsvector3f = svector3f ? (float *)svector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
+ rsurface.modeltvector3f = tvector3f ? (float *)tvector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
+ rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
}
else if (wantnormals)
{
- rsurface.modelvertex3f = vertex3f;
+ rsurface.modelvertex3f = (float *)vertex3f;
rsurface.modelsvector3f = NULL;
rsurface.modeltvector3f = NULL;
- rsurface.modelnormal3f = normal3f ? normal3f : rsurface.array_modelnormal3f;
+ rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
}
else
{
- rsurface.modelvertex3f = vertex3f;
+ rsurface.modelvertex3f = (float *)vertex3f;
rsurface.modelsvector3f = NULL;
rsurface.modeltvector3f = NULL;
rsurface.modelnormal3f = NULL;
}
rsurface.modelvertexmesh = NULL;
rsurface.modelvertexmeshbuffer = NULL;
- rsurface.modelvertexposition = NULL;
- rsurface.modelvertexpositionbuffer = NULL;
+ rsurface.modelvertex3fbuffer = NULL;
rsurface.modelvertex3f_vertexbuffer = 0;
rsurface.modelvertex3f_bufferoffset = 0;
rsurface.modelsvector3f_vertexbuffer = 0;
rsurface.modelnormal3f_vertexbuffer = 0;
rsurface.modelnormal3f_bufferoffset = 0;
rsurface.modelgeneratedvertex = true;
- rsurface.modellightmapcolor4f = color4f;
+ rsurface.modellightmapcolor4f = (float *)color4f;
rsurface.modellightmapcolor4f_vertexbuffer = 0;
rsurface.modellightmapcolor4f_bufferoffset = 0;
- rsurface.modeltexcoordtexture2f = texcoord2f;
+ rsurface.modeltexcoordtexture2f = (float *)texcoord2f;
rsurface.modeltexcoordtexture2f_vertexbuffer = 0;
rsurface.modeltexcoordtexture2f_bufferoffset = 0;
rsurface.modeltexcoordlightmap2f = NULL;
rsurface.modeltexcoordlightmap2f_vertexbuffer = 0;
rsurface.modeltexcoordlightmap2f_bufferoffset = 0;
- rsurface.modelelement3i = element3i;
+ rsurface.modelelement3i = (int *)element3i;
rsurface.modelelement3i_indexbuffer = NULL;
rsurface.modelelement3i_bufferoffset = 0;
- rsurface.modelelement3s = element3s;
+ rsurface.modelelement3s = (unsigned short *)element3s;
rsurface.modelelement3s_indexbuffer = NULL;
rsurface.modelelement3s_bufferoffset = 0;
rsurface.modellightmapoffsets = NULL;
rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
rsurface.batchvertexmesh = NULL;
rsurface.batchvertexmeshbuffer = NULL;
- rsurface.batchvertexposition = NULL;
- rsurface.batchvertexpositionbuffer = NULL;
+ rsurface.batchvertex3fbuffer = NULL;
rsurface.batchelement3i = NULL;
rsurface.batchelement3i_indexbuffer = NULL;
rsurface.batchelement3i_bufferoffset = 0;
{
if ((wantnormals || wanttangents) && !normal3f)
{
- Mod_BuildNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modelelement3i, rsurface.array_modelnormal3f, r_smoothnormals_areaweighting.integer != 0);
- rsurface.modelnormal3f = rsurface.array_modelnormal3f;
+ rsurface.modelnormal3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
+ Mod_BuildNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modelelement3i, rsurface.modelnormal3f, r_smoothnormals_areaweighting.integer != 0);
}
if (wanttangents && !svector3f)
{
- Mod_BuildTextureVectorsFromNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modeltexcoordtexture2f, rsurface.modelnormal3f, rsurface.modelelement3i, rsurface.array_modelsvector3f, rsurface.array_modeltvector3f, r_smoothnormals_areaweighting.integer != 0);
- rsurface.modelsvector3f = rsurface.array_modelsvector3f;
- rsurface.modeltvector3f = rsurface.array_modeltvector3f;
+ rsurface.modelsvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
+ rsurface.modeltvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
+ Mod_BuildTextureVectorsFromNormals(0, rsurface.modelnumvertices, rsurface.modelnumtriangles, rsurface.modelvertex3f, rsurface.modeltexcoordtexture2f, rsurface.modelnormal3f, rsurface.modelelement3i, rsurface.modelsvector3f, rsurface.modeltvector3f, r_smoothnormals_areaweighting.integer != 0);
}
}
-
- // now convert arrays into vertexmesh structs
- for (i = 0;i < numvertices;i++)
- {
- VectorCopy(rsurface.modelvertex3f + 3*i, rsurface.array_modelvertexposition[i].vertex3f);
- VectorCopy(rsurface.modelvertex3f + 3*i, rsurface.array_modelvertexmesh[i].vertex3f);
- if (rsurface.modelsvector3f)
- VectorCopy(rsurface.modelsvector3f + 3*i, rsurface.array_modelvertexmesh[i].svector3f);
- if (rsurface.modeltvector3f)
- VectorCopy(rsurface.modeltvector3f + 3*i, rsurface.array_modelvertexmesh[i].tvector3f);
- if (rsurface.modelnormal3f)
- VectorCopy(rsurface.modelnormal3f + 3*i, rsurface.array_modelvertexmesh[i].normal3f);
- if (rsurface.modellightmapcolor4f)
- Vector4Scale(rsurface.modellightmapcolor4f + 4*i, 255.0f, rsurface.array_modelvertexmesh[i].color4ub);
- if (rsurface.modeltexcoordtexture2f)
- Vector2Copy(rsurface.modeltexcoordtexture2f + 2*i, rsurface.array_modelvertexmesh[i].texcoordtexture2f);
- if (rsurface.modeltexcoordlightmap2f)
- Vector2Copy(rsurface.modeltexcoordlightmap2f + 2*i, rsurface.array_modelvertexmesh[i].texcoordlightmap2f);
- }
}
float RSurf_FogPoint(const float *v)
int surfacefirstvertex;
int surfaceendvertex;
int surfacenumvertices;
- int surfaceadjustvertex;
+ int batchnumvertices;
+ int batchnumtriangles;
int needsupdate;
int i, j;
qboolean gaps;
float waveparms[4];
q3shaderinfo_deform_t *deform;
const msurface_t *surface, *firstsurface;
- r_vertexposition_t *vertexposition;
r_vertexmesh_t *vertexmesh;
if (!texturenumsurfaces)
return;
gaps = false;
firstsurface = texturesurfacelist[0];
firsttriangle = firstsurface->num_firsttriangle;
- numtriangles = 0;
+ batchnumvertices = 0;
+ batchnumtriangles = 0;
firstvertex = endvertex = firstsurface->num_firstvertex;
for (i = 0;i < texturenumsurfaces;i++)
{
gaps = true;
surfacefirstvertex = surface->num_firstvertex;
surfaceendvertex = surfacefirstvertex + surface->num_vertices;
+ surfacenumvertices = surface->num_vertices;
surfacenumtriangles = surface->num_triangles;
if (firstvertex > surfacefirstvertex)
firstvertex = surfacefirstvertex;
if (endvertex < surfaceendvertex)
endvertex = surfaceendvertex;
- numtriangles += surfacenumtriangles;
+ batchnumvertices += surfacenumvertices;
+ batchnumtriangles += surfacenumtriangles;
}
- if (!numtriangles)
- return;
// we now know the vertex range used, and if there are any gaps in it
rsurface.batchfirstvertex = firstvertex;
rsurface.batchnumvertices = endvertex - firstvertex;
rsurface.batchfirsttriangle = firsttriangle;
- rsurface.batchnumtriangles = numtriangles;
+ rsurface.batchnumtriangles = batchnumtriangles;
// this variable holds flags for which properties have been updated that
- // may require regenerating vertexmesh or vertexposition arrays...
+ // may require regenerating vertexmesh array...
needsupdate = 0;
+ // check if any dynamic vertex processing must occur
+ dynamicvertex = false;
+
+ // if there is a chance of animated vertex colors, it's a dynamic batch
if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_ARRAY_VERTEXCOLOR)) && texturesurfacelist[0]->lightmapinfo)
- needsupdate |= BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_NOGAPS;
- for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
+ {
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_NOGAPS;
+ needsupdate |= BATCHNEED_VERTEXMESH_VERTEXCOLOR;
+ }
+
+ for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform && r_deformvertexes.integer;deformindex++, deform++)
{
switch (deform->deform)
{
case Q3DEFORM_NONE:
break;
case Q3DEFORM_AUTOSPRITE:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
- needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
+ needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_AUTOSPRITE2:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
- needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
+ needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_NORMAL:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_WAVE:
+ if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
+ break; // if wavefunc is a nop, ignore this transform
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
- needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
+ needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_BULGE:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
- needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
+ needsupdate |= BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR;
break;
case Q3DEFORM_MOVE:
+ if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
+ break; // if wavefunc is a nop, ignore this transform
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
- needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX;
+ needsupdate |= BATCHNEED_VERTEXMESH_VERTEX;
break;
}
}
case Q3TCGEN_TEXTURE:
break;
case Q3TCGEN_LIGHTMAP:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_LIGHTMAP | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
break;
case Q3TCGEN_VECTOR:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
break;
case Q3TCGEN_ENVIRONMENT:
+ dynamicvertex = true;
batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
break;
}
if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
- batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
}
- // check if any dynamic vertex processing must occur
- dynamicvertex = false;
-
if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
{
dynamicvertex = true;
needsupdate |= (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP));
}
- if (needsupdate & batchneed & BATCHNEED_VERTEXPOSITION)
- {
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
- needsupdate |= (batchneed & BATCHNEED_VERTEXPOSITION);
- }
-
if (dynamicvertex || gaps || rsurface.batchfirstvertex)
{
// when copying, we need to consider the regeneration of vertexmesh, any dependencies it may have must be set...
// when the model data has no vertex buffer (dynamic mesh), we need to
// eliminate gaps
- if (!rsurface.modelvertexmeshbuffer || (!gl_vbo.integer && !vid.forcevbo))
+ if (vid.useinterleavedarrays ? !rsurface.modelvertexmeshbuffer : !rsurface.modelvertex3f_vertexbuffer)
batchneed |= BATCHNEED_NOGAPS;
// if needsupdate, we have to do a dynamic vertex batch for sure
if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
dynamicvertex = true;
- // see if we need to build vertexposition from arrays
- if (!rsurface.modelvertexposition && (batchneed & BATCHNEED_VERTEXPOSITION))
- dynamicvertex = true;
-
// if gaps are unacceptable, and there are gaps, it's a dynamic batch...
+ // also some drivers strongly dislike firstvertex
if ((batchneed & BATCHNEED_NOGAPS) && (gaps || firstvertex))
dynamicvertex = true;
- // if there is a chance of animated vertex colors, it's a dynamic batch
- if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_ARRAY_VERTEXCOLOR)) && texturesurfacelist[0]->lightmapinfo)
- dynamicvertex = true;
-
rsurface.batchvertex3f = rsurface.modelvertex3f;
rsurface.batchvertex3f_vertexbuffer = rsurface.modelvertex3f_vertexbuffer;
rsurface.batchvertex3f_bufferoffset = rsurface.modelvertex3f_bufferoffset;
rsurface.batchtexcoordlightmap2f = rsurface.modeltexcoordlightmap2f;
rsurface.batchtexcoordlightmap2f_vertexbuffer = rsurface.modeltexcoordlightmap2f_vertexbuffer;
rsurface.batchtexcoordlightmap2f_bufferoffset = rsurface.modeltexcoordlightmap2f_bufferoffset;
- rsurface.batchvertexposition = rsurface.modelvertexposition;
- rsurface.batchvertexpositionbuffer = rsurface.modelvertexpositionbuffer;
+ rsurface.batchvertex3fbuffer = rsurface.modelvertex3fbuffer;
rsurface.batchvertexmesh = rsurface.modelvertexmesh;
rsurface.batchvertexmeshbuffer = rsurface.modelvertexmeshbuffer;
rsurface.batchelement3i = rsurface.modelelement3i;
// otherwise use the original static buffer with an appropriate offset
if (gaps)
{
- firsttriangle = 0;
+ // build a new triangle elements array for this batch
+ rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
+ rsurface.batchfirsttriangle = 0;
numtriangles = 0;
for (i = 0;i < texturenumsurfaces;i++)
{
surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
surfacenumtriangles = texturesurfacelist[i]->num_triangles;
- memcpy(rsurface.array_batchelement3i + 3*numtriangles, rsurface.modelelement3i + 3*surfacefirsttriangle, surfacenumtriangles*sizeof(int[3]));
+ memcpy(rsurface.batchelement3i + 3*numtriangles, rsurface.modelelement3i + 3*surfacefirsttriangle, surfacenumtriangles*sizeof(int[3]));
numtriangles += surfacenumtriangles;
}
- rsurface.batchelement3i = rsurface.array_batchelement3i;
rsurface.batchelement3i_indexbuffer = NULL;
rsurface.batchelement3i_bufferoffset = 0;
rsurface.batchelement3s = NULL;
rsurface.batchelement3s_bufferoffset = 0;
if (endvertex <= 65536)
{
- rsurface.batchelement3s = rsurface.array_batchelement3s;
+ // make a 16bit (unsigned short) index array if possible
+ rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
for (i = 0;i < numtriangles*3;i++)
- rsurface.array_batchelement3s[i] = rsurface.array_batchelement3i[i];
+ rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
}
- rsurface.batchfirsttriangle = firsttriangle;
- rsurface.batchnumtriangles = numtriangles;
}
return;
}
// something needs software processing, do it for real...
- // we only directly handle interleaved array data in this case...
+ // we only directly handle separate array data in this case and then
+ // generate interleaved data if needed...
rsurface.batchgeneratedvertex = true;
// now copy the vertex data into a combined array and make an index array
// (this is what Quake3 does all the time)
//if (gaps || rsurface.batchfirstvertex)
{
- rsurface.batchvertexposition = NULL;
- rsurface.batchvertexpositionbuffer = NULL;
+ rsurface.batchvertex3fbuffer = NULL;
rsurface.batchvertexmesh = NULL;
rsurface.batchvertexmeshbuffer = NULL;
rsurface.batchvertex3f = NULL;
rsurface.batchtexcoordlightmap2f = NULL;
rsurface.batchtexcoordlightmap2f_vertexbuffer = NULL;
rsurface.batchtexcoordlightmap2f_bufferoffset = 0;
- rsurface.batchelement3i = rsurface.array_batchelement3i;
+ rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
rsurface.batchelement3i_indexbuffer = NULL;
rsurface.batchelement3i_bufferoffset = 0;
rsurface.batchelement3s = NULL;
rsurface.batchelement3s_indexbuffer = NULL;
rsurface.batchelement3s_bufferoffset = 0;
// we'll only be setting up certain arrays as needed
- if (batchneed & BATCHNEED_VERTEXPOSITION)
- rsurface.batchvertexposition = rsurface.array_batchvertexposition;
if (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP))
- rsurface.batchvertexmesh = rsurface.array_batchvertexmesh;
+ rsurface.batchvertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(batchnumvertices * sizeof(r_vertexmesh_t));
if (batchneed & BATCHNEED_ARRAY_VERTEX)
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
+ rsurface.batchvertex3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
if (batchneed & BATCHNEED_ARRAY_NORMAL)
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
+ rsurface.batchnormal3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
if (batchneed & BATCHNEED_ARRAY_VECTOR)
{
- rsurface.batchsvector3f = rsurface.array_batchsvector3f;
- rsurface.batchtvector3f = rsurface.array_batchtvector3f;
+ rsurface.batchsvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+ rsurface.batchtvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
}
if (batchneed & BATCHNEED_ARRAY_VERTEXCOLOR)
- rsurface.batchlightmapcolor4f = rsurface.array_batchlightmapcolor4f;
+ rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
if (batchneed & BATCHNEED_ARRAY_TEXCOORD)
- rsurface.batchtexcoordtexture2f = rsurface.array_batchtexcoordtexture2f;
+ rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
if (batchneed & BATCHNEED_ARRAY_LIGHTMAP)
- rsurface.batchtexcoordlightmap2f = rsurface.array_batchtexcoordlightmap2f;
+ rsurface.batchtexcoordlightmap2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
numvertices = 0;
numtriangles = 0;
for (i = 0;i < texturenumsurfaces;i++)
surfacefirstvertex = texturesurfacelist[i]->num_firstvertex;
surfacenumvertices = texturesurfacelist[i]->num_vertices;
surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
- surfaceadjustvertex = numvertices - surfacefirstvertex;
surfacenumtriangles = texturesurfacelist[i]->num_triangles;
// copy only the data requested
- if ((batchneed & BATCHNEED_VERTEXPOSITION) && rsurface.modelvertexposition)
- memcpy(rsurface.array_batchvertexposition + numvertices, rsurface.modelvertexposition + surfacefirstvertex, surfacenumvertices * sizeof(rsurface.batchvertexposition[0]));
if ((batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)) && rsurface.modelvertexmesh)
- memcpy(rsurface.array_batchvertexmesh + numvertices, rsurface.modelvertexmesh + surfacefirstvertex, surfacenumvertices * sizeof(rsurface.batchvertexmesh[0]));
+ memcpy(rsurface.batchvertexmesh + numvertices, rsurface.modelvertexmesh + surfacefirstvertex, surfacenumvertices * sizeof(rsurface.batchvertexmesh[0]));
if (batchneed & (BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_ARRAY_LIGHTMAP))
{
if (batchneed & BATCHNEED_ARRAY_VERTEX)
- memcpy(rsurface.array_batchvertex3f + 3*numvertices, rsurface.modelvertex3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
- if ((batchneed & BATCHNEED_ARRAY_NORMAL) && rsurface.modelnormal3f)
- memcpy(rsurface.array_batchnormal3f + 3*numvertices, rsurface.modelnormal3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
- if ((batchneed & BATCHNEED_ARRAY_VECTOR) && rsurface.modelsvector3f)
{
- memcpy(rsurface.array_batchsvector3f + 3*numvertices, rsurface.modelsvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
- memcpy(rsurface.array_batchtvector3f + 3*numvertices, rsurface.modeltvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
+ if (rsurface.batchvertex3f)
+ memcpy(rsurface.batchvertex3f + 3*numvertices, rsurface.modelvertex3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
+ else
+ memset(rsurface.batchvertex3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
+ }
+ if (batchneed & BATCHNEED_ARRAY_NORMAL)
+ {
+ if (rsurface.modelnormal3f)
+ memcpy(rsurface.batchnormal3f + 3*numvertices, rsurface.modelnormal3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
+ else
+ memset(rsurface.batchnormal3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
+ }
+ if (batchneed & BATCHNEED_ARRAY_VECTOR)
+ {
+ if (rsurface.modelsvector3f)
+ {
+ memcpy(rsurface.batchsvector3f + 3*numvertices, rsurface.modelsvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
+ memcpy(rsurface.batchtvector3f + 3*numvertices, rsurface.modeltvector3f + 3*surfacefirstvertex, surfacenumvertices * sizeof(float[3]));
+ }
+ else
+ {
+ memset(rsurface.batchsvector3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
+ memset(rsurface.batchtvector3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
+ }
+ }
+ if (batchneed & BATCHNEED_ARRAY_VERTEXCOLOR)
+ {
+ if (rsurface.modellightmapcolor4f)
+ memcpy(rsurface.batchlightmapcolor4f + 4*numvertices, rsurface.modellightmapcolor4f + 4*surfacefirstvertex, surfacenumvertices * sizeof(float[4]));
+ else
+ memset(rsurface.batchlightmapcolor4f + 4*numvertices, 0, surfacenumvertices * sizeof(float[4]));
+ }
+ if (batchneed & BATCHNEED_ARRAY_TEXCOORD)
+ {
+ if (rsurface.modeltexcoordtexture2f)
+ memcpy(rsurface.batchtexcoordtexture2f + 2*numvertices, rsurface.modeltexcoordtexture2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
+ else
+ memset(rsurface.batchtexcoordtexture2f + 2*numvertices, 0, surfacenumvertices * sizeof(float[2]));
+ }
+ if (batchneed & BATCHNEED_ARRAY_LIGHTMAP)
+ {
+ if (rsurface.modeltexcoordlightmap2f)
+ memcpy(rsurface.batchtexcoordlightmap2f + 2*numvertices, rsurface.modeltexcoordlightmap2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
+ else
+ memset(rsurface.batchtexcoordlightmap2f + 2*numvertices, 0, surfacenumvertices * sizeof(float[2]));
}
- if ((batchneed & BATCHNEED_ARRAY_VERTEXCOLOR) && rsurface.modellightmapcolor4f)
- memcpy(rsurface.array_batchlightmapcolor4f + 4*numvertices, rsurface.modellightmapcolor4f + 4*surfacefirstvertex, surfacenumvertices * sizeof(float[4]));
- if ((batchneed & BATCHNEED_ARRAY_TEXCOORD) && rsurface.modeltexcoordtexture2f)
- memcpy(rsurface.array_batchtexcoordtexture2f + 2*numvertices, rsurface.modeltexcoordtexture2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
- if ((batchneed & BATCHNEED_ARRAY_LIGHTMAP) && rsurface.modeltexcoordlightmap2f)
- memcpy(rsurface.array_batchtexcoordlightmap2f + 2*numvertices, rsurface.modeltexcoordlightmap2f + 2*surfacefirstvertex, surfacenumvertices * sizeof(float[2]));
}
- RSurf_RenumberElements(rsurface.modelelement3i + 3*surfacefirsttriangle, rsurface.array_batchelement3i + 3*numtriangles, 3*surfacenumtriangles, numvertices - surfacefirstvertex);
+ RSurf_RenumberElements(rsurface.modelelement3i + 3*surfacefirsttriangle, rsurface.batchelement3i + 3*numtriangles, 3*surfacenumtriangles, numvertices - surfacefirstvertex);
numvertices += surfacenumvertices;
numtriangles += surfacenumtriangles;
}
// (in general, dynamic batches fit)
if (numvertices <= 65536)
{
- rsurface.batchelement3s = rsurface.array_batchelement3s;
+ rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
for (i = 0;i < numtriangles*3;i++)
- rsurface.array_batchelement3s[i] = rsurface.array_batchelement3i[i];
+ rsurface.batchelement3s[i] = rsurface.batchelement3i[i];
}
// since we've copied everything, the batch now starts at 0
rsurface.batchfirstvertex = 0;
- rsurface.batchnumvertices = numvertices;
+ rsurface.batchnumvertices = batchnumvertices;
rsurface.batchfirsttriangle = 0;
- rsurface.batchnumtriangles = numtriangles;
+ rsurface.batchnumtriangles = batchnumtriangles;
}
// q1bsp surfaces rendered in vertex color mode have to have colors
int size3;
const int *offsets;
const unsigned char *lm;
- numvertices = 0;
- rsurface.batchlightmapcolor4f = rsurface.array_batchlightmapcolor4f;
+ rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
rsurface.batchlightmapcolor4f_vertexbuffer = NULL;
rsurface.batchlightmapcolor4f_bufferoffset = 0;
+ numvertices = 0;
for (i = 0;i < texturenumsurfaces;i++)
{
surface = texturesurfacelist[i];
}
}
}
- c[0] >>= 15;
- c[1] >>= 15;
- c[2] >>= 15;
- Vector4Set(rsurface.array_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);
+ c[0] >>= 7;
+ c[1] >>= 7;
+ c[2] >>= 7;
+ 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);
numvertices++;
}
}
{
for (j = 0;j < surfacenumvertices;j++)
{
- Vector4Set(rsurface.array_batchlightmapcolor4f + 4*numvertices, 0, 0, 0, 1);
+ Vector4Set(rsurface.batchlightmapcolor4f + 4*numvertices, 0, 0, 0, 1);
numvertices++;
}
}
// if vertices are deformed (sprite flares and things in maps, possibly
// water waves, bulges and other deformations), modify the copied vertices
// in place
- for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
+ for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform && r_deformvertexes.integer;deformindex++, deform++)
{
switch (deform->deform)
{
VectorNormalize(newforward);
VectorNormalize(newright);
VectorNormalize(newup);
+// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
+// rsurface.batchvertex3f_vertexbuffer = NULL;
+// rsurface.batchvertex3f_bufferoffset = 0;
+// rsurface.batchsvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f);
+// rsurface.batchsvector3f_vertexbuffer = NULL;
+// rsurface.batchsvector3f_bufferoffset = 0;
+// rsurface.batchtvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f);
+// rsurface.batchtvector3f_vertexbuffer = NULL;
+// rsurface.batchtvector3f_bufferoffset = 0;
+// rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
+// rsurface.batchnormal3f_vertexbuffer = NULL;
+// rsurface.batchnormal3f_bufferoffset = 0;
+ // sometimes we're on a renderpath that does not use vectors (GL11/GL13/GLES1)
+ if (!VectorLength2(rsurface.batchnormal3f + 3*rsurface.batchfirstvertex))
+ Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
+ if (!VectorLength2(rsurface.batchsvector3f + 3*rsurface.batchfirstvertex))
+ 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);
// a single autosprite surface can contain multiple sprites...
- for (j = 0;j < rsurface.batchnumvertices - 3;j += 4)
+ for (j = 0;j < batchnumvertices - 3;j += 4)
{
VectorClear(center);
for (i = 0;i < 4;i++)
for (i = 0;i < 4;i++)
{
VectorSubtract(rsurface.batchvertex3f + 3*(j+i), center, v);
- VectorMAMAMAM(1, center, DotProduct(forward, v), newforward, DotProduct(right, v), newright, DotProduct(up, v), newup, rsurface.array_batchvertex3f + 3*(j+i));
+ VectorMAMAMAM(1, center, DotProduct(forward, v), newforward, DotProduct(right, v), newright, DotProduct(up, v), newup, rsurface.batchvertex3f + 3*(j+i));
}
}
- Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
- Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
- rsurface.batchsvector3f = rsurface.array_batchsvector3f;
- rsurface.batchsvector3f_vertexbuffer = NULL;
- rsurface.batchsvector3f_bufferoffset = 0;
- rsurface.batchtvector3f = rsurface.array_batchtvector3f;
- rsurface.batchtvector3f_vertexbuffer = NULL;
- rsurface.batchtvector3f_bufferoffset = 0;
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
+ // if we get here, BATCHNEED_ARRAY_NORMAL and BATCHNEED_ARRAY_VECTOR are in batchneed, so no need to check
+ Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
+ 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);
break;
case Q3DEFORM_AUTOSPRITE2:
Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, newforward);
VectorNormalize(newforward);
VectorNormalize(newright);
VectorNormalize(newup);
+// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
+// rsurface.batchvertex3f_vertexbuffer = NULL;
+// rsurface.batchvertex3f_bufferoffset = 0;
{
const float *v1, *v2;
vec3_t start, end;
shortest[2];
memset(shortest, 0, sizeof(shortest));
// a single autosprite surface can contain multiple sprites...
- for (j = 0;j < rsurface.batchnumvertices - 3;j += 4)
+ for (j = 0;j < batchnumvertices - 3;j += 4)
{
VectorClear(center);
for (i = 0;i < 4;i++)
{
v1 = rsurface.batchvertex3f + 3*(j+i);
f = DotProduct(right, v1) - l;
- VectorMAMAM(1, v1, -f, right, f, newright, rsurface.array_batchvertex3f + 3*(j+i));
+ VectorMAMAM(1, v1, -f, right, f, newright, rsurface.batchvertex3f + 3*(j+i));
}
}
}
- Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
- Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
- rsurface.batchsvector3f = rsurface.array_batchsvector3f;
- rsurface.batchsvector3f_vertexbuffer = NULL;
- rsurface.batchsvector3f_bufferoffset = 0;
- rsurface.batchtvector3f = rsurface.array_batchtvector3f;
- rsurface.batchtvector3f_vertexbuffer = NULL;
- rsurface.batchtvector3f_bufferoffset = 0;
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
+ if(batchneed & (BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR)) // otherwise these can stay NULL
+ {
+// rsurface.batchnormal3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchnormal3f_vertexbuffer = NULL;
+// rsurface.batchnormal3f_bufferoffset = 0;
+ Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
+ }
+ if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+ {
+// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchsvector3f_vertexbuffer = NULL;
+// rsurface.batchsvector3f_bufferoffset = 0;
+// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchtvector3f_vertexbuffer = NULL;
+// rsurface.batchtvector3f_bufferoffset = 0;
+ 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);
+ }
break;
case Q3DEFORM_NORMAL:
// deform the normals to make reflections wavey
- for (j = 0;j < rsurface.batchnumvertices;j++)
+ rsurface.batchnormal3f = (float *)R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
+ rsurface.batchnormal3f_vertexbuffer = NULL;
+ rsurface.batchnormal3f_bufferoffset = 0;
+ for (j = 0;j < batchnumvertices;j++)
{
float vertex[3];
- float *normal = rsurface.array_batchnormal3f + 3*j;
+ float *normal = rsurface.batchnormal3f + 3*j;
VectorScale(rsurface.batchvertex3f + 3*j, 0.98f, vertex);
- normal[0] = rsurface.batchnormal3f[j*3+0] + deform->parms[0] * noise4f( vertex[0], vertex[1], vertex[2], r_refdef.scene.time * deform->parms[1]);
- 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]);
- 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]);
+ normal[0] = rsurface.batchnormal3f[j*3+0] + deform->parms[0] * noise4f( vertex[0], vertex[1], vertex[2], rsurface.shadertime * deform->parms[1]);
+ normal[1] = rsurface.batchnormal3f[j*3+1] + deform->parms[0] * noise4f( 98 + vertex[0], vertex[1], vertex[2], rsurface.shadertime * deform->parms[1]);
+ normal[2] = rsurface.batchnormal3f[j*3+2] + deform->parms[0] * noise4f(196 + vertex[0], vertex[1], vertex[2], rsurface.shadertime * deform->parms[1]);
VectorNormalize(normal);
}
- Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
- rsurface.batchsvector3f = rsurface.array_batchsvector3f;
- rsurface.batchsvector3f_vertexbuffer = NULL;
- rsurface.batchsvector3f_bufferoffset = 0;
- rsurface.batchtvector3f = rsurface.array_batchtvector3f;
- rsurface.batchtvector3f_vertexbuffer = NULL;
- rsurface.batchtvector3f_bufferoffset = 0;
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
+ if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+ {
+// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchsvector3f_vertexbuffer = NULL;
+// rsurface.batchsvector3f_bufferoffset = 0;
+// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchtvector3f_vertexbuffer = NULL;
+// rsurface.batchtvector3f_bufferoffset = 0;
+ 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);
+ }
break;
case Q3DEFORM_WAVE:
// deform vertex array to make wavey water and flags and such
waveparms[1] = deform->waveparms[1];
waveparms[2] = deform->waveparms[2];
waveparms[3] = deform->waveparms[3];
+ if(!R_TestQ3WaveFunc(deform->wavefunc, waveparms))
+ break; // if wavefunc is a nop, don't make a dynamic vertex array
// this is how a divisor of vertex influence on deformation
animpos = deform->parms[0] ? 1.0f / deform->parms[0] : 100.0f;
scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
- for (j = 0;j < rsurface.batchnumvertices;j++)
+// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
+// rsurface.batchvertex3f_vertexbuffer = NULL;
+// rsurface.batchvertex3f_bufferoffset = 0;
+// rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
+// rsurface.batchnormal3f_vertexbuffer = NULL;
+// rsurface.batchnormal3f_bufferoffset = 0;
+ for (j = 0;j < batchnumvertices;j++)
{
// if the wavefunc depends on time, evaluate it per-vertex
if (waveparms[3])
waveparms[2] = deform->waveparms[2] + (rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+1] + rsurface.batchvertex3f[j*3+2]) * animpos;
scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
}
- VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.array_batchvertex3f + 3*j);
+ VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.batchvertex3f + 3*j);
+ }
+ // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
+ Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
+ if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+ {
+// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchsvector3f_vertexbuffer = NULL;
+// rsurface.batchsvector3f_bufferoffset = 0;
+// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchtvector3f_vertexbuffer = NULL;
+// rsurface.batchtvector3f_bufferoffset = 0;
+ 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);
}
- Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
- Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
- rsurface.batchsvector3f = rsurface.array_batchsvector3f;
- rsurface.batchsvector3f_vertexbuffer = NULL;
- rsurface.batchsvector3f_bufferoffset = 0;
- rsurface.batchtvector3f = rsurface.array_batchtvector3f;
- rsurface.batchtvector3f_vertexbuffer = NULL;
- rsurface.batchtvector3f_bufferoffset = 0;
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
break;
case Q3DEFORM_BULGE:
// deform vertex array to make the surface have moving bulges
- for (j = 0;j < rsurface.batchnumvertices;j++)
+// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
+// rsurface.batchvertex3f_vertexbuffer = NULL;
+// rsurface.batchvertex3f_bufferoffset = 0;
+// rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
+// rsurface.batchnormal3f_vertexbuffer = NULL;
+// rsurface.batchnormal3f_bufferoffset = 0;
+ for (j = 0;j < batchnumvertices;j++)
{
- scale = sin(rsurface.batchtexcoordtexture2f[j*2+0] * deform->parms[0] + r_refdef.scene.time * deform->parms[2]) * deform->parms[1];
- VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.array_batchvertex3f + 3*j);
+ scale = sin(rsurface.batchtexcoordtexture2f[j*2+0] * deform->parms[0] + rsurface.shadertime * deform->parms[2]) * deform->parms[1];
+ VectorMA(rsurface.batchvertex3f + 3*j, scale, rsurface.batchnormal3f + 3*j, rsurface.batchvertex3f + 3*j);
+ }
+ // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
+ Mod_BuildNormals(rsurface.batchfirstvertex, batchnumvertices, batchnumtriangles, rsurface.batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.batchnormal3f, r_smoothnormals_areaweighting.integer != 0);
+ if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
+ {
+// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchsvector3f_vertexbuffer = NULL;
+// rsurface.batchsvector3f_bufferoffset = 0;
+// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
+// rsurface.batchtvector3f_vertexbuffer = NULL;
+// rsurface.batchtvector3f_bufferoffset = 0;
+ 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);
}
- Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
- Mod_BuildTextureVectorsFromNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchtexcoordtexture2f, rsurface.array_batchnormal3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchsvector3f, rsurface.array_batchtvector3f, true);
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
- rsurface.batchsvector3f = rsurface.array_batchsvector3f;
- rsurface.batchsvector3f_vertexbuffer = NULL;
- rsurface.batchsvector3f_bufferoffset = 0;
- rsurface.batchtvector3f = rsurface.array_batchtvector3f;
- rsurface.batchtvector3f_vertexbuffer = NULL;
- rsurface.batchtvector3f_bufferoffset = 0;
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
break;
case Q3DEFORM_MOVE:
// deform vertex array
+ if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
+ break; // if wavefunc is a nop, don't make a dynamic vertex array
scale = R_EvaluateQ3WaveFunc(deform->wavefunc, deform->waveparms);
VectorScale(deform->parms, scale, waveparms);
- for (j = 0;j < rsurface.batchnumvertices;j++)
- VectorAdd(rsurface.batchvertex3f + 3*j, waveparms, rsurface.array_batchvertex3f + 3*j);
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
+// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
+// rsurface.batchvertex3f_vertexbuffer = NULL;
+// rsurface.batchvertex3f_bufferoffset = 0;
+ for (j = 0;j < batchnumvertices;j++)
+ VectorAdd(rsurface.batchvertex3f + 3*j, waveparms, rsurface.batchvertex3f + 3*j);
break;
}
}
case Q3TCGEN_TEXTURE:
break;
case Q3TCGEN_LIGHTMAP:
+// rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+// rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+// rsurface.batchtexcoordtexture2f_bufferoffset = 0;
if (rsurface.batchtexcoordlightmap2f)
- memcpy(rsurface.array_batchtexcoordlightmap2f, rsurface.batchtexcoordtexture2f, rsurface.batchnumvertices * sizeof(float[2]));
- rsurface.batchtexcoordtexture2f = rsurface.array_batchtexcoordtexture2f;
- rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
- rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+ memcpy(rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordtexture2f, batchnumvertices * sizeof(float[2]));
break;
case Q3TCGEN_VECTOR:
- for (j = 0;j < rsurface.batchnumvertices;j++)
+// rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+// rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+// rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+ for (j = 0;j < batchnumvertices;j++)
{
- rsurface.array_batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
- rsurface.array_batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
+ rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
+ rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
}
- rsurface.batchtexcoordtexture2f = rsurface.array_batchtexcoordtexture2f;
- rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
- rsurface.batchtexcoordtexture2f_bufferoffset = 0;
break;
case Q3TCGEN_ENVIRONMENT:
// make environment reflections using a spheremap
- for (j = 0;j < rsurface.batchnumvertices;j++)
+ rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+ rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+ rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+ for (j = 0;j < batchnumvertices;j++)
{
// identical to Q3A's method, but executed in worldspace so
// carried models can be shiny too
// note: this sphere map only uses world x and z!
// so positive and negative y will LOOK THE SAME.
- rsurface.array_batchtexcoordtexture2f[j*2+0] = 0.5 + 0.5 * worldreflected[1];
- rsurface.array_batchtexcoordtexture2f[j*2+1] = 0.5 - 0.5 * worldreflected[2];
+ rsurface.batchtexcoordtexture2f[j*2+0] = 0.5 + 0.5 * worldreflected[1];
+ rsurface.batchtexcoordtexture2f[j*2+1] = 0.5 - 0.5 * worldreflected[2];
}
- rsurface.batchtexcoordtexture2f = rsurface.array_batchtexcoordtexture2f;
- rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
- rsurface.batchtexcoordtexture2f_bufferoffset = 0;
break;
}
// the only tcmod that needs software vertex processing is turbulent, so
if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
amplitude = rsurface.texture->tcmods[0].parms[1];
- animpos = rsurface.texture->tcmods[0].parms[2] + r_refdef.scene.time * rsurface.texture->tcmods[0].parms[3];
- for (j = 0;j < rsurface.batchnumvertices;j++)
+ animpos = rsurface.texture->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->tcmods[0].parms[3];
+// rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+// rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+// rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+ for (j = 0;j < batchnumvertices;j++)
{
- rsurface.array_batchtexcoordtexture2f[j*2+0] += amplitude * sin(((rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+2]) * 1.0 / 1024.0f + animpos) * M_PI * 2);
- rsurface.array_batchtexcoordtexture2f[j*2+1] += amplitude * sin(((rsurface.batchvertex3f[j*3+1] ) * 1.0 / 1024.0f + animpos) * M_PI * 2);
+ 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);
+ rsurface.batchtexcoordtexture2f[j*2+1] += amplitude * sin(((rsurface.batchvertex3f[j*3+1] ) * 1.0 / 1024.0f + animpos) * M_PI * 2);
}
- rsurface.batchtexcoordtexture2f = rsurface.array_batchtexcoordtexture2f;
- rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
- rsurface.batchtexcoordtexture2f_bufferoffset = 0;
}
if (needsupdate & batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP))
{
// convert the modified arrays to vertex structs
- rsurface.batchvertexmesh = rsurface.array_batchvertexmesh;
- rsurface.batchvertexmeshbuffer = NULL;
+// rsurface.batchvertexmesh = R_FrameData_Alloc(batchnumvertices * sizeof(r_vertexmesh_t));
+// rsurface.batchvertexmeshbuffer = NULL;
if (batchneed & BATCHNEED_VERTEXMESH_VERTEX)
- for (j = 0, vertexmesh = rsurface.array_batchvertexmesh;j < rsurface.batchnumvertices;j++, vertexmesh++)
+ for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
VectorCopy(rsurface.batchvertex3f + 3*j, vertexmesh->vertex3f);
if (batchneed & BATCHNEED_VERTEXMESH_NORMAL)
- for (j = 0, vertexmesh = rsurface.array_batchvertexmesh;j < rsurface.batchnumvertices;j++, vertexmesh++)
+ for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
VectorCopy(rsurface.batchnormal3f + 3*j, vertexmesh->normal3f);
if (batchneed & BATCHNEED_VERTEXMESH_VECTOR)
{
- for (j = 0, vertexmesh = rsurface.array_batchvertexmesh;j < rsurface.batchnumvertices;j++, vertexmesh++)
+ for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
{
VectorCopy(rsurface.batchsvector3f + 3*j, vertexmesh->svector3f);
VectorCopy(rsurface.batchtvector3f + 3*j, vertexmesh->tvector3f);
}
}
if ((batchneed & BATCHNEED_VERTEXMESH_VERTEXCOLOR) && rsurface.batchlightmapcolor4f)
- for (j = 0, vertexmesh = rsurface.array_batchvertexmesh;j < rsurface.batchnumvertices;j++, vertexmesh++)
- Vector4Scale(rsurface.batchlightmapcolor4f + 4*j, 255.0f, vertexmesh->color4ub);
+ for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
+ Vector4Copy(rsurface.batchlightmapcolor4f + 4*j, vertexmesh->color4f);
if (batchneed & BATCHNEED_VERTEXMESH_TEXCOORD)
- for (j = 0, vertexmesh = rsurface.array_batchvertexmesh;j < rsurface.batchnumvertices;j++, vertexmesh++)
+ for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
Vector2Copy(rsurface.batchtexcoordtexture2f + 2*j, vertexmesh->texcoordtexture2f);
if ((batchneed & BATCHNEED_VERTEXMESH_LIGHTMAP) && rsurface.batchtexcoordlightmap2f)
- for (j = 0, vertexmesh = rsurface.array_batchvertexmesh;j < rsurface.batchnumvertices;j++, vertexmesh++)
+ for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
Vector2Copy(rsurface.batchtexcoordlightmap2f + 2*j, vertexmesh->texcoordlightmap2f);
}
-
- if (needsupdate & batchneed & BATCHNEED_VERTEXPOSITION)
- {
- // convert the modified arrays to vertex structs
- rsurface.batchvertexposition = rsurface.array_batchvertexposition;
- rsurface.batchvertexpositionbuffer = NULL;
- if (sizeof(r_vertexposition_t) == sizeof(float[3]))
- memcpy(rsurface.array_batchvertexposition, rsurface.batchvertex3f, rsurface.batchnumvertices * sizeof(r_vertexposition_t));
- else
- for (j = 0, vertexposition = rsurface.array_batchvertexposition;j < rsurface.batchnumvertices;j++, vertexposition++)
- VectorCopy(rsurface.batchvertex3f + 3*j, vertexposition->vertex3f);
- }
}
void RSurf_DrawBatch(void)
{
- 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);
-}
-
-static void RSurf_BindLightmapForBatch(void)
-{
- switch(vid.renderpath)
+ // sometimes a zero triangle surface (usually a degenerate patch) makes it
+ // through the pipeline, killing it earlier in the pipeline would have
+ // per-surface overhead rather than per-batch overhead, so it's best to
+ // reject it here, before it hits glDraw.
+ if (rsurface.batchnumtriangles == 0)
+ return;
+#if 0
+ // batch debugging code
+ if (r_test.integer && rsurface.entity == r_refdef.scene.worldentity && rsurface.batchvertex3f == r_refdef.scene.worldentity->model->surfmesh.data_vertex3f)
{
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- if (r_cg_permutation->fp_Texture_Lightmap ) CG_BindTexture(r_cg_permutation->fp_Texture_Lightmap , rsurface.lightmaptexture );CHECKCGERROR
- if (r_cg_permutation->fp_Texture_Deluxemap) CG_BindTexture(r_cg_permutation->fp_Texture_Deluxemap, rsurface.deluxemaptexture);CHECKCGERROR
-#endif
- break;
- case RENDERPATH_GL20:
- if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(GL20TU_LIGHTMAP , rsurface.lightmaptexture );
- if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(GL20TU_DELUXEMAP, rsurface.deluxemaptexture);
- break;
- case RENDERPATH_GL13:
- case RENDERPATH_GL11:
- R_Mesh_TexBind(0, rsurface.lightmaptexture);
- break;
+ int i;
+ int j;
+ int c;
+ const int *e;
+ e = rsurface.batchelement3i + rsurface.batchfirsttriangle*3;
+ for (i = 0;i < rsurface.batchnumtriangles*3;i++)
+ {
+ c = e[i];
+ for (j = 0;j < rsurface.entity->model->num_surfaces;j++)
+ {
+ if (c >= rsurface.modelsurfaces[j].num_firstvertex && c < (rsurface.modelsurfaces[j].num_firstvertex + rsurface.modelsurfaces[j].num_vertices))
+ {
+ if (rsurface.modelsurfaces[j].texture != rsurface.texture)
+ 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);
+ break;
+ }
+ }
+ }
}
+#endif
+ 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);
}
static int RSurf_FindWaterPlaneForSurface(const msurface_t *surface)
vec3_t vert;
const float *v;
r_waterstate_waterplane_t *p;
+ qboolean prepared = false;
bestd = 0;
for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
{
if(p->camera_entity != rsurface.texture->camera_entity)
continue;
d = 0;
- RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, 1, &surface);
+ if(!prepared)
+ {
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, 1, &surface);
+ prepared = true;
+ if(rsurface.batchnumvertices == 0)
+ break;
+ }
for (vertexindex = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3;vertexindex < rsurface.batchnumvertices;vertexindex++, v += 3)
{
Matrix4x4_Transform(&rsurface.matrix, v, vert);
if (bestd > d || bestplaneindex < 0)
{
bestd = d;
- bestplaneindex = planeindex;
- }
- }
- return bestplaneindex;
-}
-
-static void RSurf_BindReflectionForBatch(int planeindex)
-{
- // pick the closest matching water plane and bind textures
- r_waterstate_waterplane_t *bestp = planeindex >= 0 ? r_waterstate.waterplanes + planeindex : NULL;
- switch(vid.renderpath)
- {
- case RENDERPATH_CGGL:
-#ifdef SUPPORTCG
- if (r_cg_permutation->fp_Texture_Refraction) {CG_BindTexture(r_cg_permutation->fp_Texture_Refraction, bestp ? bestp->texture_refraction : r_texture_black);CHECKCGERROR}
- else if (r_cg_permutation->fp_Texture_First) {CG_BindTexture(r_cg_permutation->fp_Texture_First, bestp ? bestp->texture_camera : r_texture_black);CHECKCGERROR}
- if (r_cg_permutation->fp_Texture_Reflection) {CG_BindTexture(r_cg_permutation->fp_Texture_Reflection, bestp ? bestp->texture_reflection : r_texture_black);CHECKCGERROR}
-#endif
- break;
- case RENDERPATH_GL20:
- if (r_glsl_permutation->loc_Texture_Refraction >= 0) R_Mesh_TexBind(GL20TU_REFRACTION, bestp ? bestp->texture_refraction : r_texture_black);
- else if (r_glsl_permutation->loc_Texture_First >= 0) R_Mesh_TexBind(GL20TU_FIRST, bestp ? bestp->texture_camera : r_texture_black);
- if (r_glsl_permutation->loc_Texture_Reflection >= 0) R_Mesh_TexBind(GL20TU_REFLECTION, bestp ? bestp->texture_reflection : r_texture_black);
- break;
- case RENDERPATH_GL13:
- case RENDERPATH_GL11:
- break;
+ bestplaneindex = planeindex;
+ }
}
+ return bestplaneindex;
+ // NOTE: this MAY return a totally unrelated water plane; we can ignore
+ // this situation though, as it might be better to render single larger
+ // batches with useless stuff (backface culled for example) than to
+ // render multiple smaller batches
}
static void RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray(void)
{
int i;
- for (i = 0;i < rsurface.batchnumvertices;i++)
- Vector4Set(rsurface.array_passcolor4f + 4*i, 0.5f, 0.5f, 0.5f, 1.0f);
- rsurface.passcolor4f = rsurface.array_passcolor4f;
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
rsurface.passcolor4f_vertexbuffer = 0;
rsurface.passcolor4f_bufferoffset = 0;
+ for (i = 0;i < rsurface.batchnumvertices;i++)
+ Vector4Set(rsurface.passcolor4f + 4*i, 0.5f, 0.5f, 0.5f, 1.0f);
}
static void RSurf_DrawBatch_GL11_ApplyFog(void)
if (rsurface.passcolor4f)
{
// generate color arrays
- for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4, c2 = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4, c2 += 4)
+ c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+ 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)
{
f = RSurf_FogVertex(v);
c2[0] = c[0] * f;
}
else
{
- for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c2 = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c2 += 4)
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+ for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c2 += 4)
{
f = RSurf_FogVertex(v);
c2[0] = f;
c2[3] = 1;
}
}
- rsurface.passcolor4f = rsurface.array_passcolor4f;
- rsurface.passcolor4f_vertexbuffer = 0;
- rsurface.passcolor4f_bufferoffset = 0;
}
static void RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors(void)
float *c2;
if (!rsurface.passcolor4f)
return;
- for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4, c2 = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4, c2 += 4)
+ c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+ 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)
{
f = RSurf_FogVertex(v);
c2[0] = c[0] * f + r_refdef.fogcolor[0] * (1 - f);
c2[2] = c[2] * f + r_refdef.fogcolor[2] * (1 - f);
c2[3] = c[3];
}
- rsurface.passcolor4f = rsurface.array_passcolor4f;
- rsurface.passcolor4f_vertexbuffer = 0;
- rsurface.passcolor4f_bufferoffset = 0;
}
static void RSurf_DrawBatch_GL11_ApplyColor(float r, float g, float b, float a)
float *c2;
if (!rsurface.passcolor4f)
return;
- for (i = 0, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4, c2 = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
+ c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+ for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
{
c2[0] = c[0] * r;
c2[1] = c[1] * g;
c2[2] = c[2] * b;
c2[3] = c[3] * a;
}
- rsurface.passcolor4f = rsurface.array_passcolor4f;
- rsurface.passcolor4f_vertexbuffer = 0;
- rsurface.passcolor4f_bufferoffset = 0;
}
static void RSurf_DrawBatch_GL11_ApplyAmbient(void)
float *c2;
if (!rsurface.passcolor4f)
return;
- for (i = 0, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4, c2 = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
+ c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+ for (i = 0, c2 = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, c += 4, c2 += 4)
{
c2[0] = c[0] + r_refdef.scene.ambient;
c2[1] = c[1] + r_refdef.scene.ambient;
c2[2] = c[2] + r_refdef.scene.ambient;
c2[3] = c[3];
}
- rsurface.passcolor4f = rsurface.array_passcolor4f;
- rsurface.passcolor4f_vertexbuffer = 0;
- rsurface.passcolor4f_bufferoffset = 0;
}
static void RSurf_DrawBatch_GL11_Lightmap(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
GL_Color(r, g, b, a);
- RSurf_BindLightmapForBatch();
+ R_Mesh_TexBind(0, rsurface.lightmaptexture);
RSurf_DrawBatch();
}
float *c2;
if (!rsurface.passcolor4f)
return;
- for (i = 0, c1 = rsurface.passcolor4f + 4*rsurface.batchfirstvertex, c2 = rsurface.array_passcolor4f + 4*rsurface.batchfirstvertex;i < rsurface.batchnumvertices;i++, c1 += 4, c2 += 4)
+ for (i = 0, c1 = rsurface.passcolor4f + 4*rsurface.batchfirstvertex, c2 = rsurface.passcolor4f + 4*rsurface.batchfirstvertex;i < rsurface.batchnumvertices;i++, c1 += 4, c2 += 4)
{
c2[0] = bound(0.0f, c1[0], 1.0f);
c2[1] = bound(0.0f, c1[1], 1.0f);
}
}
+static void RSurf_DrawBatch_GL11_ApplyFakeLight(void)
+{
+ int i;
+ float f;
+ const float *v;
+ const float *n;
+ float *c;
+ //vec3_t eyedir;
+
+ // fake shading
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+ 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)
+ {
+ f = -DotProduct(r_refdef.view.forward, n);
+ f = max(0, f);
+ f = f * 0.85 + 0.15; // work around so stuff won't get black
+ f *= r_refdef.lightmapintensity;
+ Vector4Set(c, f, f, f, 1);
+ }
+}
+
+static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
+{
+ RSurf_DrawBatch_GL11_ApplyFakeLight();
+ if (applyfog) RSurf_DrawBatch_GL11_ApplyFog();
+ if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset);
+ GL_Color(r, g, b, a);
+ RSurf_DrawBatch();
+}
+
static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor)
{
int i;
if (VectorLength2(diffusecolor) > 0)
{
// q3-style directional shading
- for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, n = rsurface.batchnormal3f + rsurface.batchfirstvertex * 3, c = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, n += 3, c += 4)
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+ 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)
{
if ((f = DotProduct(n, lightdir)) > 0)
VectorMA(ambientcolor, f, diffusecolor, c);
*g = 1;
*b = 1;
*a = 1;
- rsurface.passcolor4f = rsurface.array_passcolor4f;
- rsurface.passcolor4f_vertexbuffer = 0;
- rsurface.passcolor4f_bufferoffset = 0;
*applycolor = false;
}
else
float f;
const float *v;
float *c;
- for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4)
+
+ // fake shading
+ rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4]));
+ rsurface.passcolor4f_vertexbuffer = 0;
+ rsurface.passcolor4f_bufferoffset = 0;
+
+ for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4)
{
f = 1 - RSurf_FogVertex(v);
c[0] = r;
// transparent sky would be ridiculous
if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
return;
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
skyrenderlater = true;
RSurf_SetupDepthAndCulling();
GL_DepthMask(true);
// in Quake3 maps as it causes problems with q3map2 sky tricks,
// and skymasking also looks very bad when noclipping outside the
// level, so don't use it then either.
- if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis)
+ if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_refdef.viewcache.world_novis && !r_trippy.integer)
{
R_Mesh_ResetTextureState();
if (skyrendermasked)
{
- R_SetupShader_DepthOrShadow();
+ R_SetupShader_DepthOrShadow(false);
// depth-only (masking)
GL_ColorMask(0,0,0,0);
// just to make sure that braindead drivers don't draw
// anything despite that colormask...
GL_BlendFunc(GL_ZERO, GL_ONE);
- RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXPOSITION, texturenumsurfaces, texturesurfacelist);
- R_Mesh_PrepareVertices_Position(rsurface.batchnumvertices, rsurface.batchvertexposition, rsurface.batchvertexpositionbuffer);
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
+ if (rsurface.batchvertex3fbuffer)
+ R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
+ else
+ R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
}
else
{
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
// fog sky
GL_BlendFunc(GL_ONE, GL_ZERO);
- RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
GL_Color(r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], 1);
R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
}
{
// render screenspace normalmap to texture
GL_DepthMask(true);
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist);
+ R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist, NULL, false);
RSurf_DrawBatch();
- return;
}
// bind lightmap texture
// water/refraction/reflection/camera surfaces have to be handled specially
- if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA | MATERIALFLAG_REFLECTION)) && !r_waterstate.renderingscene)
+ if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA | MATERIALFLAG_REFLECTION)))
{
int start, end, startplaneindex;
for (start = 0;start < texturenumsurfaces;start = end)
{
startplaneindex = RSurf_FindWaterPlaneForSurface(texturesurfacelist[start]);
+ if(startplaneindex < 0)
+ {
+ // this happens if the plane e.g. got backface culled and thus didn't get a water plane. We can just ignore this.
+ // Con_Printf("No matching water plane for surface with material flags 0x%08x - PLEASE DEBUG THIS\n", rsurface.texture->currentmaterialflags);
+ end = start + 1;
+ continue;
+ }
for (end = start + 1;end < texturenumsurfaces && startplaneindex == RSurf_FindWaterPlaneForSurface(texturesurfacelist[end]);end++)
;
// now that we have a batch using the same planeindex, render it
- if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)) && !r_waterstate.renderingscene)
+ if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)))
{
// render water or distortion background
GL_DepthMask(true);
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start);
- RSurf_BindReflectionForBatch(startplaneindex);
- if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
- RSurf_BindLightmapForBatch();
+ 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), false);
RSurf_DrawBatch();
// blend surface on top
GL_DepthMask(false);
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start);
+ R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start, NULL, false);
RSurf_DrawBatch();
}
- else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) && !r_waterstate.renderingscene)
+ else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION))
{
// render surface with reflection texture as input
GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start);
- RSurf_BindReflectionForBatch(startplaneindex);
- if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
- RSurf_BindLightmapForBatch();
+ 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), false);
RSurf_DrawBatch();
}
}
// render surface batch normally
GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
- R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist);
- if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
- RSurf_BindLightmapForBatch();
+ R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist, NULL, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) != 0);
RSurf_DrawBatch();
}
else
{
GL_AlphaTest(false);
- qglDepthFunc(GL_EQUAL);CHECKGLERROR
+ GL_DepthFunc(GL_EQUAL);
}
}
GL_DepthMask(layer->depthmask && writedepth);
R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
RSurf_DrawBatch_GL11_VertexShade(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
+ else if (FAKELIGHT_ENABLED)
+ RSurf_DrawBatch_GL11_FakeLight(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
else if (rsurface.uselightmaptexture)
RSurf_DrawBatch_GL11_Lightmap(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
else
R_Mesh_TexBind(1, 0);
R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
// generate a color array for the fog pass
- R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.array_passcolor4f, 0, 0);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
RSurf_DrawBatch_GL11_MakeFogColor(layercolor[0], layercolor[1], layercolor[2], layercolor[3]);
RSurf_DrawBatch();
break;
Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
}
}
- CHECKGLERROR
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
{
- qglDepthFunc(GL_LEQUAL);CHECKGLERROR
+ GL_DepthFunc(GL_LEQUAL);
GL_AlphaTest(false);
}
}
else
{
GL_AlphaTest(false);
- qglDepthFunc(GL_EQUAL);CHECKGLERROR
+ GL_DepthFunc(GL_EQUAL);
}
}
GL_DepthMask(layer->depthmask && writedepth);
R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset);
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
RSurf_DrawBatch_GL11_VertexShade(1, 1, 1, 1, false, false);
+ else if (FAKELIGHT_ENABLED)
+ RSurf_DrawBatch_GL11_FakeLight(1, 1, 1, 1, false, false);
else if (rsurface.uselightmaptexture)
RSurf_DrawBatch_GL11_Lightmap(1, 1, 1, 1, false, false);
else
R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, 0, 0);
}
// generate a color array for the fog pass
- R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.array_passcolor4f, 0, 0);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, 0, 0);
RSurf_DrawBatch_GL11_MakeFogColor(layer->color[0], layer->color[1], layer->color[2], layer->color[3]);
RSurf_DrawBatch();
break;
Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type);
}
}
- CHECKGLERROR
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
{
- qglDepthFunc(GL_LEQUAL);CHECKGLERROR
+ GL_DepthFunc(GL_LEQUAL);
GL_AlphaTest(false);
}
}
r_vertexgeneric_t *batchvertex;
float c[4];
- GL_AlphaTest(false);
- R_Mesh_ResetTextureState();
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+// R_Mesh_ResetTextureState();
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
if(rsurface.texture && rsurface.texture->currentskinframe)
{
RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor);
r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
}
+ else if (FAKELIGHT_ENABLED)
+ {
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
+
+ r_refdef.lightmapintensity = r_fakelight_intensity.value;
+ RSurf_DrawBatch_GL11_ApplyFakeLight();
+ r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all
+ }
else
{
RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
RSurf_DrawBatch_GL11_ClampColor();
R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.passcolor4f, NULL);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
RSurf_DrawBatch();
}
else if (!r_refdef.view.showdebug)
for (j = 0, vi = rsurface.batchfirstvertex;j < rsurface.batchnumvertices;j++, vi++)
{
VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
- Vector4Set(batchvertex[vi].color4ub, 0, 0, 0, 255);
+ Vector4Set(batchvertex[vi].color4f, 0, 0, 0, 1);
}
R_Mesh_PrepareVertices_Generic_Unlock();
RSurf_DrawBatch();
batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchnumvertices);
for (j = 0, vi = rsurface.batchfirstvertex;j < rsurface.batchnumvertices;j++, vi++)
{
- unsigned char c = vi << 3;
+ unsigned char c = (vi << 3) * (1.0f / 256.0f);
VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
- Vector4Set(batchvertex[vi].color4ub, c, c, c, 255);
+ Vector4Set(batchvertex[vi].color4f, c, c, c, 1);
}
R_Mesh_PrepareVertices_Generic_Unlock();
RSurf_DrawBatch();
batchvertex = R_Mesh_PrepareVertices_Generic_Lock(3*rsurface.batchnumtriangles);
for (j = 0, e = rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle;j < rsurface.batchnumtriangles;j++, e += 3)
{
- unsigned char c = (j + rsurface.batchfirsttriangle) << 3;
+ unsigned char c = ((j + rsurface.batchfirsttriangle) << 3) * (1.0f / 256.0f);
VectorCopy(rsurface.batchvertex3f + 3*e[0], batchvertex[j*3+0].vertex3f);
VectorCopy(rsurface.batchvertex3f + 3*e[1], batchvertex[j*3+1].vertex3f);
VectorCopy(rsurface.batchvertex3f + 3*e[2], batchvertex[j*3+2].vertex3f);
- Vector4Set(batchvertex[j*3+0].color4ub, c, c, c, 255);
- Vector4Set(batchvertex[j*3+1].color4ub, c, c, c, 255);
- Vector4Set(batchvertex[j*3+2].color4ub, c, c, c, 255);
+ Vector4Set(batchvertex[j*3+0].color4f, c, c, c, 1);
+ Vector4Set(batchvertex[j*3+1].color4f, c, c, c, 1);
+ Vector4Set(batchvertex[j*3+2].color4f, c, c, c, 1);
}
R_Mesh_PrepareVertices_Generic_Unlock();
R_Mesh_Draw(0, rsurface.batchnumtriangles*3, 0, rsurface.batchnumtriangles, NULL, NULL, 0, NULL, NULL, 0);
int texturesurfaceindex;
int k;
const msurface_t *surface;
- unsigned char surfacecolor4ub[4];
+ float surfacecolor4f[4];
RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist);
batchvertex = R_Mesh_PrepareVertices_Generic_Lock(rsurface.batchfirstvertex + rsurface.batchnumvertices);
vi = 0;
{
surface = texturesurfacelist[texturesurfaceindex];
k = (int)(((size_t)surface) / sizeof(msurface_t));
- Vector4Set(surfacecolor4ub, (k & 0xF) << 4, (k & 0xF0), (k & 0xF00) >> 4, 255);
+ Vector4Set(surfacecolor4f, (k & 0xF) * (1.0f / 16.0f), (k & 0xF0) * (1.0f / 256.0f), (k & 0xF00) * (1.0f / 4096.0f), 1);
for (j = 0;j < surface->num_vertices;j++)
{
VectorCopy(rsurface.batchvertex3f + 3*vi, batchvertex[vi].vertex3f);
- Vector4Copy(surfacecolor4ub, batchvertex[vi].color4ub);
+ Vector4Copy(surfacecolor4f, batchvertex[vi].color4f);
vi++;
}
}
switch (vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
break;
case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth);
break;
case RENDERPATH_GL11:
switch (vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
break;
case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth);
break;
case RENDERPATH_GL11:
int texturenumsurfaces, endsurface;
texture_t *texture;
const msurface_t *surface;
-#define MAXBATCH_TRANSPARENTSURFACES 256
- const msurface_t *texturesurfacelist[MAXBATCH_TRANSPARENTSURFACES];
+ const msurface_t *texturesurfacelist[MESHQUEUE_TRANSPARENT_BATCHSIZE];
// if the model is static it doesn't matter what value we give for
// wantnormals and wanttangents, so this logic uses only rules applicable
switch (vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
RSurf_ActiveModelEntity(ent, true, true, false);
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
RSurf_ActiveModelEntity(ent, true, false, false);
break;
}
GL_DepthTest(true);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(true);
- GL_AlphaTest(false);
- R_Mesh_ResetTextureState();
- R_SetupShader_DepthOrShadow();
+// R_Mesh_ResetTextureState();
+ R_SetupShader_DepthOrShadow(false);
}
RSurf_SetupDepthAndCulling();
- RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXPOSITION, texturenumsurfaces, texturesurfacelist);
- R_Mesh_PrepareVertices_Position(rsurface.batchnumvertices, rsurface.batchvertexposition, rsurface.batchvertexpositionbuffer);
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
+ if (rsurface.batchvertex3fbuffer)
+ R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
+ else
+ R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
RSurf_DrawBatch();
}
if (setup)
surface = rsurface.modelsurfaces + surfacelist[i];
texture = surface->texture;
rsurface.texture = R_GetCurrentTexture(texture);
- rsurface.lightmaptexture = surface->lightmaptexture;
- rsurface.deluxemaptexture = surface->deluxemaptexture;
- rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
// scan ahead until we find a different texture
- endsurface = min(i + MAXBATCH_TRANSPARENTSURFACES, numsurfaces);
+ endsurface = min(i + MESHQUEUE_TRANSPARENT_BATCHSIZE, numsurfaces);
texturenumsurfaces = 0;
texturesurfacelist[texturenumsurfaces++] = surface;
- for (;j < endsurface;j++)
+ if(FAKELIGHT_ENABLED)
{
- surface = rsurface.modelsurfaces + surfacelist[j];
- if (texture != surface->texture || rsurface.lightmaptexture != surface->lightmaptexture)
- break;
- texturesurfacelist[texturenumsurfaces++] = surface;
+ rsurface.lightmaptexture = NULL;
+ rsurface.deluxemaptexture = NULL;
+ rsurface.uselightmaptexture = false;
+ for (;j < endsurface;j++)
+ {
+ surface = rsurface.modelsurfaces + surfacelist[j];
+ if (texture != surface->texture)
+ break;
+ texturesurfacelist[texturenumsurfaces++] = surface;
+ }
+ }
+ else
+ {
+ rsurface.lightmaptexture = surface->lightmaptexture;
+ rsurface.deluxemaptexture = surface->deluxemaptexture;
+ rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
+ for (;j < endsurface;j++)
+ {
+ surface = rsurface.modelsurfaces + surfacelist[j];
+ if (texture != surface->texture || rsurface.lightmaptexture != surface->lightmaptexture)
+ break;
+ texturesurfacelist[texturenumsurfaces++] = surface;
+ }
}
// render the range of surfaces
if (ent == r_refdef.scene.worldentity)
R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, false, false);
}
rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
- GL_AlphaTest(false);
}
static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, const entity_render_t *queueentity)
if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION)))
return;
RSurf_SetupDepthAndCulling();
- RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXPOSITION, texturenumsurfaces, texturesurfacelist);
- R_Mesh_PrepareVertices_Position(rsurface.batchnumvertices, rsurface.batchvertexposition, rsurface.batchvertexpositionbuffer);
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist);
+ if (rsurface.batchvertex3fbuffer)
+ R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3fbuffer);
+ else
+ R_Mesh_PrepareVertices_Vertex3f(rsurface.batchnumvertices, rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer);
RSurf_DrawBatch();
}
else
R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
}
- else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer)
+ else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && (!r_showsurfaces.integer || r_showsurfaces.integer == 3))
R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
else if (!rsurface.texture->currentnumlayers)
return;
{
int i, j;
texture_t *texture;
+ R_FrameData_SetMark();
// break the surface list down into batches by texture and use of lightmapping
for (i = 0;i < numsurfaces;i = j)
{
// use skin 1 instead)
texture = surfacelist[i]->texture;
rsurface.texture = R_GetCurrentTexture(texture);
- rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
- rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
- rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL && !depthonly && !prepass;
if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
{
// if this texture is not the kind we want, skip ahead to the next one
;
continue;
}
- // simply scan ahead until we find a different texture or lightmap state
- for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
- ;
+ if(FAKELIGHT_ENABLED || depthonly || prepass)
+ {
+ rsurface.lightmaptexture = NULL;
+ rsurface.deluxemaptexture = NULL;
+ rsurface.uselightmaptexture = false;
+ // simply scan ahead until we find a different texture or lightmap state
+ for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
+ ;
+ }
+ else
+ {
+ rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
+ rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
+ rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL;
+ // simply scan ahead until we find a different texture or lightmap state
+ for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
+ ;
+ }
// render the range of surfaces
R_ProcessWorldTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass);
}
+ R_FrameData_ReturnToMark();
}
static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, const entity_render_t *queueentity, qboolean prepass)
else
R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
}
- else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer)
+ else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && (!r_showsurfaces.integer || r_showsurfaces.integer == 3))
R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
else if (!rsurface.texture->currentnumlayers)
return;
{
int i, j;
texture_t *texture;
+ R_FrameData_SetMark();
// break the surface list down into batches by texture and use of lightmapping
for (i = 0;i < numsurfaces;i = j)
{
// use skin 1 instead)
texture = surfacelist[i]->texture;
rsurface.texture = R_GetCurrentTexture(texture);
- rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
- rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
- rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL && !depthonly && !prepass;
if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW))
{
// if this texture is not the kind we want, skip ahead to the next one
;
continue;
}
- // simply scan ahead until we find a different texture or lightmap state
- for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
- ;
+ if(FAKELIGHT_ENABLED || depthonly || prepass)
+ {
+ rsurface.lightmaptexture = NULL;
+ rsurface.deluxemaptexture = NULL;
+ rsurface.uselightmaptexture = false;
+ // simply scan ahead until we find a different texture or lightmap state
+ for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
+ ;
+ }
+ else
+ {
+ rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
+ rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture;
+ rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL;
+ // simply scan ahead until we find a different texture or lightmap state
+ for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
+ ;
+ }
// render the range of surfaces
R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, ent, prepass);
}
+ R_FrameData_ReturnToMark();
}
float locboxvertex3f[6*4*3] =
GL_CullFace(GL_NONE);
R_EntityMatrix(&identitymatrix);
- R_Mesh_ResetTextureState();
+// R_Mesh_ResetTextureState();
i = surfacelist[0];
GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_refdef.view.colorscale,
vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i];
R_Mesh_PrepareVertices_Generic_Arrays(6*4, vertex3f, NULL, NULL);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
R_Mesh_Draw(0, 6*4, 0, 6*2, NULL, NULL, 0, locboxelements, NULL, 0);
}
qboolean useshortelements;
decalsystem->maxdecals = max(16, decalsystem->maxdecals * 2);
useshortelements = decalsystem->maxdecals * 3 <= 65536;
- decalsystem->decals = 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)));
+ 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)));
decalsystem->color4f = (float *)(decalsystem->decals + decalsystem->maxdecals);
decalsystem->texcoord2f = (float *)(decalsystem->color4f + decalsystem->maxdecals*12);
decalsystem->vertex3f = (float *)(decalsystem->texcoord2f + decalsystem->maxdecals*6);
// grab a decal and search for another free slot for the next one
decals = decalsystem->decals;
decal = decalsystem->decals + (i = decalsystem->freedecal++);
- for (i = decalsystem->freedecal;i < decalsystem->numdecals && decals[i].color4ub[0][3];i++)
+ for (i = decalsystem->freedecal;i < decalsystem->numdecals && decals[i].color4f[0][3];i++)
;
decalsystem->freedecal = i;
if (decalsystem->numdecals <= i)
decal->triangleindex = triangleindex;
decal->surfaceindex = surfaceindex;
decal->decalsequence = decalsequence;
- decal->color4ub[0][0] = (unsigned char)(c0[0]*255.0f);
- decal->color4ub[0][1] = (unsigned char)(c0[1]*255.0f);
- decal->color4ub[0][2] = (unsigned char)(c0[2]*255.0f);
- decal->color4ub[0][3] = 255;
- decal->color4ub[1][0] = (unsigned char)(c1[0]*255.0f);
- decal->color4ub[1][1] = (unsigned char)(c1[1]*255.0f);
- decal->color4ub[1][2] = (unsigned char)(c1[2]*255.0f);
- decal->color4ub[1][3] = 255;
- decal->color4ub[2][0] = (unsigned char)(c2[0]*255.0f);
- decal->color4ub[2][1] = (unsigned char)(c2[1]*255.0f);
- decal->color4ub[2][2] = (unsigned char)(c2[2]*255.0f);
- decal->color4ub[2][3] = 255;
+ decal->color4f[0][0] = c0[0];
+ decal->color4f[0][1] = c0[1];
+ decal->color4f[0][2] = c0[2];
+ decal->color4f[0][3] = 1;
+ decal->color4f[1][0] = c1[0];
+ decal->color4f[1][1] = c1[1];
+ decal->color4f[1][2] = c1[2];
+ decal->color4f[1][3] = 1;
+ decal->color4f[2][0] = c2[0];
+ decal->color4f[2][1] = c2[1];
+ decal->color4f[2][2] = c2[2];
+ decal->color4f[2][3] = 1;
decal->vertex3f[0][0] = v0[0];
decal->vertex3f[0][1] = v0[1];
decal->vertex3f[0][2] = v0[2];
decal->texcoord2f[1][1] = t1[1];
decal->texcoord2f[2][0] = t2[0];
decal->texcoord2f[2][1] = t2[1];
+ TriangleNormal(v0, v1, v2, decal->plane);
+ VectorNormalize(decal->plane);
+ decal->plane[3] = DotProduct(v0, decal->plane);
}
extern cvar_t cl_decals_bias;
extern cvar_t cl_decals_models;
extern cvar_t cl_decals_newsystem_intensitymultiplier;
+// baseparms, parms, temps
+static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, int decalsequence, qboolean dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex)
+{
+ int cornerindex;
+ int index;
+ float v[9][3];
+ const float *vertex3f;
+ const float *normal3f;
+ int numpoints;
+ float points[2][9][3];
+ float temp[3];
+ float tc[9][2];
+ float f;
+ float c[9][4];
+ const int *e;
+
+ e = rsurface.modelelement3i + 3*triangleindex;
+
+ vertex3f = rsurface.modelvertex3f;
+ normal3f = rsurface.modelnormal3f;
+
+ if (normal3f)
+ {
+ for (cornerindex = 0;cornerindex < 3;cornerindex++)
+ {
+ index = 3*e[cornerindex];
+ VectorMA(vertex3f + index, cl_decals_bias.value, normal3f + index, v[cornerindex]);
+ }
+ }
+ else
+ {
+ for (cornerindex = 0;cornerindex < 3;cornerindex++)
+ {
+ index = 3*e[cornerindex];
+ VectorCopy(vertex3f + index, v[cornerindex]);
+ }
+ }
+
+ // cull backfaces
+ //TriangleNormal(v[0], v[1], v[2], normal);
+ //if (DotProduct(normal, localnormal) < 0.0f)
+ // continue;
+ // clip by each of the box planes formed from the projection matrix
+ // if anything survives, we emit the decal
+ 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]);
+ if (numpoints < 3)
+ return;
+ 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]);
+ if (numpoints < 3)
+ return;
+ 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]);
+ if (numpoints < 3)
+ return;
+ 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]);
+ if (numpoints < 3)
+ return;
+ 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]);
+ if (numpoints < 3)
+ return;
+ 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]);
+ if (numpoints < 3)
+ return;
+ // some part of the triangle survived, so we have to accept it...
+ if (dynamic)
+ {
+ // dynamic always uses the original triangle
+ numpoints = 3;
+ for (cornerindex = 0;cornerindex < 3;cornerindex++)
+ {
+ index = 3*e[cornerindex];
+ VectorCopy(vertex3f + index, v[cornerindex]);
+ }
+ }
+ for (cornerindex = 0;cornerindex < numpoints;cornerindex++)
+ {
+ // convert vertex positions to texcoords
+ Matrix4x4_Transform(projection, v[cornerindex], temp);
+ tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
+ tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
+ // calculate distance fade from the projection origin
+ f = a * (1.0f-fabs(temp[0])) * cl_decals_newsystem_intensitymultiplier.value;
+ f = bound(0.0f, f, 1.0f);
+ c[cornerindex][0] = r * f;
+ c[cornerindex][1] = g * f;
+ c[cornerindex][2] = b * f;
+ c[cornerindex][3] = 1.0f;
+ //VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
+ }
+ if (dynamic)
+ 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);
+ else
+ for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
+ R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence);
+}
static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, int decalsequence)
{
matrix4x4_t projection;
decalsystem_t *decalsystem;
qboolean dynamic;
dp_model_t *model;
- const float *vertex3f;
const msurface_t *surface;
const msurface_t *surfaces;
const int *surfacelist;
int surfacelistindex;
int surfaceindex;
int triangleindex;
- int cornerindex;
- int index;
- int numpoints;
- const int *e;
float localorigin[3];
float localnormal[3];
float localmins[3];
float localmaxs[3];
float localsize;
- float v[9][3];
- float tc[9][2];
- float c[9][4];
//float normal[3];
float planes[6][4];
- float f;
- float points[2][9][3];
float angles[3];
- float temp[3];
+ bih_t *bih;
+ int bih_triangles_count;
+ int bih_triangles[256];
+ int bih_surfaces[256];
decalsystem = &ent->decalsystem;
model = ent->model;
return;
}
- if (!model->brush.data_nodes && !cl_decals_models.integer)
+ if (!model->brush.data_leafs && !cl_decals_models.integer)
{
if (decalsystem->model)
R_DecalSystem_Reset(decalsystem);
R_DecalSystem_Reset(decalsystem);
decalsystem->model = model;
- RSurf_ActiveModelEntity(ent, false, false, false);
+ RSurf_ActiveModelEntity(ent, true, false, false);
Matrix4x4_Transform(&rsurface.inversematrix, worldorigin, localorigin);
Matrix4x4_Transform3x3(&rsurface.inversematrix, worldnormal, localnormal);
#endif
dynamic = model->surfmesh.isanimated;
- vertex3f = rsurface.modelvertex3f;
numsurfacelist = model->nummodelsurfaces;
surfacelist = model->sortedmodelsurfaces;
surfaces = model->data_surfaces;
- for (surfacelistindex = 0;surfacelistindex < numsurfacelist;surfacelistindex++)
+
+ bih = NULL;
+ bih_triangles_count = -1;
+ if(!dynamic)
{
- surfaceindex = surfacelist[surfacelistindex];
- surface = surfaces + surfaceindex;
- // check cull box first because it rejects more than any other check
- if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
- continue;
- // skip transparent surfaces
- texture = surface->texture;
- if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
- continue;
- if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
- continue;
- numtriangles = surface->num_triangles;
- for (triangleindex = 0, e = rsurface.modelelement3i + 3*surface->num_firsttriangle;triangleindex < numtriangles;triangleindex++, e += 3)
+ if(model->render_bih.numleafs)
+ bih = &model->render_bih;
+ else if(model->collision_bih.numleafs)
+ bih = &model->collision_bih;
+ }
+ if(bih)
+ bih_triangles_count = BIH_GetTriangleListForBox(bih, sizeof(bih_triangles) / sizeof(*bih_triangles), bih_triangles, bih_surfaces, localmins, localmaxs);
+ if(bih_triangles_count == 0)
+ return;
+ if(bih_triangles_count > (int) (sizeof(bih_triangles) / sizeof(*bih_triangles))) // hit too many, likely bad anyway
+ return;
+ if(bih_triangles_count > 0)
+ {
+ for (triangleindex = 0; triangleindex < bih_triangles_count; ++triangleindex)
{
- for (cornerindex = 0;cornerindex < 3;cornerindex++)
- {
- index = 3*e[cornerindex];
- VectorCopy(vertex3f + index, v[cornerindex]);
- }
- // cull backfaces
- //TriangleNormal(v[0], v[1], v[2], normal);
- //if (DotProduct(normal, localnormal) < 0.0f)
- // continue;
- // clip by each of the box planes formed from the projection matrix
- // if anything survives, we emit the decal
- 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]);
- if (numpoints < 3)
- continue;
- 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]);
- if (numpoints < 3)
+ surfaceindex = bih_surfaces[triangleindex];
+ surface = surfaces + surfaceindex;
+ texture = surface->texture;
+ if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
continue;
- 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]);
- if (numpoints < 3)
+ if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
continue;
- 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]);
- if (numpoints < 3)
+ R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, bih_triangles[triangleindex], surfaceindex);
+ }
+ }
+ else
+ {
+ for (surfacelistindex = 0;surfacelistindex < numsurfacelist;surfacelistindex++)
+ {
+ surfaceindex = surfacelist[surfacelistindex];
+ surface = surfaces + surfaceindex;
+ // check cull box first because it rejects more than any other check
+ if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
continue;
- 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]);
- if (numpoints < 3)
+ // skip transparent surfaces
+ texture = surface->texture;
+ if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
continue;
- 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]);
- if (numpoints < 3)
+ if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
continue;
- // some part of the triangle survived, so we have to accept it...
- if (dynamic)
- {
- // dynamic always uses the original triangle
- numpoints = 3;
- for (cornerindex = 0;cornerindex < 3;cornerindex++)
- {
- index = 3*e[cornerindex];
- VectorCopy(vertex3f + index, v[cornerindex]);
- }
- }
- for (cornerindex = 0;cornerindex < numpoints;cornerindex++)
- {
- // convert vertex positions to texcoords
- Matrix4x4_Transform(&projection, v[cornerindex], temp);
- tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
- tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
- // calculate distance fade from the projection origin
- f = a * (1.0f-fabs(temp[0])) * cl_decals_newsystem_intensitymultiplier.value;
- f = bound(0.0f, f, 1.0f);
- c[cornerindex][0] = r * f;
- c[cornerindex][1] = g * f;
- c[cornerindex][2] = b * f;
- c[cornerindex][3] = 1.0f;
- //VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
- }
- if (dynamic)
- R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[1], v[2], tc[0], tc[1], tc[2], c[0], c[1], c[2], triangleindex+surface->num_firsttriangle, surfaceindex, decalsequence);
- else
- for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
- R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence);
+ numtriangles = surface->num_triangles;
+ for (triangleindex = 0; triangleindex < numtriangles; triangleindex++)
+ R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, triangleindex + surface->num_firsttriangle, surfaceindex);
}
}
}
lifetime = cl_decals_time.value + cl_decals_fadetime.value;
if (decalsystem->lastupdatetime)
- frametime = (cl.time - decalsystem->lastupdatetime);
+ frametime = (r_refdef.scene.time - decalsystem->lastupdatetime);
else
frametime = 0;
- decalsystem->lastupdatetime = cl.time;
+ decalsystem->lastupdatetime = r_refdef.scene.time;
decal = decalsystem->decals;
numdecals = decalsystem->numdecals;
for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
{
- if (decal->color4ub[0][3])
+ if (decal->color4f[0][3])
{
decal->lived += frametime;
if (killsequence - decal->decalsequence > 0 || decal->lived >= lifetime)
}
}
decal = decalsystem->decals;
- while (numdecals > 0 && !decal[numdecals-1].color4ub[0][3])
+ while (numdecals > 0 && !decal[numdecals-1].color4f[0][3])
numdecals--;
// collapse the array by shuffling the tail decals into the gaps
for (;;)
{
- while (decalsystem->freedecal < numdecals && decal[decalsystem->freedecal].color4ub[0][3])
+ while (decalsystem->freedecal < numdecals && decal[decalsystem->freedecal].color4f[0][3])
decalsystem->freedecal++;
if (decalsystem->freedecal == numdecals)
break;
else
RSurf_ActiveModelEntity(ent, false, false, false);
- decalsystem->lastupdatetime = cl.time;
+ decalsystem->lastupdatetime = r_refdef.scene.time;
decal = decalsystem->decals;
faderate = 1.0f / max(0.001f, cl_decals_fadetime.value);
t2f = decalsystem->texcoord2f;
for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
{
- if (!decal->color4ub[0][3])
+ if (!decal->color4f[0][3])
continue;
if (surfacevisible && !surfacevisible[decal->surfaceindex])
continue;
+ // skip backfaces
+ if (decal->triangleindex < 0 && DotProduct(r_refdef.view.origin, decal->plane) < decal->plane[3])
+ continue;
+
// update color values for fading decals
if (decal->lived >= cl_decals_time.value)
- {
alpha = 1 - faderate * (decal->lived - cl_decals_time.value);
- alpha *= (1.0f/255.0f);
- }
else
- alpha = 1.0f/255.0f;
+ alpha = 1.0f;
- c4f[ 0] = decal->color4ub[0][0] * alpha;
- c4f[ 1] = decal->color4ub[0][1] * alpha;
- c4f[ 2] = decal->color4ub[0][2] * alpha;
+ c4f[ 0] = decal->color4f[0][0] * alpha;
+ c4f[ 1] = decal->color4f[0][1] * alpha;
+ c4f[ 2] = decal->color4f[0][2] * alpha;
c4f[ 3] = 1;
- c4f[ 4] = decal->color4ub[1][0] * alpha;
- c4f[ 5] = decal->color4ub[1][1] * alpha;
- c4f[ 6] = decal->color4ub[1][2] * alpha;
+ c4f[ 4] = decal->color4f[1][0] * alpha;
+ c4f[ 5] = decal->color4f[1][1] * alpha;
+ c4f[ 6] = decal->color4f[1][2] * alpha;
c4f[ 7] = 1;
- c4f[ 8] = decal->color4ub[2][0] * alpha;
- c4f[ 9] = decal->color4ub[2][1] * alpha;
- c4f[10] = decal->color4ub[2][2] * alpha;
+ c4f[ 8] = decal->color4f[2][0] * alpha;
+ c4f[ 9] = decal->color4f[2][1] * alpha;
+ c4f[10] = decal->color4f[2][2] * alpha;
c4f[11] = 1;
t2f[0] = decal->texcoord2f[0][0];
if (decal->triangleindex >= 0 && decal->triangleindex < rsurface.modelnumtriangles)
{
e = rsurface.modelelement3i + 3*decal->triangleindex;
- VectorCopy(rsurface.modelvertexposition[e[0]].vertex3f, v3f);
- VectorCopy(rsurface.modelvertexposition[e[1]].vertex3f, v3f + 3);
- VectorCopy(rsurface.modelvertexposition[e[2]].vertex3f, v3f + 6);
+ VectorCopy(rsurface.modelvertex3f + 3*e[0], v3f);
+ VectorCopy(rsurface.modelvertex3f + 3*e[1], v3f + 3);
+ VectorCopy(rsurface.modelvertex3f + 3*e[2], v3f + 6);
}
else
{
// now render the decals all at once
// (this assumes they all use one particle font texture!)
- 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);
- R_Mesh_ResetTextureState();
+ RSurf_ActiveCustomEntity(&rsurface.matrix, &rsurface.inversematrix, rsurface.ent_flags, ent->shadertime, 1, 1, 1, 1, numdecals*3, decalsystem->vertex3f, decalsystem->texcoord2f, NULL, NULL, NULL, decalsystem->color4f, numtris, decalsystem->element3i, decalsystem->element3s, false, false);
+// R_Mesh_ResetTextureState();
R_Mesh_PrepareVertices_Generic_Arrays(numtris * 3, decalsystem->vertex3f, decalsystem->color4f, decalsystem->texcoord2f);
GL_DepthMask(false);
GL_DepthRange(0, 1);
GL_DepthTest(true);
GL_CullFace(GL_NONE);
GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
- R_SetupShader_Generic(decalskinframe->base, NULL, GL_MODULATE, 1);
+ R_SetupShader_Generic(decalskinframe->base, NULL, GL_MODULATE, 1, false);
R_Mesh_Draw(0, numtris * 3, 0, numtris, decalsystem->element3i, NULL, 0, decalsystem->element3s, NULL, 0);
}
}
dp_model_t *model = ent->model;
vec3_t v;
+ if (!sv.active && !cls.demoplayback && ent != r_refdef.scene.worldentity)
+ return;
+
+ if (r_showoverdraw.value > 0)
+ {
+ float c = r_refdef.view.colorscale * r_showoverdraw.value * 0.125f;
+ flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL;
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
+ GL_DepthTest(false);
+ GL_DepthMask(false);
+ GL_DepthRange(0, 1);
+ GL_BlendFunc(GL_ONE, GL_ONE);
+ for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+ {
+ if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
+ continue;
+ rsurface.texture = R_GetCurrentTexture(surface->texture);
+ if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
+ {
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, 1, &surface);
+ GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_refdef.view.cullface_back);
+ if (!rsurface.texture->currentlayers->depthmask)
+ GL_Color(c, 0, 0, 1.0f);
+ else if (ent == r_refdef.scene.worldentity)
+ GL_Color(c, c, c, 1.0f);
+ else
+ GL_Color(0, c, 0, 1.0f);
+ R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
+ RSurf_DrawBatch();
+ }
+ }
+ rsurface.texture = NULL;
+ }
+
flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL;
- R_Mesh_ResetTextureState();
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
+// R_Mesh_ResetTextureState();
+ R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false);
GL_DepthRange(0, 1);
GL_DepthTest(!r_showdisabledepthtest.integer);
GL_DepthMask(false);
GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
- if (r_showtris.integer || r_shownormals.integer)
+ if (r_showtris.integer && qglPolygonMode)
{
if (r_showdisabledepthtest.integer)
{
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(true);
}
+ qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);CHECKGLERROR
for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
{
if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
{
RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_NOGAPS, 1, &surface);
- if (r_showtris.value > 0)
- {
- if (!rsurface.texture->currentlayers->depthmask)
- GL_Color(r_refdef.view.colorscale, 0, 0, r_showtris.value);
- else if (ent == r_refdef.scene.worldentity)
- GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, r_showtris.value);
- else
- GL_Color(0, r_refdef.view.colorscale, 0, r_showtris.value);
- R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
- qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- RSurf_DrawBatch();
- qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- CHECKGLERROR
- }
- if (r_shownormals.value < 0)
+ if (!rsurface.texture->currentlayers->depthmask)
+ GL_Color(r_refdef.view.colorscale, 0, 0, r_showtris.value);
+ else if (ent == r_refdef.scene.worldentity)
+ GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, r_showtris.value);
+ else
+ GL_Color(0, r_refdef.view.colorscale, 0, r_showtris.value);
+ R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL);
+ RSurf_DrawBatch();
+ }
+ }
+ qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);CHECKGLERROR
+ rsurface.texture = NULL;
+ }
+
+ if (r_shownormals.value != 0 && qglBegin)
+ {
+ if (r_showdisabledepthtest.integer)
+ {
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
+ }
+ else
+ {
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ }
+ for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++)
+ {
+ if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j])
+ continue;
+ rsurface.texture = R_GetCurrentTexture(surface->texture);
+ if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
+ {
+ RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_NOGAPS, 1, &surface);
+ qglBegin(GL_LINES);
+ if (r_shownormals.value < 0 && rsurface.batchnormal3f)
{
- qglBegin(GL_LINES);
- for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
+ for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
{
VectorCopy(rsurface.batchvertex3f + l * 3, v);
- GL_Color(r_refdef.view.colorscale, 0, 0, 1);
+ GL_Color(0, 0, r_refdef.view.colorscale, 1);
qglVertex3f(v[0], v[1], v[2]);
- VectorMA(v, -r_shownormals.value, rsurface.batchsvector3f + l * 3, v);
- GL_Color(r_refdef.view.colorscale, 1, 1, 1);
+ VectorMA(v, -r_shownormals.value, rsurface.batchnormal3f + l * 3, v);
+ GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
qglVertex3f(v[0], v[1], v[2]);
}
- qglEnd();
- CHECKGLERROR
}
if (r_shownormals.value > 0 && rsurface.batchsvector3f)
{
- qglBegin(GL_LINES);
- for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
+ for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
{
VectorCopy(rsurface.batchvertex3f + l * 3, v);
GL_Color(r_refdef.view.colorscale, 0, 0, 1);
qglVertex3f(v[0], v[1], v[2]);
VectorMA(v, r_shownormals.value, rsurface.batchsvector3f + l * 3, v);
- GL_Color(r_refdef.view.colorscale, 1, 1, 1);
+ GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
qglVertex3f(v[0], v[1], v[2]);
}
- qglEnd();
- CHECKGLERROR
- qglBegin(GL_LINES);
- for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
+ }
+ if (r_shownormals.value > 0 && rsurface.batchtvector3f)
+ {
+ for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
{
VectorCopy(rsurface.batchvertex3f + l * 3, v);
GL_Color(0, r_refdef.view.colorscale, 0, 1);
qglVertex3f(v[0], v[1], v[2]);
VectorMA(v, r_shownormals.value, rsurface.batchtvector3f + l * 3, v);
- GL_Color(r_refdef.view.colorscale, 1, 1, 1);
+ GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
qglVertex3f(v[0], v[1], v[2]);
}
- qglEnd();
- CHECKGLERROR
- qglBegin(GL_LINES);
- for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++)
+ }
+ if (r_shownormals.value > 0 && rsurface.batchnormal3f)
+ {
+ for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++)
{
VectorCopy(rsurface.batchvertex3f + l * 3, v);
GL_Color(0, 0, r_refdef.view.colorscale, 1);
qglVertex3f(v[0], v[1], v[2]);
VectorMA(v, r_shownormals.value, rsurface.batchnormal3f + l * 3, v);
- GL_Color(r_refdef.view.colorscale, 1, 1, 1);
+ GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1);
qglVertex3f(v[0], v[1], v[2]);
}
- qglEnd();
- CHECKGLERROR
}
+ qglEnd();
+ CHECKGLERROR
}
}
rsurface.texture = NULL;
return;
}
R_QueueWorldSurfaceList(numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
- GL_AlphaTest(false);
// add to stats if desired
if (r_speeds.integer && !skysurfaces && !depthonly)
switch (vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
RSurf_ActiveModelEntity(ent, model->wantnormals, model->wanttangents, false);
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
RSurf_ActiveModelEntity(ent, model->wantnormals, false, false);
break;
}
switch (vid.renderpath)
{
case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ case RENDERPATH_GLES2:
RSurf_ActiveModelEntity(ent, true, true, false);
break;
- case RENDERPATH_GL13:
case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
RSurf_ActiveModelEntity(ent, true, false, false);
break;
}
if (update[j])
R_BuildLightMap(ent, surfaces + j);
R_QueueModelSurfaceList(ent, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, prepass);
- GL_AlphaTest(false);
// add to stats if desired
if (r_speeds.integer && !skysurfaces && !depthonly)
const msurface_t *surfacelist = &surface;
// fake enough texture and surface state to render this geometry
-
surface.texture = texture;
surface.num_triangles = numtriangles;
surface.num_firsttriangle = firsttriangle;