From 488a91a0cdecad34bb37bd60ba3f2703166bb20f Mon Sep 17 00:00:00 2001 From: Richard Allen Date: Tue, 17 Sep 2013 22:28:18 +0000 Subject: [PATCH] Updating to ioquake3 dated 16 september 2013 --- code/cgame/cg_consolecmds.c | 4 +- code/cgame/cg_players.c | 2 +- code/client/cl_keys.c | 8 +- code/client/snd_openal.c | 16 +- code/q3_ui/ui_players.c | 2 +- code/renderercommon/qgl.h | 5 + code/renderergl1/tr_image.c | 5 + code/renderergl2/glsl/generic_fp.glsl | 4 +- code/renderergl2/glsl/lightall_fp.glsl | 520 ++++++++++++++----------- code/renderergl2/glsl/lightall_vp.glsl | 169 ++++---- code/renderergl2/tr_animation.c | 13 +- code/renderergl2/tr_backend.c | 122 +++--- code/renderergl2/tr_bsp.c | 281 +++++++++++-- code/renderergl2/tr_extensions.c | 50 ++- code/renderergl2/tr_fbo.c | 16 + code/renderergl2/tr_flares.c | 2 +- code/renderergl2/tr_glsl.c | 73 ++-- code/renderergl2/tr_image.c | 103 ++++- code/renderergl2/tr_init.c | 15 +- code/renderergl2/tr_light.c | 29 ++ code/renderergl2/tr_local.h | 69 +++- code/renderergl2/tr_main.c | 150 ++++++- code/renderergl2/tr_mesh.c | 5 +- code/renderergl2/tr_model_iqm.c | 9 +- code/renderergl2/tr_scene.c | 97 +++-- code/renderergl2/tr_shade.c | 47 +-- code/renderergl2/tr_shader.c | 96 ++++- code/renderergl2/tr_sky.c | 4 +- code/renderergl2/tr_surface.c | 8 +- code/renderergl2/tr_world.c | 2 +- code/sdl/sdl_glimp.c | 2 +- code/sdl/sdl_input.c | 2 +- code/sys/con_win32.c | 11 +- code/sys/sys_unix.c | 13 +- code/tools/lcc/lburg/gram.c | 511 ++++++++++++------------ code/ui/ui_players.c | 2 +- make-macosx-app.sh | 12 +- make-macosx-ub.sh | 7 - make-macosx.sh | 6 - 39 files changed, 1653 insertions(+), 839 deletions(-) diff --git a/code/cgame/cg_consolecmds.c b/code/cgame/cg_consolecmds.c index 1cd829c7..92f16566 100644 --- a/code/cgame/cg_consolecmds.c +++ b/code/cgame/cg_consolecmds.c @@ -134,12 +134,12 @@ void CG_TargetCommand_f(void) char test[4]; targetNum = CG_CrosshairPlayer(); - if (!targetNum) { + if ( targetNum == -1 ) { return; } trap_Argv(1, test, 4); - trap_SendConsoleCommand(va("gc %i %i", targetNum, atoi(test))); + trap_SendClientCommand( va( "gc %i %i", targetNum, atoi( test ) ) ); } /* diff --git a/code/cgame/cg_players.c b/code/cgame/cg_players.c index bff4687a..aeafcb5c 100644 --- a/code/cgame/cg_players.c +++ b/code/cgame/cg_players.c @@ -337,7 +337,7 @@ static qboolean CG_ParseAnimationFile(const char *filename, clientInfo_t * ci) text_p = prev; // unget the token break; } - Com_Printf("^1unknown token '%s' is %s\n", token, filename); + Com_Printf("^1unknown token '%s' in %s\n", token, filename); } // read information for each frame diff --git a/code/client/cl_keys.c b/code/client/cl_keys.c index 7d797199..ce90801d 100644 --- a/code/client/cl_keys.c +++ b/code/client/cl_keys.c @@ -992,7 +992,7 @@ void Key_Bind_f (void) if (c == 2) { - if (keys[b].binding) + if (keys[b].binding && keys[b].binding[0]) Com_Printf ("\"%s\" = \"%s\"\n", Key_KeynumToString(b), keys[b].binding ); else Com_Printf ("\"%s\" is not bound\n", Key_KeynumToString(b) ); @@ -1267,6 +1267,9 @@ void CL_KeyDownEvent( int key, unsigned time ) return; } + // send the bound action + CL_ParseBinding( key, qtrue, time ); + // distribute the key down event to the apropriate handler if ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) { Console_Key( key ); @@ -1283,9 +1286,6 @@ void CL_KeyDownEvent( int key, unsigned time ) } else if ( clc.state == CA_DISCONNECTED ) { Console_Key( key ); } - - // send the bound action - CL_ParseBinding( key, qtrue, time ); } /* diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index c4308f0f..c15d366a 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -2017,6 +2017,7 @@ static void S_AL_MusicSourceFree( void ) { // Release the output musicSource S_AL_SrcUnlock(musicSourceHandle); + S_AL_SrcKill(musicSourceHandle); musicSource = 0; musicSourceHandle = -1; } @@ -2049,17 +2050,22 @@ S_AL_StopBackgroundTrack static void S_AL_StopBackgroundTrack( void ) { + int numBuffers; + if(!musicPlaying) return; // Stop playing qalSourceStop(musicSource); - // De-queue the musicBuffers - qalSourceUnqueueBuffers(musicSource, NUM_MUSIC_BUFFERS, musicBuffers); - - // Destroy the musicBuffers - qalDeleteBuffers(NUM_MUSIC_BUFFERS, musicBuffers); + // Un-queue any buffers, and delete them + qalGetSourcei( musicSource, AL_BUFFERS_PROCESSED, &numBuffers ); + while( numBuffers-- ) + { + ALuint buffer; + qalSourceUnqueueBuffers(musicSource, 1, &buffer); + qalDeleteBuffers(1, &buffer); + } // Free the musicSource S_AL_MusicSourceFree(); diff --git a/code/q3_ui/ui_players.c b/code/q3_ui/ui_players.c index 40ee0c2c..1271abd7 100644 --- a/code/q3_ui/ui_players.c +++ b/code/q3_ui/ui_players.c @@ -1001,7 +1001,7 @@ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animat break; } - Com_Printf( "unknown token '%s' is %s\n", token, filename ); + Com_Printf( "unknown token '%s' in %s\n", token, filename ); } // read information for each frame diff --git a/code/renderercommon/qgl.h b/code/renderercommon/qgl.h index 9dc1b8c1..02045a49 100644 --- a/code/renderercommon/qgl.h +++ b/code/renderercommon/qgl.h @@ -721,6 +721,11 @@ extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs); #define GL_DEPTH_CLAMP 0x864F #endif +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#endif + #if defined(WIN32) // WGL_ARB_create_context #ifndef WGL_ARB_create_context diff --git a/code/renderergl1/tr_image.c b/code/renderergl1/tr_image.c index 14cf9890..921bf7d0 100644 --- a/code/renderergl1/tr_image.c +++ b/code/renderergl1/tr_image.c @@ -1602,6 +1602,11 @@ qhandle_t RE_RegisterSkin( const char *name ) { // parse the shader name token = CommaParse( &text_p ); + if ( skin->numSurfaces >= MD3_MAX_SURFACES ) { + ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MD3_MAX_SURFACES ); + break; + } + surf = skin->surfaces[ skin->numSurfaces ] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); Q_strncpyz( surf->name, surfName, sizeof( surf->name ) ); surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue ); diff --git a/code/renderergl2/glsl/generic_fp.glsl b/code/renderergl2/glsl/generic_fp.glsl index dea52e06..997d4daa 100644 --- a/code/renderergl2/glsl/generic_fp.glsl +++ b/code/renderergl2/glsl/generic_fp.glsl @@ -20,8 +20,8 @@ void main() vec4 color = texture2D(u_DiffuseMap, var_DiffuseTex); #if defined(USE_LIGHTMAP) vec4 color2 = texture2D(u_LightMap, var_LightTex); - #if defined(RGBE_LIGHTMAP) - color2.rgb *= exp2(color2.a * 255.0 - 128.0); + #if defined(RGBM_LIGHTMAP) + color2.rgb *= 32.0 * color2.a; color2.a = 1.0; #endif diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index 0b455dd6..6aec2b4a 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -20,14 +20,11 @@ uniform sampler2D u_SpecularMap; uniform sampler2D u_ShadowMap; #endif -uniform vec3 u_ViewOrigin; - -#if defined(USE_TCGEN) -uniform int u_TCGen0; +#if defined(USE_CUBEMAP) +uniform samplerCube u_CubeMap; #endif #if defined(USE_LIGHT_VECTOR) -uniform vec4 u_LightOrigin; uniform vec3 u_DirectedLight; uniform vec3 u_AmbientLight; uniform float u_LightRadius; @@ -39,7 +36,6 @@ uniform vec3 u_PrimaryLightAmbient; uniform float u_PrimaryLightRadius; #endif - #if defined(USE_LIGHT) uniform vec2 u_MaterialInfo; #endif @@ -50,43 +46,35 @@ varying vec2 var_LightTex; #endif varying vec4 var_Color; -#if defined(USE_NORMALMAP) && !defined(USE_VERT_TANGENT_SPACE) -varying vec3 var_Position; -#endif - -#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) -varying vec3 var_SampleToView; -#endif - -#if !defined(USE_FAST_LIGHT) +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) +varying vec3 var_ViewDir; varying vec3 var_Normal; -#endif - -#if defined(USE_VERT_TANGENT_SPACE) varying vec3 var_Tangent; varying vec3 var_Bitangent; #endif -varying vec3 var_VertLight; +#if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) +varying vec3 var_lightColor; +#endif #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) -varying vec3 var_LightDirection; +varying vec4 var_LightDir; #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) -varying vec3 var_PrimaryLightDirection; +varying vec3 var_PrimaryLightDir; #endif #define EPSILON 0.00000001 #if defined(USE_PARALLAXMAP) -float SampleHeight(sampler2D normalMap, vec2 t) +float SampleDepth(sampler2D normalMap, vec2 t) { #if defined(SWIZZLE_NORMALMAP) - return texture2D(normalMap, t).r; + return 1.0 - texture2D(normalMap, t).r; #else - return texture2D(normalMap, t).a; + return 1.0 - texture2D(normalMap, t).a; #endif } @@ -95,10 +83,8 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) const int linearSearchSteps = 16; const int binarySearchSteps = 6; - float depthStep = 1.0 / float(linearSearchSteps); - // current size of search window - float size = depthStep; + float size = 1.0 / float(linearSearchSteps); // current depth position float depth = 0.0; @@ -111,7 +97,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) { depth += size; - float t = 1.0 - SampleHeight(normalMap, dp + ds * depth); + float t = SampleDepth(normalMap, dp + ds * depth); if(bestDepth > 0.996) // if no depth found yet if(depth >= t) @@ -125,7 +111,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) { size *= 0.5; - float t = 1.0 - SampleHeight(normalMap, dp + ds * depth); + float t = SampleDepth(normalMap, dp + ds * depth); if(depth >= t) { @@ -157,7 +143,7 @@ vec3 CalcDiffuse(vec3 diffuseAlbedo, vec3 N, vec3 L, vec3 E, float NE, float NL, if (gamma >= 0.0) #endif { - B *= max(max(NL, NE), EPSILON); + B = max(B * max(NL, NE), EPSILON); } return diffuseAlbedo * (A + gamma / B); @@ -166,157 +152,218 @@ vec3 CalcDiffuse(vec3 diffuseAlbedo, vec3 N, vec3 L, vec3 E, float NE, float NL, #endif } -#if defined(USE_SPECULARMAP) -vec3 CalcSpecular(vec3 specularReflectance, float NH, float NL, float NE, float EH, float shininess) +vec3 EnvironmentBRDF(float gloss, float NE, vec3 specular) { - #if defined(USE_BLINN) || defined(USE_TRIACE) || defined(USE_TORRANCE_SPARROW) - float blinn = pow(NH, shininess); - #endif - - #if defined(USE_BLINN) - return specularReflectance * blinn; - #endif - - #if defined(USE_COOK_TORRANCE) || defined (USE_TRIACE) || defined (USE_TORRANCE_SPARROW) - vec3 fresnel = specularReflectance + (vec3(1.0) - specularReflectance) * pow(1.0 - EH, 5); - #endif - - #if defined(USE_COOK_TORRANCE) || defined(USE_TORRANCE_SPARROW) - float geo = 2.0 * NH * min(NE, NL); - geo /= max(EH, geo); - #endif - - #if defined(USE_COOK_TORRANCE) - float m_sq = 2.0 / max(shininess, EPSILON); - float NH_sq = NH * NH; - float m_NH_sq = m_sq * NH_sq; - float beckmann = exp((NH_sq - 1.0) / max(m_NH_sq, EPSILON)) / max(4.0 * m_NH_sq * NH_sq, EPSILON); - - return fresnel * geo * beckmann / max(NE, EPSILON); - #endif - - #if defined(USE_TRIACE) - float scale = 0.1248582 * shininess + 0.2691817; - - return fresnel * scale * blinn / max(max(NL, NE), EPSILON); - #endif - - #if defined(USE_TORRANCE_SPARROW) - float scale = 0.125 * shininess + 1.0; - - return fresnel * geo * scale * blinn / max(NE, EPSILON); + #if 1 + // from http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf + vec4 t = vec4( 1/0.96, 0.475, (0.0275 - 0.25 * 0.04)/0.96,0.25 ) * gloss; + t += vec4( 0.0, 0.0, (0.015 - 0.75 * 0.04)/0.96,0.75 ); + float a0 = t.x * min( t.y, exp2( -9.28 * NE ) ) + t.z; + float a1 = t.w; + return clamp( a0 + specular * ( a1 - a0 ), 0.0, 1.0 ); + #elif 0 + // from http://seblagarde.wordpress.com/2011/08/17/hello-world/ + return mix(specular.rgb, max(specular.rgb, vec3(gloss)), CalcFresnel(NE)); + #else + // from http://advances.realtimerendering.com/s2011/Lazarov-Physically-Based-Lighting-in-Black-Ops%20%28Siggraph%202011%20Advances%20in%20Real-Time%20Rendering%20Course%29.pptx + return mix(specular.rgb, vec3(1.0), CalcFresnel(NE) / (4.0 - 3.0 * gloss)); #endif } + +float CalcBlinn(float NH, float shininess) +{ +#if 0 + // from http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/ + float a = shininess + 0.775; + return exp(a * NH - a); +#else + return pow(NH, shininess); #endif +} + +float CalcGGX(float NH, float shininess) +{ + // from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf + float m_sq = 2.0 / shininess; + float d = ((NH * NH) * (m_sq - 1.0) + 1.0); + return m_sq / (d * d); +} + +float CalcFresnel(float EH) +{ +#if 1 + // From http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/ + return exp2((-5.55473 * EH - 6.98316) * EH); +#elif 0 + float blend = 1.0 - EH; + float blend2 = blend * blend; + blend *= blend2 * blend2; + + return blend; +#else + return pow(1.0 - NH, 5.0); +#endif +} + +float CalcVisibility(float NH, float NL, float NE, float EH, float shininess) +{ +#if 0 + float geo = 2.0 * NH * min(NE, NL); + geo /= max(EH, geo); + + return geo; +#else + // Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes.pdf + // NL, NE in numerator factored out from cook-torrance + #if defined(USE_GGX) + float roughness = sqrt(2.0 / (shininess + 2.0)); + float k = (roughness + 1.0); + k *= k * 0.125; + #else + float k = 2.0 / sqrt(3.1415926535 * (shininess + 2.0)); + #endif + float k2 = 1.0 - k; + + float invGeo1 = NL * k2 + k; + float invGeo2 = NE * k2 + k; + + return 1.0 / (invGeo1 * invGeo2); + #endif +} + + +vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float shininess) +{ + float blinn = CalcBlinn(NH, shininess); + vec3 fSpecular = mix(specular, vec3(1.0), CalcFresnel(EH)); + float vis = CalcVisibility(NH, NL, NE, EH, shininess); + + #if defined(USE_BLINN) + // Normalized Blinn-Phong + return specular * blinn * (shininess * 0.125 + 1.0); + #elif defined(USE_BLINN_FRESNEL) + // Normalized Blinn-Phong with Fresnel + return fSpecular * blinn * (shininess * 0.125 + 1.0); + #elif defined(USE_MCAULEY) + // Cook-Torrance as done by Stephen McAuley + // http://blog.selfshadow.com/publications/s2012-shading-course/mcauley/s2012_pbs_farcry3_notes_v2.pdf + return fSpecular * blinn * (shininess * 0.25 + 0.125); + #elif defined(USE_GOTANDA) + // Neumann-Neumann as done by Yoshiharu Gotanda + // http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf + return fSpecular * blinn * (shininess * 0.124858 + 0.269182) / max(max(NL, NE), EPSILON); + #elif defined(USE_LAZAROV) + // Cook-Torrance as done by Dimitar Lazarov + // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf + return fSpecular * blinn * (shininess * 0.125 + 0.25) * vis; + #endif + + return vec3(0.0); +} void main() { -#if !defined(USE_FAST_LIGHT) && (defined(USE_LIGHT) || defined(USE_NORMALMAP)) - vec3 surfN = normalize(var_Normal); + vec3 L, N, E, H; + float NL, NH, NE, EH; + +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + mat3 tangentToWorld = mat3(var_Tangent, var_Bitangent, var_Normal); #endif #if defined(USE_DELUXEMAP) - vec3 L = 2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0); - //L += var_LightDirection * 0.0001; -#elif defined(USE_LIGHT) - vec3 L = var_LightDirection; + L = (2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0)); + #if defined(USE_TANGENT_SPACE_LIGHT) + L = L * tangentToWorld; + #endif +#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + L = var_LightDir.xyz; +#endif + +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + E = normalize(var_ViewDir); #endif #if defined(USE_LIGHTMAP) vec4 lightSample = texture2D(u_LightMap, var_LightTex).rgba; - #if defined(RGBE_LIGHTMAP) - lightSample.rgb *= exp2(lightSample.a * 255.0 - 128.0); + #if defined(RGBM_LIGHTMAP) + lightSample.rgb *= 32.0 * lightSample.a; #endif vec3 lightColor = lightSample.rgb; #elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) - #if defined(USE_INVSQRLIGHT) - float intensity = 1.0 / dot(L, L); - #else - float intensity = clamp((1.0 - dot(L, L) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0); - #endif + // inverse square light + float attenuation = u_LightRadius * u_LightRadius / dot(L, L); + + // zero light at radius, approximating q3 style + attenuation = 0.5 * attenuation - 0.5; + //attenuation = 0.0697168 * attenuation; + //attenuation *= step(0.294117, attenuation); + + // clamp attenuation + #if defined(NO_LIGHT_CLAMP) + attenuation *= step(0.0, attenuation); + #else + attenuation = clamp(attenuation, 0.0, 1.0); + #endif + + // don't attenuate directional light + attenuation = (attenuation - 1.0) * var_LightDir.w + 1.0; - vec3 lightColor = u_DirectedLight * intensity; - vec3 ambientColor = u_AmbientLight; + vec3 lightColor = u_DirectedLight * attenuation; + vec3 ambientColor = u_AmbientLight; #elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - vec3 lightColor = var_VertLight; + vec3 lightColor = var_lightColor; #endif -#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) - vec3 E = normalize(var_SampleToView); -#endif vec2 texCoords = var_DiffuseTex; - float ambientDiff = 1.0; - -#if defined(USE_NORMALMAP) - #if defined(USE_VERT_TANGENT_SPACE) - mat3 tangentToWorld = mat3(var_Tangent, var_Bitangent, var_Normal); +#if defined(USE_PARALLAXMAP) + #if defined(USE_TANGENT_SPACE_LIGHT) + vec3 offsetDir = E; #else - vec3 q0 = dFdx(var_Position); - vec3 q1 = dFdy(var_Position); - vec2 st0 = dFdx(texCoords); - vec2 st1 = dFdy(texCoords); - float dir = sign(st1.t * st0.s - st0.t * st1.s); - - vec3 tangent = normalize(q0 * st1.t - q1 * st0.t) * dir; - vec3 bitangent = -normalize(q0 * st1.s - q1 * st0.s) * dir; - - mat3 tangentToWorld = mat3(tangent, bitangent, var_Normal); + vec3 offsetDir = E * tangentToWorld; #endif - #if defined(USE_PARALLAXMAP) - vec3 offsetDir = normalize(E * tangentToWorld); offsetDir.xy *= -0.05 / offsetDir.z; texCoords += offsetDir.xy * RayIntersectDisplaceMap(texCoords, offsetDir.xy, u_NormalMap); +#endif + + vec4 diffuse = texture2D(u_DiffuseMap, texCoords); + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) + + #if defined(USE_LINEAR_LIGHT) + diffuse.rgb *= diffuse.rgb; #endif - vec3 texN; - #if defined(SWIZZLE_NORMALMAP) - texN.xy = 2.0 * texture2D(u_NormalMap, texCoords).ag - 1.0; + + #if defined(USE_NORMALMAP) + #if defined(SWIZZLE_NORMALMAP) + N.xy = 2.0 * texture2D(u_NormalMap, texCoords).ag - vec2(1.0); + #else + N.xy = 2.0 * texture2D(u_NormalMap, texCoords).rg - vec2(1.0); + #endif + N.z = sqrt(1.0 - clamp(dot(N.xy, N.xy), 0.0, 1.0)); + #if !defined(USE_TANGENT_SPACE_LIGHT) + N = normalize(tangentToWorld * N); + #endif + #elif defined(USE_TANGENT_SPACE_LIGHT) + N = vec3(0.0, 0.0, 1.0); #else - texN.xy = 2.0 * texture2D(u_NormalMap, texCoords).rg - 1.0; + N = normalize(var_Normal); #endif - texN.z = sqrt(clamp(1.0 - dot(texN.xy, texN.xy), 0.0, 1.0)); - vec3 N = tangentToWorld * texN; - #if defined(r_normalAmbient) - ambientDiff = 0.781341 * texN.z + 0.218659; - #endif -#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) - vec3 N = surfN; -#endif - -#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || (defined(USE_TCGEN) && defined(USE_NORMALMAP)) - N = normalize(N); -#endif - -#if defined(USE_TCGEN) && defined(USE_NORMALMAP) - if (u_TCGen0 == TCGEN_ENVIRONMENT_MAPPED) - { - texCoords = -reflect(E, N).yz * vec2(0.5, -0.5) + 0.5; - } -#endif - - vec4 diffuseAlbedo = texture2D(u_DiffuseMap, texCoords); -#if defined(USE_LIGHT) && defined(USE_GAMMA2_TEXTURES) - diffuseAlbedo.rgb *= diffuseAlbedo.rgb; -#endif - -#if defined(USE_LIGHT) && defined(USE_FAST_LIGHT) - gl_FragColor = diffuse.rgb; - #if defined(USE_LIGHTMAP) - gl_FragColor *= lightColor; - #endif -#elif defined(USE_LIGHT) + L = normalize(L); - float surfNL = clamp(dot(surfN, L), 0.0, 1.0); - #if defined(USE_SHADOWMAP) vec2 shadowTex = gl_FragCoord.xy * r_FBufScale; float shadowValue = texture2D(u_ShadowMap, shadowTex).r; // surfaces not facing the light are always shadowed - shadowValue *= step(0.0, dot(surfN, var_PrimaryLightDirection)); + #if defined(USE_TANGENT_SPACE_LIGHT) + shadowValue *= step(0.0, var_PrimaryLightDir.z); + #else + shadowValue *= step(0.0, dot(var_Normal, var_PrimaryLightDir)); + #endif #if defined(SHADOWMAP_MODULATE) //vec3 shadowColor = min(u_PrimaryLightAmbient, lightColor); @@ -324,106 +371,141 @@ void main() #if 0 // Only shadow when the world light is parallel to the primary light - shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDirection), 0.0, 1.0); + shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir), 0.0, 1.0); #endif lightColor = mix(shadowColor, lightColor, shadowValue); #endif #endif #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX) - #if defined(USE_STANDARD_DELUXEMAP) - // Standard deluxe mapping treats the light sample as fully directed - // and doesn't compensate for light angle attenuation. - vec3 ambientColor = vec3(0.0); - #else - // Separate the light sample into directed and ambient parts. - // - // ambientMax - if the cosine of the angle between the surface - // normal and the light is below this value, the light - // is fully ambient. - // directedMax - if the cosine of the angle between the surface - // normal and the light is above this value, the light - // is fully directed. - const float ambientMax = 0.25; - const float directedMax = 0.5; - - float directedScale = clamp((surfNL - ambientMax) / (directedMax - ambientMax), 0.0, 1.0); - - // Scale the directed portion to compensate for the baked-in - // light angle attenuation. - directedScale /= max(surfNL, ambientMax); - - #if defined(r_normalAmbient) - directedScale *= 1.0 - r_normalAmbient; - #endif - - // Recover any unused light as ambient vec3 ambientColor = lightColor; - lightColor *= directedScale; + + #if defined(USE_TANGENT_SPACE_LIGHT) + float surfNL = L.z; + #else + float surfNL = clamp(dot(var_Normal, L), 0.0, 1.0); + #endif + + // Scale the incoming light to compensate for the baked-in light angle + // attenuation. + lightColor /= max(surfNL, 0.25); + + // Recover any unused light as ambient, in case attenuation is over 4x or + // light is below the surface ambientColor -= lightColor * surfNL; - #endif #endif + + vec3 reflectance; - float NL = clamp(dot(N, L), 0.0, 1.0); - float NE = clamp(dot(N, E), 0.0, 1.0); - - float maxReflectance = u_MaterialInfo.x; - float shininess = u_MaterialInfo.y; + NL = clamp(dot(N, L), 0.0, 1.0); + NE = clamp(dot(N, E), 0.0, 1.0); #if defined(USE_SPECULARMAP) - vec4 specularReflectance = texture2D(u_SpecularMap, texCoords); - specularReflectance.rgb *= maxReflectance; - shininess *= specularReflectance.a; - // adjust diffuse by specular reflectance, to maintain energy conservation - diffuseAlbedo.rgb *= vec3(1.0) - specularReflectance.rgb; + vec4 specular = texture2D(u_SpecularMap, texCoords); + #if defined(USE_LINEAR_LIGHT) + specular.rgb *= specular.rgb; + #endif + #else + vec4 specular = vec4(1.0); + #endif + + specular *= u_MaterialInfo.xxxy; + + float gloss = specular.a; + float shininess = exp2(gloss * 13.0); + float localOcclusion = clamp((diffuse.r + diffuse.g + diffuse.b) * 16.0f, 0.0, 1.0); + + #if defined(SPECULAR_IS_METALLIC) + // diffuse is actually base color, and red of specular is metallicness + float metallic = specular.r; + + specular.rgb = vec3(0.04) + 0.96 * diffuse.rgb * metallic; + diffuse.rgb *= 1.0 - metallic; + #else + // adjust diffuse by specular reflectance, to maintain energy conservation + diffuse.rgb *= vec3(1.0) - specular.rgb; + #endif + + + reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess); + + #if defined(r_deluxeSpecular) || defined(USE_LIGHT_VECTOR) + float adjShininess = shininess; + + #if !defined(USE_LIGHT_VECTOR) + adjShininess = exp2(gloss * r_deluxeSpecular * 13.0); + #endif + + H = normalize(L + E); + + EH = clamp(dot(E, H), 0.0, 1.0); + NH = clamp(dot(N, H), 0.0, 1.0); + + #if !defined(USE_LIGHT_VECTOR) + reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * r_deluxeSpecular * localOcclusion; + #else + reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjShininess) * localOcclusion; + #endif + #endif + + gl_FragColor.rgb = lightColor * reflectance * NL; + gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb); + + #if defined(USE_CUBEMAP) + reflectance = EnvironmentBRDF(gloss, NE, specular.rgb); + + vec3 R = reflect(E, N); + #if defined(USE_TANGENT_SPACE_LIGHT) + R = tangentToWorld * R; + #endif + + vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb; + + #if defined(USE_LINEAR_LIGHT) + cubeLightColor *= cubeLightColor; + #endif + + #if defined(USE_LIGHTMAP) + cubeLightColor *= lightSample.rgb; + #elif defined (USE_LIGHT_VERTEX) + cubeLightColor *= var_lightColor; + #else + cubeLightColor *= lightColor * NL + ambientColor; + #endif + + //gl_FragColor.rgb += diffuse.rgb * textureCubeLod(u_CubeMap, N, 7.0).rgb; + gl_FragColor.rgb += cubeLightColor * reflectance * localOcclusion; #endif - gl_FragColor.rgb = lightColor * NL * CalcDiffuse(diffuseAlbedo.rgb, N, L, E, NE, NL, shininess); - gl_FragColor.rgb += ambientDiff * ambientColor * diffuseAlbedo.rgb; #if defined(USE_PRIMARY_LIGHT) - vec3 L2 = var_PrimaryLightDirection; - float NL2 = clamp(dot(N, L2), 0.0, 1.0); + L = normalize(var_PrimaryLightDir); + NL = clamp(dot(N, L), 0.0, 1.0); + + H = normalize(L + E); + EH = clamp(dot(E, H), 0.0, 1.0); + NH = clamp(dot(N, H), 0.0, 1.0); + + reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess); + reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, shininess); #if defined(USE_SHADOWMAP) - gl_FragColor.rgb += u_PrimaryLightColor * shadowValue * NL2 * CalcDiffuse(diffuseAlbedo.rgb, N, L2, E, NE, NL2, shininess); - #else - gl_FragColor.rgb += u_PrimaryLightColor * NL2 * CalcDiffuse(diffuseAlbedo.rgb, N, L2, E, NE, NL2, shininess); + reflectance *= shadowValue; #endif + + gl_FragColor.rgb += u_PrimaryLightColor * reflectance * NL; #endif - #if defined(USE_SPECULARMAP) - vec3 H = normalize(L + E); + #if defined(USE_LINEAR_LIGHT) + gl_FragColor.rgb = sqrt(gl_FragColor.rgb); + #endif - float EH = clamp(dot(E, H), 0.0, 1.0); - float NH = clamp(dot(N, H), 0.0, 1.0); - - gl_FragColor.rgb += lightColor * NL * CalcSpecular(specularReflectance.rgb, NH, NL, NE, EH, shininess); - - #if defined(r_normalAmbient) - vec3 ambientHalf = normalize(surfN + E); - float ambientSpec = max(dot(ambientHalf, N) + 0.5, 0.0); - ambientSpec *= ambientSpec * 0.44; - gl_FragColor.rgb += specularReflectance.rgb * ambientSpec * ambientColor; - #endif - - #if defined(USE_PRIMARY_LIGHT) - vec3 H2 = normalize(L2 + E); - float EH2 = clamp(dot(E, H2), 0.0, 1.0); - float NH2 = clamp(dot(N, H2), 0.0, 1.0); - - - #if defined(USE_SHADOWMAP) - gl_FragColor.rgb += u_PrimaryLightColor * shadowValue * NL2 * CalcSpecular(specularReflectance.rgb, NH2, NL2, NE, EH2, shininess); - #else - gl_FragColor.rgb += u_PrimaryLightColor * NL2 * CalcSpecular(specularReflectance.rgb, NH2, NL2, NE, EH2, shininess); - #endif - #endif - #endif + gl_FragColor.a = diffuse.a; #else - gl_FragColor.rgb = diffuseAlbedo.rgb; + gl_FragColor = diffuse; + #if defined(USE_LIGHTMAP) + gl_FragColor.rgb *= lightColor; + #endif #endif - gl_FragColor.a = diffuseAlbedo.a; - gl_FragColor *= var_Color; } diff --git a/code/renderergl2/glsl/lightall_vp.glsl b/code/renderergl2/glsl/lightall_vp.glsl index 03775caf..d2bfb395 100644 --- a/code/renderergl2/glsl/lightall_vp.glsl +++ b/code/renderergl2/glsl/lightall_vp.glsl @@ -4,21 +4,16 @@ attribute vec4 attr_TexCoord1; #endif attribute vec4 attr_Color; -attribute vec4 attr_Position; +attribute vec3 attr_Position; attribute vec3 attr_Normal; - -#if defined(USE_VERT_TANGENT_SPACE) attribute vec3 attr_Tangent; attribute vec3 attr_Bitangent; -#endif #if defined(USE_VERTEX_ANIMATION) -attribute vec4 attr_Position2; +attribute vec3 attr_Position2; attribute vec3 attr_Normal2; - #if defined(USE_VERT_TANGENT_SPACE) attribute vec3 attr_Tangent2; attribute vec3 attr_Bitangent2; - #endif #endif #if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR) @@ -71,35 +66,28 @@ varying vec2 var_DiffuseTex; varying vec2 var_LightTex; #endif -#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) -varying vec3 var_SampleToView; +#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) +varying vec3 var_ViewDir; #endif varying vec4 var_Color; -#if defined(USE_NORMALMAP) && !defined(USE_VERT_TANGENT_SPACE) -varying vec3 var_Position; -#endif - - -#if !defined(USE_FAST_LIGHT) +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) varying vec3 var_Normal; - #if defined(USE_VERT_TANGENT_SPACE) varying vec3 var_Tangent; varying vec3 var_Bitangent; - #endif #endif #if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) -varying vec3 var_VertLight; +varying vec3 var_lightColor; #endif #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) -varying vec3 var_LightDirection; +varying vec4 var_LightDir; #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) -varying vec3 var_PrimaryLightDirection; +varying vec3 var_PrimaryLightDir; #endif #if defined(USE_TCGEN) @@ -132,7 +120,7 @@ vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb) float phase = offTurb.w; vec2 st2 = vec2(dot(st, texMatrix.xz), dot(st, texMatrix.yw)) + offTurb.xy; - vec3 offsetPos = vec3(0); //position / 1024.0; + vec3 offsetPos = position * 0.0009765625; offsetPos.x += offsetPos.z; vec2 texOffset = sin((offsetPos.xy + vec2(phase)) * 2.0 * M_PI); @@ -145,83 +133,53 @@ vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb) void main() { #if defined(USE_VERTEX_ANIMATION) - vec4 position = mix(attr_Position, attr_Position2, u_VertexLerp); + vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp); vec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp)); - #if defined(USE_VERT_TANGENT_SPACE) vec3 tangent = normalize(mix(attr_Tangent, attr_Tangent2, u_VertexLerp)); vec3 bitangent = normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexLerp)); - #endif #else - vec4 position = attr_Position; + vec3 position = attr_Position; vec3 normal = attr_Normal; - #if defined(USE_VERT_TANGENT_SPACE) vec3 tangent = attr_Tangent; vec3 bitangent = attr_Bitangent; - #endif -#endif - - gl_Position = u_ModelViewProjectionMatrix * position; - -#if (defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) - vec3 L = attr_LightDirection; -#endif - -#if defined(USE_MODELMATRIX) - position = u_ModelMatrix * position; - normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz; - #if defined(USE_VERT_TANGENT_SPACE) - tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; - bitangent = (u_ModelMatrix * vec4(bitangent, 0.0)).xyz; - #endif - - #if defined(USE_LIGHTMAP) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) - L = (u_ModelMatrix * vec4(L, 0.0)).xyz; - #endif -#endif - -#if defined(USE_NORMALMAP) && !defined(USE_VERT_TANGENT_SPACE) - var_Position = position.xyz; -#endif - -#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) - var_SampleToView = u_ViewOrigin - position.xyz; #endif #if defined(USE_TCGEN) - vec2 texCoords = GenTexCoords(u_TCGen0, position.xyz, normal, u_TCGen0Vector0, u_TCGen0Vector1); + vec2 texCoords = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1); #else vec2 texCoords = attr_TexCoord0.st; #endif #if defined(USE_TCMOD) - var_DiffuseTex = ModTexCoords(texCoords, position.xyz, u_DiffuseTexMatrix, u_DiffuseTexOffTurb); + var_DiffuseTex = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb); #else var_DiffuseTex = texCoords; #endif + gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0); + +#if defined(USE_MODELMATRIX) + position = (u_ModelMatrix * vec4(position, 1.0)).xyz; + normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz; + tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; + bitangent = (u_ModelMatrix * vec4(bitangent, 0.0)).xyz; +#endif + +#if defined(USE_LIGHT_VECTOR) + vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w); +#elif defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR) + vec3 L = attr_LightDirection; + #if defined(USE_MODELMATRIX) + L = (u_ModelMatrix * vec4(L, 0.0)).xyz; + #endif +#endif + #if defined(USE_LIGHTMAP) var_LightTex = attr_TexCoord1.st; #endif - -#if !defined(USE_FAST_LIGHT) - var_Normal = normal; - #if defined(USE_VERT_TANGENT_SPACE) - var_Tangent = tangent; - var_Bitangent = bitangent; - #endif -#endif - -#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) - #if defined(USE_LIGHT_VECTOR) - vec3 L = u_LightOrigin.xyz - (position.xyz * u_LightOrigin.w); - #endif - #if !defined(USE_FAST_LIGHT) - var_LightDirection = L; - #endif -#endif #if defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) - var_VertLight = u_VertColor.rgb * attr_Color.rgb; + var_lightColor = u_VertColor.rgb * attr_Color.rgb; var_Color.rgb = vec3(1.0); var_Color.a = u_VertColor.a * attr_Color.a + u_BaseColor.a; #else @@ -229,17 +187,64 @@ void main() #endif #if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT) - #if defined(USE_INVSQRLIGHT) - float intensity = 1.0 / dot(L, L); - #else - float intensity = clamp((1.0 - dot(L, L) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0); - #endif + // inverse square light + float attenuation = u_LightRadius * u_LightRadius / dot(L, L); + + // zero light at radius, approximating q3 style + attenuation = 0.5 * attenuation - 0.5; + //attenuation = 0.0697168 * attenuation; + //attenuation *= step(0.294117, attenuation); + + // clamp attenuation + #if defined(NO_LIGHT_CLAMP) + attenuation *= step(0.0, attenuation); + #else + attenuation = clamp(attenuation, 0.0, 1.0); + #endif + + // don't attenuate directional light + attenuation = (attenuation - 1.0) * u_LightOrigin.w + 1.0; + float NL = clamp(dot(normal, normalize(L)), 0.0, 1.0); - var_Color.rgb *= u_DirectedLight * intensity * NL + u_AmbientLight; + var_Color.rgb *= u_DirectedLight * attenuation * NL + u_AmbientLight; +#endif + +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || defined(USE_PARALLAXMAP) + var_Normal = normal; + var_Tangent = tangent; + var_Bitangent = bitangent; #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) - var_PrimaryLightDirection = u_PrimaryLightOrigin.xyz - (position.xyz * u_PrimaryLightOrigin.w); -#endif + var_PrimaryLightDir = (u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w)); +#endif + +#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) + #if defined(USE_LIGHT_VECTOR) + var_LightDir = vec4(L, u_LightOrigin.w); + #else + var_LightDir = vec4(L, 0.0); + #endif +#endif + +#if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) + var_ViewDir = (u_ViewOrigin - position); +#endif + +#if defined(USE_TANGENT_SPACE_LIGHT) + mat3 tangentToWorld = mat3(tangent, bitangent, normal); + + #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) + var_PrimaryLightDir = var_PrimaryLightDir * tangentToWorld; + #endif + + #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) + var_LightDir.xyz = var_LightDir.xyz * tangentToWorld; + #endif + + #if defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) + var_ViewDir = var_ViewDir * tangentToWorld; + #endif +#endif } diff --git a/code/renderergl2/tr_animation.c b/code/renderergl2/tr_animation.c index c4c9debb..985fe9bb 100644 --- a/code/renderergl2/tr_animation.c +++ b/code/renderergl2/tr_animation.c @@ -43,15 +43,17 @@ void R_AddAnimSurfaces( trRefEntity_t *ent ) { md4Surface_t *surface; md4LOD_t *lod; shader_t *shader; + int cubemapIndex; int i; header = (md4Header_t *) tr.currentModel->modelData; lod = (md4LOD_t *)( (byte *)header + header->ofsLODs ); + cubemapIndex = R_CubemapForPoint(ent->e.origin); surface = (md4Surface_t *)( (byte *)lod + lod->ofsSurfaces ); for ( i = 0 ; i < lod->numSurfaces ; i++ ) { shader = R_GetShaderByHandle( surface->shaderIndex ); - R_AddDrawSurf( (void *)surface, shader, 0 /*fogNum*/, qfalse, qfalse ); + R_AddDrawSurf( (void *)surface, shader, 0 /*fogNum*/, qfalse, qfalse, cubemapIndex ); surface = (md4Surface_t *)( (byte *)surface + surface->ofsEnd ); } } @@ -323,6 +325,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { int lodnum = 0; int fogNum = 0; int cull; + int cubemapIndex; qboolean personalModel; header = (mdrHeader_t *) tr.currentModel->modelData; @@ -384,6 +387,8 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { // fogNum? fogNum = R_MDRComputeFogNum( header, ent ); + cubemapIndex = R_CubemapForPoint(ent->e.origin); + surface = (mdrSurface_t *)( (byte *)lod + lod->ofsSurfaces ); for ( i = 0 ; i < lod->numSurfaces ; i++ ) @@ -419,7 +424,7 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { && !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) ) && shader->sort == SS_OPAQUE ) { - R_AddDrawSurf( (void *)surface, tr.shadowShader, 0, qfalse, qfalse ); + R_AddDrawSurf( (void *)surface, tr.shadowShader, 0, qfalse, qfalse, 0 ); } // projection shadows work fine with personal models @@ -428,11 +433,11 @@ void R_MDRAddAnimSurfaces( trRefEntity_t *ent ) { && (ent->e.renderfx & RF_SHADOW_PLANE ) && shader->sort == SS_OPAQUE ) { - R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse ); + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, qfalse, qfalse, 0 ); } if (!personalModel) - R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse, qfalse ); + R_AddDrawSurf( (void *)surface, shader, fogNum, qfalse, qfalse, cubemapIndex ); surface = (mdrSurface_t *)( (byte *)surface + surface->ofsEnd ); } diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index de05f53b..08dc167e 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -36,13 +36,13 @@ static float s_flipMatrix[16] = { /* -** GL_Bind2 +** GL_Bind */ -void GL_Bind2( image_t *image, GLenum type ) { +void GL_Bind( image_t *image ) { int texnum; if ( !image ) { - ri.Printf( PRINT_WARNING, "GL_Bind2: NULL image\n" ); + ri.Printf( PRINT_WARNING, "GL_Bind: NULL image\n" ); texnum = tr.defaultImage->texnum; } else { texnum = image->texnum; @@ -57,26 +57,13 @@ void GL_Bind2( image_t *image, GLenum type ) { image->frameUsed = tr.frameCount; } glState.currenttextures[glState.currenttmu] = texnum; - qglBindTexture (type, texnum); + if (image && image->flags & IMGFLAG_CUBEMAP) + qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum ); + else + qglBindTexture( GL_TEXTURE_2D, texnum ); } } -/* -** GL_Bind2 -*/ -void GL_Bind( image_t *image ) -{ - GL_Bind2( image, GL_TEXTURE_2D ); -} - -/* -** GL_BindCubemap -*/ -void GL_BindCubemap( image_t *image ) -{ - GL_Bind2( image, GL_TEXTURE_CUBE_MAP ); -} - /* ** GL_SelectTexture */ @@ -95,34 +82,6 @@ void GL_SelectTexture( int unit ) glState.currenttmu = unit; } - -/* -** GL_BindMultitexture -*/ -void GL_BindMultitexture( image_t *image0, GLuint env0, image_t *image1, GLuint env1 ) { - int texnum0, texnum1; - - texnum0 = image0->texnum; - texnum1 = image1->texnum; - - if ( r_nobind->integer && tr.dlightImage ) { // performance evaluation option - texnum0 = texnum1 = tr.dlightImage->texnum; - } - - if ( glState.currenttextures[1] != texnum1 ) { - GL_SelectTexture( 1 ); - image1->frameUsed = tr.frameCount; - glState.currenttextures[1] = texnum1; - qglBindTexture( GL_TEXTURE_2D, texnum1 ); - } - if ( glState.currenttextures[0] != texnum0 ) { - GL_SelectTexture( 0 ); - image0->frameUsed = tr.frameCount; - glState.currenttextures[0] = texnum0; - qglBindTexture( GL_TEXTURE_2D, texnum0 ); - } -} - /* ** GL_BindToTMU */ @@ -141,7 +100,11 @@ void GL_BindToTMU( image_t *image, int tmu ) if (image) image->frameUsed = tr.frameCount; glState.currenttextures[tmu] = texnum; - qglBindTexture( GL_TEXTURE_2D, texnum ); + + if (image && (image->flags & IMGFLAG_CUBEMAP)) + qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum ); + else + qglBindTexture( GL_TEXTURE_2D, texnum ); GL_SelectTexture( oldtmu ); } } @@ -496,6 +459,13 @@ void RB_BeginDrawingView (void) { else { FBO_Bind(backEnd.viewParms.targetFbo); + + // FIXME: hack for cubemap testing + if (backEnd.viewParms.targetFbo == tr.renderCubeFbo) + { + //qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, backEnd.viewParms.targetFbo->colorImage[0]->texnum, 0); + qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]->texnum, 0); + } } } @@ -530,6 +500,13 @@ void RB_BeginDrawingView (void) { qglClearColor( 1.0f, 1.0f, 1.0f, 1.0f ); } + // clear to black for cube maps + if (backEnd.viewParms.targetFbo == tr.renderCubeFbo) + { + clearBits |= GL_COLOR_BUFFER_BIT; + qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + } + qglClear( clearBits ); if ( ( backEnd.refdef.rdflags & RDF_HYPERSPACE ) ) @@ -581,6 +558,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { int entityNum, oldEntityNum; int dlighted, oldDlighted; int pshadowed, oldPshadowed; + int cubemapIndex, oldCubemapIndex; qboolean depthRange, oldDepthRange, isCrosshair, wasCrosshair; int i; drawSurf_t *drawSurf; @@ -606,6 +584,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { wasCrosshair = qfalse; oldDlighted = qfalse; oldPshadowed = qfalse; + oldCubemapIndex = -1; oldSort = -1; depth[0] = 0.f; @@ -614,7 +593,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { backEnd.pc.c_surfaces += numDrawSurfs; for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) { - if ( drawSurf->sort == oldSort ) { + if ( drawSurf->sort == oldSort && drawSurf->cubemapIndex == oldCubemapIndex) { if (backEnd.depthFill && shader && shader->sort != SS_OPAQUE) continue; @@ -624,22 +603,24 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) { } oldSort = drawSurf->sort; R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed ); + cubemapIndex = drawSurf->cubemapIndex; // // change the tess parameters if needed // a "entityMergable" shader is a shader that can have surfaces from seperate // entities merged into a single batch, like smoke and blood puff sprites - if ( shader != NULL && ( shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted || pshadowed != oldPshadowed + if ( shader != NULL && ( shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted || pshadowed != oldPshadowed || cubemapIndex != oldCubemapIndex || ( entityNum != oldEntityNum && !shader->entityMergable ) ) ) { if (oldShader != NULL) { RB_EndSurface(); } - RB_BeginSurface( shader, fogNum ); + RB_BeginSurface( shader, fogNum, cubemapIndex ); backEnd.pc.c_surfBatches++; oldShader = shader; oldFogNum = fogNum; oldDlighted = dlighted; oldPshadowed = pshadowed; + oldCubemapIndex = cubemapIndex; } if (backEnd.depthFill && shader && shader->sort != SS_OPAQUE) @@ -981,7 +962,7 @@ const void *RB_StretchPic ( const void *data ) { RB_EndSurface(); } backEnd.currentEntity = &backEnd.entity2D; - RB_BeginSurface( shader, 0 ); + RB_BeginSurface( shader, 0, 0 ); } RB_CHECKOVERFLOW( 4, 6 ); @@ -1311,8 +1292,14 @@ const void *RB_DrawSurfs( const void *data ) { RB_RenderFlares(); } - //if (glRefConfig.framebufferObject) - //FBO_Bind(NULL); + if (glRefConfig.framebufferObject && backEnd.viewParms.targetFbo == tr.renderCubeFbo) + { + FBO_Bind(NULL); + GL_SelectTexture(TB_CUBEMAP); + GL_BindToTMU(tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex], TB_CUBEMAP); + qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); + GL_SelectTexture(0); + } return (const void *)(cmd + 1); } @@ -1586,7 +1573,7 @@ const void *RB_CapShadowMap(const void *data) GL_SelectTexture(0); if (cmd->cubeSide != -1) { - GL_BindCubemap(tr.shadowCubemaps[cmd->map]); + GL_Bind(tr.shadowCubemaps[cmd->map]); qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); } else @@ -1650,7 +1637,11 @@ const void *RB_PostProcess(const void *data) srcBox[2] = backEnd.viewParms.viewportWidth * tr.screenSsaoImage->width / (float)glConfig.vidWidth; srcBox[3] = backEnd.viewParms.viewportHeight * tr.screenSsaoImage->height / (float)glConfig.vidHeight; - FBO_BlitFromTexture(tr.screenSsaoImage, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); + //FBO_BlitFromTexture(tr.screenSsaoImage, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); + srcBox[1] = tr.screenSsaoImage->height - srcBox[1]; + srcBox[3] = -srcBox[3]; + + FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); } srcBox[0] = backEnd.viewParms.viewportX; @@ -1678,7 +1669,7 @@ const void *RB_PostProcess(const void *data) color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); color[3] = 1.0f; - FBO_Blit(srcFbo, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, color, 0); + FBO_Blit(srcFbo, srcBox, NULL, tr.screenScratchFbo, dstBox, NULL, color, 0); } } @@ -1717,6 +1708,21 @@ const void *RB_PostProcess(const void *data) FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); } +#if 0 + if (r_cubeMapping->integer && tr.numCubemaps) + { + vec4i_t dstBox; + int cubemapIndex = R_CubemapForPoint( backEnd.viewParms.or.origin ); + + if (cubemapIndex) + { + VectorSet4(dstBox, 0, glConfig.vidHeight - 256, 256, 256); + //FBO_BlitFromTexture(tr.renderCubeImage, NULL, NULL, tr.screenScratchFbo, dstBox, &tr.testcubeShader, NULL, 0); + FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1], NULL, NULL, tr.screenScratchFbo, dstBox, &tr.testcubeShader, NULL, 0); + } + } +#endif + backEnd.framePostProcessed = qtrue; return (const void *)(cmd + 1); diff --git a/code/renderergl2/tr_bsp.c b/code/renderergl2/tr_bsp.c index 05b933e8..bbe3f228 100644 --- a/code/renderergl2/tr_bsp.c +++ b/code/renderergl2/tr_bsp.c @@ -142,49 +142,32 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale ) out[3] = in[3]; } - -void ColorToRGBE(const vec3_t color, unsigned char rgbe[4]) +// Modified from http://graphicrants.blogspot.jp/2009/04/rgbm-color-encoding.html +void ColorToRGBM(const vec3_t color, unsigned char rgbm[4]) { vec3_t sample; float maxComponent; - int e; - VectorCopy(color, sample); + VectorScale(color, 1.0f / 32.0f, sample); maxComponent = sample[0]; if(sample[1] > maxComponent) maxComponent = sample[1]; if(sample[2] > maxComponent) maxComponent = sample[2]; + if(0.000001f > maxComponent) + maxComponent = 0.000001f; + if(maxComponent > 1.0f) + maxComponent = 1.0f; - if(maxComponent < 1e-32) - { - rgbe[0] = 0; - rgbe[1] = 0; - rgbe[2] = 0; - rgbe[3] = 0; - } - else - { -#if 0 - maxComponent = frexp(maxComponent, &e) * 255.0 / maxComponent; - rgbe[0] = (unsigned char) (sample[0] * maxComponent); - rgbe[1] = (unsigned char) (sample[1] * maxComponent); - rgbe[2] = (unsigned char) (sample[2] * maxComponent); - rgbe[3] = (unsigned char) (e + 128); -#else - e = ceil(log(maxComponent) / log(2.0f));//ceil(log2(maxComponent)); - VectorScale(sample, 1.0 / pow(2.0f, e)/*exp2(e)*/, sample); + VectorScale(sample, 1.0f / maxComponent, sample); - rgbe[0] = (unsigned char) (sample[0] * 255); - rgbe[1] = (unsigned char) (sample[1] * 255); - rgbe[2] = (unsigned char) (sample[2] * 255); - rgbe[3] = (unsigned char) (e + 128); -#endif - } + rgbm[0] = (unsigned char) (sample[0] * 255); + rgbm[1] = (unsigned char) (sample[1] * 255); + rgbm[2] = (unsigned char) (sample[2] * 255); + rgbm[3] = (unsigned char) (maxComponent * 255); } - void ColorToRGBA16F(const vec3_t color, unsigned short rgba16f[4]) { rgba16f[0] = FloatToHalf(color[0]); @@ -290,8 +273,13 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) { tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low ); } - if (r_hdr->integer && glRefConfig.textureFloat && glRefConfig.halfFloatPixel) - textureInternalFormat = GL_RGBA16F_ARB; + if (r_hdr->integer) + { + if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel) + textureInternalFormat = GL_RGBA16F_ARB; + else + textureInternalFormat = GL_RGBA8; + } if (r_mergeLightmaps->integer) { @@ -429,7 +417,7 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) { if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel) ColorToRGBA16F(color, (unsigned short *)(&image[j*8])); else - ColorToRGBE(color, &image[j*4]); + ColorToRGBM(color, &image[j*4]); } else { @@ -1805,6 +1793,14 @@ static int BSPSurfaceCompare(const void *a, const void *b) else if(aa->fogIndex > bb->fogIndex) return 1; + // by cubemapIndex + if(aa->cubemapIndex < bb->cubemapIndex) + return -1; + + else if(aa->cubemapIndex > bb->cubemapIndex) + return 1; + + return 0; } @@ -2814,6 +2810,191 @@ qboolean R_GetEntityToken( char *buffer, int size ) { } } +#ifndef MAX_SPAWN_VARS +#define MAX_SPAWN_VARS 64 +#endif + +// derived from G_ParseSpawnVars() in g_spawn.c +qboolean R_ParseSpawnVars( char *spawnVarChars, int maxSpawnVarChars, int *numSpawnVars, char *spawnVars[MAX_SPAWN_VARS][2] ) +{ + char keyname[MAX_TOKEN_CHARS]; + char com_token[MAX_TOKEN_CHARS]; + int numSpawnVarChars = 0; + + *numSpawnVars = 0; + + // parse the opening brace + if ( !R_GetEntityToken( com_token, sizeof( com_token ) ) ) { + // end of spawn string + return qfalse; + } + if ( com_token[0] != '{' ) { + ri.Printf( PRINT_ALL, "R_ParseSpawnVars: found %s when expecting {",com_token ); + } + + // go through all the key / value pairs + while ( 1 ) { + int keyLength, tokenLength; + + // parse key + if ( !R_GetEntityToken( keyname, sizeof( keyname ) ) ) { + ri.Printf( PRINT_ALL, "R_ParseSpawnVars: EOF without closing brace" ); + } + + if ( keyname[0] == '}' ) { + break; + } + + // parse value + if ( !R_GetEntityToken( com_token, sizeof( com_token ) ) ) { + ri.Printf( PRINT_ALL, "R_ParseSpawnVars: EOF without closing brace" ); + break; + } + + if ( com_token[0] == '}' ) { + ri.Printf( PRINT_ALL, "R_ParseSpawnVars: closing brace without data" ); + break; + } + + if ( *numSpawnVars == MAX_SPAWN_VARS ) { + ri.Printf( PRINT_ALL, "R_ParseSpawnVars: MAX_SPAWN_VARS" ); + break; + } + + keyLength = strlen(keyname) + 1; + tokenLength = strlen(com_token) + 1; + + if (numSpawnVarChars + keyLength + tokenLength > maxSpawnVarChars) + { + ri.Printf( PRINT_ALL, "R_ParseSpawnVars: MAX_SPAWN_VAR_CHARS" ); + break; + } + + strcpy(spawnVarChars + numSpawnVarChars, keyname); + spawnVars[ *numSpawnVars ][0] = spawnVarChars + numSpawnVarChars; + numSpawnVarChars += keyLength; + + strcpy(spawnVarChars + numSpawnVarChars, com_token); + spawnVars[ *numSpawnVars ][1] = spawnVarChars + numSpawnVarChars; + numSpawnVarChars += tokenLength; + + (*numSpawnVars)++; + } + + return qtrue; +} + +void R_LoadCubemapEntities(char *cubemapEntityName) +{ + char spawnVarChars[2048]; + int numSpawnVars; + char *spawnVars[MAX_SPAWN_VARS][2]; + int numCubemaps = 0; + + // count cubemaps + numCubemaps = 0; + while(R_ParseSpawnVars(spawnVarChars, sizeof(spawnVarChars), &numSpawnVars, spawnVars)) + { + int i; + + for (i = 0; i < numSpawnVars; i++) + { + if (!Q_stricmp(spawnVars[i][0], "classname") && !Q_stricmp(spawnVars[i][1], cubemapEntityName)) + numCubemaps++; + } + } + + if (!numCubemaps) + return; + + tr.numCubemaps = numCubemaps; + tr.cubemapOrigins = ri.Hunk_Alloc( tr.numCubemaps * sizeof(*tr.cubemapOrigins), h_low); + tr.cubemaps = ri.Hunk_Alloc( tr.numCubemaps * sizeof(*tr.cubemaps), h_low); + + numCubemaps = 0; + while(R_ParseSpawnVars(spawnVarChars, sizeof(spawnVarChars), &numSpawnVars, spawnVars)) + { + int i; + qboolean isCubemap = qfalse; + qboolean positionSet = qfalse; + vec3_t origin; + + for (i = 0; i < numSpawnVars; i++) + { + if (!Q_stricmp(spawnVars[i][0], "classname") && !Q_stricmp(spawnVars[i][1], cubemapEntityName)) + isCubemap = qtrue; + + if (!Q_stricmp(spawnVars[i][0], "origin")) + { + sscanf(spawnVars[i][1], "%f %f %f", &origin[0], &origin[1], &origin[2]); + positionSet = qtrue; + } + } + + if (isCubemap && positionSet) + { + //ri.Printf(PRINT_ALL, "cubemap at %f %f %f\n", origin[0], origin[1], origin[2]); + VectorCopy(origin, tr.cubemapOrigins[numCubemaps]); + numCubemaps++; + } + } +} + +void R_AssignCubemapsToWorldSurfaces(void) +{ + world_t *w; + int i; + + w = &s_worldData; + + for (i = 0; i < w->numsurfaces; i++) + { + msurface_t *surf = &w->surfaces[i]; + vec3_t surfOrigin; + + if (surf->cullinfo.type & CULLINFO_SPHERE) + { + VectorCopy(surf->cullinfo.localOrigin, surfOrigin); + } + else if (surf->cullinfo.type & CULLINFO_BOX) + { + surfOrigin[0] = (surf->cullinfo.bounds[0][0] + surf->cullinfo.bounds[1][0]) * 0.5f; + surfOrigin[1] = (surf->cullinfo.bounds[0][1] + surf->cullinfo.bounds[1][1]) * 0.5f; + surfOrigin[2] = (surf->cullinfo.bounds[0][2] + surf->cullinfo.bounds[1][2]) * 0.5f; + } + else + { + //ri.Printf(PRINT_ALL, "surface %d has no cubemap\n", i); + continue; + } + + surf->cubemapIndex = R_CubemapForPoint(surfOrigin); + //ri.Printf(PRINT_ALL, "surface %d has cubemap %d\n", i, surf->cubemapIndex); + } +} + + +void R_RenderAllCubemaps(void) +{ + int i, j; + + for (i = 0; i < tr.numCubemaps; i++) + { + tr.cubemaps[i] = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); + } + + for (i = 0; i < tr.numCubemaps; i++) + { + for (j = 0; j < 6; j++) + { + RE_ClearScene(); + R_RenderCubemapSide(i, j, qfalse); + R_IssuePendingRenderCommands(); + R_InitNextFrame(); + } + } +} + /* ================= @@ -2866,6 +3047,7 @@ void R_MergeLeafSurfaces(void) msurface_t *surf1; shader_t *shader1; int fogIndex1; + int cubemapIndex1; int surfNum1; surfNum1 = *(s_worldData.marksurfaces + leaf->firstmarksurface + j); @@ -2890,6 +3072,7 @@ void R_MergeLeafSurfaces(void) continue; fogIndex1 = surf1->fogIndex; + cubemapIndex1 = surf1->cubemapIndex; s_worldData.surfacesViewCount[surfNum1] = surfNum1; @@ -2898,6 +3081,7 @@ void R_MergeLeafSurfaces(void) msurface_t *surf2; shader_t *shader2; int fogIndex2; + int cubemapIndex2; int surfNum2; surfNum2 = *(s_worldData.marksurfaces + leaf->firstmarksurface + k); @@ -2920,6 +3104,11 @@ void R_MergeLeafSurfaces(void) if (fogIndex1 != fogIndex2) continue; + cubemapIndex2 = surf2->cubemapIndex; + + if (cubemapIndex1 != cubemapIndex2) + continue; + s_worldData.surfacesViewCount[surfNum2] = surfNum1; } } @@ -3153,6 +3342,7 @@ void R_MergeLeafSurfaces(void) vboSurf->shader = surf1->shader; vboSurf->fogIndex = surf1->fogIndex; + vboSurf->cubemapIndex = surf1->cubemapIndex; VectorCopy(bounds[0], vboSurf->bounds[0]); VectorCopy(bounds[1], vboSurf->bounds[1]); @@ -3163,6 +3353,7 @@ void R_MergeLeafSurfaces(void) mergedSurf->cullinfo.type = CULLINFO_BOX; mergedSurf->data = (surfaceType_t *)vboSurf; mergedSurf->fogIndex = surf1->fogIndex; + mergedSurf->cubemapIndex = surf1->cubemapIndex; mergedSurf->shader = surf1->shader; // redirect view surfaces to this surf @@ -3356,12 +3547,12 @@ void RE_LoadWorldMap( const char *name ) { if (0) { world_t *w; - - w = &s_worldData; uint8_t *primaryLightGrid, *data; int lightGridSize; int i; + w = &s_worldData; + lightGridSize = w->lightGridBounds[0] * w->lightGridBounds[1] * w->lightGridBounds[2]; primaryLightGrid = ri.Malloc(lightGridSize * sizeof(*primaryLightGrid)); @@ -3539,6 +3730,22 @@ void RE_LoadWorldMap( const char *name ) { ri.Free(primaryLightGrid); } + // load cubemaps + if (r_cubeMapping->integer) + { + R_LoadCubemapEntities("misc_cubemap"); + if (!tr.numCubemaps) + { + // use deathmatch spawn points as cubemaps + R_LoadCubemapEntities("info_player_deathmatch"); + } + + if (tr.numCubemaps) + { + R_AssignCubemapsToWorldSurfaces(); + } + } + // create static VBOS from the world R_CreateWorldVBO(); if (r_mergeLeafSurfaces->integer) @@ -3555,5 +3762,11 @@ void RE_LoadWorldMap( const char *name ) { R_BindNullVBO(); R_BindNullIBO(); + // Render all cubemaps + if (r_cubeMapping->integer && tr.numCubemaps) + { + R_RenderAllCubemaps(); + } + ri.FS_FreeFile( buffer.v ); } diff --git a/code/renderergl2/tr_extensions.c b/code/renderergl2/tr_extensions.c index 0b70d48b..41cd9164 100644 --- a/code/renderergl2/tr_extensions.c +++ b/code/renderergl2/tr_extensions.c @@ -595,19 +595,50 @@ void GLimp_InitExtraExtensions() // GL_EXT_texture_sRGB extension = "GL_EXT_texture_sRGB"; - glRefConfig.texture_srgb = qfalse; + glRefConfig.textureSrgb = qfalse; if (GLimp_HaveExtension(extension)) { if (r_srgb->integer) - glRefConfig.texture_srgb = qtrue; + glRefConfig.textureSrgb = qtrue; - ri.Printf(PRINT_ALL, result[glRefConfig.texture_srgb], extension); + ri.Printf(PRINT_ALL, result[glRefConfig.textureSrgb], extension); } else { ri.Printf(PRINT_ALL, result[2], extension); } + // GL_EXT_framebuffer_sRGB + extension = "GL_EXT_framebuffer_sRGB"; + glRefConfig.framebufferSrgb = qfalse; + if (GLimp_HaveExtension(extension)) + { + if (r_srgb->integer) + glRefConfig.framebufferSrgb = qtrue; + + ri.Printf(PRINT_ALL, result[glRefConfig.framebufferSrgb], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } + + // GL_EXT_texture_sRGB_decode + extension = "GL_EXT_texture_sRGB_decode"; + glRefConfig.textureSrgbDecode = qfalse; + if (GLimp_HaveExtension(extension)) + { + if (r_srgb->integer) + glRefConfig.textureSrgbDecode = qtrue; + + ri.Printf(PRINT_ALL, result[glRefConfig.textureSrgbDecode], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } + + glRefConfig.textureCompression = TCR_NONE; // GL_EXT_texture_compression_latc @@ -664,4 +695,17 @@ void GLimp_InitExtraExtensions() { ri.Printf(PRINT_ALL, result[2], extension); } + + // GL_ARB_seamless_cube_map + extension = "GL_ARB_seamless_cube_map"; + glRefConfig.seamlessCubeMap = qfalse; + if( GLimp_HaveExtension( extension ) ) + { + glRefConfig.seamlessCubeMap = qtrue; + ri.Printf(PRINT_ALL, result[1], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } } diff --git a/code/renderergl2/tr_fbo.c b/code/renderergl2/tr_fbo.c index fee11d5c..a1d1339b 100644 --- a/code/renderergl2/tr_fbo.c +++ b/code/renderergl2/tr_fbo.c @@ -579,6 +579,19 @@ void FBO_Init(void) R_CheckFBO(tr.screenSsaoFbo); } + { + tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height); + FBO_Bind(tr.renderCubeFbo); + + //FBO_AttachTextureImage(tr.renderCubeImage, 0); + R_AttachFBOTexture2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, tr.renderCubeImage->texnum, 0); + glState.currentFBO->colorImage[0] = tr.renderCubeImage; + + FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); + + R_CheckFBO(tr.renderCubeFbo); + } + GL_CheckErrors(); FBO_Bind(NULL); @@ -783,7 +796,10 @@ void FBO_Blit(FBO_t *src, vec4i_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, vec4 vec4i_t srcBox; if (!src) + { + ri.Printf(PRINT_WARNING, "Tried to blit from a NULL FBO!\n"); return; + } // framebuffers are 0 bottom, Y up. if (inSrcBox) diff --git a/code/renderergl2/tr_flares.c b/code/renderergl2/tr_flares.c index 5bcefa2a..bc016c1c 100644 --- a/code/renderergl2/tr_flares.c +++ b/code/renderergl2/tr_flares.c @@ -370,7 +370,7 @@ void RB_RenderFlare( flare_t *f ) { iColor[1] = color[1] * fogFactors[1]; iColor[2] = color[2] * fogFactors[2]; - RB_BeginSurface( tr.flareShader, f->fogNum ); + RB_BeginSurface( tr.flareShader, f->fogNum, 0 ); // FIXME: use quadstamp? tess.xyz[tess.numVertexes][0] = f->windowX - size; diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index d8b07432..a2707cd0 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -71,6 +71,7 @@ static uniformInfo_t uniformsInfo[] = { "u_TextureMap", GLSL_INT }, { "u_LevelsMap", GLSL_INT }, + { "u_CubeMap", GLSL_INT }, { "u_ScreenImageMap", GLSL_INT }, { "u_ScreenDepthMap", GLSL_INT }, @@ -907,7 +908,7 @@ void GLSL_InitGPUShaders(void) Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n"); if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel)) - Q_strcat(extradefines, 1024, "#define RGBE_LIGHTMAP\n"); + Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n"); if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackShader_generic_vp, fallbackShader_generic_fp)) { @@ -997,37 +998,35 @@ void GLSL_InitGPUShaders(void) for (i = 0; i < LIGHTDEF_COUNT; i++) { // skip impossible combos - if ((i & LIGHTDEF_USE_NORMALMAP) && !r_normalMapping->integer) - continue; - if ((i & LIGHTDEF_USE_PARALLAXMAP) && !r_parallaxMapping->integer) continue; - if ((i & LIGHTDEF_USE_SPECULARMAP) && !r_specularMapping->integer) - continue; - if ((i & LIGHTDEF_USE_DELUXEMAP) && !r_deluxeMapping->integer) continue; + if ((i & LIGHTDEF_USE_CUBEMAP) && !r_cubeMapping->integer) + continue; + if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHTMAP) && (i & LIGHTDEF_USE_DELUXEMAP)) continue; - if (!(i & LIGHTDEF_USE_NORMALMAP) && (i & LIGHTDEF_USE_PARALLAXMAP)) - continue; - - //if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHT_VECTOR)) if (!(i & LIGHTDEF_LIGHTTYPE_MASK)) { if (i & LIGHTDEF_USE_SHADOWMAP) continue; + if (i & LIGHTDEF_USE_CUBEMAP) + continue; } attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL; extradefines[0] = '\0'; - if (r_normalAmbient->value > 0.003f) - Q_strcat(extradefines, 1024, va("#define r_normalAmbient %f\n", r_normalAmbient->value)); + if (r_deluxeSpecular->value > 0.000001f) + Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value)); + + if (r_specularIsMetallic->value) + Q_strcat(extradefines, 1024, va("#define SPECULAR_IS_METALLIC\n")); if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); @@ -1038,7 +1037,7 @@ void GLSL_InitGPUShaders(void) } if (r_hdr->integer && !(glRefConfig.textureFloat && glRefConfig.halfFloatPixel)) - Q_strcat(extradefines, 1024, "#define RGBE_LIGHTMAP\n"); + Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n"); if (i & LIGHTDEF_LIGHTTYPE_MASK) { @@ -1065,7 +1064,7 @@ void GLSL_InitGPUShaders(void) } } - if ((i & LIGHTDEF_USE_NORMALMAP) && r_normalMapping->integer) + if (r_normalMapping->integer) { Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n"); @@ -1081,7 +1080,7 @@ void GLSL_InitGPUShaders(void) #endif } - if ((i & LIGHTDEF_USE_SPECULARMAP) && r_specularMapping->integer) + if (r_specularMapping->integer) { Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n"); @@ -1089,19 +1088,23 @@ void GLSL_InitGPUShaders(void) { case 1: default: - Q_strcat(extradefines, 1024, "#define USE_TRIACE\n"); - break; - - case 2: Q_strcat(extradefines, 1024, "#define USE_BLINN\n"); break; + case 2: + Q_strcat(extradefines, 1024, "#define USE_BLINN_FRESNEL\n"); + break; + case 3: - Q_strcat(extradefines, 1024, "#define USE_COOK_TORRANCE\n"); + Q_strcat(extradefines, 1024, "#define USE_MCAULEY\n"); break; case 4: - Q_strcat(extradefines, 1024, "#define USE_TORRANCE_SPARROW\n"); + Q_strcat(extradefines, 1024, "#define USE_GOTANDA\n"); + break; + + case 5: + Q_strcat(extradefines, 1024, "#define USE_LAZAROV\n"); break; } } @@ -1112,6 +1115,9 @@ void GLSL_InitGPUShaders(void) if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer) Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); + if ((i & LIGHTDEF_USE_CUBEMAP)) + Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n"); + if (i & LIGHTDEF_USE_SHADOWMAP) { Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); @@ -1134,7 +1140,7 @@ void GLSL_InitGPUShaders(void) attribs |= ATTR_POSITION2 | ATTR_NORMAL2; #ifdef USE_VERT_TANGENT_SPACE - if (i & LIGHTDEF_USE_NORMALMAP && r_normalMapping->integer) + if (r_normalMapping->integer) { attribs |= ATTR_TANGENT2 | ATTR_BITANGENT2; } @@ -1155,6 +1161,7 @@ void GLSL_InitGPUShaders(void) GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DELUXEMAP, TB_DELUXEMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SPECULARMAP, TB_SPECULARMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SHADOWMAP, TB_SHADOWMAP); + GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_CUBEMAP, TB_CUBEMAP); qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.lightallShader[i]); @@ -1361,6 +1368,26 @@ void GLSL_InitGPUShaders(void) numEtcShaders++; } +#if 0 + attribs = ATTR_POSITION | ATTR_TEXCOORD; + extradefines[0] = '\0'; + + if (!GLSL_InitGPUShader(&tr.testcubeShader, "testcube", attribs, qtrue, extradefines, qtrue, NULL, NULL)) + { + ri.Error(ERR_FATAL, "Could not load testcube shader!"); + } + + GLSL_InitUniforms(&tr.testcubeShader); + + qglUseProgramObjectARB(tr.testcubeShader.program); + GLSL_SetUniformInt(&tr.testcubeShader, UNIFORM_TEXTUREMAP, TB_COLORMAP); + qglUseProgramObjectARB(0); + + GLSL_FinishGPUShader(&tr.testcubeShader); + + numEtcShaders++; +#endif + endTime = ri.Milliseconds(); diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index c9ca6ce6..a80c975b 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -408,7 +408,9 @@ static void RGBAtoNormal(const byte *in, byte *out, int width, int height, qbool for (x = 0; x < width; x++) { - *outbyte = (inbyte[0] >> 2) + (inbyte[1] >> 1) + (inbyte[2] >> 2); + byte result = (inbyte[0] >> 2) + (inbyte[1] >> 1) + (inbyte[2] >> 2); + result = result * result / 255; // Make linear + *outbyte = result; max = MAX(max, *outbyte); outbyte += 4; inbyte += 4; @@ -1856,7 +1858,7 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light } } - if (glRefConfig.texture_srgb && (flags & IMGFLAG_SRGB)) + if (glRefConfig.textureSrgb && (flags & IMGFLAG_SRGB)) { switch(internalFormat) { @@ -2049,7 +2051,7 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag } // Convert to RGB if sRGB textures aren't supported in hardware - if (!glRefConfig.texture_srgb && (flags & IMGFLAG_SRGB)) + if (!glRefConfig.textureSrgb && (flags & IMGFLAG_SRGB)) { byte *in = data; int c = width * height; @@ -2278,12 +2280,21 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT if (image->flags & IMGFLAG_CUBEMAP) { - GL_BindCubemap(image); + GL_Bind(image); qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + if (image->flags & IMGFLAG_MIPMAP) + { + qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); + qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } + else + { + qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); @@ -2599,6 +2610,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) normalPic = ri.Malloc(width * height * 4); RGBAtoNormal(pic, normalPic, width, height, flags & IMGFLAG_CLAMPTOEDGE); +#if 1 // Brighten up the original image to work with the normal map RGBAtoYCoCgA(pic, pic, width, height); for (y = 0; y < height; y++) @@ -2614,6 +2626,61 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) } } YCoCgAtoRGBA(pic, pic, width, height); +#else + // Blur original image's luma to work with the normal map + { + byte *blurPic; + + RGBAtoYCoCgA(pic, pic, width, height); + blurPic = ri.Malloc(width * height); + + for (y = 1; y < height - 1; y++) + { + byte *picbyte = pic + y * width * 4; + byte *blurbyte = blurPic + y * width; + + picbyte += 4; + blurbyte += 1; + + for (x = 1; x < width - 1; x++) + { + int result; + + result = *(picbyte - (width + 1) * 4) + *(picbyte - width * 4) + *(picbyte - (width - 1) * 4) + + *(picbyte - 1 * 4) + *(picbyte ) + *(picbyte + 1 * 4) + + *(picbyte + (width - 1) * 4) + *(picbyte + width * 4) + *(picbyte + (width + 1) * 4); + + result /= 9; + + *blurbyte = result; + picbyte += 4; + blurbyte += 1; + } + } + + // FIXME: do borders + + for (y = 1; y < height - 1; y++) + { + byte *picbyte = pic + y * width * 4; + byte *blurbyte = blurPic + y * width; + + picbyte += 4; + blurbyte += 1; + + for (x = 1; x < width - 1; x++) + { + picbyte[0] = *blurbyte; + picbyte += 4; + blurbyte += 1; + } + } + + ri.Free(blurPic); + + YCoCgAtoRGBA(pic, pic, width, height); + } +#endif R_CreateImage( normalName, normalPic, normalWidth, normalHeight, IMGTYPE_NORMAL, normalFlags, 0 ); ri.Free( normalPic ); @@ -2805,6 +2872,9 @@ void R_CreateBuiltinImages( void ) { Com_Memset( data, 255, sizeof( data ) ); tr.whiteImage = R_CreateImage("*white", (byte *)data, 8, 8, IMGTYPE_COLORALPHA, IMGFLAG_NONE, 0); + Com_Memset( data, 128, sizeof( data ) ); + tr.greyImage = R_CreateImage("*grey", (byte *)data, 8, 8, IMGTYPE_COLORALPHA, IMGFLAG_NONE, GL_RGBA8); + if (r_dlightMode->integer >= 2) { for( x = 0; x < MAX_DLIGHTS; x++) @@ -2837,7 +2907,7 @@ void R_CreateBuiltinImages( void ) { if (glRefConfig.framebufferObject) { - int width, height, hdrFormat; + int width, height, hdrFormat, rgbFormat; if(glRefConfig.textureNonPowerOfTwo) { @@ -2854,19 +2924,15 @@ void R_CreateBuiltinImages( void ) { if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat) hdrFormat = GL_RGB16F_ARB; + rgbFormat = GL_RGBA8; + tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); if (r_drawSunRays->integer) - tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); + tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); if (r_softOverbright->integer) - { - int format; - - format = GL_RGBA8; - - tr.screenScratchImage = R_CreateImage("*screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, format); - } + tr.screenScratchImage = R_CreateImage("*screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); if (glRefConfig.framebufferObject) { @@ -2926,6 +2992,8 @@ void R_CreateBuiltinImages( void ) { { tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); } + + tr.renderCubeImage = R_CreateImage("*renderCube", NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat); } } @@ -3284,6 +3352,11 @@ qhandle_t RE_RegisterSkin( const char *name ) { // parse the shader name token = CommaParse( &text_p ); + if ( skin->numSurfaces >= MD3_MAX_SURFACES ) { + ri.Printf( PRINT_WARNING, "WARNING: Ignoring surfaces in '%s', the max is %d surfaces!\n", name, MD3_MAX_SURFACES ); + break; + } + surf = skin->surfaces[ skin->numSurfaces ] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); Q_strncpyz( surf->name, surfName, sizeof( surf->name ) ); surf->shader = R_FindShader( token, LIGHTMAP_NONE, qtrue ); diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index d5330248..b9e5fb58 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -131,7 +131,11 @@ cvar_t *r_normalMapping; cvar_t *r_specularMapping; cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; -cvar_t *r_normalAmbient; +cvar_t *r_cubeMapping; +cvar_t *r_deluxeSpecular; +cvar_t *r_specularIsMetallic; +cvar_t *r_baseSpecular; +cvar_t *r_baseGloss; cvar_t *r_recalcMD3Normals; cvar_t *r_mergeLightmaps; cvar_t *r_dlightMode; @@ -955,6 +959,9 @@ void GL_SetDefaultState( void ) qglDrawBuffer( GL_BACK ); qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT ); + + if (glRefConfig.seamlessCubeMap) + qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); } /* @@ -1185,7 +1192,11 @@ void R_Register( void ) r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); - r_normalAmbient = ri.Cvar_Get( "r_normalAmbient", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_deluxeSpecular = ri.Cvar_Get( "r_deluxeSpecular", "0.3", CVAR_ARCHIVE | CVAR_LATCH ); + r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_baseSpecular = ri.Cvar_Get( "r_baseSpecular", "0.04", CVAR_ARCHIVE | CVAR_LATCH ); + r_baseGloss = ri.Cvar_Get( "r_baseGloss", "0.3", CVAR_ARCHIVE | CVAR_LATCH ); r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_pshadowDist = ri.Cvar_Get( "r_pshadowDist", "128", CVAR_ARCHIVE ); r_recalcMD3Normals = ri.Cvar_Get( "r_recalcMD3Normals", "0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/code/renderergl2/tr_light.c b/code/renderergl2/tr_light.c index a34d9bab..ee7dad92 100644 --- a/code/renderergl2/tr_light.c +++ b/code/renderergl2/tr_light.c @@ -449,3 +449,32 @@ int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *w return qtrue; } + + +int R_CubemapForPoint( vec3_t point ) +{ + int cubemapIndex = -1; + + if (r_cubeMapping->integer && tr.numCubemaps) + { + int i; + vec_t shortest = (float)WORLD_SIZE * (float)WORLD_SIZE; + + for (i = 0; i < tr.numCubemaps; i++) + { + vec3_t diff; + vec_t length; + + VectorSubtract(point, tr.cubemapOrigins[i], diff); + length = DotProduct(diff, diff); + + if (shortest > length) + { + shortest = length; + cubemapIndex = i; + } + } + } + + return cubemapIndex + 1; +} diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 144b16eb..838845b4 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -59,6 +59,8 @@ typedef unsigned int glIndex_t; #define MAX_CALC_PSHADOWS 64 #define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces #define PSHADOW_MAP_SIZE 512 +#define CUBE_MAP_MIPS 7 +#define CUBE_MAP_SIZE (1 << CUBE_MAP_MIPS) #define USE_VERT_TANGENT_SPACE @@ -368,7 +370,8 @@ enum TB_SHADOWMAP2 = 3, TB_SPECULARMAP = 4, TB_SHADOWMAP = 5, - NUM_TEXTURE_BUNDLES = 6 + TB_CUBEMAP = 6, + NUM_TEXTURE_BUNDLES = 7 }; typedef enum @@ -698,13 +701,12 @@ enum LIGHTDEF_LIGHTTYPE_MASK = 0x0003, LIGHTDEF_ENTITY = 0x0004, LIGHTDEF_USE_TCGEN_AND_TCMOD = 0x0008, - LIGHTDEF_USE_NORMALMAP = 0x0010, - LIGHTDEF_USE_SPECULARMAP = 0x0020, - LIGHTDEF_USE_DELUXEMAP = 0x0040, - LIGHTDEF_USE_PARALLAXMAP = 0x0080, - LIGHTDEF_USE_SHADOWMAP = 0x0100, - LIGHTDEF_ALL = 0x01FF, - LIGHTDEF_COUNT = 0x0200 + LIGHTDEF_USE_DELUXEMAP = 0x0010, + LIGHTDEF_USE_PARALLAXMAP = 0x0020, + LIGHTDEF_USE_SHADOWMAP = 0x0040, + LIGHTDEF_USE_CUBEMAP = 0x0080, + LIGHTDEF_ALL = 0x00FF, + LIGHTDEF_COUNT = 0x0100 }; enum @@ -728,6 +730,7 @@ typedef enum UNIFORM_TEXTUREMAP, UNIFORM_LEVELSMAP, + UNIFORM_CUBEMAP, UNIFORM_SCREENIMAGEMAP, UNIFORM_SCREENDEPTHMAP, @@ -896,12 +899,14 @@ typedef struct { typedef enum { VPF_NONE = 0x00, - VPF_SHADOWMAP = 0x01, - VPF_DEPTHSHADOW = 0x02, - VPF_DEPTHCLAMP = 0x04, - VPF_ORTHOGRAPHIC = 0x08, - VPF_USESUNLIGHT = 0x10, - VPF_FARPLANEFRUSTUM = 0x20 + VPF_NOVIEWMODEL = 0x01, + VPF_SHADOWMAP = 0x02, + VPF_DEPTHSHADOW = 0x04, + VPF_DEPTHCLAMP = 0x08, + VPF_ORTHOGRAPHIC = 0x10, + VPF_USESUNLIGHT = 0x20, + VPF_FARPLANEFRUSTUM = 0x40, + VPF_NOCUBEMAPS = 0x80 } viewParmFlags_t; typedef struct { @@ -916,6 +921,8 @@ typedef struct { cplane_t portalPlane; // clip anything behind this if mirroring int viewportX, viewportY, viewportWidth, viewportHeight; FBO_t *targetFbo; + int targetFboLayer; + int targetFboCubemapIndex; float fovX, fovY; float projectionMatrix[16]; cplane_t frustum[5]; @@ -958,7 +965,8 @@ typedef enum { } surfaceType_t; typedef struct drawSurf_s { - unsigned sort; // bit combination for fast compares + unsigned int sort; // bit combination for fast compares + int cubemapIndex; surfaceType_t *surface; // any of surface*_t } drawSurf_t; @@ -1170,6 +1178,7 @@ typedef struct srfVBOMesh_s struct shader_s *shader; // FIXME move this to somewhere else int fogIndex; + int cubemapIndex; // dynamic lighting information int dlightBits; @@ -1271,6 +1280,7 @@ typedef struct msurface_s { //int viewCount; // if == tr.viewCount, already added struct shader_s *shader; int fogIndex; + int cubemapIndex; cullinfo_t cullinfo; surfaceType_t *data; // any of srf*_t @@ -1600,9 +1610,12 @@ typedef struct { qboolean framebufferMultisample; qboolean framebufferBlit; - qboolean texture_srgb; + qboolean textureSrgb; + qboolean framebufferSrgb; + qboolean textureSrgbDecode; qboolean depthClamp; + qboolean seamlessCubeMap; } glRefConfig_t; @@ -1695,6 +1708,7 @@ typedef struct { image_t *fogImage; image_t *dlightImage; // inverse-quare highlight for projective adding image_t *flareImage; + image_t *greyImage; // full of 0x80 image_t *whiteImage; // full of 0xff image_t *identityLightImage; // full of tr.identityLightByte @@ -1715,6 +1729,7 @@ typedef struct { image_t *screenShadowImage; image_t *screenSsaoImage; image_t *hdrDepthImage; + image_t *renderCubeImage; image_t *textureDepthImage; @@ -1732,6 +1747,7 @@ typedef struct { FBO_t *screenShadowFbo; FBO_t *screenSsaoFbo; FBO_t *hdrDepthFbo; + FBO_t *renderCubeFbo; shader_t *defaultShader; shader_t *shadowShader; @@ -1749,6 +1765,10 @@ typedef struct { int fatLightmapSize; int fatLightmapStep; + int numCubemaps; + vec3_t *cubemapOrigins; + image_t **cubemaps; + trRefEntity_t *currentEntity; trRefEntity_t worldEntity; // point currentEntity at this when rendering world int currentEntityNum; @@ -1772,6 +1792,7 @@ typedef struct { shaderProgram_t shadowmaskShader; shaderProgram_t ssaoShader; shaderProgram_t depthBlurShader[2]; + shaderProgram_t testcubeShader; // ----------------------------------------- @@ -1961,7 +1982,11 @@ extern cvar_t *r_normalMapping; extern cvar_t *r_specularMapping; extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; -extern cvar_t *r_normalAmbient; +extern cvar_t *r_cubeMapping; +extern cvar_t *r_deluxeSpecular; +extern cvar_t *r_specularIsMetallic; +extern cvar_t *r_baseSpecular; +extern cvar_t *r_baseGloss; extern cvar_t *r_dlightMode; extern cvar_t *r_pshadowDist; extern cvar_t *r_recalcMD3Normals; @@ -2008,6 +2033,7 @@ void R_RenderView( viewParms_t *parms ); void R_RenderDlightCubemaps(const refdef_t *fd); void R_RenderPshadowMaps(const refdef_t *fd); void R_RenderSunShadowMaps(const refdef_t *fd, int level); +void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ); void R_AddMD3Surfaces( trRefEntity_t *e ); void R_AddNullModelSurfaces( trRefEntity_t *e ); @@ -2021,7 +2047,7 @@ void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader, int *fogNum, int *dlightMap, int *pshadowMap ); void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, - int fogIndex, int dlightMap, int pshadowMap ); + int fogIndex, int dlightMap, int pshadowMap, int cubemap ); void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal, const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2); @@ -2047,7 +2073,6 @@ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, ** GL wrapper/helper functions */ void GL_Bind( image_t *image ); -void GL_BindCubemap( image_t *image ); void GL_BindToTMU( image_t *image, int tmu ); void GL_SetDefaultState (void); void GL_SelectTexture( int unit ); @@ -2198,6 +2223,7 @@ typedef struct shaderCommands_s shader_t *shader; float shaderTime; int fogNum; + int cubemapIndex; int dlightBits; // or together of all vertexDlightBits int pshadowBits; @@ -2223,7 +2249,7 @@ typedef struct shaderCommands_s extern shaderCommands_t tess; -void RB_BeginSurface(shader_t *shader, int fogNum ); +void RB_BeginSurface(shader_t *shader, int fogNum, int cubemapIndex ); void RB_EndSurface(void); void RB_CheckOverflow( int verts, int indexes ); #define RB_CHECKOVERFLOW(v,i) if (tess.numVertexes + (v) >= SHADER_MAX_VERTEXES || tess.numIndexes + (i) >= SHADER_MAX_INDEXES ) {RB_CheckOverflow(v,i);} @@ -2283,6 +2309,7 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ); void R_TransformDlights( int count, dlight_t *dl, orientationr_t *or ); int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ); int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *world ); +int R_CubemapForPoint( vec3_t point ); /* @@ -2405,7 +2432,9 @@ void RE_AddRefEntityToScene( const refEntity_t *ent ); void RE_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num ); void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ); void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b ); +void RE_BeginScene( const refdef_t *fd ); void RE_RenderScene( const refdef_t *fd ); +void RE_EndScene( void ); /* ============================================================= diff --git a/code/renderergl2/tr_main.c b/code/renderergl2/tr_main.c index b67c5fa4..9899432b 100644 --- a/code/renderergl2/tr_main.c +++ b/code/renderergl2/tr_main.c @@ -1607,7 +1607,7 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128 R_RotateForViewer(); R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed ); - RB_BeginSurface( shader, fogNum ); + RB_BeginSurface( shader, fogNum, drawSurf->cubemapIndex); rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface ); assert( tess.numVertexes < 128 ); @@ -1725,6 +1725,9 @@ qboolean R_MirrorViewBySurface (drawSurf_t *drawSurf, int entityNum) { return qfalse; // bad portal, no portalentity } + if (newParms.isMirror) + newParms.flags |= VPF_NOVIEWMODEL; + R_MirrorPoint (oldParms.or.origin, &surface, &camera, newParms.or.origin ); VectorSubtract( vec3_origin, camera.axis[0], newParms.portalPlane.normal ); @@ -1844,7 +1847,7 @@ R_AddDrawSurf ================= */ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, - int fogIndex, int dlightMap, int pshadowMap ) { + int fogIndex, int dlightMap, int pshadowMap, int cubemap ) { int index; // instead of checking for overflow, we just mask the index @@ -1855,6 +1858,7 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT) | tr.shiftedEntityNum | ( fogIndex << QSORT_FOGNUM_SHIFT ) | ((int)pshadowMap << QSORT_PSHADOW_SHIFT) | (int)dlightMap; + tr.refdef.drawSurfs[index].cubemapIndex = cubemap; tr.refdef.drawSurfs[index].surface = surface; tr.refdef.numDrawSurfs++; } @@ -1958,8 +1962,7 @@ static void R_AddEntitySurface (int entityNum) // we don't want the hacked weapon position showing in // mirrors, because the true body position will already be drawn // - if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.isPortal - || (tr.viewParms.flags & (VPF_SHADOWMAP | VPF_DEPTHSHADOW))) ) { + if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.flags & VPF_NOVIEWMODEL)) { return; } @@ -1979,7 +1982,7 @@ static void R_AddEntitySurface (int entityNum) return; } shader = R_GetShaderByHandle( ent->e.customShader ); - R_AddDrawSurf( &entitySurface, shader, R_SpriteFogNum( ent ), 0, 0 ); + R_AddDrawSurf( &entitySurface, shader, R_SpriteFogNum( ent ), 0, 0, 0 /*cubeMap*/ ); break; case RT_MODEL: @@ -1988,7 +1991,7 @@ static void R_AddEntitySurface (int entityNum) tr.currentModel = R_GetModelByHandle( ent->e.hModel ); if (!tr.currentModel) { - R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0, 0 ); + R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0, 0, 0 /*cubeMap*/ ); } else { switch ( tr.currentModel->type ) { case MOD_MESH: @@ -2010,7 +2013,7 @@ static void R_AddEntitySurface (int entityNum) if ( (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal) { break; } - R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0, 0 ); + R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0, 0, 0 ); break; default: ri.Error( ERR_DROP, "R_AddEntitySurfaces: Bad modeltype" ); @@ -2186,7 +2189,7 @@ void R_RenderDlightCubemaps(const refdef_t *fd) shadowParms.fovX = 90; shadowParms.fovY = 90; - shadowParms.flags = VPF_SHADOWMAP | VPF_DEPTHSHADOW; + shadowParms.flags = VPF_SHADOWMAP | VPF_DEPTHSHADOW | VPF_NOVIEWMODEL; shadowParms.zFar = tr.refdef.dlights[i].radius; VectorCopy( tr.refdef.dlights[i].origin, shadowParms.or.origin ); @@ -2490,7 +2493,7 @@ void R_RenderPshadowMaps(const refdef_t *fd) if (glRefConfig.framebufferObject) shadowParms.targetFbo = tr.pshadowFbos[i]; - shadowParms.flags = VPF_SHADOWMAP | VPF_DEPTHSHADOW; + shadowParms.flags = VPF_SHADOWMAP | VPF_DEPTHSHADOW | VPF_NOVIEWMODEL; shadowParms.zFar = shadow->lightRadius; VectorCopy(shadow->lightOrigin, shadowParms.or.origin); @@ -2835,7 +2838,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) if (glRefConfig.framebufferObject) shadowParms.targetFbo = tr.sunShadowFbo[level]; - shadowParms.flags = VPF_DEPTHSHADOW | VPF_DEPTHCLAMP | VPF_ORTHOGRAPHIC; + shadowParms.flags = VPF_DEPTHSHADOW | VPF_DEPTHCLAMP | VPF_ORTHOGRAPHIC | VPF_NOVIEWMODEL; shadowParms.zFar = lightviewBounds[1][0]; VectorCopy(lightOrigin, shadowParms.or.origin); @@ -2874,3 +2877,130 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) Matrix16Multiply(tr.viewParms.projectionMatrix, tr.viewParms.world.modelMatrix, tr.refdef.sunShadowMvp[level]); } } + +void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) +{ + refdef_t refdef; + viewParms_t parms; + float oldColorScale = tr.refdef.colorScale; + + memset( &refdef, 0, sizeof( refdef ) ); + refdef.rdflags = 0; + VectorCopy(tr.cubemapOrigins[cubemapIndex], refdef.vieworg); + + switch(cubemapSide) + { + case 0: + // -X + VectorSet( refdef.viewaxis[0], -1, 0, 0); + VectorSet( refdef.viewaxis[1], 0, 0, -1); + VectorSet( refdef.viewaxis[2], 0, 1, 0); + break; + case 1: + // +X + VectorSet( refdef.viewaxis[0], 1, 0, 0); + VectorSet( refdef.viewaxis[1], 0, 0, 1); + VectorSet( refdef.viewaxis[2], 0, 1, 0); + break; + case 2: + // -Y + VectorSet( refdef.viewaxis[0], 0, -1, 0); + VectorSet( refdef.viewaxis[1], 1, 0, 0); + VectorSet( refdef.viewaxis[2], 0, 0, -1); + break; + case 3: + // +Y + VectorSet( refdef.viewaxis[0], 0, 1, 0); + VectorSet( refdef.viewaxis[1], 1, 0, 0); + VectorSet( refdef.viewaxis[2], 0, 0, 1); + break; + case 4: + // -Z + VectorSet( refdef.viewaxis[0], 0, 0, -1); + VectorSet( refdef.viewaxis[1], 1, 0, 0); + VectorSet( refdef.viewaxis[2], 0, 1, 0); + break; + case 5: + // +Z + VectorSet( refdef.viewaxis[0], 0, 0, 1); + VectorSet( refdef.viewaxis[1], -1, 0, 0); + VectorSet( refdef.viewaxis[2], 0, 1, 0); + break; + } + + refdef.fov_x = 90; + refdef.fov_y = 90; + + refdef.x = 0; + refdef.y = 0; + refdef.width = tr.renderCubeFbo->width; + refdef.height = tr.renderCubeFbo->height; + + refdef.time = 0; + + if (!subscene) + { + RE_BeginScene(&refdef); + + // FIXME: sun shadows aren't rendered correctly in cubemaps + // fix involves changing r_FBufScale to fit smaller cubemap image size, or rendering cubemap to framebuffer first + if(0) //(glRefConfig.framebufferObject && (r_forceSun->integer || tr.sunShadows)) + { + R_RenderSunShadowMaps(&refdef, 0); + R_RenderSunShadowMaps(&refdef, 1); + R_RenderSunShadowMaps(&refdef, 2); + } + } + + { + vec3_t ambient, directed, lightDir; + R_LightForPoint(tr.refdef.vieworg, ambient, directed, lightDir); + tr.refdef.colorScale = 766.0f / (directed[0] + directed[1] + directed[2] + 1.0f); + if (directed[0] + directed[1] + directed[2] == 0) + { + ri.Printf(PRINT_ALL, "cubemap %d (%f, %f, %f) is outside the lightgrid!\n", cubemapIndex, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]); + } + } + + Com_Memset( &parms, 0, sizeof( parms ) ); + + parms.viewportX = 0; + parms.viewportY = 0; + parms.viewportWidth = tr.renderCubeFbo->width; + parms.viewportHeight = tr.renderCubeFbo->height; + parms.isPortal = qfalse; + parms.isMirror = qtrue; + parms.flags = VPF_NOVIEWMODEL | VPF_NOCUBEMAPS; + + parms.fovX = 90; + parms.fovY = 90; + + VectorCopy( refdef.vieworg, parms.or.origin ); + VectorCopy( refdef.viewaxis[0], parms.or.axis[0] ); + VectorCopy( refdef.viewaxis[1], parms.or.axis[1] ); + VectorCopy( refdef.viewaxis[2], parms.or.axis[2] ); + + VectorCopy( refdef.vieworg, parms.pvsOrigin ); + + // FIXME: sun shadows aren't rendered correctly in cubemaps + // fix involves changing r_FBufScale to fit smaller cubemap image size, or rendering cubemap to framebuffer first + if (0) //(r_depthPrepass->value && ((r_forceSun->integer) || tr.sunShadows)) + { + parms.flags = VPF_USESUNLIGHT; + } + + parms.targetFbo = tr.renderCubeFbo; + parms.targetFboLayer = cubemapSide; + parms.targetFboCubemapIndex = cubemapIndex; + + R_RenderView(&parms); + + if (subscene) + { + tr.refdef.colorScale = oldColorScale; + } + else + { + RE_EndScene(); + } +} \ No newline at end of file diff --git a/code/renderergl2/tr_mesh.c b/code/renderergl2/tr_mesh.c index 28c2e5fb..618958be 100644 --- a/code/renderergl2/tr_mesh.c +++ b/code/renderergl2/tr_mesh.c @@ -288,6 +288,7 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { int cull; int lod; int fogNum; + int cubemapIndex; qboolean personalModel; // don't add third_person objects if not in a portal @@ -344,6 +345,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { // fogNum = R_ComputeFogNum( model, ent ); + cubemapIndex = R_CubemapForPoint(ent->e.origin); + // // draw all surfaces // @@ -387,7 +390,7 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) { { srfVBOMDVMesh_t *vboSurface = &model->vboSurfaces[i]; - R_AddDrawSurf((void *)vboSurface, shader, fogNum, qfalse, qfalse ); + R_AddDrawSurf((void *)vboSurface, shader, fogNum, qfalse, qfalse, cubemapIndex ); } surface++; diff --git a/code/renderergl2/tr_model_iqm.c b/code/renderergl2/tr_model_iqm.c index 30b8ff07..44c98ee0 100644 --- a/code/renderergl2/tr_model_iqm.c +++ b/code/renderergl2/tr_model_iqm.c @@ -786,6 +786,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { qboolean personalModel; int cull; int fogNum; + int cubemapIndex; shader_t *shader; skin_t *skin; @@ -838,6 +839,8 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { // fogNum = R_ComputeIQMFogNum( data, ent ); + cubemapIndex = R_CubemapForPoint(ent->e.origin); + for ( i = 0 ; i < data->num_surfaces ; i++ ) { if(ent->e.customShader) shader = R_GetShaderByHandle( ent->e.customShader ); @@ -866,7 +869,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { && fogNum == 0 && !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) ) && shader->sort == SS_OPAQUE ) { - R_AddDrawSurf( (void *)surface, tr.shadowShader, 0, 0, 0 ); + R_AddDrawSurf( (void *)surface, tr.shadowShader, 0, 0, 0, 0 ); } // projection shadows work fine with personal models @@ -874,11 +877,11 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { && fogNum == 0 && (ent->e.renderfx & RF_SHADOW_PLANE ) && shader->sort == SS_OPAQUE ) { - R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, 0, 0 ); + R_AddDrawSurf( (void *)surface, tr.projectionShadowShader, 0, 0, 0, 0 ); } if( !personalModel ) { - R_AddDrawSurf( (void *)surface, shader, fogNum, 0, 0 ); + R_AddDrawSurf( (void *)surface, shader, fogNum, 0, 0, cubemapIndex ); } surface++; diff --git a/code/renderergl2/tr_scene.c b/code/renderergl2/tr_scene.c index 7e774185..e3f52958 100644 --- a/code/renderergl2/tr_scene.c +++ b/code/renderergl2/tr_scene.c @@ -99,7 +99,7 @@ void R_AddPolygonSurfaces( void ) { for ( i = 0, poly = tr.refdef.polys; i < tr.refdef.numPolys ; i++, poly++ ) { sh = R_GetShaderByHandle( poly->hShader ); - R_AddDrawSurf( ( void * )poly, sh, poly->fogIndex & fogMask, qfalse, qfalse ); + R_AddDrawSurf( ( void * )poly, sh, poly->fogIndex & fogMask, qfalse, qfalse, 0 /*cubeMap*/ ); } } @@ -283,36 +283,9 @@ void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, flo RE_AddDynamicLightToScene( org, intensity, r, g, b, qtrue ); } -/* -@@@@@@@@@@@@@@@@@@@@@ -RE_RenderScene - -Draw a 3D view into a part of the window, then return -to 2D drawing. - -Rendering a scene may require multiple views to be rendered -to handle mirrors, -@@@@@@@@@@@@@@@@@@@@@ -*/ -void RE_RenderScene( const refdef_t *fd ) { - viewParms_t parms; - int startTime; - - if ( !tr.registered ) { - return; - } - GLimp_LogComment( "====== RE_RenderScene =====\n" ); - - if ( r_norefresh->integer ) { - return; - } - - startTime = ri.Milliseconds(); - - if (!tr.world && !( fd->rdflags & RDF_NOWORLDMODEL ) ) { - ri.Error (ERR_DROP, "R_RenderScene: NULL worldmodel"); - } +void RE_BeginScene(const refdef_t *fd) +{ Com_Memcpy( tr.refdef.text, fd->text, sizeof( tr.refdef.text ) ); tr.refdef.x = fd->x; @@ -466,6 +439,49 @@ void RE_RenderScene( const refdef_t *fd ) { // each scene / view. tr.frameSceneNum++; tr.sceneCount++; +} + + +void RE_EndScene() +{ + // the next scene rendered in this frame will tack on after this one + r_firstSceneDrawSurf = tr.refdef.numDrawSurfs; + r_firstSceneEntity = r_numentities; + r_firstSceneDlight = r_numdlights; + r_firstScenePoly = r_numpolys; +} + +/* +@@@@@@@@@@@@@@@@@@@@@ +RE_RenderScene + +Draw a 3D view into a part of the window, then return +to 2D drawing. + +Rendering a scene may require multiple views to be rendered +to handle mirrors, +@@@@@@@@@@@@@@@@@@@@@ +*/ +void RE_RenderScene( const refdef_t *fd ) { + viewParms_t parms; + int startTime; + + if ( !tr.registered ) { + return; + } + GLimp_LogComment( "====== RE_RenderScene =====\n" ); + + if ( r_norefresh->integer ) { + return; + } + + startTime = ri.Milliseconds(); + + if (!tr.world && !( fd->rdflags & RDF_NOWORLDMODEL ) ) { + ri.Error (ERR_DROP, "R_RenderScene: NULL worldmodel"); + } + + RE_BeginScene(fd); // SmileTheory: playing with shadow mapping if (!( fd->rdflags & RDF_NOWORLDMODEL ) && tr.refdef.num_dlights && r_dlightMode->integer >= 2) @@ -487,6 +503,21 @@ void RE_RenderScene( const refdef_t *fd ) { R_RenderSunShadowMaps(fd, 2); } + // playing with cube maps + // this is where dynamic cubemaps would be rendered + if (0) //(glRefConfig.framebufferObject && !( fd->rdflags & RDF_NOWORLDMODEL )) + { + int i, j; + + for (i = 0; i < tr.numCubemaps; i++) + { + for (j = 0; j < 6; j++) + { + R_RenderCubemapSide(i, j, qtrue); + } + } + } + // setup view parms for the initial view // // set up viewport @@ -522,11 +553,7 @@ void RE_RenderScene( const refdef_t *fd ) { if(!( fd->rdflags & RDF_NOWORLDMODEL )) R_AddPostProcessCmd(); - // the next scene rendered in this frame will tack on after this one - r_firstSceneDrawSurf = tr.refdef.numDrawSurfs; - r_firstSceneEntity = r_numentities; - r_firstSceneDlight = r_numdlights; - r_firstScenePoly = r_numpolys; + RE_EndScene(); tr.frontEndMsec += ri.Milliseconds() - startTime; } diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index 633b3f43..c704310b 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -186,7 +186,7 @@ because a surface may be forced to perform a RB_End due to overflow. ============== */ -void RB_BeginSurface( shader_t *shader, int fogNum ) { +void RB_BeginSurface( shader_t *shader, int fogNum, int cubemapIndex ) { shader_t *state = (shader->remappedShader) ? shader->remappedShader : shader; @@ -196,6 +196,7 @@ void RB_BeginSurface( shader_t *shader, int fogNum ) { tess.multiDrawPrimitives = 0; tess.shader = state; tess.fogNum = fogNum; + tess.cubemapIndex = cubemapIndex; tess.dlightBits = 0; // will be OR'd in by surface functions tess.pshadowBits = 0; // will be OR'd in by surface functions tess.xstages = state->stages; @@ -846,7 +847,7 @@ static void ForwardDlight( void ) { if (r_dlightMode->integer >= 2) { GL_SelectTexture(TB_SHADOWMAP); - GL_BindCubemap(tr.shadowCubemaps[l]); + GL_Bind(tr.shadowCubemaps[l]); GL_SelectTexture(0); } @@ -1133,6 +1134,11 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) index |= LIGHTDEF_USE_SHADOWMAP; } + if (!(tr.viewParms.flags & VPF_NOCUBEMAPS) && (index & LIGHTDEF_LIGHTTYPE_MASK) && input->cubemapIndex) + { + index |= LIGHTDEF_USE_CUBEMAP; + } + if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP) { index = LIGHTDEF_USE_LIGHTMAP; @@ -1177,39 +1183,10 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { vec4_t baseColor; vec4_t vertColor; - qboolean tint = qtrue; - int stage2; ComputeShaderColors(pStage, baseColor, vertColor); - for ( stage2 = stage + 1; stage2 < MAX_SHADER_STAGES; stage2++ ) - { - shaderStage_t *pStage2 = input->xstages[stage2]; - unsigned int srcBlendBits; - //unsigned int dstBlendBits; - - if ( !pStage2 ) - { - break; - } - - srcBlendBits = pStage2->stateBits & GLS_SRCBLEND_BITS; - //dstBlendBits = pStage2->stateBits & GLS_DSTBLEND_BITS; - - if (srcBlendBits == GLS_SRCBLEND_DST_COLOR) - { - tint = qfalse; - break; - } - } - - if (!((tr.sunShadows || r_forceSun->integer) && tess.shader->sort <= SS_OPAQUE - && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader)) - { - tint = qfalse; - } - - if (tint) + if ((backEnd.refdef.colorScale != 1.0f) && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL)) { // use VectorScale to only scale first three values, not alpha VectorScale(baseColor, backEnd.refdef.colorScale, baseColor); @@ -1373,6 +1350,12 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) GLSL_SetUniformInt(sp, UNIFORM_TEXTURE1ENV, 0); } + // + // testing cube map + // + if (!(tr.viewParms.flags & VPF_NOCUBEMAPS) && input->cubemapIndex && r_cubeMapping->integer) + GL_BindToTMU( tr.cubemaps[input->cubemapIndex - 1], TB_CUBEMAP); + // // draw // diff --git a/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index da2a7c60..c246127d 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -910,8 +910,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) else if(!Q_stricmp(token, "specularMap")) { stage->type = ST_SPECULARMAP; - stage->materialInfo[0] = 0.04f; - stage->materialInfo[1] = 256.0f; + stage->materialInfo[0] = 1.0f; + stage->materialInfo[1] = 1.0f; } else { @@ -937,12 +937,35 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) // else if (!Q_stricmp(token, "specularexponent")) { + float exponent; + token = COM_ParseExt(text, qfalse); if ( token[0] == 0 ) { ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular exponent in shader '%s'\n", shader.name ); continue; } + + exponent = atof( token ); + + // Change shininess to gloss + // FIXME: assumes max exponent of 8192 and min of 1, must change here if altered in lightall_fp.glsl + exponent = CLAMP(exponent, 1.0, 8192.0); + + stage->materialInfo[1] = log(exponent) / log(8192.0); + } + // + // gloss + // + else if (!Q_stricmp(token, "gloss")) + { + token = COM_ParseExt(text, qfalse); + if ( token[0] == 0 ) + { + ri.Printf( PRINT_WARNING, "WARNING: missing parameter for gloss in shader '%s'\n", shader.name ); + continue; + } + stage->materialInfo[1] = atof( token ); } // @@ -1926,7 +1949,7 @@ static void ComputeVertexAttribs(void) shader.vertexAttribs |= ATTR_NORMAL; #ifdef USE_VERT_TANGENT_SPACE - if (pStage->glslShaderIndex & LIGHTDEF_USE_NORMALMAP) + if ((pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && !(r_normalMapping->integer == 0 && r_specularMapping->integer == 0)) { shader.vertexAttribs |= ATTR_BITANGENT | ATTR_TANGENT; } @@ -2200,7 +2223,6 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, { //ri.Printf(PRINT_ALL, ", normalmap %s", normal->bundle[0].image[0]->imgName); diffuse->bundle[TB_NORMALMAP] = normal->bundle[0]; - defs |= LIGHTDEF_USE_NORMALMAP; if (parallax && r_parallaxMapping->integer) defs |= LIGHTDEF_USE_PARALLAXMAP; } @@ -2218,13 +2240,22 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, if (normalImg) { diffuse->bundle[TB_NORMALMAP] = diffuse->bundle[0]; + diffuse->bundle[TB_NORMALMAP].numImageAnimations = 0; diffuse->bundle[TB_NORMALMAP].image[0] = normalImg; - defs |= LIGHTDEF_USE_NORMALMAP; if (parallax && r_parallaxMapping->integer) defs |= LIGHTDEF_USE_PARALLAXMAP; } } + + if (!diffuse->bundle[TB_NORMALMAP].image[0]) + { + // use 0x80 image, shader will interpret as (0,0,1) + diffuse->bundle[TB_NORMALMAP] = diffuse->bundle[0]; + diffuse->bundle[TB_NORMALMAP].numImageAnimations = 0; + diffuse->bundle[TB_NORMALMAP].image[0] = tr.greyImage; + //ri.Printf(PRINT_ALL, ", normalmap %s", diffuse->bundle[TB_NORMALMAP].image[0]->imgName); + } } if (r_specularMapping->integer) @@ -2235,7 +2266,18 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, diffuse->bundle[TB_SPECULARMAP] = specular->bundle[0]; diffuse->materialInfo[0] = specular->materialInfo[0]; diffuse->materialInfo[1] = specular->materialInfo[1]; - defs |= LIGHTDEF_USE_SPECULARMAP; + } + else if (lightmap || useLightVector || useLightVertex) + { + // use a white image, materialinfo will do the rest + diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0]; + diffuse->bundle[TB_SPECULARMAP].numImageAnimations = 0; + diffuse->bundle[TB_SPECULARMAP].image[0] = tr.whiteImage; + if (!diffuse->materialInfo[0]) + diffuse->materialInfo[0] = r_baseSpecular->value; + if (!diffuse->materialInfo[1]) + diffuse->materialInfo[1] = r_baseGloss->value; + //ri.Printf(PRINT_ALL, ", specularmap %s", diffuse->bundle[TB_SPECULARMAP].image[0]->imgName); } } @@ -2493,7 +2535,7 @@ static qboolean CollapseStagesToGLSL(void) // convert any remaining lightmap stages to a lighting pass with a white texture // only do this with r_sunlightMode non-zero, as it's only for correct shadows. - if (r_sunlightMode->integer) + if (r_sunlightMode->integer && shader.numDeforms == 0) { for (i = 0; i < MAX_SHADER_STAGES; i++) { @@ -2502,6 +2544,9 @@ static qboolean CollapseStagesToGLSL(void) if (!pStage->active) continue; + if (pStage->adjustColorsForFog) + continue; + if (pStage->bundle[TB_DIFFUSEMAP].isLightmap) { pStage->glslShaderGroup = tr.lightallShader; @@ -2515,6 +2560,43 @@ static qboolean CollapseStagesToGLSL(void) } } + // convert any remaining lightingdiffuse stages to a lighting pass + if (shader.numDeforms == 0) + { + for (i = 0; i < MAX_SHADER_STAGES; i++) + { + shaderStage_t *pStage = &stages[i]; + + if (!pStage->active) + continue; + + if (pStage->adjustColorsForFog) + continue; + + if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) + { + pStage->glslShaderGroup = tr.lightallShader; + pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR; + } + } + } + + // convert any remaining lightingdiffuse stages to a lighting pass + for (i = 0; i < MAX_SHADER_STAGES; i++) + { + shaderStage_t *pStage = &stages[i]; + + if (!pStage->active) + continue; + + if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) + { + pStage->glslShaderGroup = tr.lightallShader; + pStage->glslShaderIndex = LIGHTDEF_USE_LIGHT_VECTOR; + } + } + + return numStages; } diff --git a/code/renderergl2/tr_sky.c b/code/renderergl2/tr_sky.c index f1e5249d..7fd4b3aa 100644 --- a/code/renderergl2/tr_sky.c +++ b/code/renderergl2/tr_sky.c @@ -449,7 +449,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max color[0] = color[1] = - color[2] = tr.identityLight; + color[2] = tr.identityLight * backEnd.refdef.colorScale; color[3] = 1.0f; GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, color); @@ -826,7 +826,7 @@ void RB_DrawSun( float scale, shader_t *shader ) { // farthest depth range qglDepthRange( 1.0, 1.0 ); - RB_BeginSurface( shader, 0 ); + RB_BeginSurface( shader, 0, 0 ); RB_AddQuadStamp(origin, vec1, vec2, colorWhite); diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index 427d153d..06072a82 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -63,7 +63,7 @@ void RB_CheckOverflow( int verts, int indexes ) { ri.Error(ERR_DROP, "RB_CheckOverflow: indices > MAX (%d > %d)", indexes, SHADER_MAX_INDEXES ); } - RB_BeginSurface(tess.shader, tess.fogNum ); + RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex ); } void RB_CheckVBOandIBO(VBO_t *vbo, IBO_t *ibo) @@ -71,7 +71,7 @@ void RB_CheckVBOandIBO(VBO_t *vbo, IBO_t *ibo) if (!(vbo == glState.currentVBO && ibo == glState.currentIBO) || tess.multiDrawPrimitives >= MAX_MULTIDRAW_PRIMITIVES) { RB_EndSurface(); - RB_BeginSurface(tess.shader, tess.fogNum); + RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex); R_BindVBO(vbo); R_BindIBO(ibo); @@ -1370,7 +1370,7 @@ static void RB_SurfaceGrid( srfGridMesh_t *srf ) { // if we don't have enough space for at least one strip, flush the buffer if ( vrows < 2 || irows < 1 ) { RB_EndSurface(); - RB_BeginSurface(tess.shader, tess.fogNum ); + RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex ); } else { break; } @@ -1593,7 +1593,7 @@ void RB_SurfaceVBOMDVMesh(srfVBOMDVMesh_t * surface) //RB_CheckVBOandIBO(surface->vbo, surface->ibo); RB_EndSurface(); - RB_BeginSurface(tess.shader, tess.fogNum); + RB_BeginSurface(tess.shader, tess.fogNum, tess.cubemapIndex); R_BindVBO(surface->vbo); R_BindIBO(surface->ibo); diff --git a/code/renderergl2/tr_world.c b/code/renderergl2/tr_world.c index e67be16f..0ee4ad28 100644 --- a/code/renderergl2/tr_world.c +++ b/code/renderergl2/tr_world.c @@ -337,7 +337,7 @@ static void R_AddWorldSurface( msurface_t *surf, int dlightBits, int pshadowBits pshadowBits = ( pshadowBits != 0 ); } - R_AddDrawSurf( surf->data, surf->shader, surf->fogIndex, dlightBits, pshadowBits ); + R_AddDrawSurf( surf->data, surf->shader, surf->fogIndex, dlightBits, pshadowBits, surf->cubemapIndex ); } /* diff --git a/code/sdl/sdl_glimp.c b/code/sdl/sdl_glimp.c index 0936c43d..4d8c752f 100644 --- a/code/sdl/sdl_glimp.c +++ b/code/sdl/sdl_glimp.c @@ -817,7 +817,7 @@ void GLimp_EndFrame( void ) { // SDL_WM_ToggleFullScreen didn't work, so do it the slow way if( !sdlToggled ) - ri.Cmd_ExecuteText(EXEC_APPEND, "vid_restart"); + ri.Cmd_ExecuteText(EXEC_APPEND, "vid_restart\n"); ri.IN_Restart( ); } diff --git a/code/sdl/sdl_input.c b/code/sdl/sdl_input.c index 72c66096..88c0ef58 100644 --- a/code/sdl/sdl_input.c +++ b/code/sdl/sdl_input.c @@ -999,7 +999,7 @@ void IN_Frame( void ) if ( (vidRestartTime != 0) && (vidRestartTime < Sys_Milliseconds()) ) { vidRestartTime = 0; - Cbuf_AddText( "vid_restart" ); + Cbuf_AddText( "vid_restart\n" ); } } diff --git a/code/sys/con_win32.c b/code/sys/con_win32.c index edfa4e6a..ea64e013 100644 --- a/code/sys/con_win32.c +++ b/code/sys/con_win32.c @@ -37,6 +37,7 @@ static CONSOLE_CURSOR_INFO qconsole_orig_cursorinfo; // cmd history static char qconsole_history[ QCONSOLE_HISTORY ][ MAX_EDIT_LINE ]; static int qconsole_history_pos = -1; +static int qconsole_history_lines = 0; static int qconsole_history_oldest = 0; // current edit buffer @@ -107,6 +108,9 @@ static void CON_HistAdd( void ) Q_strncpyz( qconsole_history[ qconsole_history_oldest ], qconsole_line, sizeof( qconsole_history[ qconsole_history_oldest ] ) ); + if( qconsole_history_lines < QCONSOLE_HISTORY ) + qconsole_history_lines++; + if( qconsole_history_oldest >= QCONSOLE_HISTORY - 1 ) qconsole_history_oldest = 0; else @@ -128,7 +132,7 @@ static void CON_HistPrev( void ) ( QCONSOLE_HISTORY - 1 ) : ( qconsole_history_pos - 1 ); // don' t allow looping through history - if( pos == qconsole_history_oldest ) + if( pos == qconsole_history_oldest || pos >= qconsole_history_lines ) return; qconsole_history_pos = pos; @@ -146,12 +150,17 @@ static void CON_HistNext( void ) { int pos; + // don' t allow looping through history + if( qconsole_history_pos == qconsole_history_oldest ) + return; + pos = ( qconsole_history_pos >= QCONSOLE_HISTORY - 1 ) ? 0 : ( qconsole_history_pos + 1 ); // clear the edit buffer if they try to advance to a future command if( pos == qconsole_history_oldest ) { + qconsole_history_pos = pos; qconsole_line[ 0 ] = '\0'; qconsole_linelen = 0; return; diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c index 607d0f21..c2de336d 100644 --- a/code/sys/sys_unix.c +++ b/code/sys/sys_unix.c @@ -513,6 +513,7 @@ void Sys_ErrorDialog( const char *error ) const char *homepath = Cvar_VariableString( "fs_homepath" ); const char *gamedir = Cvar_VariableString( "fs_game" ); const char *fileName = "crashlog.txt"; + char *dirpath = FS_BuildOSPath( homepath, gamedir, ""); char *ospath = FS_BuildOSPath( homepath, gamedir, fileName ); Sys_Print( va( "%s\n", error ) ); @@ -522,8 +523,16 @@ void Sys_ErrorDialog( const char *error ) #endif // Make sure the write path for the crashlog exists... - if( FS_CreatePath( ospath ) ) { - Com_Printf( "ERROR: couldn't create path '%s' for crash log.\n", ospath ); + + if(!Sys_Mkdir(homepath)) + { + Com_Printf("ERROR: couldn't create path '%s' for crash log.\n", homepath); + return; + } + + if(!Sys_Mkdir(dirpath)) + { + Com_Printf("ERROR: couldn't create path '%s' for crash log.\n", dirpath); return; } diff --git a/code/tools/lcc/lburg/gram.c b/code/tools/lcc/lburg/gram.c index 8de09010..a7891031 100644 --- a/code/tools/lcc/lburg/gram.c +++ b/code/tools/lcc/lburg/gram.c @@ -1,36 +1,73 @@ -#if defined(__STDC__) || defined(__cplusplus) -#define YYCONST const -#define YYPARAMS(x) x -#define YYDEFUN(name, arglist, args) name(args) -#define YYAND , -#define YYPTR void * -#else -#define YYCONST -#define YYPARAMS(x) () -#define YYDEFUN(name, arglist, args) name arglist args; -#define YYAND ; -#define YYPTR char * -#endif #ifndef lint -YYCONST static char yysccsid[] = "@(#)yaccpar 1.8 (Berkeley +Cygnus.28) 01/20/91"; +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; #endif + #define YYBYACC 1 -#ifndef YYDONT_INCLUDE_STDIO -#include -#endif -#include /* for malloc/realloc/free */ -#line 2 "lburg/gram.y" +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20130304 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "code/tools/lcc/lburg/gram.y" #include #include "lburg.h" +static char rcsid[] = "$Id: gram.y 145 2001-10-17 21:53:10Z timo $"; /*lint -e616 -e527 -e652 -esym(552,yynerrs) -esym(563,yynewstate,yyerrlab) */ static int yylineno = 0; -#line 8 "lburg/gram.y" +#line 8 "code/tools/lcc/lburg/gram.y" +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 typedef union { int n; char *string; Tree tree; } YYSTYPE; -#line 37 "y.tab.c" +#endif /* !YYSTYPE_IS_DECLARED */ +#line 38 "y.tab.c" + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + #define TERMINAL 257 #define START 258 #define PPERCENT 259 @@ -39,40 +76,40 @@ typedef union { #define CODE 262 #define INT 263 #define YYERRCODE 256 -static YYCONST short yylhs[] = { -1, +static const short yylhs[] = { -1, 0, 0, 4, 4, 6, 6, 6, 6, 7, 7, 5, 5, 5, 5, 1, 3, 3, 3, 2, }; -static YYCONST short yylen[] = { 2, +static const short yylen[] = { 2, 3, 1, 0, 2, 3, 3, 1, 2, 0, 4, 0, 7, 2, 3, 1, 1, 4, 6, 1, }; -static YYCONST short yydefred[] = { 3, +static const short yydefred[] = { 3, 0, 0, 0, 9, 0, 11, 7, 4, 8, 0, 15, 0, 0, 0, 5, 6, 0, 13, 0, 0, 14, 0, 10, 0, 0, 0, 0, 0, 19, 0, 17, 0, 12, 0, 18, }; -static YYCONST short yydgoto[] = { 1, +static const short yydgoto[] = { 1, 12, 30, 25, 2, 13, 8, 10, }; -static YYCONST short yysindex[] = { 0, +static const short yysindex[] = { 0, 0, -4, -2, 0, -250, 0, 0, 0, 0, -9, 0, 1, -10, -49, 0, 0, 3, 0, -44, -248, 0, -244, 0, -22, -242, -244, -245, -37, 0, 10, 0, -244, 0, -20, 0, }; -static YYCONST short yyrindex[] = { 0, +static const short yyrindex[] = { 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -static YYCONST short yygindex[] = { 0, +static const short yygindex[] = { 0, 11, 0, -23, 0, 0, 0, 0, }; #define YYTABLESIZE 255 -static YYCONST short yytable[] = { 18, +static const short yytable[] = { 18, 15, 16, 28, 31, 16, 7, 32, 9, 34, 11, 16, 20, 21, 22, 23, 24, 29, 26, 27, 33, 35, 2, 1, 19, 0, 0, 0, 0, 0, 0, @@ -100,7 +137,7 @@ static YYCONST short yytable[] = { 18, 0, 0, 0, 0, 0, 17, 0, 0, 0, 11, 14, 3, 4, 5, 6, }; -static YYCONST short yycheck[] = { 10, +static const short yycheck[] = { 10, 10, 41, 26, 41, 44, 10, 44, 10, 32, 260, 10, 61, 10, 58, 263, 260, 262, 40, 261, 10, 41, 0, 0, 13, -1, -1, -1, -1, -1, -1, @@ -134,7 +171,8 @@ static YYCONST short yycheck[] = { 10, #endif #define YYMAXTOKEN 263 #if YYDEBUG -static YYCONST char *YYCONST yyname[] = { +static const char *yyname[] = { + "end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,"'('","')'",0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0, "'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -144,7 +182,7 @@ static YYCONST char *YYCONST yyname[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, "TERMINAL","START","PPERCENT","ID","TEMPLATE","CODE","INT", }; -static YYCONST char *YYCONST yyrule[] = { +static const char *yyrule[] = { "$accept : spec", "spec : decls PPERCENT rules", "spec : decls", @@ -165,96 +203,44 @@ static YYCONST char *YYCONST yyrule[] = { "tree : ID '(' tree ')'", "tree : ID '(' tree ',' tree ')'", "cost : CODE", + }; #endif -#define YYLEX yylex() -#define YYEMPTY -1 -#define yyclearin (yychar=(YYEMPTY)) -#define yyerrok (yyerrflag=0) -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ #ifdef YYSTACKSIZE -#ifndef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#endif +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE #else #ifdef YYMAXDEPTH #define YYSTACKSIZE YYMAXDEPTH #else -#define YYSTACKSIZE 500 -#define YYMAXDEPTH 500 +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 500 #endif #endif -#ifndef YYMAXSTACKSIZE -#define YYMAXSTACKSIZE 10000 -#endif -int yydebug; -int yynerrs; -int yyerrflag; -int yychar; -YYSTYPE yyval; -YYSTYPE yylval; -static short *yyss; -static YYSTYPE *yyvs; -static int yystacksize; -#define yyfree(x) free(x) -extern int yylex(); -static YYPTR -YYDEFUN (yymalloc, (bytes), unsigned bytes) -{ - YYPTR ptr = (YYPTR) malloc (bytes); - if (ptr != 0) return (ptr); - yyerror ("yyparse: memory exhausted"); - return (0); -} +#define YYINITSTACKSIZE 500 -static YYPTR -YYDEFUN (yyrealloc, (old, bytes), YYPTR old YYAND unsigned bytes) -{ - YYPTR ptr = (YYPTR) realloc (old, bytes); - if (ptr != 0) return (ptr); - yyerror ("yyparse: memory exhausted"); - return (0); -} - -static int -#ifdef __GNUC__ -inline -#endif -yygrow () -{ -#if YYDEBUG - int old_stacksize = yystacksize; -#endif - short *new_yyss; - YYSTYPE *new_yyvs; - - if (yystacksize == YYMAXSTACKSIZE) - return (1); - yystacksize += (yystacksize + 1 ) / 2; - if (yystacksize > YYMAXSTACKSIZE) - yystacksize = YYMAXSTACKSIZE; -#if YYDEBUG - if (yydebug) - printf("yydebug: growing stack size from %d to %d\n", - old_stacksize, yystacksize); -#endif - new_yyss = (short *) yyrealloc ((char *)yyss, yystacksize * sizeof (short)); - if (new_yyss == 0) - return (1); - new_yyvs = (YYSTYPE *) yyrealloc ((char *)yyvs, yystacksize * sizeof (YYSTYPE)); - if (new_yyvs == 0) - { - yyfree (new_yyss); - return (1); - } - yyss = new_yyss; - yyvs = new_yyvs; - return (0); -} -#line 60 "lburg/gram.y" +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 60 "code/tools/lcc/lburg/gram.y" #include #include #include @@ -398,30 +384,74 @@ void yywarn(char *fmt, ...) { fprintf(stderr, "warning: "); vfprintf(stderr, fmt, ap); } -#line 403 "y.tab.c" -#define YYABORT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab +#line 387 "y.tab.c" #if YYDEBUG -#ifdef __cplusplus -extern "C" char *getenv(); +#include /* needed for printf */ +#endif + +#include /* needed for malloc, etc */ +#include /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} #else -extern char *getenv(); -#endif +#define yyfreestack(data) /* nothing */ #endif +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + int -yyparse() +YYPARSE_DECL() { - register int yym, yyn, yystate; - register YYSTYPE *yyvsp; - register short *yyssp; - short *yysse; + int yym, yyn, yystate; #if YYDEBUG - register YYCONST char *yys; + const char *yys; - if (yys = getenv("YYDEBUG")) + if ((yys = getenv("YYDEBUG")) != 0) { yyn = *yys; if (yyn >= '0' && yyn <= '9') @@ -431,120 +461,102 @@ yyparse() yynerrs = 0; yyerrflag = 0; - yychar = (-1); + yychar = YYEMPTY; + yystate = 0; - if (yyss == 0) - { - yyss = (short *) yymalloc (YYSTACKSIZE * sizeof (short)); - if (yyss == 0) - goto yyabort; - yyvs = (YYSTYPE *) yymalloc (YYSTACKSIZE * sizeof (YYSTYPE)); - if (yyvs == 0) - { - yyfree (yyss); - goto yyabort; - } - yystacksize = YYSTACKSIZE; - } - yysse = yyss + yystacksize - 1; - yyssp = yyss; - yyvsp = yyvs; - *yyssp = yystate = 0; - goto yyloop; +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif -yypush_lex: - yyval = yylval; - yystate = yytable[yyn]; -yypush: - if (yyssp >= yysse) - { - int depth = yyssp - yyss; - if (yygrow() != 0) - goto yyoverflow; - yysse = yyss + yystacksize -1; - yyssp = depth + yyss; - yyvsp = depth + yyvs; - } - *++yyssp = yystate; - *++yyvsp = yyval; + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; yyloop: - if ((yyn = yydefred[yystate])) goto yyreduce; - yyn = yysindex[yystate]; + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; if (yychar < 0) { - if ((yychar = yylex()) < 0) yychar = 0; + if ((yychar = YYLEX) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; - printf("yydebug: state %d, reading %d (%s)\n", yystate, - yychar, yys); + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); } #endif } - if (yyn != 0 - && ((yyn += yychar), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == yychar) + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) - printf("yydebug: state %d, shifting to state %d\n", - yystate, yytable[yyn]); + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); #endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; if (yyerrflag > 0) --yyerrflag; - yychar = (-1); - goto yypush_lex; + goto yyloop; } - yyn = yyrindex[yystate]; - if (yyn != 0 - && ((yyn += yychar), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == yychar) + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery; -#ifdef lint - goto yynewerror; -yynewerror: -#endif + yyerror("syntax error"); -#ifdef lint + goto yyerrlab; + yyerrlab: -#endif ++yynerrs; + yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { - yyn = yysindex[*yyssp]; - if (yyn != 0 - && ((yyn += YYERRCODE), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == YYERRCODE) + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) - printf("yydebug: state %d, error recovery shifting\ - to state %d\n", *yyssp, yytable[yyn]); + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); #endif - goto yypush_lex; + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; } else { #if YYDEBUG if (yydebug) - printf("yydebug: error recovery discarding state %d\n", - *yyssp); + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); #endif - if (yyssp <= yyss) goto yyabort; - --yyssp; - --yyvsp; + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; } } } @@ -557,124 +569,137 @@ yyinrecovery: yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; - printf("yydebug: state %d, error recovery discards token %d (%s)\n", - yystate, yychar, yys); + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); } #endif - yychar = (-1); + yychar = YYEMPTY; goto yyloop; } + yyreduce: #if YYDEBUG if (yydebug) - printf("yydebug: state %d, reducing by rule %d (%s)\n", - yystate, yyn, yyrule[yyn]); + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; - yyval = yyvsp[1-yym]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); switch (yyn) { case 1: -#line 22 "lburg/gram.y" -{ yylineno = 0; } +#line 22 "code/tools/lcc/lburg/gram.y" + { yylineno = 0; } break; case 2: -#line 23 "lburg/gram.y" -{ yylineno = 0; } +#line 23 "code/tools/lcc/lburg/gram.y" + { yylineno = 0; } break; case 6: -#line 31 "lburg/gram.y" -{ - if (nonterm(yyvsp[-1].string)->number != 1) +#line 31 "code/tools/lcc/lburg/gram.y" + { + if (nonterm(yystack.l_mark[-1].string)->number != 1) yyerror("redeclaration of the start symbol\n"); } break; case 8: -#line 36 "lburg/gram.y" -{ yyerrok; } +#line 36 "code/tools/lcc/lburg/gram.y" + { yyerrok; } break; case 10: -#line 40 "lburg/gram.y" -{ term(yyvsp[-2].string, yyvsp[0].n); } +#line 40 "code/tools/lcc/lburg/gram.y" + { term(yystack.l_mark[-2].string, yystack.l_mark[0].n); } break; case 12: -#line 44 "lburg/gram.y" -{ rule(yyvsp[-5].string, yyvsp[-3].tree, yyvsp[-2].string, yyvsp[-1].string); } +#line 44 "code/tools/lcc/lburg/gram.y" + { rule(yystack.l_mark[-5].string, yystack.l_mark[-3].tree, yystack.l_mark[-2].string, yystack.l_mark[-1].string); } break; case 14: -#line 46 "lburg/gram.y" -{ yyerrok; } +#line 46 "code/tools/lcc/lburg/gram.y" + { yyerrok; } break; case 15: -#line 49 "lburg/gram.y" -{ nonterm(yyval.string = yyvsp[0].string); } +#line 49 "code/tools/lcc/lburg/gram.y" + { nonterm(yyval.string = yystack.l_mark[0].string); } break; case 16: -#line 52 "lburg/gram.y" -{ yyval.tree = tree(yyvsp[0].string, 0, 0); } +#line 52 "code/tools/lcc/lburg/gram.y" + { yyval.tree = tree(yystack.l_mark[0].string, 0, 0); } break; case 17: -#line 53 "lburg/gram.y" -{ yyval.tree = tree(yyvsp[-3].string, yyvsp[-1].tree, 0); } +#line 53 "code/tools/lcc/lburg/gram.y" + { yyval.tree = tree(yystack.l_mark[-3].string, yystack.l_mark[-1].tree, 0); } break; case 18: -#line 54 "lburg/gram.y" -{ yyval.tree = tree(yyvsp[-5].string, yyvsp[-3].tree, yyvsp[-1].tree); } +#line 54 "code/tools/lcc/lburg/gram.y" + { yyval.tree = tree(yystack.l_mark[-5].string, yystack.l_mark[-3].tree, yystack.l_mark[-1].tree); } break; case 19: -#line 57 "lburg/gram.y" -{ if (*yyvsp[0].string == 0) yyval.string = "0"; } +#line 57 "code/tools/lcc/lburg/gram.y" + { if (*yystack.l_mark[0].string == 0) yyval.string = "0"; } break; -#line 630 "y.tab.c" +#line 644 "y.tab.c" } - yyssp -= yym; - yyvsp -= yym; + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; yym = yylhs[yyn]; - yystate = *yyssp; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) - printf("yydebug: after reduction, shifting from state 0 to\ - state %d\n", YYFINAL); + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); #endif yystate = YYFINAL; - *++yyssp = YYFINAL; - *++yyvsp = yyval; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; if (yychar < 0) { - if ((yychar = yylex()) < 0) yychar = 0; + if ((yychar = YYLEX) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; - printf("yydebug: state %d, reading %d (%s)\n", - YYFINAL, yychar, yys); + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); } #endif } if (yychar == 0) goto yyaccept; goto yyloop; } - yyn = yygindex[yym]; - if (yyn != 0 - && ((yyn += yystate), ((unsigned)yyn <= (unsigned)YYTABLESIZE)) - && yycheck[yyn] == yystate) + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) - printf("yydebug: after reduction, shifting from state %d \ -to state %d\n", *yyssp, yystate); + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); #endif - goto yypush; + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + yyoverflow: yyerror("yacc stack overflow"); + yyabort: + yyfreestack(&yystack); return (1); + yyaccept: + yyfreestack(&yystack); return (0); } diff --git a/code/ui/ui_players.c b/code/ui/ui_players.c index 99aaed6d..8c0f3853 100644 --- a/code/ui/ui_players.c +++ b/code/ui/ui_players.c @@ -1112,7 +1112,7 @@ static qboolean UI_ParseAnimationFile(const char *filename, animation_t * animat break; } - Com_Printf("unknown token '%s' is %s\n", token, filename); + Com_Printf("unknown token '%s' in %s\n", token, filename); } // read information for each frame diff --git a/make-macosx-app.sh b/make-macosx-app.sh index 4ed57d61..7768964a 100755 --- a/make-macosx-app.sh +++ b/make-macosx-app.sh @@ -75,11 +75,11 @@ function symlinkArch() pushd "${DSTPATH}" > /dev/null - IS32=`file "${SRCFILE}.${EXT}" | grep "i386" | awk '{print $NF}'` - IS64=`file "${SRCFILE}.${EXT}" | grep "x86_64" | awk '{print $NF}'` - ISPPC=`file "${SRCFILE}.${EXT}" | grep "ppc" | awk '{print $NF}'` + IS32=`file "${SRCFILE}.${EXT}" | grep "i386"` + IS64=`file "${SRCFILE}.${EXT}" | grep "x86_64"` + ISPPC=`file "${SRCFILE}.${EXT}" | grep "ppc"` - if [ "${IS32}" == "i386" ]; then + if [ "${IS32}" != "" ]; then if [ ! -L "${DSTFILE}x86.${EXT}" ]; then ln -s "${SRCFILE}.${EXT}" "${DSTFILE}x86.${EXT}" fi @@ -87,7 +87,7 @@ function symlinkArch() rm "${DSTFILE}x86.${EXT}" fi - if [ "${IS64}" == "x86_64" ]; then + if [ "${IS64}" != "" ]; then if [ ! -L "${DSTFILE}x86_64.${EXT}" ]; then ln -s "${SRCFILE}.${EXT}" "${DSTFILE}x86_64.${EXT}" fi @@ -95,7 +95,7 @@ function symlinkArch() rm "${DSTFILE}x86_64.${EXT}" fi - if [ "${ISPPC}" == "ppc" ]; then + if [ "${ISPPC}" != "" ]; then if [ ! -L "${DSTFILE}ppc.${EXT}" ]; then ln -s "${SRCFILE}.${EXT}" "${DSTFILE}ppc.${EXT}" fi diff --git a/make-macosx-ub.sh b/make-macosx-ub.sh index 5f73fe36..bd7c9b91 100755 --- a/make-macosx-ub.sh +++ b/make-macosx-ub.sh @@ -1,6 +1,5 @@ #!/bin/bash CC=gcc-4.0 -BINARY=ioquake3.ub cd `dirname $0` if [ ! -f Makefile ]; then @@ -8,12 +7,6 @@ if [ ! -f Makefile ]; then exit 1 fi -Q3_VERSION=`grep '^VERSION=' Makefile | sed -e 's/.*=\(.*\)/\1/'` - -# We only care if we're >= 10.4, not if we're specifically Tiger. -# "8" is the Darwin major kernel version. -TIGERHOST=`uname -r |perl -w -p -e 's/\A(\d+)\..*\Z/$1/; $_ = (($_ >= 8) ? "1" : "0");'` - # we want to use the oldest available SDK for max compatiblity. However 10.4 and older # can not build 64bit binaries, making 10.5 the minimum version. This has been tested # with xcode 3.1 (xcode31_2199_developerdvd.dmg). It contains the 10.5 SDK and a decent diff --git a/make-macosx.sh b/make-macosx.sh index 6dd5df17..035b3998 100644 --- a/make-macosx.sh +++ b/make-macosx.sh @@ -38,12 +38,6 @@ if [ ! -f Makefile ]; then exit 1 fi -Q3_VERSION=`grep '^VERSION=' Makefile | sed -e 's/.*=\(.*\)/\1/'` - -# We only care if we're >= 10.4, not if we're specifically Tiger. -# "8" is the Darwin major kernel version. -TIGERHOST=`uname -r |perl -w -p -e 's/\A(\d+)\..*\Z/$1/; $_ = (($_ >= 8) ? "1" : "0");'` - # we want to use the oldest available SDK for max compatiblity. However 10.4 and older # can not build 64bit binaries, making 10.5 the minimum version. This has been tested # with xcode 3.1 (xcode31_2199_developerdvd.dmg). It contains the 10.5 SDK and a decent