#include "ft2.h"
#include "csprogs.h"
#include "cl_video.h"
+#include "dpsoftrast.h"
#ifdef SUPPORTD3D
#include <d3d9.h>
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_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_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_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_overheadsprites_perspective = {CVAR_SAVE, "r_overheadsprites_perspective", "5", "fake perspective effect for SPR_OVERHEAD sprites"};
+cvar_t r_overheadsprites_pushback = {CVAR_SAVE, "r_overheadsprites_pushback", "15", "how far to pull the SPR_OVERHEAD sprites toward the eye (used to avoid intersections with 3D models)"};
+cvar_t r_overheadsprites_scalex = {CVAR_SAVE, "r_overheadsprites_scalex", "1", "additional scale for overhead sprites for x axis"};
+cvar_t r_overheadsprites_scaley = {CVAR_SAVE, "r_overheadsprites_scaley", "1", "additional scale for overhead sprites for y axis"};
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_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;
"#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"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n"
"#define USEEYEVECTOR\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"
+" // 'vampire sight' effect, wheres red is compensated\n"
+" #ifdef SATURATION_REDCOMPENSATE\n"
+" float rboost = max(0.0, (gl_FragColor.r - max(gl_FragColor.g, gl_FragColor.b))*(1.0 - Saturation));\n"
+" gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
+" gl_FragColor.r += rboost;\n"
+" #else\n"
+" // normal desaturation\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"
"#endif\n"
"\n"
"#ifdef USEGAMMARAMPS\n"
"\n"
"void main(void)\n"
"{\n"
+"#ifdef USEVIEWTINT\n"
" gl_FragColor = gl_Color;\n"
+"#else\n"
+" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
+"#endif\n"
"#ifdef USEDIFFUSE\n"
" gl_FragColor *= texture2D(Texture_First, TexCoord1);\n"
"#endif\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"
+" gl_FragColor = vec4(texture2D(Texture_Refraction, ScreenTexCoord).rgb, 1.0) * RefractColor;\n"
"}\n"
"#endif\n"
"#else // !MODE_REFRACTION\n"
"uniform vec4 ReflectColor;\n"
"uniform float ReflectFactor;\n"
"uniform float ReflectOffset;\n"
+"uniform float ClientTime;\n"
+"#ifdef USENORMALMAPSCROLLBLEND\n"
+"uniform vec2 NormalmapScrollBlend;\n"
+"#endif\n"
"\n"
"void main(void)\n"
"{\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"
+" // slight water animation via 2 layer scrolling (todo: tweak)\n"
+" #ifdef USENORMALMAPSCROLLBLEND\n"
+" vec3 normal = texture2D(Texture_Normal, (TexCoord + vec2(0.08, 0.08)*ClientTime*NormalmapScrollBlend.x*0.5)*NormalmapScrollBlend.y).rgb - vec3(1.0);\n"
+" normal += texture2D(Texture_Normal, (TexCoord + vec2(-0.06, -0.09)*ClientTime*NormalmapScrollBlend.x)*NormalmapScrollBlend.y*0.75).rgb;\n"
+" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(normal) + vec3(0.15)).xyxy * DistortScaleRefractReflect;\n"
+" #else\n"
+" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
+" #endif\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"
+" float f = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, 0.01)).rgb) / 0.002);\n"
+" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, -0.01)).rgb) / 0.002);\n"
+" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, 0.01)).rgb) / 0.002);\n"
+" f *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, -0.01)).rgb) / 0.002);\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"
+" f = min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, 0.005)).rgb) / 0.002);\n"
+" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, -0.005)).rgb) / 0.002);\n"
+" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, 0.005)).rgb) / 0.002);\n"
+" f *= min(1.0, length(texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, -0.005)).rgb) / 0.002);\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"
+" gl_FragColor = mix(vec4(texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, vec4(texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
"}\n"
"#endif\n"
"#else // !MODE_WATER\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"
+" // 2 sample offset mapping (only 2 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"
+" OffsetVector *= 0.5;\n"
" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n"
" return TexCoord;\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"
+" lightnormal = normalize(lightnormal); // VectorS/T/R are not always perfectly normalized, and EXACTSPECULARMATH is very picky about this\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"
"\n"
"\n"
"\n"
+"#ifdef MODE_FAKELIGHT\n"
+"#define SHADING\n"
+"myhalf3 lightnormal = myhalf3(normalize(EyeVector));\n"
+"myhalf3 lightcolor = myhalf3(1.0);\n"
+"#endif // MODE_FAKELIGHT\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"
"#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"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n"
"#define USEEYEVECTOR\n"
"#endif\n"
"\n"
"out float4 gl_FragColor : COLOR\n"
")\n"
"{\n"
-"// float3 temp = float3(Depth,Depth*(65536.0/255.0),Depth*(16777216.0/255.0));\n"
+"// float4 temp = float4(Depth,Depth*(65536.0/255.0),Depth*(16777216.0/255.0),0.0);\n"
" float4 temp = float4(Depth,Depth*256.0,Depth*65536.0,0.0);\n"
" temp.yz -= floor(temp.yz);\n"
" gl_FragColor = temp;\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,y,y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
-" gl_FragColor.rgb = lerp(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
+" // 'vampire sight' effect, wheres red is compensated\n"
+" #ifdef SATURATION_REDCOMPENSATE\n"
+" float rboost = max(0.0, (gl_FragColor.r - max(gl_FragColor.g, gl_FragColor.b))*(1.0 - Saturation));\n"
+" gl_FragColor.rgb = mix(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
+" gl_FragColor.r += r;\n"
+" #else\n"
+" // normal desaturation\n"
+" //gl_FragColor = float3(y,y,y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
+" gl_FragColor.rgb = lerp(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
+" #endif\n"
"#endif\n"
"\n"
"#ifdef USEGAMMARAMPS\n"
"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
"out float4 gl_Position : POSITION,\n"
-"out float4 gl_FrontColor : COLOR,\n"
+"#ifdef USEDIFFUSE\n"
"out float2 TexCoord1 : TEXCOORD0,\n"
-"out float2 TexCoord2 : TEXCOORD1\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"out float2 TexCoord2 : TEXCOORD1,\n"
+"#endif\n"
+"out float4 gl_FrontColor : COLOR\n"
")\n"
"{\n"
"#ifdef HLSL\n"
"out float4 gl_FragColor : COLOR\n"
")\n"
"{\n"
+"#ifdef USEVIEWTINT\n"
" gl_FragColor = gl_FrontColor;\n"
+"#else\n"
+" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
+"#endif\n"
"#ifdef USEDIFFUSE\n"
" gl_FragColor *= tex2D(Texture_First, TexCoord1);\n"
"#endif\n"
" float2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
" //float2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(tex2D(Texture_Normal, TexCoord).rgb - float3(0.5,0.5,0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
" float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
-" float2 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(tex2D(Texture_Normal, TexCoord).rgb - float3(0.5,0.5,0.5))).xy * DistortScaleRefractReflect.xy;\n"
+" float2 ScreenTexCoord = SafeScreenTexCoord + normalize(tex2D(Texture_Normal, TexCoord).rgb - float3(0.5,0.5,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"
" 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"
+" gl_FragColor = float4(tex2D(Texture_Refraction, ScreenTexCoord).rgb, 1) * RefractColor;\n"
"}\n"
"#endif\n"
"#else // !MODE_REFRACTION\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"
+" 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"
+" gl_FragColor = lerp(float4(tex2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, float4(tex2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
"}\n"
"#endif\n"
"#else // !MODE_WATER\n"
"uniform float3 EyePosition : register(c24),\n"
"#endif\n"
"out float4 gl_Position : POSITION,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
"out float4 gl_FrontColor : COLOR,\n"
+"#endif\n"
"out float4 TexCoordBoth : TEXCOORD0,\n"
"#ifdef USEOFFSETMAPPING\n"
"out float3 EyeVector : TEXCOORD2,\n"
"#ifdef USESHADOWMAPORTHO\n"
"uniform float4x4 ShadowMapMatrix : register(c16),\n"
"#endif\n"
-"\n"
+"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
"out float4 gl_FrontColor : COLOR,\n"
+"#endif\n"
"out float4 TexCoordBoth : TEXCOORD0,\n"
"#ifdef USELIGHTMAP\n"
"out float2 TexCoordLightmap : TEXCOORD1,\n"
"#ifdef USEFOG\n"
"out float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
"#endif\n"
-"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
+"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE) || defined(USEDIFFUSE)\n"
"out float3 LightVector : TEXCOORD1,\n"
"#endif\n"
"#ifdef MODE_LIGHTSOURCE\n"
"\n"
"\n"
"\n"
+"#ifdef MODE_FAKELIGHT\n"
+"#define SHADING\n"
+"half3 lightnormal = half3(normalize(EyeVector));\n"
+"half3 lightcolor = half3(1.0,1.0,1.0);\n"
+"#endif // MODE_FAKELIGHT\n"
+"\n"
+"\n"
+"\n"
+"\n"
"#ifdef MODE_LIGHTMAP\n"
" color.rgb = diffusetex * (Color_Ambient + half3(tex2D(Texture_Lightmap, TexCoordLightmap).rgb) * Color_Diffuse);\n"
"#endif // MODE_LIGHTMAP\n"
}
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_SHADOWMAP2D = 1<<18, ///< (lightsource) use shadowmap texture as light filter
- SHADERPERMUTATION_SHADOWMAPPCF = 1<<19, ///< (lightsource) use percentage closer filtering on shadowmap test results
- SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<20, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
- SHADERPERMUTATION_SHADOWSAMPLER = 1<<21, ///< (lightsource) use hardware shadowmap test
- SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<22, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
- SHADERPERMUTATION_SHADOWMAPORTHO = 1<<23, //< (lightsource) use orthographic shadowmap projection
- SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<24, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
- SHADERPERMUTATION_ALPHAKILL = 1<<25, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
- SHADERPERMUTATION_REFLECTCUBE = 1<<26, ///< fake reflections using global cubemap (not HDRI light probe)
- SHADERPERMUTATION_LIMIT = 1<<27, ///< size of permutations array
- SHADERPERMUTATION_COUNT = 27 ///< size of shaderpermutationinfo array
-}
-shaderpermutation_t;
-
// NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] =
{
{"#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 USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
{"#define USEALPHAKILL\n", " alphakill"},
{"#define USEREFLECTCUBE\n", " reflectcube"},
+ {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
};
-/// 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"},
{
{"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_DEPTH_OR_SHADOW\n", " depth/shadow"},
{"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_FAKELIGHT\n", " fakelight"},
{"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"},
{
{"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"},
+ {"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"},
int loc_ModelToReflectCube;
int loc_ShadowMapMatrix;
int loc_BloomColorSubtract;
+ int loc_NormalmapScrollBlend;
}
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
+};
+#define SHADERSTATICPARMS_COUNT 6
+
+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_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");
+}
+
/// information about each possible shader permutation
r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
/// currently selected permutation
{
int i;
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;
}
}
+ // 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;
p->loc_ModelToReflectCube = qglGetUniformLocationARB(p->program, "ModelToReflectCube");
p->loc_ShadowMapMatrix = qglGetUniformLocationARB(p->program, "ShadowMapMatrix");
p->loc_BloomColorSubtract = qglGetUniformLocationARB(p->program, "BloomColorSubtract");
+ p->loc_NormalmapScrollBlend = qglGetUniformLocationARB(p->program, "NormalmapScrollBlend");
// 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);
CGparameter fp_PixelToScreenTexCoord;
CGparameter fp_ModelToReflectCube;
CGparameter fp_BloomColorSubtract;
+ CGparameter fp_NormalmapScrollBlend;
}
r_cg_permutation_t;
{
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;
+ 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;
}
}
+ // 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] == ' ')
p->fp_PixelToScreenTexCoord = cgGetNamedParameter(p->fprogram, "PixelToScreenTexCoord");
p->fp_ModelToReflectCube = cgGetNamedParameter(p->fprogram, "ModelToReflectCube");
p->fp_BloomColorSubtract = cgGetNamedParameter(p->fprogram, "BloomColorSubtract");
+ p->fp_NormalmapScrollBlend = cgGetNamedParameter(p->fprogram, "NormalmapScrollBlend");
CHECKCGERROR
}
D3DPSREGISTER_BloomColorSubtract = 43,
D3DPSREGISTER_ViewToLight = 44, // float4x4
D3DPSREGISTER_ModelToReflectCube = 48, // float4x4
- // next at 52
+ D3DPSREGISTER_NormalmapScrollBlend = 52,
+ // next at 53
}
D3DPSREGISTER_t;
int psresult = 0;
char temp[MAX_INPUTLINE];
const char *vsversion = "vs_3_0", *psversion = "ps_3_0";
- qboolean debugshader = 1;//gl_paranoid.integer != 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)
{
int i;
shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
- int vertstrings_count = 0, vertstring_length = 0;
- int geomstrings_count = 0, geomstring_length = 0;
- int fragstrings_count = 0, fragstring_length = 0;
+ 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];
+ 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;
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";
}
}
+ // 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] == ' ')
}
#endif
+void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation)
+{
+ DPSOFTRAST_SetShader(mode, permutation);
+ DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
+ DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_ClientTime, cl.time);
+}
+
void R_GLSL_Restart_f(void)
{
unsigned int i, limit;
case RENDERPATH_GL13:
case RENDERPATH_GL11:
break;
+ case RENDERPATH_SOFT:
+ break;
}
}
{
case RENDERPATH_D3D9:
#ifdef SUPPORTD3D
- R_SetupShader_SetPermutationHLSL(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))));
+ R_SetupShader_SetPermutationHLSL(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
R_Mesh_TexBind(GL20TU_FIRST , first );
R_Mesh_TexBind(GL20TU_SECOND, second);
#endif
Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
break;
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))));
+ R_SetupShader_SetPermutationGLSL(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
R_Mesh_TexBind(GL20TU_FIRST , first );
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))));
+ R_SetupShader_SetPermutationCG(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
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
#endif
case RENDERPATH_GL11:
R_Mesh_TexBind(0, first );
break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationSoft(SHADERMODE_GENERIC, SHADERPERMUTATION_VIEWTINT | (first ? SHADERPERMUTATION_DIFFUSE : 0) | (second ? SHADERPERMUTATION_SPECULAR : 0) | (texturemode == GL_MODULATE ? SHADERPERMUTATION_COLORMAPPING : (texturemode == GL_ADD ? SHADERPERMUTATION_GLOW : (texturemode == GL_DECAL ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0))));
+ R_Mesh_TexBind(GL20TU_FIRST , first );
+ R_Mesh_TexBind(GL20TU_SECOND, second);
+ break;
}
}
case RENDERPATH_GL11:
R_Mesh_TexBind(0, 0);
break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationSoft(SHADERMODE_DEPTH_OR_SHADOW, 0);
+ break;
}
}
break;
case RENDERPATH_GL11:
break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationSoft(SHADERMODE_SHOWDEPTH, 0);
+ break;
}
}
extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture;
extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
extern rtexture_t *r_shadow_prepasslightingspeculartexture;
-extern cvar_t gl_mesh_separatearrays;
static qboolean R_BlendFuncAllowsColormod(int src, int dst)
{
// a blendfunc allows colormod if:
{
// distorted background
if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER)
+ {
mode = SHADERMODE_WATER;
+ if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
+ permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND;
+ 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);
+ allow_colormod = R_BlendFuncAllowsColormod(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);
+ allow_colormod = R_BlendFuncAllowsColormod(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);
+ allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
else
{
mode = SHADERMODE_GENERIC;
permutation |= SHADERPERMUTATION_DIFFUSE;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
}
GL_AlphaTest(false);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
}
else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
{
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_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)
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)
{
}
else
{
- if (mode == SHADERMODE_LIGHTDIRECTION)
+ if (mode == SHADERMODE_LIGHTDIRECTION)
{
hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
}
// additive passes are only darkened by fog, not tinted
hlslPSSetParameter3f(D3DPSREGISTER_FogColor, 0, 0, 0);
- hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
+ hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
}
else
{
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]);
- hlslPSSetParameter4fv(D3DPSREGISTER_RefractColor, rsurface.texture->refractcolor4f);
- hlslPSSetParameter4fv(D3DPSREGISTER_ReflectColor, rsurface.texture->reflectcolor4f);
+ 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 * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
+ 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]);
+ 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]);
Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
break;
case RENDERPATH_GL20:
- if (gl_mesh_separatearrays.integer)
+ 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);
// 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));
+ if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
}
else
{
}
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) * 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]);
+ 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 * 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) qglUniform3fARB(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) 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, 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) 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_LightColor >= 0) qglUniform3fARB(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) qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
}
else
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_RefractColor >= 0) qglUniform4fARB(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) qglUniform4fARB(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) 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_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ if (r_glsl_permutation->loc_NormalmapScrollBlend >= 0) qglUniform2fARB(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);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_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_Alpha >= 0) qglUniform1fARB(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) qglUniform3fARB(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
if (r_glsl_permutation->loc_Color_Pants >= 0)
{
break;
case RENDERPATH_CGGL:
#ifdef SUPPORTCG
- if (gl_mesh_separatearrays.integer)
+ 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);
// 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
+ if (r_cg_permutation->fp_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
}
else
{
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_RefractColor) cgGLSetParameter4f(r_cg_permutation->fp_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);CHECKCGERROR
+ if (r_cg_permutation->fp_ReflectColor) cgGLSetParameter4f(r_cg_permutation->fp_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);CHECKCGERROR
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_SpecularPower) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
+ if (r_cg_permutation->fp_NormalmapScrollBlend) cgGLSetParameter2f(r_cg_permutation->fp_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
}
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_Alpha) cgGLSetParameter1f(r_cg_permutation->fp_Alpha, rsurface.texture->lightmapcolor[3] * ((rsurface.texture->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) ? rsurface.texture->r_water_wateralpha : 1));CHECKCGERROR
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)
{
case RENDERPATH_GL13:
case RENDERPATH_GL11:
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_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ModelToReflectCubeM1, 1, false, m16f);}
+ if (mode == SHADERMODE_LIGHTSOURCE)
+ {
+ {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ModelToLightM1, 1, false, m16f);}
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
+ DPSOFTRAST_Uniform3fARB(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
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ }
+ else
+ {
+ if (mode == SHADERMODE_FLATCOLOR)
+ {
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Ambient, colormod[0], colormod[1], colormod[2]);
+ }
+ else if (mode == SHADERMODE_LIGHTDIRECTION)
+ {
+ DPSOFTRAST_Uniform3fARB(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_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
+ DPSOFTRAST_Uniform3fARB(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_Uniform3fARB(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_Uniform3fARB(DPSOFTRAST_UNIFORM_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
+ DPSOFTRAST_Uniform3fARB(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_Uniform3fARB(DPSOFTRAST_UNIFORM_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
+ }
+ else
+ {
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
+ DPSOFTRAST_Uniform3fARB(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_Uniform3fARB(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_Uniform3fARB(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 (rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD)
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_FogColor, 0, 0, 0);
+ else
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_FogColor, r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2]);
+ DPSOFTRAST_Uniform4fARB(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_Uniform4fARB(DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_RefractColor, rsurface.texture->refractcolor4f[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_ReflectColor, rsurface.texture->reflectcolor4f[0], rsurface.texture->reflectcolor4f[1], rsurface.texture->reflectcolor4f[2], rsurface.texture->reflectcolor4f[3] * rsurface.texture->lightmapcolor[3]);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_ReflectOffset, rsurface.texture->reflectmin);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_SpecularPower, rsurface.texture->specularpower * (r_shadow_glossexact.integer ? 0.25f : 1.0f));
+ DPSOFTRAST_Uniform2fARB(DPSOFTRAST_UNIFORM_NormalmapScrollBlend, rsurface.texture->r_water_waterscroll[0], rsurface.texture->r_water_waterscroll[1]);
+ }
+ {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_TexMatrixM1, 1, false, m16f);}
+ {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1, 1, false, m16f);}
+ {Matrix4x4_ToArrayFloatGL(&r_shadow_shadowmapmatrix, m16f);DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ShadowMapMatrixM1, 1, false, m16f);}
+ DPSOFTRAST_Uniform2fARB(DPSOFTRAST_UNIFORM_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ DPSOFTRAST_Uniform4fARB(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_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]);
+ DPSOFTRAST_Uniform1fARB(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_Uniform3fARB(DPSOFTRAST_UNIFORM_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);
+ if (DPSOFTRAST_UNIFORM_Color_Pants >= 0)
+ {
+ if (rsurface.texture->pantstexture)
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Pants, rsurface.colormap_pantscolor[0], rsurface.colormap_pantscolor[1], rsurface.colormap_pantscolor[2]);
+ else
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Pants, 0, 0, 0);
+ }
+ if (DPSOFTRAST_UNIFORM_Color_Shirt >= 0)
+ {
+ if (rsurface.texture->shirttexture)
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Shirt, rsurface.colormap_shirtcolor[0], rsurface.colormap_shirtcolor[1], rsurface.colormap_shirtcolor[2]);
+ else
+ DPSOFTRAST_Uniform3fARB(DPSOFTRAST_UNIFORM_Color_Shirt, 0, 0, 0);
+ }
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_FogPlane, rsurface.fogplane[0], rsurface.fogplane[1], rsurface.fogplane[2], rsurface.fogplane[3]);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale);
+ DPSOFTRAST_Uniform2fARB(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ DPSOFTRAST_Uniform2fARB(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)))
+ {
+ R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture);
+ if (rsurface.rtlight)
+ {
+ if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap );
+ if (permutation & SHADERPERMUTATION_SHADOWMAPVSDCT ) R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture );
+ }
+ }
+ break;
}
}
if (diffusescale > 0)
permutation |= SHADERPERMUTATION_DIFFUSE;
if (specularscale > 0)
- {
permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE;
- if (r_shadow_glossexact.integer)
- permutation |= SHADERPERMUTATION_EXACTSPECULARMATH;
- }
if (r_shadow_usingshadowmap2d)
{
permutation |= SHADERPERMUTATION_SHADOWMAP2D;
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) * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f));
+ 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);
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_SpecularPower >= 0) qglUniform1fARB( 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) 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_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_SpecularPower ) cgGLSetParameter1f(r_cg_permutation->fp_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
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
case RENDERPATH_GL13:
case RENDERPATH_GL11:
break;
+ case RENDERPATH_SOFT:
+ R_SetupShader_SetPermutationGLSL(mode, permutation);
+ DPSOFTRAST_Uniform3fARB( DPSOFTRAST_UNIFORM_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);
+ DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ViewToLightM1 , 1, false, viewtolight16f);
+ DPSOFTRAST_Uniform3fARB( DPSOFTRAST_UNIFORM_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);
+ DPSOFTRAST_Uniform3fARB( DPSOFTRAST_UNIFORM_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range);
+ DPSOFTRAST_Uniform3fARB( DPSOFTRAST_UNIFORM_DeferredColor_Specular , lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range);
+ DPSOFTRAST_Uniform2fARB( DPSOFTRAST_UNIFORM_ShadowMap_TextureScale , r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]);
+ DPSOFTRAST_Uniform4fARB( 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_Uniform1fARB( 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_Uniform2fARB( DPSOFTRAST_UNIFORM_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]);
+ DPSOFTRAST_Uniform2fARB(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;
}
}
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 = (unsigned char *)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;
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_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
Cvar_SetValueQuick(&r_textureunits, vid.texunits);
Cvar_SetValueQuick(&gl_combine, 1);
Cvar_SetValueQuick(&r_glsl, 1);
case RENDERPATH_D3D11:
Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
break;
+ case RENDERPATH_SOFT:
+ break;
}
r_numqueries = 0;
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));
+ Mem_ExpandableArray_FreeArray(&r_cg_permutationarray);
+ cgshaderstring = NULL;
+#endif
+#ifdef SUPPORTD3D
+ r_hlsl_permutation = NULL;
+ memset(r_hlsl_permutationhash, 0, sizeof(r_hlsl_permutationhash));
+ Mem_ExpandableArray_FreeArray(&r_hlsl_permutationarray);
+ hlslshaderstring = NULL;
+#endif
}
extern void CL_ParseEntityLump(char *entitystring);
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_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_lerpsprites);
Cvar_RegisterVariable(&r_lerpmodels);
Cvar_RegisterVariable(&r_lerplightstyles);
Cvar_RegisterVariable(&gl_lightmaps);
Cvar_RegisterVariable(&r_test);
Cvar_RegisterVariable(&r_glsl_saturation);
+ Cvar_RegisterVariable(&r_glsl_saturation_redcompensate);
Cvar_RegisterVariable(&r_framedatasize);
if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
Cvar_SetValue("r_fullbrights", 0);
Cvar_RegisterVariable(&r_track_sprites_scaleh);
Cvar_RegisterVariable(&r_overheadsprites_perspective);
Cvar_RegisterVariable(&r_overheadsprites_pushback);
+ Cvar_RegisterVariable(&r_overheadsprites_scalex);
+ Cvar_RegisterVariable(&r_overheadsprites_scaley);
}
extern void R_Textures_Init(void);
// 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;
}
}
{
int i;
- // identical memory layout, so no need to allocate...
- // this also provides the vertexposition structure to everything, e.g.
- // depth masked rendering currently uses it even if having separate
- // arrays
- // NOTE: get rid of this optimization if changing it to e.g. 4f
- ent->animcache_vertexposition = (r_vertexposition_t *)ent->animcache_vertex3f;
-
- // TODO:
- // get rid of following uses of VERTEXPOSITION, change to the array:
- // R_DrawTextureSurfaceList_Sky if skyrendermasked
- // R_DrawSurface_TransparentCallback if r_transparentdepthmasking.integer
- // R_DrawTextureSurfaceList_DepthOnly
- // R_Q1BSP_DrawShadowMap
-
- switch(vid.renderpath)
- {
- case RENDERPATH_GL20:
- case RENDERPATH_CGGL:
- // need the meshbuffers if !gl_mesh_separatearrays.integer
- if (gl_mesh_separatearrays.integer)
- return;
- break;
- case RENDERPATH_D3D9:
- case RENDERPATH_D3D10:
- case RENDERPATH_D3D11:
- // always need the meshbuffers
- break;
- case RENDERPATH_GL13:
- case RENDERPATH_GL11:
- // never need the meshbuffers
+ // check if we need the meshbuffers
+ if (!vid.useinterleavedarrays)
return;
- }
if (!ent->animcache_vertexmesh && ent->animcache_normal3f)
ent->animcache_vertexmesh = (r_vertexmesh_t *)R_FrameData_Alloc(sizeof(r_vertexmesh_t)*numvertices);
- /*
- if (!ent->animcache_vertexposition)
- ent->animcache_vertexposition = (r_vertexposition_t *)R_FrameData_Alloc(sizeof(r_vertexposition_t)*numvertices);
- */
- if (ent->animcache_vertexposition)
- {
- /*
- for (i = 0;i < numvertices;i++)
- memcpy(ent->animcache_vertexposition[i].vertex3f, ent->animcache_vertex3f + 3*i, sizeof(float[3]));
- */
- // TODO: upload vertex buffer?
- }
+ // TODO: upload vertex3f buffer?
if (ent->animcache_vertexmesh)
{
memcpy(ent->animcache_vertexmesh, ent->model->surfmesh.vertexmesh, sizeof(r_vertexmesh_t)*numvertices);
if (ent->animcache_normal3f)
for (i = 0;i < numvertices;i++)
memcpy(ent->animcache_vertexmesh[i].normal3f, ent->animcache_normal3f + 3*i, sizeof(float[3]));
- // TODO: upload vertex buffer?
+ // TODO: upload vertexmeshbuffer?
}
}
ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
ent->animcache_tvector3f = (float *)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);
- }
+ 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);
}
- 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);
- }
+ 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)
case RENDERPATH_GL11:
wanttangents = false;
break;
+ case RENDERPATH_SOFT:
+ break;
}
if (r_shownormals.integer)
{
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_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, ent->modellight_lightdir, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
+ }
+ else
+ r_refdef.scene.worldmodel->brush.LightPoint(r_refdef.scene.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal);
+
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);
}
}
}
}
}
-static void R_View_SetFrustum(void)
+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:
+ case RENDERPATH_SOFT:
+ // 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_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_CGGL:
+ // 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();
case RENDERPATH_GL11:
qglLoadMatrixf(gl_modelview16f);CHECKGLERROR
break;
+ case RENDERPATH_SOFT:
+ DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f);
+ DPSOFTRAST_UniformMatrix4fvARB(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f);
+ break;
}
}
}
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
break;
}
GL_CullFace(GL_NONE);
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
break;
}
GL_CullFace(r_refdef.view.cullface_back);
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
break;
case RENDERPATH_GL13:
case RENDERPATH_GL11:
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;
static void R_Water_ProcessPlanes(void)
{
+ int myscissor[4];
r_refdef_view_t originalview;
r_refdef_view_t myview;
int planeindex;
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)
Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin);
r_refdef.view.clipplane = p->plane;
+
// reverse the cullface settings for this render
r_refdef.view.cullface_front = GL_FRONT;
r_refdef.view.cullface_back = GL_BACK;
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_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;
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
break;
case RENDERPATH_GL13:
case RENDERPATH_GL11:
case RENDERPATH_GL13:
case RENDERPATH_GL20:
case RENDERPATH_CGGL:
+ case RENDERPATH_SOFT:
break;
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_GL13:
case RENDERPATH_GL20:
case RENDERPATH_CGGL:
+ case RENDERPATH_SOFT:
R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
break;
case RENDERPATH_D3D9:
{
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;
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
permutation =
(r_bloomstate.texture_bloom ? SHADERPERMUTATION_BLOOM : 0)
| (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VIEWTINT : 0)
case RENDERPATH_GL13:
case RENDERPATH_GL20:
case RENDERPATH_CGGL:
+ case RENDERPATH_SOFT:
R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f);
break;
case RENDERPATH_D3D9:
#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);
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_Uniform4fARB(DPSOFTRAST_UNIFORM_ViewTintColor , r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
+ DPSOFTRAST_Uniform2fARB(DPSOFTRAST_UNIFORM_PixelSize , 1.0/r_bloomstate.screentexturewidth, 1.0/r_bloomstate.screentextureheight);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_UserVec1 , uservecs[0][0], uservecs[0][1], uservecs[0][2], uservecs[0][3]);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_UserVec2 , uservecs[1][0], uservecs[1][1], uservecs[1][2], uservecs[1][3]);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]);
+ DPSOFTRAST_Uniform1fARB(DPSOFTRAST_UNIFORM_Saturation , r_glsl_saturation.value);
+ DPSOFTRAST_Uniform2fARB(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height);
+ DPSOFTRAST_Uniform4fARB(DPSOFTRAST_UNIFORM_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f);
+ break;
default:
break;
}
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;
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
if(v_glslgamma.integer && !vid_gammatables_trivial)
{
if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial)
R_RenderView
================
*/
+int dpsoftrast_test;
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]
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;
GL_Scissor(0, 0, vid.width, vid.height);
GL_ScissorTest(false);
+
+ r_refdef.view.matrix = originalmatrix;
+
CHECKGLERROR
}
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];
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);
R_Mesh_PrepareVertices_Generic_Arrays(6, nomodelvertex3f, color4f, NULL);
R_Mesh_Draw(0, 6, 0, 8, nomodelelement3i, NULL, 0, nomodelelement3s, NULL, 0);
}
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[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % 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[(unsigned int)(t->skinframerate * (cl.time - rsurface.ent_shadertime)) % t->numskinframes];
if (t->backgroundnumskinframes >= 2)
- t->backgroundcurrentskinframe = t->backgroundskinframes[(int)(t->backgroundskinframerate * (cl.time - rsurface.ent_shadertime)) % t->backgroundnumskinframes];
+ t->backgroundcurrentskinframe = t->backgroundskinframes[(unsigned int)(t->backgroundskinframerate * (cl.time - rsurface.ent_shadertime)) % t->backgroundnumskinframes];
t->currentmaterialflags = t->basematerialflags;
t->currentalpha = rsurface.colormod[3];
if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.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
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;
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.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;
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.matrix = ent->matrix;
rsurface.inversematrix = ent->inversematrix;
rsurface.matrixscale = Matrix4x4_ScaleFromMatrix(&rsurface.matrix);
}
if (model->surfmesh.isanimated && model->AnimateVertices && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].subframe != 0))
{
- 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_flags = entflags;
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;
+ {
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_NOGAPS;
+ needsupdate |= BATCHNEED_VERTEXMESH_VERTEXCOLOR;
+ }
+
for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform;deformindex++, deform++)
{
switch (deform->deform)
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;
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;
}
}
if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS;
+ batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS;
needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
}
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)
+ 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]));
+ memcpy(rsurface.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]));
+ memcpy(rsurface.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]));
+ 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]));
}
if ((batchneed & BATCHNEED_ARRAY_VERTEXCOLOR) && rsurface.modellightmapcolor4f)
- memcpy(rsurface.array_batchlightmapcolor4f + 4*numvertices, rsurface.modellightmapcolor4f + 4*surfacefirstvertex, surfacenumvertices * sizeof(float[4]));
+ memcpy(rsurface.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]));
+ memcpy(rsurface.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]));
+ memcpy(rsurface.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++;
}
}
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;
// 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));
}
}
// if we get here, BATCHNEED_ARRAY_NORMAL and BATCHNEED_ARRAY_VECTOR are in batchneed, so no need to check
- 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;
+ 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));
}
}
}
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
if(batchneed & (BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR)) // otherwise these can stay NULL
{
- Mod_BuildNormals(rsurface.batchfirstvertex, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
+// 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
{
- 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.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]);
VectorNormalize(normal);
}
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- rsurface.batchnormal3f_vertexbuffer = NULL;
- rsurface.batchnormal3f_bufferoffset = 0;
if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
{
- 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.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:
// 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, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- 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
{
- 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.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_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);
+ 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, rsurface.batchnumvertices, rsurface.batchnumtriangles, rsurface.array_batchvertex3f, rsurface.batchelement3i + 3 * rsurface.batchfirsttriangle, rsurface.array_batchnormal3f, true);
- rsurface.batchvertex3f = rsurface.array_batchvertex3f;
- rsurface.batchvertex3f_vertexbuffer = NULL;
- rsurface.batchvertex3f_bufferoffset = 0;
- rsurface.batchnormal3f = rsurface.array_batchnormal3f;
- 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
{
- 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.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_MOVE:
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
{
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++)
+// 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++)
+ for (j = 0, vertexmesh = rsurface.batchvertexmesh;j < batchnumvertices;j++, vertexmesh++)
Vector4Scale(rsurface.batchlightmapcolor4f + 4*j, 255.0f, vertexmesh->color4ub);
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)
{
+ // 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)
+ {
+ 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);
}
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);
}
}
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)
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)
+ 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;
// just to make sure that braindead drivers don't draw
// anything despite that colormask...
GL_BlendFunc(GL_ZERO, GL_ONE);
- RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXPOSITION | BATCHNEED_NOGAPS, 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
{
// 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_BASE, end-start, texturesurfacelist + start, NULL);
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_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;
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;
float c[4];
GL_AlphaTest(false);
- R_Mesh_ResetTextureState();
+// R_Mesh_ResetTextureState();
R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
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);
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
break;
case RENDERPATH_GL13:
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass);
break;
case RENDERPATH_GL13:
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
RSurf_ActiveModelEntity(ent, true, true, false);
break;
case RENDERPATH_GL13:
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(true);
GL_AlphaTest(false);
- R_Mesh_ResetTextureState();
+// R_Mesh_ResetTextureState();
R_SetupShader_DepthOrShadow();
}
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);
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)
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();
}
{
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)
{
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,
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();
+// R_Mesh_ResetTextureState();
R_Mesh_PrepareVertices_Generic_Arrays(numtris * 3, decalsystem->vertex3f, decalsystem->color4f, decalsystem->texcoord2f);
GL_DepthMask(false);
GL_DepthRange(0, 1);
case RENDERPATH_D3D11:
Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
return;
+ case RENDERPATH_SOFT:
+ //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ return;
}
flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL;
- R_Mesh_ResetTextureState();
+// R_Mesh_ResetTextureState();
R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
GL_DepthRange(0, 1);
GL_DepthTest(!r_showdisabledepthtest.integer);
GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
- if (r_showtris.integer || r_shownormals.integer)
+ if (r_showtris.integer || (r_shownormals.value != 0))
{
if (r_showdisabledepthtest.integer)
{
if (r_shownormals.value < 0)
{
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();
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++)
+ 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++)
+ 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();
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
RSurf_ActiveModelEntity(ent, model->wantnormals, model->wanttangents, false);
break;
case RENDERPATH_GL13:
case RENDERPATH_D3D9:
case RENDERPATH_D3D10:
case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
RSurf_ActiveModelEntity(ent, true, true, false);
break;
case RENDERPATH_GL13:
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;