X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=r_shadow.c;h=d4cf86b71b7152fc24c51d10ff6cf030fda0f669;hb=8603a48360a8ad27c781778f2a727dff178ceb82;hp=c5d14ec2cd44ad597a221691aded0cb272b9647c;hpb=b641cdf4343692743e15b2427f183a92890e118f;p=xonotic%2Fdarkplaces.git diff --git a/r_shadow.c b/r_shadow.c index c5d14ec2..d4cf86b7 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -146,7 +146,7 @@ demonstrated by the game Doom3. extern LPDIRECT3DDEVICE9 vid_d3d9dev; #endif -extern void R_Shadow_EditLights_Init(void); +static void R_Shadow_EditLights_Init(void); typedef enum r_shadow_rendermode_e { @@ -196,6 +196,7 @@ int r_shadow_shadowmapdepthbits; int r_shadow_shadowmapmaxsize; qboolean r_shadow_shadowmapvsdct; qboolean r_shadow_shadowmapsampler; +qboolean r_shadow_shadowmapshadowsampler; int r_shadow_shadowmappcf; int r_shadow_shadowmapborder; matrix4x4_t r_shadow_shadowmapmatrix; @@ -244,8 +245,8 @@ rtexture_t *r_shadow_attenuationgradienttexture; rtexture_t *r_shadow_attenuation2dtexture; rtexture_t *r_shadow_attenuation3dtexture; skinframe_t *r_shadow_lightcorona; -rtexture_t *r_shadow_shadowmap2dtexture; -rtexture_t *r_shadow_shadowmap2dcolortexture; +rtexture_t *r_shadow_shadowmap2ddepthbuffer; +rtexture_t *r_shadow_shadowmap2ddepthtexture; rtexture_t *r_shadow_shadowmapvsdcttexture; int r_shadow_shadowmapsize; // changes for each light based on distance int r_shadow_shadowmaplod; // changes for each light based on distance @@ -255,8 +256,7 @@ GLuint r_shadow_prepasslightingdiffusespecularfbo; GLuint r_shadow_prepasslightingdiffusefbo; int r_shadow_prepass_width; int r_shadow_prepass_height; -rtexture_t *r_shadow_prepassgeometrydepthtexture; -rtexture_t *r_shadow_prepassgeometrydepthcolortexture; +rtexture_t *r_shadow_prepassgeometrydepthbuffer; rtexture_t *r_shadow_prepassgeometrynormalmaptexture; rtexture_t *r_shadow_prepasslightingdiffusetexture; rtexture_t *r_shadow_prepasslightingspeculartexture; @@ -272,16 +272,10 @@ char r_shadow_mapname[MAX_QPATH]; // used only for light filters (cubemaps) rtexturepool_t *r_shadow_filters_texturepool; -#ifndef USE_GLES2 -static const GLenum r_shadow_prepasslightingdrawbuffers[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; -#endif - cvar_t r_shadow_bumpscale_basetexture = {0, "r_shadow_bumpscale_basetexture", "0", "generate fake bumpmaps from diffuse textures at this bumpyness, try 4 to match tenebrae, higher values increase depth, requires r_restart to take effect"}; cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4", "what magnitude to interpret _bump.tga textures as, higher values increase depth, requires r_restart to take effect"}; cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1", "renders only one light, for level design purposes or debugging"}; cvar_t r_shadow_deferred = {CVAR_SAVE, "r_shadow_deferred", "0", "uses image-based lighting instead of geometry-based lighting, the method used renders a depth image and a normalmap image, renders lights into separate diffuse and specular images, and then combines this into the normal rendering, requires r_shadow_shadowmapping"}; -cvar_t r_shadow_deferred_8bitrange = {CVAR_SAVE, "r_shadow_deferred_8bitrange", "4", "dynamic range of image-based lighting when using 32bit color (does not apply to fp)"}; -//cvar_t r_shadow_deferred_fp = {CVAR_SAVE, "r_shadow_deferred_fp", "0", "use 16bit (1) or 32bit (2) floating point for accumulation of image-based lighting"}; cvar_t r_shadow_usebihculling = {0, "r_shadow_usebihculling", "1", "use BIH (Bounding Interval Hierarchy) for culling lit surfaces instead of BSP (Binary Space Partitioning)"}; cvar_t r_shadow_usenormalmap = {CVAR_SAVE, "r_shadow_usenormalmap", "1", "enables use of directional shading on lights"}; cvar_t r_shadow_gloss = {CVAR_SAVE, "r_shadow_gloss", "1", "0 disables gloss (specularity) rendering, 1 uses gloss if textures are found, 2 forces a flat metallic specular effect on everything without textures (similar to tenebrae)"}; @@ -310,6 +304,7 @@ cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_wor cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1", "use scissor optimization of light rendering (restricts rendering to the portion of the screen affected by the light)"}; cvar_t r_shadow_shadowmapping = {CVAR_SAVE, "r_shadow_shadowmapping", "1", "enables use of shadowmapping (depth texture sampling) instead of stencil shadow volumes, requires gl_fbo 1"}; cvar_t r_shadow_shadowmapping_filterquality = {CVAR_SAVE, "r_shadow_shadowmapping_filterquality", "-1", "shadowmap filter modes: -1 = auto-select, 0 = no filtering, 1 = bilinear, 2 = bilinear 2x2 blur (fast), 3 = 3x3 blur (moderate), 4 = 4x4 blur (slow)"}; +cvar_t r_shadow_shadowmapping_useshadowsampler = {CVAR_SAVE, "r_shadow_shadowmapping_useshadowsampler", "1", "whether to use sampler2DShadow if available"}; cvar_t r_shadow_shadowmapping_depthbits = {CVAR_SAVE, "r_shadow_shadowmapping_depthbits", "24", "requested minimum shadowmap texture depth bits"}; cvar_t r_shadow_shadowmapping_vsdct = {CVAR_SAVE, "r_shadow_shadowmapping_vsdct", "1", "enables use of virtual shadow depth cube texture"}; cvar_t r_shadow_shadowmapping_minsize = {CVAR_SAVE, "r_shadow_shadowmapping_minsize", "32", "shadowmap size limit"}; @@ -361,6 +356,22 @@ cvar_t r_editlights_cursorpushback = {0, "r_editlights_cursorpushback", "0", "ho cvar_t r_editlights_cursorpushoff = {0, "r_editlights_cursorpushoff", "4", "how far to push the cursor off the impacted surface"}; cvar_t r_editlights_cursorgrid = {0, "r_editlights_cursorgrid", "4", "snaps cursor to this grid size"}; cvar_t r_editlights_quakelightsizescale = {CVAR_SAVE, "r_editlights_quakelightsizescale", "1", "changes size of light entities loaded from a map"}; +cvar_t r_editlights_drawproperties = {0, "r_editlights_drawproperties", "1", "draw properties of currently selected light"}; +cvar_t r_editlights_current_origin = {0, "r_editlights_current_origin", "0 0 0", "origin of selected light"}; +cvar_t r_editlights_current_angles = {0, "r_editlights_current_angles", "0 0 0", "angles of selected light"}; +cvar_t r_editlights_current_color = {0, "r_editlights_current_color", "1 1 1", "color of selected light"}; +cvar_t r_editlights_current_radius = {0, "r_editlights_current_radius", "0", "radius of selected light"}; +cvar_t r_editlights_current_corona = {0, "r_editlights_current_corona", "0", "corona intensity of selected light"}; +cvar_t r_editlights_current_coronasize = {0, "r_editlights_current_coronasize", "0", "corona size of selected light"}; +cvar_t r_editlights_current_style = {0, "r_editlights_current_style", "0", "style of selected light"}; +cvar_t r_editlights_current_shadows = {0, "r_editlights_current_shadows", "0", "shadows flag of selected light"}; +cvar_t r_editlights_current_cubemap = {0, "r_editlights_current_cubemap", "0", "cubemap of selected light"}; +cvar_t r_editlights_current_ambient = {0, "r_editlights_current_ambient", "0", "ambient intensity of selected light"}; +cvar_t r_editlights_current_diffuse = {0, "r_editlights_current_diffuse", "1", "diffuse intensity of selected light"}; +cvar_t r_editlights_current_specular = {0, "r_editlights_current_specular", "1", "specular intensity of selected light"}; +cvar_t r_editlights_current_normalmode = {0, "r_editlights_current_normalmode", "0", "normalmode flag of selected light"}; +cvar_t r_editlights_current_realtimemode = {0, "r_editlights_current_realtimemode", "0", "realtimemode flag of selected light"}; + typedef struct r_shadow_bouncegrid_settings_s { @@ -429,11 +440,12 @@ skinframe_t *r_editlights_sprcubemaplight; skinframe_t *r_editlights_sprcubemapnoshadowlight; skinframe_t *r_editlights_sprselection; -void R_Shadow_SetShadowMode(void) +static void R_Shadow_SetShadowMode(void) { r_shadow_shadowmapmaxsize = bound(1, r_shadow_shadowmapping_maxsize.integer, (int)vid.maxtexturesize_2d / 4); r_shadow_shadowmapvsdct = r_shadow_shadowmapping_vsdct.integer != 0 && vid.renderpath == RENDERPATH_GL20; r_shadow_shadowmapfilterquality = r_shadow_shadowmapping_filterquality.integer; + r_shadow_shadowmapshadowsampler = r_shadow_shadowmapping_useshadowsampler.integer != 0; r_shadow_shadowmapdepthbits = r_shadow_shadowmapping_depthbits.integer; r_shadow_shadowmapborder = bound(0, r_shadow_shadowmapping_bordersize.integer, 16); r_shadow_shadowmaplod = -1; @@ -448,27 +460,29 @@ void R_Shadow_SetShadowMode(void) case RENDERPATH_GL20: if(r_shadow_shadowmapfilterquality < 0) { - if(vid.support.amd_texture_texture4 || vid.support.arb_texture_gather) + if (!r_fb.usedepthtextures) + r_shadow_shadowmappcf = 1; + else if(vid.support.amd_texture_texture4 || vid.support.arb_texture_gather) r_shadow_shadowmappcf = 1; else if(strstr(gl_vendor, "NVIDIA") || strstr(gl_renderer, "Radeon HD")) { - r_shadow_shadowmapsampler = vid.support.arb_shadow; + r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler; r_shadow_shadowmappcf = 1; } - else if(strstr(gl_vendor, "ATI")) + else if((strstr(gl_vendor, "ATI") || strstr(gl_vendor, "Advanced Micro Devices")) && !strstr(gl_renderer, "Mesa") && !strstr(gl_version, "Mesa")) r_shadow_shadowmappcf = 1; else - r_shadow_shadowmapsampler = vid.support.arb_shadow; + r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler; } else { switch (r_shadow_shadowmapfilterquality) { case 1: - r_shadow_shadowmapsampler = vid.support.arb_shadow; + r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler; break; case 2: - r_shadow_shadowmapsampler = vid.support.arb_shadow; + r_shadow_shadowmapsampler = vid.support.arb_shadow && r_shadow_shadowmapshadowsampler; r_shadow_shadowmappcf = 1; break; case 3: @@ -479,6 +493,8 @@ void R_Shadow_SetShadowMode(void) break; } } + if (!r_fb.usedepthtextures) + r_shadow_shadowmapsampler = false; r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D; break; case RENDERPATH_D3D9: @@ -496,6 +512,9 @@ void R_Shadow_SetShadowMode(void) break; } } + + if(R_CompileShader_CheckStaticParms()) + R_GLSL_Restart_f(); } qboolean R_Shadow_ShadowMappingEnabled(void) @@ -509,7 +528,7 @@ qboolean R_Shadow_ShadowMappingEnabled(void) } } -void R_Shadow_FreeShadowMaps(void) +static void R_Shadow_FreeShadowMaps(void) { R_Shadow_SetShadowMode(); @@ -517,20 +536,20 @@ void R_Shadow_FreeShadowMaps(void) r_shadow_fbo2d = 0; - if (r_shadow_shadowmap2dtexture) - R_FreeTexture(r_shadow_shadowmap2dtexture); - r_shadow_shadowmap2dtexture = NULL; + if (r_shadow_shadowmap2ddepthtexture) + R_FreeTexture(r_shadow_shadowmap2ddepthtexture); + r_shadow_shadowmap2ddepthtexture = NULL; - if (r_shadow_shadowmap2dcolortexture) - R_FreeTexture(r_shadow_shadowmap2dcolortexture); - r_shadow_shadowmap2dcolortexture = NULL; + if (r_shadow_shadowmap2ddepthbuffer) + R_FreeTexture(r_shadow_shadowmap2ddepthbuffer); + r_shadow_shadowmap2ddepthbuffer = NULL; if (r_shadow_shadowmapvsdcttexture) R_FreeTexture(r_shadow_shadowmapvsdcttexture); r_shadow_shadowmapvsdcttexture = NULL; } -void r_shadow_start(void) +static void r_shadow_start(void) { // allocate vertex processing arrays r_shadow_bouncegridpixels = NULL; @@ -542,8 +561,8 @@ void r_shadow_start(void) r_shadow_attenuation2dtexture = NULL; r_shadow_attenuation3dtexture = NULL; r_shadow_shadowmode = R_SHADOW_SHADOWMODE_STENCIL; - r_shadow_shadowmap2dtexture = NULL; - r_shadow_shadowmap2dcolortexture = NULL; + r_shadow_shadowmap2ddepthtexture = NULL; + r_shadow_shadowmap2ddepthbuffer = NULL; r_shadow_shadowmapvsdcttexture = NULL; r_shadow_shadowmapmaxsize = 0; r_shadow_shadowmapsize = 0; @@ -596,7 +615,7 @@ void r_shadow_start(void) } static void R_Shadow_FreeDeferred(void); -void r_shadow_shutdown(void) +static void r_shadow_shutdown(void) { CHECKGLERROR R_Shadow_UncompileWorldLights(); @@ -679,7 +698,7 @@ void r_shadow_shutdown(void) Mem_Free(r_shadow_buffer_lighttrispvs); } -void r_shadow_newmap(void) +static void r_shadow_newmap(void) { if (r_shadow_bouncegridtexture) R_FreeTexture(r_shadow_bouncegridtexture);r_shadow_bouncegridtexture = NULL; if (r_shadow_lightcorona) R_SkinFrame_MarkUsed(r_shadow_lightcorona); @@ -701,8 +720,6 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_shadow_usenormalmap); Cvar_RegisterVariable(&r_shadow_debuglight); Cvar_RegisterVariable(&r_shadow_deferred); - Cvar_RegisterVariable(&r_shadow_deferred_8bitrange); -// Cvar_RegisterVariable(&r_shadow_deferred_fp); Cvar_RegisterVariable(&r_shadow_gloss); Cvar_RegisterVariable(&r_shadow_gloss2intensity); Cvar_RegisterVariable(&r_shadow_glossintensity); @@ -730,6 +747,7 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_shadow_shadowmapping); Cvar_RegisterVariable(&r_shadow_shadowmapping_vsdct); Cvar_RegisterVariable(&r_shadow_shadowmapping_filterquality); + Cvar_RegisterVariable(&r_shadow_shadowmapping_useshadowsampler); Cvar_RegisterVariable(&r_shadow_shadowmapping_depthbits); Cvar_RegisterVariable(&r_shadow_shadowmapping_precision); Cvar_RegisterVariable(&r_shadow_shadowmapping_maxsize); @@ -826,7 +844,7 @@ matrix4x4_t matrix_attenuationz = } }; -void R_Shadow_ResizeShadowArrays(int numvertices, int numtriangles, int vertscale, int triscale) +static void R_Shadow_ResizeShadowArrays(int numvertices, int numtriangles, int vertscale, int triscale) { numvertices = ((numvertices + 255) & ~255) * vertscale; numtriangles = ((numtriangles + 255) & ~255) * triscale; @@ -1301,7 +1319,7 @@ void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *inv } } -qboolean R_Shadow_UseZPass(vec3_t mins, vec3_t maxs) +static qboolean R_Shadow_UseZPass(vec3_t mins, vec3_t maxs) { #if 1 return false; @@ -1456,7 +1474,7 @@ int R_Shadow_CalcTriangleSideMask(const vec3_t p1, const vec3_t p2, const vec3_t return mask; } -int R_Shadow_CalcBBoxSideMask(const vec3_t mins, const vec3_t maxs, const matrix4x4_t *worldtolight, const matrix4x4_t *radiustolight, float bias) +static int R_Shadow_CalcBBoxSideMask(const vec3_t mins, const vec3_t maxs, const matrix4x4_t *worldtolight, const matrix4x4_t *radiustolight, float bias) { vec3_t center, radius, lightcenter, lightradius, pmin, pmax; float dp1, dn1, ap1, an1, dp2, dn2, ap2, an2; @@ -1525,18 +1543,19 @@ int R_Shadow_CalcSphereSideMask(const vec3_t p, float radius, float bias) return mask; } -int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border) +static int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border) { int i; - vec3_t p, n; + vec3_t o, p, n; int sides = 0x3F, masks[6] = { 3<<4, 3<<4, 3<<0, 3<<0, 3<<2, 3<<2 }; float scale = (size - 2*border)/size, len; float bias = border / (float)(size - border), dp, dn, ap, an; // check if cone enclosing side would cross frustum plane scale = 2 / (scale*scale + 2); + Matrix4x4_OriginFromMatrix(&rtlight->matrix_lighttoworld, o); for (i = 0;i < 5;i++) { - if (PlaneDiff(rtlight->shadoworigin, &r_refdef.view.frustum[i]) > -0.03125) + if (PlaneDiff(o, &r_refdef.view.frustum[i]) > -0.03125) continue; Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[i].normal, n); len = scale*VectorLength2(n); @@ -1544,10 +1563,10 @@ int R_Shadow_CullFrustumSides(rtlight_t *rtlight, float size, float border) if(n[1]*n[1] > len) sides &= n[1] < 0 ? ~(1<<2) : ~(2 << 2); if(n[2]*n[2] > len) sides &= n[2] < 0 ? ~(1<<4) : ~(2 << 4); } - if (PlaneDiff(rtlight->shadoworigin, &r_refdef.view.frustum[4]) >= r_refdef.farclip - r_refdef.nearclip + 0.03125) + if (PlaneDiff(o, &r_refdef.view.frustum[4]) >= r_refdef.farclip - r_refdef.nearclip + 0.03125) { Matrix4x4_Transform3x3(&rtlight->matrix_worldtolight, r_refdef.view.frustum[4].normal, n); - len = scale*VectorLength(n); + len = scale*VectorLength2(n); if(n[0]*n[0] > len) sides &= n[0] >= 0 ? ~(1<<0) : ~(2 << 0); if(n[1]*n[1] > len) sides &= n[1] >= 0 ? ~(1<<2) : ~(2 << 2); if(n[2]*n[2] > len) sides &= n[2] >= 0 ? ~(1<<4) : ~(2 << 4); @@ -2035,7 +2054,7 @@ void R_Shadow_RenderMode_Reset(void) GL_Color(1, 1, 1, 1); GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1); GL_BlendFunc(GL_ONE, GL_ZERO); - R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false, false); + R_SetupShader_Generic_NoTexture(false, false); r_shadow_usingshadowmap2d = false; r_shadow_usingshadowmaportho = false; R_SetStencil(false, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_ALWAYS, 128, 255); @@ -2057,7 +2076,7 @@ void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass) GL_ColorMask(0, 0, 0, 0); GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR GL_CullFace(GL_NONE); - R_SetupShader_DepthOrShadow(false); + R_SetupShader_DepthOrShadow(false, false); r_shadow_rendermode = mode; switch(mode) { @@ -2099,46 +2118,26 @@ static void R_Shadow_MakeShadowMap(int side, int size) switch (r_shadow_shadowmode) { case R_SHADOW_SHADOWMODE_SHADOWMAP2D: - if (r_shadow_shadowmap2dtexture) return; - r_shadow_shadowmap2dtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), r_shadow_shadowmapdepthbits, r_shadow_shadowmapsampler); - r_shadow_shadowmap2dcolortexture = NULL; - switch(vid.renderpath) + if (r_shadow_shadowmap2ddepthtexture) return; + if (r_fb.usedepthtextures) { -#ifdef SUPPORTD3D - case RENDERPATH_D3D9: - r_shadow_shadowmap2dcolortexture = R_LoadTexture2D(r_shadow_texturepool, "shadowmaprendertarget", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), NULL, TEXTYPE_BGRA, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL); - r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2dtexture, r_shadow_shadowmap2dcolortexture, NULL, NULL, NULL); - break; -#endif - default: - r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2dtexture, NULL, NULL, NULL, NULL); - break; + r_shadow_shadowmap2ddepthtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), r_shadow_shadowmapdepthbits >= 24 ? (r_shadow_shadowmapsampler ? TEXTYPE_SHADOWMAP24_COMP : TEXTYPE_SHADOWMAP24_RAW) : (r_shadow_shadowmapsampler ? TEXTYPE_SHADOWMAP16_COMP : TEXTYPE_SHADOWMAP16_RAW), r_shadow_shadowmapsampler); + r_shadow_shadowmap2ddepthbuffer = NULL; + r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL); + } + else + { + r_shadow_shadowmap2ddepthtexture = R_LoadTexture2D(r_shadow_texturepool, "shadowmaprendertarget", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL); + r_shadow_shadowmap2ddepthbuffer = R_LoadTextureRenderBuffer(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), r_shadow_shadowmapdepthbits >= 24 ? TEXTYPE_DEPTHBUFFER24 : TEXTYPE_DEPTHBUFFER16); + r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL); } break; default: return; } - -#ifndef USE_GLES2 - // render depth into the fbo, do not render color at all - // validate the fbo now - if (qglDrawBuffer) - { - int status; - qglDrawBuffer(GL_NONE);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE && (r_shadow_shadowmapping.integer || r_shadow_deferred.integer)) - { - Con_Printf("R_Shadow_MakeShadowMap: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_shadowmapping, 0); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - } - } -#endif } -void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size) +static void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size) { float nearclip, farclip, bias; r_viewport_t viewport; @@ -2161,17 +2160,20 @@ void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size) // complex unrolled cube approach (more flexible) if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapvsdcttexture) R_Shadow_MakeVSDCT(); - if (!r_shadow_shadowmap2dtexture) + if (!r_shadow_shadowmap2ddepthtexture) R_Shadow_MakeShadowMap(side, r_shadow_shadowmapmaxsize); - if (r_shadow_shadowmap2dtexture) fbo2d = r_shadow_fbo2d; - r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2dtexture); - r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2dtexture); + fbo2d = r_shadow_fbo2d; + r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2ddepthtexture); + r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2ddepthtexture); r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D; R_Mesh_ResetTextureState(); R_Shadow_RenderMode_Reset(); - R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2dtexture, r_shadow_shadowmap2dcolortexture, NULL, NULL, NULL); - R_SetupShader_DepthOrShadow(true); + if (r_shadow_shadowmap2ddepthbuffer) + R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL); + else + R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL); + R_SetupShader_DepthOrShadow(true, r_shadow_shadowmap2ddepthbuffer != NULL); GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value); GL_DepthMask(true); GL_DepthTest(true); @@ -2181,6 +2183,17 @@ init_done: flipped = (side & 1) ^ (side >> 2); r_refdef.view.cullface_front = flipped ? r_shadow_cullface_back : r_shadow_cullface_front; r_refdef.view.cullface_back = flipped ? r_shadow_cullface_front : r_shadow_cullface_back; + if (r_shadow_shadowmap2ddepthbuffer) + { + // completely different meaning than in depthtexture approach + r_shadow_shadowmap_parameters[1] = 0; + r_shadow_shadowmap_parameters[3] = -bias; + } + Vector4Set(clearcolor, 1,1,1,1); + if (r_shadow_shadowmap2ddepthbuffer) + GL_ColorMask(1,1,1,1); + else + GL_ColorMask(0,0,0,0); switch(vid.renderpath) { case RENDERPATH_GL11: @@ -2199,33 +2212,30 @@ init_done: int y1 = clear & 0x03 ? 0 : (clear & 0xC ? size : 2 * size); int y2 = clear & 0x30 ? 3 * size : (clear & 0xC ? 2 * size : size); GL_Scissor(x1, y1, x2 - x1, y2 - y1); - GL_Clear(GL_DEPTH_BUFFER_BIT, NULL, 1.0f, 0); + if (clear) + { + if (r_shadow_shadowmap2ddepthbuffer) + GL_Clear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0); + else + GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); + } } GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height); break; case RENDERPATH_D3D9: case RENDERPATH_D3D10: case RENDERPATH_D3D11: - Vector4Set(clearcolor, 1,1,1,1); - // completely different meaning than in OpenGL path - r_shadow_shadowmap_parameters[1] = 0; - r_shadow_shadowmap_parameters[3] = -bias; // we invert the cull mode because we flip the projection matrix // NOTE: this actually does nothing because the DrawShadowMap code sets it to doublesided... GL_CullFace(r_refdef.view.cullface_front); // D3D considers it an error to use a scissor larger than the viewport... clear just this view GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height); - if (r_shadow_shadowmapsampler) + if (clear) { - GL_ColorMask(0,0,0,0); - if (clear) - GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); - } - else - { - GL_ColorMask(1,1,1,1); - if (clear) + if (r_shadow_shadowmap2ddepthbuffer) GL_Clear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0); + else + GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); } break; } @@ -2294,9 +2304,9 @@ void R_Shadow_RenderMode_DrawDeferredLight(qboolean stenciltest, qboolean shadow // stencil is 128 (values other than this mean shadow) R_SetStencil(stenciltest, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255); if (rsurface.rtlight->specularscale > 0 && r_shadow_gloss.integer > 0) - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); else - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); r_shadow_usingshadowmap2d = shadowmapping; @@ -2702,10 +2712,16 @@ void R_Shadow_UpdateBounceGridTexture(void) r_refdef.stats.bouncegrid_traces++; //r_refdef.scene.worldmodel->TraceLineAgainstSurfaces(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace, clipstart, clipend, hitsupercontentsmask); //r_refdef.scene.worldmodel->TraceLine(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace2, clipstart, clipend, hitsupercontentsmask); - //if (settings.staticmode) - // Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, true); - //else + if (settings.staticmode) + { + // static mode fires a LOT of rays but none of them are identical, so they are not cached cliptrace = CL_TraceLine(clipstart, clipend, settings.staticmode ? MOVE_WORLDONLY : (settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS), NULL, hitsupercontentsmask, true, false, NULL, true, true); + } + else + { + // dynamic mode fires many rays and most will match the cache from the previous frame + cliptrace = CL_Cache_TraceLineSurfaces(clipstart, clipend, settings.staticmode ? MOVE_WORLDONLY : (settings.hitmodels ? MOVE_HITMODEL : MOVE_NOMONSTERS), hitsupercontentsmask); + } if (bouncecount > 0 || settings.includedirectlighting) { // calculate second order spherical harmonics values (average, slopeX, slopeY, slopeZ) @@ -3175,8 +3191,8 @@ static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numve int *newe; const int *e; float *c; - int maxtriangles = 4096; - static int newelements[4096*3]; + int maxtriangles = 1024; + int newelements[1024*3]; R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, diffusecolor2, ambientcolor2); for (renders = 0;renders < 4;renders++) { @@ -3564,7 +3580,7 @@ void R_Shadow_UncompileWorldLights(void) } } -void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight) +static void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight) { int i, j; mplane_t plane; @@ -3733,7 +3749,7 @@ void R_Shadow_ComputeShadowCasterCullingPlanes(rtlight_t *rtlight) #endif } -void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist, const unsigned char *trispvs, const unsigned char *surfacesides) +static void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist, const unsigned char *trispvs, const unsigned char *surfacesides) { shadowmesh_t *mesh; @@ -3763,7 +3779,7 @@ void R_Shadow_DrawWorldShadow_ShadowMap(int numsurfaces, int *surfacelist, const rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity } -void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, const unsigned char *trispvs) +static void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, const unsigned char *trispvs) { qboolean zpass = false; shadowmesh_t *mesh; @@ -3838,7 +3854,7 @@ void R_Shadow_DrawWorldShadow_ShadowVolume(int numsurfaces, int *surfacelist, co rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity } -void R_Shadow_DrawEntityShadow(entity_render_t *ent) +static void R_Shadow_DrawEntityShadow(entity_render_t *ent) { vec3_t relativeshadoworigin, relativeshadowmins, relativeshadowmaxs; vec_t relativeshadowradius; @@ -3874,7 +3890,7 @@ void R_Shadow_SetupEntityLight(const entity_render_t *ent) Matrix4x4_Transform(&ent->inversematrix, rsurface.rtlight->shadoworigin, rsurface.entitylightorigin); } -void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned char *lighttrispvs) +static void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned char *lighttrispvs) { if (!r_refdef.scene.worldmodel->DrawLight) return; @@ -3891,7 +3907,7 @@ void R_Shadow_DrawWorldLight(int numsurfaces, int *surfacelist, const unsigned c rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity } -void R_Shadow_DrawEntityLight(entity_render_t *ent) +static void R_Shadow_DrawEntityLight(entity_render_t *ent) { dp_model_t *model = ent->model; if (!model->DrawLight) @@ -3904,7 +3920,7 @@ void R_Shadow_DrawEntityLight(entity_render_t *ent) rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity } -void R_Shadow_PrepareLight(rtlight_t *rtlight) +static void R_Shadow_PrepareLight(rtlight_t *rtlight) { int i; float f; @@ -3925,6 +3941,18 @@ void R_Shadow_PrepareLight(rtlight_t *rtlight) qboolean nolight; rtlight->draw = false; + rtlight->cached_numlightentities = 0; + rtlight->cached_numlightentities_noselfshadow = 0; + rtlight->cached_numshadowentities = 0; + rtlight->cached_numshadowentities_noselfshadow = 0; + rtlight->cached_numsurfaces = 0; + rtlight->cached_lightentities = NULL; + rtlight->cached_lightentities_noselfshadow = NULL; + rtlight->cached_shadowentities = NULL; + rtlight->cached_shadowentities_noselfshadow = NULL; + rtlight->cached_shadowtrispvs = NULL; + rtlight->cached_lighttrispvs = NULL; + rtlight->cached_surfacelist = NULL; // skip lights that don't light because of ambientscale+diffusescale+specularscale being 0 (corona only lights) // skip lights that are basically invisible (color 0 0 0) @@ -3972,6 +4000,10 @@ void R_Shadow_PrepareLight(rtlight_t *rtlight) R_Shadow_ComputeShadowCasterCullingPlanes(rtlight); + // don't allow lights to be drawn if using r_shadow_bouncegrid 2, except if we're using static bouncegrid where dynamic lights still need to draw + if (r_shadow_bouncegrid.integer == 2 && (rtlight->isstatic || !r_shadow_bouncegrid_static.integer)) + return; + if (rtlight->compiled && r_shadow_realtime_world_compile.integer) { // compiled light, world available and can receive realtime lighting @@ -4138,7 +4170,7 @@ void R_Shadow_PrepareLight(rtlight_t *rtlight) } } -void R_Shadow_DrawLight(rtlight_t *rtlight) +static void R_Shadow_DrawLight(rtlight_t *rtlight) { int i; int numsurfaces; @@ -4387,13 +4419,9 @@ static void R_Shadow_FreeDeferred(void) R_Mesh_DestroyFramebufferObject(r_shadow_prepasslightingdiffusefbo); r_shadow_prepasslightingdiffusefbo = 0; - if (r_shadow_prepassgeometrydepthtexture) - R_FreeTexture(r_shadow_prepassgeometrydepthtexture); - r_shadow_prepassgeometrydepthtexture = NULL; - - if (r_shadow_prepassgeometrydepthcolortexture) - R_FreeTexture(r_shadow_prepassgeometrydepthcolortexture); - r_shadow_prepassgeometrydepthcolortexture = NULL; + if (r_shadow_prepassgeometrydepthbuffer) + R_FreeTexture(r_shadow_prepassgeometrydepthbuffer); + r_shadow_prepassgeometrydepthbuffer = NULL; if (r_shadow_prepassgeometrynormalmaptexture) R_FreeTexture(r_shadow_prepassgeometrynormalmaptexture); @@ -4425,7 +4453,7 @@ void R_Shadow_DrawPrepass(void) GL_BlendFunc(GL_ONE, GL_ZERO); GL_Color(1,1,1,1); GL_DepthTest(true); - R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepassgeometrynormalmaptexture, r_shadow_prepassgeometrydepthcolortexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); Vector4Set(clearcolor, 0.5f,0.5f,0.5f,1.0f); GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); if (r_timereport_active) @@ -4452,7 +4480,7 @@ void R_Shadow_DrawPrepass(void) GL_ColorMask(1,1,1,1); GL_Color(1,1,1,1); GL_DepthTest(true); - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); Vector4Set(clearcolor, 0, 0, 0, 0); GL_Clear(GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0); if (r_timereport_active) @@ -4498,12 +4526,12 @@ void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *color dlight_t *light; size_t range; float f; - GLenum status; if (r_shadow_shadowmapmaxsize != bound(1, r_shadow_shadowmapping_maxsize.integer, (int)vid.maxtexturesize_2d / 4) || (r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL) != (r_shadow_shadowmapping.integer || r_shadow_deferred.integer) || r_shadow_shadowmapvsdct != (r_shadow_shadowmapping_vsdct.integer != 0 && vid.renderpath == RENDERPATH_GL20) || r_shadow_shadowmapfilterquality != r_shadow_shadowmapping_filterquality.integer || + r_shadow_shadowmapshadowsampler != (vid.support.arb_shadow && r_shadow_shadowmapping_useshadowsampler.integer) || r_shadow_shadowmapdepthbits != r_shadow_shadowmapping_depthbits.integer || r_shadow_shadowmapborder != bound(0, r_shadow_shadowmapping_bordersize.integer, 16)) R_Shadow_FreeShadowMaps(); @@ -4538,73 +4566,29 @@ void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *color r_shadow_usingdeferredprepass = true; r_shadow_prepass_width = vid.width; r_shadow_prepass_height = vid.height; - r_shadow_prepassgeometrydepthtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "prepassgeometrydepthmap", vid.width, vid.height, 24, false); - switch (vid.renderpath) - { - case RENDERPATH_D3D9: - r_shadow_prepassgeometrydepthcolortexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrydepthcolormap", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); - break; - default: - break; - } - r_shadow_prepassgeometrynormalmaptexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrynormalmap", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); - r_shadow_prepasslightingdiffusetexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingdiffuse", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); - r_shadow_prepasslightingspeculartexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingspecular", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); + r_shadow_prepassgeometrydepthbuffer = R_LoadTextureRenderBuffer(r_shadow_texturepool, "prepassgeometrydepthbuffer", vid.width, vid.height, TEXTYPE_DEPTHBUFFER24); + r_shadow_prepassgeometrynormalmaptexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrynormalmap", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER32F, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); + r_shadow_prepasslightingdiffusetexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingdiffuse", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER16F, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); + r_shadow_prepasslightingspeculartexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingspecular", vid.width, vid.height, NULL, TEXTYPE_COLORBUFFER16F, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); // set up the geometry pass fbo (depth + normalmap) - r_shadow_prepassgeometryfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthtexture, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); - R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepassgeometrynormalmaptexture, r_shadow_prepassgeometrydepthcolortexture, NULL, NULL); - // render depth into one texture and normalmap into the other - if (qglDrawBuffersARB) - { - qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE) - { - Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - r_shadow_usingdeferredprepass = false; - } - } + r_shadow_prepassgeometryfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthbuffer, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); + // render depth into a renderbuffer and other important properties into the normalmap texture // set up the lighting pass fbo (diffuse + specular) - r_shadow_prepasslightingdiffusespecularfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + r_shadow_prepasslightingdiffusespecularfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); // render diffuse into one texture and specular into another, // with depth and normalmap bound as textures, // with depth bound as attachment as well - if (qglDrawBuffersARB) - { - qglDrawBuffersARB(2, r_shadow_prepasslightingdrawbuffers);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE) - { - Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - r_shadow_usingdeferredprepass = false; - } - } // set up the lighting pass fbo (diffuse) - r_shadow_prepasslightingdiffusefbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); + r_shadow_prepasslightingdiffusefbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); // render diffuse into one texture, // with depth and normalmap bound as textures, // with depth bound as attachment as well - if (qglDrawBuffersARB) - { - qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE) - { - Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - r_shadow_usingdeferredprepass = false; - } - } } #endif break; @@ -4619,25 +4603,22 @@ void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *color R_Shadow_EnlargeLeafSurfaceTrisBuffer(r_refdef.scene.worldmodel->brush.num_leafs, r_refdef.scene.worldmodel->num_surfaces, r_refdef.scene.worldmodel->brush.shadowmesh ? r_refdef.scene.worldmodel->brush.shadowmesh->numtriangles : r_refdef.scene.worldmodel->surfmesh.num_triangles, r_refdef.scene.worldmodel->surfmesh.num_triangles); flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE; - if (r_shadow_bouncegrid.integer != 2) + if (r_shadow_debuglight.integer >= 0) { - if (r_shadow_debuglight.integer >= 0) + lightindex = r_shadow_debuglight.integer; + light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); + if (light) + R_Shadow_PrepareLight(&light->rtlight); + } + else + { + range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked + for (lightindex = 0;lightindex < range;lightindex++) { - lightindex = r_shadow_debuglight.integer; light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); - if (light) + if (light && (light->flags & flag)) R_Shadow_PrepareLight(&light->rtlight); } - else - { - range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked - for (lightindex = 0;lightindex < range;lightindex++) - { - light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); - if (light && (light->flags & flag)) - R_Shadow_PrepareLight(&light->rtlight); - } - } } if (r_refdef.scene.rtdlight) { @@ -4668,26 +4649,23 @@ void R_Shadow_DrawLights(void) R_Shadow_RenderMode_Begin(); - if (r_shadow_bouncegrid.integer != 2) + flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE; + if (r_shadow_debuglight.integer >= 0) { - flag = r_refdef.scene.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE; - if (r_shadow_debuglight.integer >= 0) + lightindex = r_shadow_debuglight.integer; + light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); + if (light) + R_Shadow_DrawLight(&light->rtlight); + } + else + { + range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked + for (lightindex = 0;lightindex < range;lightindex++) { - lightindex = r_shadow_debuglight.integer; light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); - if (light) + if (light && (light->flags & flag)) R_Shadow_DrawLight(&light->rtlight); } - else - { - range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray); // checked - for (lightindex = 0;lightindex < range;lightindex++) - { - light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); - if (light && (light->flags & flag)) - R_Shadow_DrawLight(&light->rtlight); - } - } } if (r_refdef.scene.rtdlight) for (lnum = 0;lnum < r_refdef.scene.numlights;lnum++) @@ -4700,6 +4678,7 @@ void R_Shadow_PrepareModelShadows(void) { int i; float scale, size, radius, dot1, dot2; + prvm_vec3_t prvmshadowdir, prvmshadowfocus; vec3_t shadowdir, shadowforward, shadowright, shadoworigin, shadowfocus, shadowmins, shadowmaxs; entity_render_t *ent; @@ -4728,7 +4707,8 @@ void R_Shadow_PrepareModelShadows(void) scale = r_shadow_shadowmapping_precision.value * r_shadows_shadowmapscale.value; radius = 0.5f * size / scale; - Math_atov(r_shadows_throwdirection.string, shadowdir); + Math_atov(r_shadows_throwdirection.string, prvmshadowdir); + VectorCopy(prvmshadowdir, shadowdir); VectorNormalize(shadowdir); dot1 = DotProduct(r_refdef.view.forward, shadowdir); dot2 = DotProduct(r_refdef.view.up, shadowdir); @@ -4738,7 +4718,8 @@ void R_Shadow_PrepareModelShadows(void) VectorMA(r_refdef.view.up, -dot2, shadowdir, shadowforward); VectorNormalize(shadowforward); CrossProduct(shadowdir, shadowforward, shadowright); - Math_atov(r_shadows_focus.string, shadowfocus); + Math_atov(r_shadows_focus.string, prvmshadowfocus); + VectorCopy(prvmshadowfocus, shadowfocus); VectorM(shadowfocus[0], r_refdef.view.right, shadoworigin); VectorMA(shadoworigin, shadowfocus[1], r_refdef.view.up, shadoworigin); VectorMA(shadoworigin, -shadowfocus[2], r_refdef.view.forward, shadoworigin); @@ -4774,10 +4755,11 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort vec3_t relativelightdirection, relativeforward, relativeright; vec3_t relativeshadowmins, relativeshadowmaxs; vec3_t shadowdir, shadowforward, shadowright, shadoworigin, shadowfocus; + prvm_vec3_t prvmshadowdir, prvmshadowfocus; float m[12]; matrix4x4_t shadowmatrix, cameramatrix, mvpmatrix, invmvpmatrix, scalematrix, texmatrix; r_viewport_t viewport; - GLuint fbo2d = 0; + GLuint shadowfbo = 0; float clearcolor[4]; if (!r_refdef.scene.numentities) @@ -4802,11 +4784,11 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort switch (r_shadow_shadowmode) { case R_SHADOW_SHADOWMODE_SHADOWMAP2D: - if (!r_shadow_shadowmap2dtexture) + if (!r_shadow_shadowmap2ddepthtexture) R_Shadow_MakeShadowMap(0, r_shadow_shadowmapmaxsize); - fbo = r_shadow_fbo2d; - r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2dtexture); - r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2dtexture); + shadowfbo = r_shadow_fbo2d; + r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2ddepthtexture); + r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2ddepthtexture); r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D; break; default: @@ -4825,9 +4807,11 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort r_shadow_shadowmap_parameters[2] = 1.0; r_shadow_shadowmap_parameters[3] = bound(0.0f, 1.0f - r_shadows_darken.value, 1.0f); - Math_atov(r_shadows_throwdirection.string, shadowdir); + Math_atov(r_shadows_throwdirection.string, prvmshadowdir); + VectorCopy(prvmshadowdir, shadowdir); VectorNormalize(shadowdir); - Math_atov(r_shadows_focus.string, shadowfocus); + Math_atov(r_shadows_focus.string, prvmshadowfocus); + VectorCopy(prvmshadowfocus, shadowfocus); VectorM(shadowfocus[0], r_refdef.view.right, shadoworigin); VectorMA(shadoworigin, shadowfocus[1], r_refdef.view.up, shadoworigin); VectorMA(shadoworigin, -shadowfocus[2], r_refdef.view.forward, shadoworigin); @@ -4854,8 +4838,11 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort VectorMA(shadoworigin, (1.0f - fabs(dot1)) * radius, shadowforward, shadoworigin); - R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2dtexture, r_shadow_shadowmap2dcolortexture, NULL, NULL, NULL); - R_SetupShader_DepthOrShadow(true); + if (r_shadow_shadowmap2ddepthbuffer) + R_Mesh_SetRenderTargets(shadowfbo, r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL); + else + R_Mesh_SetRenderTargets(shadowfbo, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL); + R_SetupShader_DepthOrShadow(true, r_shadow_shadowmap2ddepthbuffer != NULL); GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value); GL_DepthMask(true); GL_DepthTest(true); @@ -4864,7 +4851,7 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort Vector4Set(clearcolor, 1,1,1,1); // in D3D9 we have to render to a color texture shadowmap // in GL we render directly to a depth texture only - if (r_shadow_shadowmap2dtexture) + if (r_shadow_shadowmap2ddepthbuffer) GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); else GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); @@ -4973,6 +4960,7 @@ void R_DrawModelShadows(int fbo, rtexture_t *depthtexture, rtexture_t *colortext vec3_t relativelightdirection; vec3_t relativeshadowmins, relativeshadowmaxs; vec3_t tmp, shadowdir; + prvm_vec3_t prvmshadowdir; if (!r_refdef.scene.numentities || !vid.stencil || (r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL && r_shadows.integer != 1)) return; @@ -4995,7 +4983,8 @@ void R_DrawModelShadows(int fbo, rtexture_t *depthtexture, rtexture_t *colortext // get shadow dir if (r_shadows.integer == 2) { - Math_atov(r_shadows_throwdirection.string, shadowdir); + Math_atov(r_shadows_throwdirection.string, prvmshadowdir); + VectorCopy(prvmshadowdir, shadowdir); VectorNormalize(shadowdir); } @@ -5081,7 +5070,7 @@ void R_DrawModelShadows(int fbo, rtexture_t *depthtexture, rtexture_t *colortext // apply the blend to the shadowed areas R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL); - R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false, true); + R_SetupShader_Generic_NoTexture(false, true); R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); // restore the viewport @@ -5091,7 +5080,7 @@ void R_DrawModelShadows(int fbo, rtexture_t *depthtexture, rtexture_t *colortext //R_Shadow_RenderMode_End(); } -void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery) +static void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery) { float zdist; vec3_t centerorigin; @@ -5153,7 +5142,7 @@ void R_BeginCoronaQuery(rtlight_t *rtlight, float scale, qboolean usequery) static float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1}; -void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale) +static void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale) { vec3_t color; GLint allpixels = 0, visiblepixels = 0; @@ -5268,7 +5257,7 @@ void R_Shadow_DrawCoronas(void) GL_PolygonOffset(0, 0); GL_DepthTest(true); R_Mesh_ResetTextureState(); - R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, false, false); + R_SetupShader_Generic_NoTexture(false, false); } #endif break; @@ -5344,12 +5333,12 @@ void R_Shadow_DrawCoronas(void) -dlight_t *R_Shadow_NewWorldLight(void) +static dlight_t *R_Shadow_NewWorldLight(void) { return (dlight_t *)Mem_ExpandableArray_AllocRecord(&r_shadow_worldlightsarray); } -void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags) +static void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, vec3_t color, vec_t radius, vec_t corona, int style, int shadowenable, const char *cubemapname, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags) { matrix4x4_t matrix; // validate parameters @@ -5390,7 +5379,7 @@ void R_Shadow_UpdateWorldLight(dlight_t *light, vec3_t origin, vec3_t angles, ve R_RTLight_Update(&light->rtlight, true, &matrix, light->color, light->style, light->cubemapname[0] ? light->cubemapname : NULL, light->shadow, light->corona, light->coronasizescale, light->ambientscale, light->diffusescale, light->specularscale, light->flags); } -void R_Shadow_FreeWorldLight(dlight_t *light) +static void R_Shadow_FreeWorldLight(dlight_t *light) { if (r_shadow_selectedlight == light) r_shadow_selectedlight = NULL; @@ -5412,7 +5401,7 @@ void R_Shadow_ClearWorldLights(void) r_shadow_selectedlight = NULL; } -void R_Shadow_SelectLight(dlight_t *light) +static void R_Shadow_SelectLight(dlight_t *light) { if (r_shadow_selectedlight) r_shadow_selectedlight->selected = false; @@ -5421,7 +5410,7 @@ void R_Shadow_SelectLight(dlight_t *light) r_shadow_selectedlight->selected = true; } -void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) +static void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) { // this is never batched (there can be only one) float vertex3f[12]; @@ -5430,7 +5419,7 @@ void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const r R_DrawCustomSurface(r_editlights_sprcursor, &identitymatrix, MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOCULLFACE, 0, 4, 0, 2, false, false); } -void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) +static void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) { float intensity; float s; @@ -5483,10 +5472,10 @@ void R_Shadow_DrawLightSprites(void) { light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex); if (light) - R_MeshQueue_AddTransparent(light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, light->origin, R_Shadow_DrawLightSprite_TransparentCallback, (entity_render_t *)light, 5, &light->rtlight); } if (!r_editlights_lockcursor) - R_MeshQueue_AddTransparent(r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL); } int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color) @@ -5509,7 +5498,7 @@ int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radiu return 1; } -void R_Shadow_SelectLightInView(void) +static void R_Shadow_SelectLightInView(void) { float bestrating, rating, temp[3]; dlight_t *best; @@ -5559,8 +5548,8 @@ void R_Shadow_LoadWorldLights(void) n = 0; while (*s) { - t = s; /* + t = s; shadow = true; for (;COM_Parse(t, true) && strcmp( if (COM_Parse(t, true)) @@ -5764,6 +5753,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) const char *data; float origin[3], angles[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], vec[4]; char key[256], value[MAX_INPUTLINE]; + char vabuf[1024]; if (cl.worldmodel == NULL) { @@ -5778,7 +5768,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) data = cl.worldmodel->brush.entities; if (!data) return; - for (entnum = 0;COM_ParseToken_Simple(&data, false, false) && com_token[0] == '{';entnum++) + for (entnum = 0;COM_ParseToken_Simple(&data, false, false, true) && com_token[0] == '{';entnum++) { type = LIGHTTYPE_MINUSX; origin[0] = origin[1] = origin[2] = 0; @@ -5796,7 +5786,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) islight = false; while (1) { - if (!COM_ParseToken_Simple(&data, false, false)) + if (!COM_ParseToken_Simple(&data, false, false, true)) break; // error if (com_token[0] == '}') break; // end of entity @@ -5806,7 +5796,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) strlcpy(key, com_token, sizeof(key)); while (key[strlen(key)-1] == ' ') // remove trailing spaces key[strlen(key)-1] = 0; - if (!COM_ParseToken_Simple(&data, false, false)) + if (!COM_ParseToken_Simple(&data, false, false, true)) break; // error strlcpy(value, com_token, sizeof(value)); @@ -5967,14 +5957,14 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) } VectorAdd(origin, originhack, origin); if (radius >= 1) - R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), origin, angles, color, radius, (pflags & PFLAGS_CORONA) != 0, style, (pflags & PFLAGS_NOSHADOW) == 0, skin >= 16 ? va("cubemaps/%i", skin) : NULL, 0.25, 0, 1, 1, LIGHTFLAG_REALTIMEMODE); + R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), origin, angles, color, radius, (pflags & PFLAGS_CORONA) != 0, style, (pflags & PFLAGS_NOSHADOW) == 0, skin >= 16 ? va(vabuf, sizeof(vabuf), "cubemaps/%i", skin) : NULL, 0.25, 0, 1, 1, LIGHTFLAG_REALTIMEMODE); } if (entfiledata) Mem_Free(entfiledata); } -void R_Shadow_SetCursorLocationForView(void) +static void R_Shadow_SetCursorLocationForView(void) { vec_t dist, push; vec3_t dest, endpos; @@ -6011,7 +6001,7 @@ void R_Shadow_UpdateWorldLightSelection(void) R_Shadow_SelectLight(NULL); } -void R_Shadow_EditLights_Clear_f(void) +static void R_Shadow_EditLights_Clear_f(void) { R_Shadow_ClearWorldLights(); } @@ -6031,26 +6021,26 @@ void R_Shadow_EditLights_Reload_f(void) } } -void R_Shadow_EditLights_Save_f(void) +static void R_Shadow_EditLights_Save_f(void) { if (!cl.worldmodel) return; R_Shadow_SaveWorldLights(); } -void R_Shadow_EditLights_ImportLightEntitiesFromMap_f(void) +static void R_Shadow_EditLights_ImportLightEntitiesFromMap_f(void) { R_Shadow_ClearWorldLights(); R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(); } -void R_Shadow_EditLights_ImportLightsFile_f(void) +static void R_Shadow_EditLights_ImportLightsFile_f(void) { R_Shadow_ClearWorldLights(); R_Shadow_LoadLightsFile(); } -void R_Shadow_EditLights_Spawn_f(void) +static void R_Shadow_EditLights_Spawn_f(void) { vec3_t color; if (!r_editlights.integer) @@ -6067,7 +6057,7 @@ void R_Shadow_EditLights_Spawn_f(void) R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), r_editlights_cursorlocation, vec3_origin, color, 200, 0, 0, true, NULL, 0.25, 0, 1, 1, LIGHTFLAG_REALTIMEMODE); } -void R_Shadow_EditLights_Edit_f(void) +static void R_Shadow_EditLights_Edit_f(void) { vec3_t origin, angles, color; vec_t radius, corona, coronasizescale, ambientscale, diffusescale, specularscale; @@ -6393,7 +6383,7 @@ void R_Shadow_EditLights_Edit_f(void) R_Shadow_UpdateWorldLight(r_shadow_selectedlight, origin, angles, color, radius, corona, style, shadows, cubemapname, coronasizescale, ambientscale, diffusescale, specularscale, flags); } -void R_Shadow_EditLights_EditAll_f(void) +static void R_Shadow_EditLights_EditAll_f(void) { size_t lightindex; dlight_t *light, *oldselected; @@ -6425,10 +6415,37 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void) int lightnumber, lightcount; size_t lightindex, range; dlight_t *light; - float x, y; char temp[256]; + float x, y; + if (!r_editlights.integer) return; + + // update cvars so QC can query them + if (r_shadow_selectedlight) + { + dpsnprintf(temp, sizeof(temp), "%f %f %f", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]); + Cvar_SetQuick(&r_editlights_current_origin, temp); + dpsnprintf(temp, sizeof(temp), "%f %f %f", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]); + Cvar_SetQuick(&r_editlights_current_angles, temp); + dpsnprintf(temp, sizeof(temp), "%f %f %f", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]); + Cvar_SetQuick(&r_editlights_current_color, temp); + Cvar_SetValueQuick(&r_editlights_current_radius, r_shadow_selectedlight->radius); + Cvar_SetValueQuick(&r_editlights_current_corona, r_shadow_selectedlight->corona); + Cvar_SetValueQuick(&r_editlights_current_coronasize, r_shadow_selectedlight->coronasizescale); + Cvar_SetValueQuick(&r_editlights_current_style, r_shadow_selectedlight->style); + Cvar_SetValueQuick(&r_editlights_current_shadows, r_shadow_selectedlight->shadow); + Cvar_SetQuick(&r_editlights_current_cubemap, r_shadow_selectedlight->cubemapname); + Cvar_SetValueQuick(&r_editlights_current_ambient, r_shadow_selectedlight->ambientscale); + Cvar_SetValueQuick(&r_editlights_current_diffuse, r_shadow_selectedlight->diffusescale); + Cvar_SetValueQuick(&r_editlights_current_specular, r_shadow_selectedlight->specularscale); + Cvar_SetValueQuick(&r_editlights_current_normalmode, (r_shadow_selectedlight->flags & LIGHTFLAG_NORMALMODE) ? 1 : 0); + Cvar_SetValueQuick(&r_editlights_current_realtimemode, (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? 1 : 0); + } + + // draw properties on screen + if (!r_editlights_drawproperties.integer) + return; x = vid_conwidth.value - 240; y = 5; DrawQ_Pic(x-5, y-5, NULL, 250, 155, 0, 0, 0, 0.75, 0); @@ -6466,7 +6483,7 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void) dpsnprintf(temp, sizeof(temp), "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);y += 8; } -void R_Shadow_EditLights_ToggleShadow_f(void) +static void R_Shadow_EditLights_ToggleShadow_f(void) { if (!r_editlights.integer) { @@ -6481,7 +6498,7 @@ void R_Shadow_EditLights_ToggleShadow_f(void) R_Shadow_UpdateWorldLight(r_shadow_selectedlight, r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, r_shadow_selectedlight->corona, r_shadow_selectedlight->style, !r_shadow_selectedlight->shadow, r_shadow_selectedlight->cubemapname, r_shadow_selectedlight->coronasizescale, r_shadow_selectedlight->ambientscale, r_shadow_selectedlight->diffusescale, r_shadow_selectedlight->specularscale, r_shadow_selectedlight->flags); } -void R_Shadow_EditLights_ToggleCorona_f(void) +static void R_Shadow_EditLights_ToggleCorona_f(void) { if (!r_editlights.integer) { @@ -6496,7 +6513,7 @@ void R_Shadow_EditLights_ToggleCorona_f(void) R_Shadow_UpdateWorldLight(r_shadow_selectedlight, r_shadow_selectedlight->origin, r_shadow_selectedlight->angles, r_shadow_selectedlight->color, r_shadow_selectedlight->radius, !r_shadow_selectedlight->corona, r_shadow_selectedlight->style, r_shadow_selectedlight->shadow, r_shadow_selectedlight->cubemapname, r_shadow_selectedlight->coronasizescale, r_shadow_selectedlight->ambientscale, r_shadow_selectedlight->diffusescale, r_shadow_selectedlight->specularscale, r_shadow_selectedlight->flags); } -void R_Shadow_EditLights_Remove_f(void) +static void R_Shadow_EditLights_Remove_f(void) { if (!r_editlights.integer) { @@ -6512,7 +6529,7 @@ void R_Shadow_EditLights_Remove_f(void) r_shadow_selectedlight = NULL; } -void R_Shadow_EditLights_Help_f(void) +static void R_Shadow_EditLights_Help_f(void) { Con_Print( "Documentation on r_editlights system:\n" @@ -6556,7 +6573,7 @@ void R_Shadow_EditLights_Help_f(void) "sizescale scale : multiply radius (size) of light (1 does nothing)\n" "originscale x y z : multiply origin of light (1 1 1 does nothing)\n" "style style : set lightstyle of light (flickering patterns, switches, etc)\n" -"cubemap basename : set filter cubemap of light (not yet supported)\n" +"cubemap basename : set filter cubemap of light\n" "shadows 1/0 : turn on/off shadows\n" "corona n : set corona intensity\n" "coronasize n : set corona size (0-1)\n" @@ -6569,7 +6586,7 @@ void R_Shadow_EditLights_Help_f(void) ); } -void R_Shadow_EditLights_CopyInfo_f(void) +static void R_Shadow_EditLights_CopyInfo_f(void) { if (!r_editlights.integer) { @@ -6598,7 +6615,7 @@ void R_Shadow_EditLights_CopyInfo_f(void) r_shadow_bufferlight.flags = r_shadow_selectedlight->flags; } -void R_Shadow_EditLights_PasteInfo_f(void) +static void R_Shadow_EditLights_PasteInfo_f(void) { if (!r_editlights.integer) { @@ -6613,7 +6630,7 @@ void R_Shadow_EditLights_PasteInfo_f(void) R_Shadow_UpdateWorldLight(r_shadow_selectedlight, r_shadow_selectedlight->origin, r_shadow_bufferlight.angles, r_shadow_bufferlight.color, r_shadow_bufferlight.radius, r_shadow_bufferlight.corona, r_shadow_bufferlight.style, r_shadow_bufferlight.shadow, r_shadow_bufferlight.cubemapname, r_shadow_bufferlight.coronasizescale, r_shadow_bufferlight.ambientscale, r_shadow_bufferlight.diffusescale, r_shadow_bufferlight.specularscale, r_shadow_bufferlight.flags); } -void R_Shadow_EditLights_Lock_f(void) +static void R_Shadow_EditLights_Lock_f(void) { if (!r_editlights.integer) { @@ -6633,7 +6650,7 @@ void R_Shadow_EditLights_Lock_f(void) r_editlights_lockcursor = true; } -void R_Shadow_EditLights_Init(void) +static void R_Shadow_EditLights_Init(void) { Cvar_RegisterVariable(&r_editlights); Cvar_RegisterVariable(&r_editlights_cursordistance); @@ -6641,6 +6658,21 @@ void R_Shadow_EditLights_Init(void) Cvar_RegisterVariable(&r_editlights_cursorpushoff); Cvar_RegisterVariable(&r_editlights_cursorgrid); Cvar_RegisterVariable(&r_editlights_quakelightsizescale); + Cvar_RegisterVariable(&r_editlights_drawproperties); + Cvar_RegisterVariable(&r_editlights_current_origin); + Cvar_RegisterVariable(&r_editlights_current_angles); + Cvar_RegisterVariable(&r_editlights_current_color); + Cvar_RegisterVariable(&r_editlights_current_radius); + Cvar_RegisterVariable(&r_editlights_current_corona); + Cvar_RegisterVariable(&r_editlights_current_coronasize); + Cvar_RegisterVariable(&r_editlights_current_style); + Cvar_RegisterVariable(&r_editlights_current_shadows); + Cvar_RegisterVariable(&r_editlights_current_cubemap); + Cvar_RegisterVariable(&r_editlights_current_ambient); + Cvar_RegisterVariable(&r_editlights_current_diffuse); + Cvar_RegisterVariable(&r_editlights_current_specular); + Cvar_RegisterVariable(&r_editlights_current_normalmode); + Cvar_RegisterVariable(&r_editlights_current_realtimemode); Cmd_AddCommand("r_editlights_help", R_Shadow_EditLights_Help_f, "prints documentation on console commands and variables in rtlight editing system"); Cmd_AddCommand("r_editlights_clear", R_Shadow_EditLights_Clear_f, "removes all world lights (let there be darkness!)"); Cmd_AddCommand("r_editlights_reload", R_Shadow_EditLights_Reload_f, "reloads rtlights file (or imports from .lights file or .ent file or the map itself)"); @@ -6668,7 +6700,7 @@ LIGHT SAMPLING ============================================================================= */ -void R_LightPoint(vec3_t color, const vec3_t p, const int flags) +void R_LightPoint(float *color, const vec3_t p, const int flags) { int i, numlights, flag; float f, relativepoint[3], dist, dist2, lightradius2;