#include "ft2.h"
#include "csprogs.h"
#include "cl_video.h"
+#include "dpsoftrast.h"
#ifdef SUPPORTD3D
#include <d3d9.h>
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;
" // content.\n"
" // Remove this 'ack once we have a better way to stop this thing from\n"
" // 'appening.\n"
-" float f1 = min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, 0.01)).rgb) / 0.002);\n"
-" f1 *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, -0.01)).rgb) / 0.002);\n"
-" f1 *= min(1.0, length(texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, 0.01)).rgb) / 0.002);\n"
-" f1 *= 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, f1);\n"
-" float 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"
+" 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.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(vec4(texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, vec4(texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n"
-" gl_FragColor.a = f1 + 0.5;\n"
"}\n"
"#endif\n"
"#else // !MODE_WATER\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"
" 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(float4(tex2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * RefractColor, float4(tex2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\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), use vertex colors (generic 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_REFLECTION = 1<<14, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
- SHADERPERMUTATION_OFFSETMAPPING = 1<<15, ///< adjust texcoords to roughly simulate a displacement mapped surface
- SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<16, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
- SHADERPERMUTATION_SHADOWMAP2D = 1<<17, ///< (lightsource) use shadowmap texture as light filter
- SHADERPERMUTATION_SHADOWMAPPCF = 1<<18, ///< (lightsource) use percentage closer filtering on shadowmap test results
- SHADERPERMUTATION_SHADOWMAPPCF2 = 1<<19, ///< (lightsource) use higher quality percentage closer filtering on shadowmap test results
- SHADERPERMUTATION_SHADOWSAMPLER = 1<<20, ///< (lightsource) use hardware shadowmap test
- SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<21, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
- SHADERPERMUTATION_SHADOWMAPORTHO = 1<<22, //< (lightsource) use orthographic shadowmap projection
- SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<23, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
- SHADERPERMUTATION_ALPHAKILL = 1<<24, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5
- SHADERPERMUTATION_REFLECTCUBE = 1<<25, ///< fake reflections using global cubemap (not HDRI light probe)
- SHADERPERMUTATION_NORMALMAPSCROLLBLEND = 1<<26, // (water) counter-direction normalmaps scrolling
- 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 USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
};
-// this enum selects which of the glslshadermodeinfo entries should be used
-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_FAKELIGHT, ///< (fakelight) modulate texture by "fake" lighting (no lightmaps, no nothing)
- 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] =
{
}
#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_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:
mode = SHADERMODE_WATER;
if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1])
permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND;
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ 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)
{
}
else
{
- if (mode == SHADERMODE_LIGHTDIRECTION)
+ if (mode == SHADERMODE_LIGHTDIRECTION)
{
hlslVSSetParameter3f(D3DVSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[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);
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);
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[0], rsurface.texture->refractcolor4f[1], rsurface.texture->refractcolor4f[2], rsurface.texture->refractcolor4f[3] * rsurface.texture->lightmapcolor[3]);CHECKCGERROR
- if (r_cg_permutation->fp_ReflectColor) cgGLSetParameter4fv(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_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 * (r_shadow_glossexact.integer ? 0.25f : 1.0f));CHECKCGERROR
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;
}
}
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_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();
+ }
- // return NULL on everything after a failure
- if (r_framedata_failed)
- return NULL;
+ data = r_framedata_mem->data + r_framedata_mem->current;
+ r_framedata_mem->current += size;
+
+ // 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)
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);
}
}
}
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);
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:
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:
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)
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
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
}
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)
{
- int newvertices;
dp_model_t *model = r_refdef.scene.worldmodel;
//if (rsurface.entity == r_refdef.scene.worldentity)
// return;
rsurface.ent_qwskin = -1;
rsurface.ent_shadertime = 0;
rsurface.ent_flags = r_refdef.scene.worldentity->flags;
- newvertices = max(model->surfmesh.num_vertices, model->surfmesh.num_triangles);
- if (rsurface.array_size < newvertices)
- R_Mesh_ResizeArrays(newvertices);
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;
void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents, qboolean prepass)
{
- int newvertices;
dp_model_t *model = ent->model;
//if (rsurface.entity == ent && (!model->surfmesh.isanimated || (!wantnormals && !wanttangents)))
// return;
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;
- newvertices = max(model->surfmesh.num_vertices, model->surfmesh.num_triangles);
- if (rsurface.array_size < newvertices)
- R_Mesh_ResizeArrays(newvertices);
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 newvertices;
-
rsurface.entity = r_refdef.scene.worldentity;
rsurface.skeleton = NULL;
rsurface.ent_skinnum = 0;
rsurface.ent_flags = entflags;
rsurface.modelnumvertices = numvertices;
rsurface.modelnumtriangles = numtriangles;
- newvertices = max(rsurface.modelnumvertices, rsurface.modelnumtriangles);
- if (rsurface.array_size < newvertices)
- R_Mesh_ResizeArrays(newvertices);
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);
}
}
}
int surfacefirstvertex;
int surfaceendvertex;
int surfacenumvertices;
+ 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;
}
// 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++)
surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
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)
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);
//vec3_t eyedir;
// fake 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)
{
f = -DotProduct(r_refdef.view.forward, n);
f = max(0, f);
f *= r_refdef.lightmapintensity;
Vector4Set(c, f, f, f, 1);
}
-
- rsurface.passcolor4f = rsurface.array_passcolor4f;
- rsurface.passcolor4f_vertexbuffer = 0;
- rsurface.passcolor4f_bufferoffset = 0;
}
static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
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_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]), 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;
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:
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)
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)
{
// 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)
{
// render the range of surfaces
R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, ent, prepass);
}
+ R_FrameData_ReturnToMark();
}
float locboxvertex3f[6*4*3] =
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;
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: