- Timestamp:
- 07/13/11 01:48:05 (13 years ago)
- Location:
- ps/trunk
- Files:
-
- 48 edited
-
binaries/data/config/default.cfg (modified) (1 diff)
-
binaries/data/mods/public/gui/session/menu.js (modified) (1 diff)
-
binaries/data/mods/public/gui/session/session.xml (modified) (3 diffs)
-
binaries/data/mods/public/hwdetect/hwdetect.js (modified) (5 diffs)
-
binaries/data/mods/public/hwdetect/test.js (modified) (1 diff)
-
binaries/data/mods/public/shaders/model_common.fp (modified) (3 diffs)
-
binaries/data/mods/public/shaders/model_common.xml (modified) (1 diff)
-
binaries/data/mods/public/shaders/model_common_instancing.xml (modified) (1 diff)
-
binaries/data/mods/public/shaders/terrain_base.xml (modified) (1 diff)
-
binaries/data/mods/public/shaders/terrain_blend.xml (modified) (1 diff)
-
binaries/data/mods/public/shaders/terrain_common.fp (modified) (3 diffs)
-
binaries/data/mods/public/shaders/terrain_decal.xml (modified) (1 diff)
-
binaries/data/mods/public/shaders/water_high.fs (modified) (4 diffs)
-
binaries/data/mods/public/shaders/water_high.vs (modified) (2 diffs)
-
source/graphics/Camera.cpp (modified) (5 diffs)
-
source/graphics/Camera.h (modified) (2 diffs)
-
source/graphics/Frustum.cpp (modified) (1 diff)
-
source/graphics/Frustum.h (modified) (1 diff)
-
source/graphics/Model.cpp (modified) (6 diffs)
-
source/graphics/Model.h (modified) (1 diff)
-
source/graphics/ModelDef.cpp (modified) (10 diffs)
-
source/graphics/ModelDef.h (modified) (7 diffs)
-
source/graphics/ShaderTechnique.cpp (modified) (4 diffs)
-
source/graphics/ShaderTechnique.h (modified) (2 diffs)
-
source/maths/Bound.cpp (modified) (2 diffs)
-
source/maths/Bound.h (modified) (2 diffs)
-
source/maths/MathUtil.h (modified) (1 diff)
-
source/maths/Matrix3D.cpp (modified) (3 diffs)
-
source/maths/Matrix3D.h (modified) (7 diffs)
-
source/maths/Plane.h (modified) (2 diffs)
-
source/ps/GameSetup/Config.cpp (modified) (2 diffs)
-
source/ps/GameSetup/Config.h (modified) (1 diff)
-
source/ps/GameSetup/GameSetup.cpp (modified) (1 diff)
-
source/ps/GameSetup/HWDetect.cpp (modified) (2 diffs)
-
source/renderer/DecalRData.h (modified) (1 diff)
-
source/renderer/ModelRenderer.cpp (modified) (4 diffs)
-
source/renderer/ModelRenderer.h (modified) (3 diffs)
-
source/renderer/PatchRData.cpp (modified) (5 diffs)
-
source/renderer/PatchRData.h (modified) (4 diffs)
-
source/renderer/RenderModifiers.cpp (modified) (1 diff)
-
source/renderer/Renderer.cpp (modified) (37 diffs)
-
source/renderer/Renderer.h (modified) (9 diffs)
-
source/renderer/ShadowMap.cpp (modified) (7 diffs)
-
source/renderer/ShadowMap.h (modified) (1 diff)
-
source/renderer/TerrainRenderer.cpp (modified) (20 diffs)
-
source/renderer/TerrainRenderer.h (modified) (7 diffs)
-
source/renderer/TransparencyRenderer.cpp (modified) (3 diffs)
-
source/renderer/TransparencyRenderer.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ps/trunk/binaries/data/config/default.cfg
r9791 r9814 30 30 fancywater = true 31 31 shadows = true 32 shadowpcf = true 32 33 vsync = false 33 34 -
ps/trunk/binaries/data/mods/public/gui/session/menu.js
r8719 r9814 16 16 { 17 17 var settings = getGUIObjectByName("settingsDialogPanel"); 18 g_SessionDialog.open("Settings", null, settings, 340, 2 24, null);18 g_SessionDialog.open("Settings", null, settings, 340, 252, null); 19 19 } 20 20 -
ps/trunk/binaries/data/mods/public/gui/session/session.xml
r9791 r9814 301 301 sprite="genericPanel" 302 302 type="image" 303 size=" 50%-180 50%-200 50%+180 50%+50"303 size="80%-180 50%-200 50%+180 50%+50" 304 304 hidden="true" 305 305 z="30" … … 311 311 <action on="Press">renderer.shadows = this.checked;</action> 312 312 </object> 313 313 314 <!-- Settings / Shadow PCF --> 315 <object size="0 35 100%-80 60" type="text" style="settingsText" ghost="true">Enable Shadow Filtering</object> 316 <object name="shadowPCFCheckbox" size="100%-56 40 100%-30 65" type="checkbox" style="wheatCrossBox" checked="true"> 317 <action on="Load">if (renderer.shadowPCF) this.checked = true; else this.checked = false;</action> 318 <action on="Press">renderer.shadowPCF = this.checked;</action> 319 </object> 320 314 321 <!-- Settings / Water --> 315 <object size="0 35 100%-80 60" type="text" style="settingsText" ghost="true">Enable Water Reflections</object>316 <object name="fancyWaterCheckbox" size="100%-56 40 100%-30 65" type="checkbox" style="wheatCrossBox" checked="true">322 <object size="0 60 100%-80 85" type="text" style="settingsText" ghost="true">Enable Water Reflections</object> 323 <object name="fancyWaterCheckbox" size="100%-56 65 100%-30 90" type="checkbox" style="wheatCrossBox" checked="true"> 317 324 <action on="Load">if (renderer.fancyWater) this.checked = true; else this.checked = false;</action> 318 325 <action on="Press">renderer.fancyWater = this.checked;</action> … … 320 327 321 328 <!-- Settings / Music--> 322 <object size="0 60 100%-80 85" type="text" style="settingsText" ghost="true">Enable Music</object>323 <object size="100%-56 65 100%-30 90" type="checkbox" style="wheatCrossBox" checked="true">329 <object size="0 85 100%-80 110" type="text" style="settingsText" ghost="true">Enable Music</object> 330 <object size="100%-56 90 100%-30 115" type="checkbox" style="wheatCrossBox" checked="true"> 324 331 <action on="Press">if (this.checked) startMusic(); else stopMusic();</action> 325 332 </object> 326 333 327 334 <!-- Settings / Dev Overlay --> 328 <object size="0 85 100%-80 110" type="text" style="settingsText" ghost="true">Developer Overlay</object>329 <object size="100%-56 90 100%-30 115" type="checkbox" style="wheatCrossBox" checked="false">335 <object size="0 110 100%-80 135" type="text" style="settingsText" ghost="true">Developer Overlay</object> 336 <object size="100%-56 115 100%-30 140" type="checkbox" style="wheatCrossBox" checked="false"> 330 337 <action on="Press">toggleDeveloperOverlay();</action> 331 338 </object> -
ps/trunk/binaries/data/mods/public/hwdetect/hwdetect.js
r9308 r9814 143 143 var disable_s3tc = undefined; 144 144 var disable_shadows = undefined; 145 var disable_shadowpcf = undefined; 145 146 var disable_fancywater = undefined; 146 147 var override_renderpath = undefined; … … 213 214 { 214 215 disable_shadows = true; 216 disable_shadowpcf = true; 215 217 } 216 218 … … 223 225 { 224 226 disable_fancywater = true; 227 disable_shadowpcf = true; 225 228 } 226 229 … … 239 242 "disable_s3tc": disable_s3tc, 240 243 "disable_shadows": disable_shadows, 244 "disable_shadowpcf": disable_shadowpcf, 241 245 "disable_fancywater": disable_fancywater, 242 246 "override_renderpath": override_renderpath, … … 270 274 Engine.SetDisableShadows(output.disable_shadows); 271 275 276 if (output.disable_shadowpcf !== undefined) 277 Engine.SetDisableShadowPCF(output.disable_shadowpcf); 278 272 279 if (output.disable_fancywater !== undefined) 273 280 Engine.SetDisableFancyWater(output.disable_fancywater); -
ps/trunk/binaries/data/mods/public/hwdetect/test.js
r9308 r9814 30 30 31 31 var disabled = []; 32 for each (var d in ["disable_audio", "disable_s3tc", "disable_shadows", "disable_ fancywater", "override_renderpath"])32 for each (var d in ["disable_audio", "disable_s3tc", "disable_shadows", "disable_shadowpcf", "disable_fancywater", "override_renderpath"]) 33 33 if (output[d] !== undefined) 34 34 disabled.push(d+"="+output[d]) -
ps/trunk/binaries/data/mods/public/shaders/model_common.fp
r9142 r9814 20 20 PARAM shadingColor = program.local[1]; 21 21 PARAM ambient = program.local[2]; 22 23 #ifdef USE_SHADOW_PCF 24 PARAM shadowOffsets1 = program.local[3]; 25 PARAM shadowOffsets2 = program.local[4]; 26 TEMP offset; 27 #endif 22 28 23 29 TEMP tex; … … 43 49 #ifdef USE_SHADOW 44 50 #ifdef USE_FP_SHADOW 45 TEX temp, fragment.texcoord[1], texture[1], SHADOW2D; 51 #ifdef USE_SHADOW_PCF 52 MOV offset.zw, fragment.texcoord[1]; 53 ADD offset.xy, fragment.texcoord[1], shadowOffsets1; 54 TEX temp.x, offset, texture[1], SHADOW2D; 55 ADD offset.xy, fragment.texcoord[1], shadowOffsets1.zwzw; 56 TEX temp.y, offset, texture[1], SHADOW2D; 57 ADD offset.xy, fragment.texcoord[1], shadowOffsets2; 58 TEX temp.z, offset, texture[1], SHADOW2D; 59 ADD offset.xy, fragment.texcoord[1], shadowOffsets2.zwzw; 60 TEX temp.w, offset, texture[1], SHADOW2D; 61 DP4 temp, temp, 0.25; 62 #else 63 TEX temp, fragment.texcoord[1], texture[1], SHADOW2D; 64 #endif 46 65 #else 47 66 TEX tex, fragment.texcoord[1], texture[1], 2D; … … 49 68 SGE temp, tex.x, temp.z; 50 69 #endif 51 MUL diffuse.rgb, fragment.color, 2.0; 52 MAD_MAYBE_SAT temp.rgb, diffuse, temp, ambient; 70 #ifdef CLAMP_LIGHTING 71 MAD_SAT diffuse.rgb, fragment.color, 2.0, ambient; 72 LRP temp.rgb, temp, diffuse, ambient; 73 #else 74 MUL diffuse.rgb, fragment.color, 2.0; 75 MAD temp.rgb, diffuse, temp, ambient; 76 #endif 53 77 MUL color.rgb, color, temp; 54 78 #else -
ps/trunk/binaries/data/mods/public/shaders/model_common.xml
r9142 r9814 20 20 <uniform name="shadingColor" loc="1" type="vec3"/> 21 21 <uniform name="ambient" loc="2" type="vec3"/> 22 <uniform name="shadowOffsets1" loc="3" type="vec4"/> 23 <uniform name="shadowOffsets2" loc="4" type="vec4"/> 22 24 </fragment> 23 25 -
ps/trunk/binaries/data/mods/public/shaders/model_common_instancing.xml
r9142 r9814 23 23 <uniform name="shadingColor" loc="1" type="vec3"/> 24 24 <uniform name="ambient" loc="2" type="vec3"/> 25 <uniform name="shadowOffsets1" loc="3" type="vec4"/> 26 <uniform name="shadowOffsets2" loc="4" type="vec4"/> 25 27 </fragment> 26 28 -
ps/trunk/binaries/data/mods/public/shaders/terrain_base.xml
r9123 r9814 14 14 15 15 <uniform name="ambient" loc="0" type="vec3"/> 16 <uniform name="shadowOffsets1" loc="2" type="vec4"/> 17 <uniform name="shadowOffsets2" loc="3" type="vec4"/> 16 18 </fragment> 17 19 -
ps/trunk/binaries/data/mods/public/shaders/terrain_blend.xml
r9123 r9814 17 17 18 18 <uniform name="ambient" loc="0" type="vec3"/> 19 <uniform name="shadowOffsets1" loc="2" type="vec4"/> 20 <uniform name="shadowOffsets2" loc="3" type="vec4"/> 19 21 </fragment> 20 22 -
ps/trunk/binaries/data/mods/public/shaders/terrain_common.fp
r9142 r9814 18 18 #ifdef DECAL 19 19 PARAM shadingColor = program.local[1]; 20 #endif 21 22 #ifdef USE_SHADOW_PCF 23 PARAM shadowOffsets1 = program.local[2]; 24 PARAM shadowOffsets2 = program.local[3]; 25 TEMP offset; 20 26 #endif 21 27 … … 44 50 #ifdef USE_SHADOW 45 51 #ifdef USE_FP_SHADOW 46 TEX temp, fragment.texcoord[2], texture[2], SHADOW2D; 52 #ifdef USE_SHADOW_PCF 53 MOV offset.zw, fragment.texcoord[2]; 54 ADD offset.xy, fragment.texcoord[2], shadowOffsets1; 55 TEX temp.x, offset, texture[2], SHADOW2D; 56 ADD offset.xy, fragment.texcoord[2], shadowOffsets1.zwzw; 57 TEX temp.y, offset, texture[2], SHADOW2D; 58 ADD offset.xy, fragment.texcoord[2], shadowOffsets2; 59 TEX temp.z, offset, texture[2], SHADOW2D; 60 ADD offset.xy, fragment.texcoord[2], shadowOffsets2.zwzw; 61 TEX temp.w, offset, texture[2], SHADOW2D; 62 DP4 temp, temp, 0.25; 63 #else 64 TEX temp, fragment.texcoord[2], texture[2], SHADOW2D; 65 #endif 47 66 #else 48 67 TEX tex, fragment.texcoord[2], texture[2], 2D; … … 50 69 SGE temp, tex.x, temp.z; 51 70 #endif 52 MUL diffuse.rgb, fragment.color, 2.0; 53 MAD_MAYBE_SAT temp.rgb, diffuse, temp, ambient; 71 #ifdef CLAMP_LIGHTING 72 MAD_SAT diffuse.rgb, fragment.color, 2.0, ambient; 73 LRP temp.rgb, temp, diffuse, ambient; 74 #else 75 MUL diffuse.rgb, fragment.color, 2.0; 76 MAD temp.rgb, diffuse, temp, ambient; 77 #endif 54 78 MUL color.rgb, color, temp; 55 79 #else -
ps/trunk/binaries/data/mods/public/shaders/terrain_decal.xml
r9142 r9814 17 17 <uniform name="ambient" loc="0" type="vec3"/> 18 18 <uniform name="shadingColor" loc="1" type="vec3"/> 19 <uniform name="shadowOffsets1" loc="2" type="vec4"/> 20 <uniform name="shadowOffsets2" loc="3" type="vec4"/> 19 21 </fragment> 20 22 -
ps/trunk/binaries/data/mods/public/shaders/water_high.fs
r8882 r9814 17 17 18 18 varying vec3 worldPos; 19 varying float w;20 19 varying float waterDepth; 21 20 … … 25 24 float ndotl, ndoth, ndotv; 26 25 float fresnel; 27 float myMurkiness; // Murkiness and tint at this pixel (tweaked based on lighting and depth)28 26 float t; // Temporary variable 29 27 vec2 reflCoords, refrCoords; … … 40 38 ndotv = dot(n, v); 41 39 42 myMurkiness = murkiness * min(waterDepth / fullDepth, 1.0);43 44 40 fresnel = pow(1.0 - ndotv, 0.8); // A rather random Fresnel approximation 45 41 46 refrCoords = 0.5 * (gl_TexCoord[2].xy / gl_TexCoord[2].w) + 0.5; // Unbias texture coords 47 refrCoords -= 0.8 * waviness * n.xz / w; // Refractions can be slightly less wavy 48 49 reflCoords = 0.5 * (gl_TexCoord[1].xy / gl_TexCoord[1].w) + 0.5; // Unbias texture coords 50 reflCoords += waviness * n.xz / w; 42 refrCoords = (0.5*gl_TexCoord[2].xy - 0.8*waviness*n.xz) / gl_TexCoord[2].w + 0.5; // Unbias texture coords 43 reflCoords = (0.5*gl_TexCoord[1].xy + waviness*n.xz) / gl_TexCoord[1].w + 0.5; // Unbias texture coords 51 44 52 45 reflColor = mix(texture2D(reflectionMap, reflCoords).rgb, sunColor * reflectionTint, … … 54 47 55 48 refrColor = (0.5 + 0.5*ndotl) * mix(texture2D(refractionMap, refrCoords).rgb, sunColor * tint, 56 m yMurkiness);49 murkiness * clamp(waterDepth / fullDepth, 0.0, 1.0)); // Murkiness and tint at this pixel (tweaked based on lighting and depth) 57 50 58 51 specular = pow(max(0.0, ndoth), shininess) * sunColor * specularStrength; -
ps/trunk/binaries/data/mods/public/shaders/water_high.vs
r8882 r9814 2 2 uniform mat4 refractionMatrix; 3 3 uniform mat4 losMatrix; 4 uniform vec4 translation; 5 6 attribute float vertexDepth; 4 uniform float repeatScale; 5 uniform vec2 translation; 7 6 8 7 varying vec3 worldPos; 9 varying float w;10 8 varying float waterDepth; 11 9 … … 13 11 { 14 12 worldPos = gl_Vertex.xyz; 15 waterDepth = vertexDepth;16 gl_TexCoord[0] = gl_MultiTexCoord0+ translation;13 waterDepth = dot(gl_Color.xyz, vec3(255.0, -255.0, 1.0)); 14 gl_TexCoord[0].st = gl_Vertex.xz*repeatScale + translation; 17 15 gl_TexCoord[1] = reflectionMatrix * gl_Vertex; // projective texturing 18 gl_TexCoord[2] = ref lectionMatrix * gl_Vertex;16 gl_TexCoord[2] = refractionMatrix * gl_Vertex; 19 17 gl_TexCoord[3] = losMatrix * gl_Vertex; 20 w = gl_TexCoord[1].w;21 18 gl_Position = ftransform(); 22 19 } -
ps/trunk/source/graphics/Camera.cpp
r9141 r9814 35 35 #include "renderer/WaterManager.h" 36 36 37 CCamera::CCamera ()37 CCamera::CCamera() 38 38 { 39 39 // set viewport to something anything should handle, but should be initialised … … 45 45 } 46 46 47 CCamera::~CCamera ()48 { 49 } 50 51 void CCamera::SetProjection (float nearp, float farp, float fov)47 CCamera::~CCamera() 48 { 49 } 50 51 void CCamera::SetProjection(float nearp, float farp, float fov) 52 52 { 53 53 m_NearPlane = nearp; … … 55 55 m_FOV = fov; 56 56 57 float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height; 58 59 float w = tanf (m_FOV*0.5f*Aspect); 60 float h = tanf (m_FOV*0.5f); 57 float aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height; 58 float f = 1.0f/tanf(m_FOV/2); 61 59 62 60 m_ProjMat.SetZero (); 63 m_ProjMat._11 = 1/w;64 m_ProjMat._22 = 1/h;65 m_ProjMat._33 = (m_FarPlane+m_NearPlane)/(m_FarPlane-m_NearPlane);66 m_ProjMat._34 = -2*m_FarPlane*m_NearPlane/(m_FarPlane-m_NearPlane);61 m_ProjMat._11 = f/aspect; 62 m_ProjMat._22 = f; 63 m_ProjMat._33 = -(m_FarPlane+m_NearPlane)/(m_NearPlane-m_FarPlane); 64 m_ProjMat._34 = 2*m_FarPlane*m_NearPlane/(m_NearPlane-m_FarPlane); 67 65 m_ProjMat._43 = 1.0f; 68 66 } 69 67 70 void CCamera::SetProjectionTile (int tiles, int tile_x, int tile_y) 71 { 72 float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height; 73 74 float w = tanf (m_FOV*0.5f*Aspect) / tiles; 75 float h = tanf (m_FOV*0.5f) / tiles; 76 77 m_ProjMat._11 = 1/w; 78 m_ProjMat._22 = 1/h; 68 void CCamera::SetProjectionTile(int tiles, int tile_x, int tile_y) 69 { 70 71 float aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height; 72 float f = 1.0f/tanf(m_FOV/2); 73 74 m_ProjMat._11 = tiles*f/aspect; 75 m_ProjMat._22 = tiles*f; 79 76 m_ProjMat._13 = -(1-tiles + 2*tile_x); 80 77 m_ProjMat._23 = -(1-tiles + 2*tile_y); … … 84 81 //everytime the view or projection matrices are 85 82 //altered. 86 void CCamera::UpdateFrustum ()83 void CCamera::UpdateFrustum(const CBound& scissor) 87 84 { 88 85 CMatrix3D MatFinal; … … 93 90 MatFinal = m_ProjMat * MatView; 94 91 95 //get the RIGHT plane 96 m_ViewFrustum.SetNumPlanes (6); 97 98 m_ViewFrustum.m_aPlanes[0].m_Norm.X = MatFinal._41-MatFinal._11; 99 m_ViewFrustum.m_aPlanes[0].m_Norm.Y = MatFinal._42-MatFinal._12; 100 m_ViewFrustum.m_aPlanes[0].m_Norm.Z = MatFinal._43-MatFinal._13; 101 m_ViewFrustum.m_aPlanes[0].m_Dist = MatFinal._44-MatFinal._14; 102 103 //get the LEFT plane 104 m_ViewFrustum.m_aPlanes[1].m_Norm.X = MatFinal._41+MatFinal._11; 105 m_ViewFrustum.m_aPlanes[1].m_Norm.Y = MatFinal._42+MatFinal._12; 106 m_ViewFrustum.m_aPlanes[1].m_Norm.Z = MatFinal._43+MatFinal._13; 107 m_ViewFrustum.m_aPlanes[1].m_Dist = MatFinal._44+MatFinal._14; 108 109 //get the BOTTOM plane 110 m_ViewFrustum.m_aPlanes[2].m_Norm.X = MatFinal._41+MatFinal._21; 111 m_ViewFrustum.m_aPlanes[2].m_Norm.Y = MatFinal._42+MatFinal._22; 112 m_ViewFrustum.m_aPlanes[2].m_Norm.Z = MatFinal._43+MatFinal._23; 113 m_ViewFrustum.m_aPlanes[2].m_Dist = MatFinal._44+MatFinal._24; 114 115 //get the TOP plane 116 m_ViewFrustum.m_aPlanes[3].m_Norm.X = MatFinal._41-MatFinal._21; 117 m_ViewFrustum.m_aPlanes[3].m_Norm.Y = MatFinal._42-MatFinal._22; 118 m_ViewFrustum.m_aPlanes[3].m_Norm.Z = MatFinal._43-MatFinal._23; 119 m_ViewFrustum.m_aPlanes[3].m_Dist = MatFinal._44-MatFinal._24; 120 121 //get the FAR plane 122 m_ViewFrustum.m_aPlanes[4].m_Norm.X = MatFinal._41-MatFinal._31; 123 m_ViewFrustum.m_aPlanes[4].m_Norm.Y = MatFinal._42-MatFinal._32; 124 m_ViewFrustum.m_aPlanes[4].m_Norm.Z = MatFinal._43-MatFinal._33; 125 m_ViewFrustum.m_aPlanes[4].m_Dist = MatFinal._44-MatFinal._34; 126 127 //get the NEAR plane 128 m_ViewFrustum.m_aPlanes[5].m_Norm.X = MatFinal._41+MatFinal._31; 129 m_ViewFrustum.m_aPlanes[5].m_Norm.Y = MatFinal._42+MatFinal._32; 130 m_ViewFrustum.m_aPlanes[5].m_Norm.Z = MatFinal._43+MatFinal._33; 131 m_ViewFrustum.m_aPlanes[5].m_Dist = MatFinal._44+MatFinal._34; 132 } 133 134 void CCamera::SetViewPort (const SViewPort& viewport) 92 // get the RIGHT plane 93 m_ViewFrustum.SetNumPlanes(6); 94 95 m_ViewFrustum.m_aPlanes[0].m_Norm.X = scissor[1].X*MatFinal._41 - MatFinal._11; 96 m_ViewFrustum.m_aPlanes[0].m_Norm.Y = scissor[1].X*MatFinal._42 - MatFinal._12; 97 m_ViewFrustum.m_aPlanes[0].m_Norm.Z = scissor[1].X*MatFinal._43 - MatFinal._13; 98 m_ViewFrustum.m_aPlanes[0].m_Dist = scissor[1].X*MatFinal._44 - MatFinal._14; 99 100 // get the LEFT plane 101 m_ViewFrustum.m_aPlanes[1].m_Norm.X = -scissor[0].X*MatFinal._41 + MatFinal._11; 102 m_ViewFrustum.m_aPlanes[1].m_Norm.Y = -scissor[0].X*MatFinal._42 + MatFinal._12; 103 m_ViewFrustum.m_aPlanes[1].m_Norm.Z = -scissor[0].X*MatFinal._43 + MatFinal._13; 104 m_ViewFrustum.m_aPlanes[1].m_Dist = -scissor[0].X*MatFinal._44 + MatFinal._14; 105 106 // get the BOTTOM plane 107 m_ViewFrustum.m_aPlanes[2].m_Norm.X = -scissor[0].Y*MatFinal._41 + MatFinal._21; 108 m_ViewFrustum.m_aPlanes[2].m_Norm.Y = -scissor[0].Y*MatFinal._42 + MatFinal._22; 109 m_ViewFrustum.m_aPlanes[2].m_Norm.Z = -scissor[0].Y*MatFinal._43 + MatFinal._23; 110 m_ViewFrustum.m_aPlanes[2].m_Dist = -scissor[0].Y*MatFinal._44 + MatFinal._24; 111 112 // get the TOP plane 113 m_ViewFrustum.m_aPlanes[3].m_Norm.X = scissor[1].Y*MatFinal._41 - MatFinal._21; 114 m_ViewFrustum.m_aPlanes[3].m_Norm.Y = scissor[1].Y*MatFinal._42 - MatFinal._22; 115 m_ViewFrustum.m_aPlanes[3].m_Norm.Z = scissor[1].Y*MatFinal._43 - MatFinal._23; 116 m_ViewFrustum.m_aPlanes[3].m_Dist = scissor[1].Y*MatFinal._44 - MatFinal._24; 117 118 // get the FAR plane 119 m_ViewFrustum.m_aPlanes[4].m_Norm.X = scissor[1].Z*MatFinal._41 - MatFinal._31; 120 m_ViewFrustum.m_aPlanes[4].m_Norm.Y = scissor[1].Z*MatFinal._42 - MatFinal._32; 121 m_ViewFrustum.m_aPlanes[4].m_Norm.Z = scissor[1].Z*MatFinal._43 - MatFinal._33; 122 m_ViewFrustum.m_aPlanes[4].m_Dist = scissor[1].Z*MatFinal._44 - MatFinal._34; 123 124 // get the NEAR plane 125 m_ViewFrustum.m_aPlanes[5].m_Norm.X = -scissor[0].Z*MatFinal._41 + MatFinal._31; 126 m_ViewFrustum.m_aPlanes[5].m_Norm.Y = -scissor[0].Z*MatFinal._42 + MatFinal._32; 127 m_ViewFrustum.m_aPlanes[5].m_Norm.Z = -scissor[0].Z*MatFinal._43 + MatFinal._33; 128 m_ViewFrustum.m_aPlanes[5].m_Dist = -scissor[0].Z*MatFinal._44 + MatFinal._34; 129 } 130 131 void CCamera::ClipFrustum(const CPlane& clipPlane) 132 { 133 m_ViewFrustum.AddPlane(clipPlane); 134 } 135 136 void CCamera::SetViewPort(const SViewPort& viewport) 135 137 { 136 138 m_ViewPort.m_X = viewport.m_X; -
ps/trunk/source/graphics/Camera.h
r7930 r9814 25 25 26 26 #include "Frustum.h" 27 #include "maths/Bound.h" 27 28 #include "maths/Matrix3D.h" 28 29 … … 36 37 }; 37 38 38 39 39 class CCamera 40 40 { 41 41 public: 42 CCamera ();43 ~CCamera ();42 CCamera(); 43 ~CCamera(); 44 44 45 45 // Methods for projection 46 void SetProjection (float nearp, float farp, float fov); 47 void SetProjectionTile (int tiles, int tile_x, int tile_y); 48 CMatrix3D& GetProjection () { return m_ProjMat; } 49 const CMatrix3D& GetProjection () const { return m_ProjMat; } 46 void SetProjection(float nearp, float farp, float fov); 47 void SetProjectionTile(int tiles, int tile_x, int tile_y); 48 CMatrix3D& GetProjection() { return m_ProjMat; } 49 const CMatrix3D& GetProjection() const { return m_ProjMat; } 50 51 CMatrix3D& GetOrientation() { return m_Orientation; } 52 const CMatrix3D& GetOrientation() const { return m_Orientation; } 53 54 CMatrix3D GetViewProjection() { return m_ProjMat * m_Orientation.GetInverse(); } 50 55 51 56 // Updates the frustum planes. Should be called 52 57 // everytime the view or projection matrices are 53 58 // altered. 54 void UpdateFrustum (); 55 const CFrustum& GetFrustum () const { return m_ViewFrustum; } 59 void UpdateFrustum(const CBound& scissor = CBound(CVector3D(-1.0f, -1.0f, -1.0f), CVector3D(1.0f, 1.0f, 1.0f))); 60 void ClipFrustum(const CPlane& clipPlane); 61 const CFrustum& GetFrustum() const { return m_ViewFrustum; } 56 62 57 void SetViewPort (const SViewPort& viewport);58 const SViewPort& GetViewPort () const { return m_ViewPort; }63 void SetViewPort(const SViewPort& viewport); 64 const SViewPort& GetViewPort() const { return m_ViewPort; } 59 65 60 66 // getters -
ps/trunk/source/graphics/Frustum.cpp
r6832 r9814 48 48 if (m_NumPlanes >= MAX_NUM_FRUSTUM_PLANES) 49 49 m_NumPlanes = MAX_NUM_FRUSTUM_PLANES-1; 50 } 51 52 void CFrustum::AddPlane (const CPlane& plane) 53 { 54 if (m_NumPlanes >= MAX_NUM_FRUSTUM_PLANES) 55 { 56 debug_warn(L"CFrustum::AddPlane: Too many planes"); 57 return; 58 } 59 60 m_aPlanes[m_NumPlanes++] = plane; 50 61 } 51 62 -
ps/trunk/source/graphics/Frustum.h
r6832 r9814 49 49 size_t GetNumPlanes() const { return m_NumPlanes; } 50 50 51 void AddPlane (const CPlane& plane); 52 51 53 //The following methods return true if the shape is 52 54 //partially or completely in front of the frustum planes -
ps/trunk/source/graphics/Model.cpp
r9761 r9814 82 82 if (numBones != 0) 83 83 { 84 size_t numBlends = modeldef->GetNumBlends(); 85 84 86 // allocate matrices for bone transformations 85 m_BoneMatrices = new CMatrix3D[numBones]; 87 m_BoneMatrices = new CMatrix3D[numBones + numBlends]; 88 for (size_t i = 0; i < numBones + numBlends; ++i) 89 { 90 m_BoneMatrices[i].SetIdentity(); 91 } 92 86 93 m_InverseBindBoneMatrices = new CMatrix3D[numBones]; 87 94 … … 90 97 for (size_t i = 0; i < numBones; ++i) 91 98 { 92 m_BoneMatrices[i].SetIdentity();93 m_BoneMatrices[i].Rotate(defpose[i].m_Rotation);94 m_BoneMatrices[i].Translate(defpose[i].m_Translation);95 96 99 m_InverseBindBoneMatrices[i].SetIdentity(); 97 100 m_InverseBindBoneMatrices[i].Translate(-defpose[i].m_Translation); … … 101 104 102 105 m_PositionValid = true; 103 106 104 107 return true; 105 108 } … … 112 115 // Need to calculate the object bounds first, if that hasn't already been done 113 116 if (! (m_Anim && m_Anim->m_AnimDef)) 114 CalcObjectBounds(); 117 { 118 if (m_ObjectBounds.IsEmpty()) 119 CalcObjectBounds(); 120 } 115 121 else 116 122 { … … 181 187 for (size_t i=0;i<numverts;i++) 182 188 { 183 result += CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices() , GetInverseBindBoneMatrices());189 result += CModelDef::SkinPoint(verts[i], GetAnimatedBoneMatrices()); 184 190 } 185 191 // advance to next frame … … 323 329 prop.m_Model->ValidatePosition(); 324 330 } 331 332 if (m_BoneMatrices) 333 { 334 for (size_t i = 0; i < m_pModelDef->GetNumBones(); i++) 335 { 336 m_BoneMatrices[i] = m_BoneMatrices[i] * m_InverseBindBoneMatrices[i]; 337 } 338 339 m_pModelDef->BlendBoneMatrices(m_BoneMatrices); 340 } 325 341 } 326 342 -
ps/trunk/source/graphics/Model.h
r9362 r9814 41 41 #define MODELFLAG_SILHOUETTE_DISPLAY (1<<2) 42 42 #define MODELFLAG_SILHOUETTE_OCCLUDER (1<<3) 43 43 #define MODELFLAG_FILTERED (1<<4) // used internally by renderer 44 44 45 45 /////////////////////////////////////////////////////////////////////////////// -
ps/trunk/source/graphics/ModelDef.cpp
r8666 r9814 28 28 29 29 CVector3D CModelDef::SkinPoint(const SModelVertex& vtx, 30 const CMatrix3D newPoseMatrices[], 31 const CMatrix3D inverseBindMatrices[]) 30 const CMatrix3D newPoseMatrices[]) 32 31 { 33 32 CVector3D result (0, 0, 0); … … 35 34 for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i) 36 35 { 37 CVector3D bindSpace = inverseBindMatrices[vtx.m_Blend.m_Bone[i]].Transform(vtx.m_Coords); 38 CVector3D worldSpace = newPoseMatrices[vtx.m_Blend.m_Bone[i]].Transform(bindSpace); 39 result += worldSpace * vtx.m_Blend.m_Weight[i]; 36 result += newPoseMatrices[vtx.m_Blend.m_Bone[i]].Transform(vtx.m_Coords) * vtx.m_Blend.m_Weight[i]; 40 37 } 41 38 … … 44 41 45 42 CVector3D CModelDef::SkinNormal(const SModelVertex& vtx, 46 const CMatrix3D newPoseMatrices[], 47 const CMatrix3D inverseBindMatrices[]) 43 const CMatrix3D newPoseMatrices[]) 48 44 { 49 45 // To be correct, the normal vectors apparently need to be multiplied by the … … 74 70 for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i) 75 71 { 76 CVector3D bindSpace = inverseBindMatrices[vtx.m_Blend.m_Bone[i]].Rotate(vtx.m_Norm); 77 CVector3D worldSpace = newPoseMatrices[vtx.m_Blend.m_Bone[i]].Rotate(bindSpace); 78 result += worldSpace * vtx.m_Blend.m_Weight[i]; 72 result += newPoseMatrices[vtx.m_Blend.m_Bone[i]].Rotate(vtx.m_Norm) * vtx.m_Blend.m_Weight[i]; 79 73 } 80 74 … … 95 89 const VertexArrayIterator<CVector3D>& Normal, 96 90 const SModelVertex* vertices, 97 const CMatrix3D newPoseMatrices[],98 const CMatrix3D inverseBindMatrices[])91 const size_t* blendIndices, 92 const CMatrix3D newPoseMatrices[]) 99 93 { 100 94 for (size_t j = 0; j < numVertices; ++j) 101 95 { 102 const SModelVertex vtx = vertices[j]; 103 104 CVector3D pos(0, 0, 0); 105 CVector3D normal(0, 0, 0); 106 107 for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i) 108 { 109 CVector3D posBindSpace = inverseBindMatrices[vtx.m_Blend.m_Bone[i]].Transform(vtx.m_Coords); 110 CVector3D normBindSpace = inverseBindMatrices[vtx.m_Blend.m_Bone[i]].Rotate(vtx.m_Norm); 111 112 CVector3D posWorldSpace = newPoseMatrices[vtx.m_Blend.m_Bone[i]].Transform(posBindSpace); 113 CVector3D normWorldSpace = newPoseMatrices[vtx.m_Blend.m_Bone[i]].Rotate(normBindSpace); 114 115 pos += posWorldSpace * vtx.m_Blend.m_Weight[i]; 116 normal += normWorldSpace * vtx.m_Blend.m_Weight[i]; 117 } 96 const SModelVertex& vtx = vertices[j]; 97 98 Position[j] = newPoseMatrices[blendIndices[j]].Transform(vtx.m_Coords); 99 Normal[j] = newPoseMatrices[blendIndices[j]].Rotate(vtx.m_Norm); 118 100 119 101 // If there was more than one influence, the result is probably not going … … 123 105 // optimise that case a bit.) 124 106 if (vtx.m_Blend.m_Bone[1] != 0xff) // if more than one influence 125 normal.Normalize(); 126 127 Position[j] = pos; 128 Normal[j] = normal; 107 Normal[j].Normalize(); 108 } 109 } 110 111 void CModelDef::BlendBoneMatrices( 112 CMatrix3D boneMatrices[]) 113 { 114 for (size_t i = 0; i < m_NumBlends; ++i) 115 { 116 const SVertexBlend& blend = m_pBlends[i]; 117 CMatrix3D& boneMatrix = boneMatrices[m_NumBones + i]; 118 boneMatrix.Blend(boneMatrices[blend.m_Bone[0]], blend.m_Weight[0]); 119 boneMatrix.AddBlend(boneMatrices[blend.m_Bone[1]], blend.m_Weight[1]); 120 for (size_t j = 2; j < SVertexBlend::SIZE && blend.m_Bone[j] != 0xFF; ++j) 121 { 122 boneMatrix.AddBlend(boneMatrices[blend.m_Bone[j]], blend.m_Weight[j]); 123 } 129 124 } 130 125 } 131 126 132 127 // CModelDef Constructor 133 CModelDef::CModelDef() 134 : m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), m_NumBones(0), m_Bones(0), 128 CModelDef::CModelDef() : 129 m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), m_NumBones(0), m_Bones(0), 130 m_NumBlends(0), m_pBlends(0), m_pBlendIndices(0), 135 131 m_Name(L"[not loaded]") 136 132 { … … 145 141 delete[] m_pFaces; 146 142 delete[] m_Bones; 143 delete[] m_pBlends; 144 delete[] m_pBlendIndices; 147 145 } 148 146 … … 188 186 mdef->m_Bones=new CBoneState[mdef->m_NumBones]; 189 187 unpacker.UnpackRaw(mdef->m_Bones,mdef->m_NumBones*sizeof(CBoneState)); 188 189 mdef->m_pBlendIndices = new size_t[mdef->m_NumVertices]; 190 std::vector<SVertexBlend> blends; 191 for (size_t i = 0; i < mdef->m_NumVertices; i++) 192 { 193 const SVertexBlend &blend = mdef->m_pVertices[i].m_Blend; 194 if (blend.m_Bone[1] == 0xFF) 195 { 196 mdef->m_pBlendIndices[i] = blend.m_Bone[0]; 197 } 198 else 199 { 200 // If there's already a vertex using the same blend as this, then 201 // reuse its entry from blends; otherwise add the new one to blends 202 size_t j; 203 for (j = 0; j < blends.size(); j++) 204 { 205 if (blend == blends[j]) break; 206 } 207 if (j >= blends.size()) 208 blends.push_back(blend); 209 mdef->m_pBlendIndices[i] = mdef->m_NumBones + j; 210 } 211 } 212 213 mdef->m_NumBlends = blends.size(); 214 mdef->m_pBlends = new SVertexBlend[mdef->m_NumBlends]; 215 std::copy(blends.begin(), blends.end(), mdef->m_pBlends); 190 216 } 191 217 … … 233 259 if (mdef->m_NumBones) // only do skinned models 234 260 { 235 CMatrix3D identity;236 identity.SetIdentity();237 std::vector<CMatrix3D> identityBones (mdef->m_NumBones, identity);238 239 261 std::vector<CMatrix3D> bindPose (mdef->m_NumBones); 240 262 … … 248 270 for (size_t i = 0; i < mdef->m_NumVertices; ++i) 249 271 { 250 mdef->m_pVertices[i].m_Coords = SkinPoint(mdef->m_pVertices[i], &bindPose[0] , &identityBones[0]);251 mdef->m_pVertices[i].m_Norm = SkinNormal(mdef->m_pVertices[i], &bindPose[0] , &identityBones[0]);272 mdef->m_pVertices[i].m_Coords = SkinPoint(mdef->m_pVertices[i], &bindPose[0]); 273 mdef->m_pVertices[i].m_Norm = SkinNormal(mdef->m_pVertices[i], &bindPose[0]); 252 274 } 253 275 } -
ps/trunk/source/graphics/ModelDef.h
r8666 r9814 29 29 #include "renderer/VertexArray.h" 30 30 #include <map> 31 #include <cstring> 31 32 32 33 class CBoneState; … … 58 59 // weight of the influence; all weights sum to 1 59 60 float m_Weight[SIZE]; 61 62 bool operator==(const SVertexBlend& o) const 63 { 64 return !memcmp(m_Bone, o.m_Bone, sizeof(m_Bone)) && !memcmp(m_Weight, o.m_Weight, sizeof(m_Weight)); 65 } 60 66 }; 61 67 … … 125 131 public: 126 132 // accessor: get vertex data 127 size_t GetNumVertices() const { return (size_t)m_NumVertices; }133 size_t GetNumVertices() const { return m_NumVertices; } 128 134 SModelVertex* GetVertices() const { return m_pVertices; } 129 135 130 136 // accessor: get face data 131 size_t GetNumFaces() const { return (size_t)m_NumFaces; }137 size_t GetNumFaces() const { return m_NumFaces; } 132 138 SModelFace* GetFaces() const { return m_pFaces; } 133 139 134 140 // accessor: get bone data 135 size_t GetNumBones() const { return (size_t)m_NumBones; }141 size_t GetNumBones() const { return m_NumBones; } 136 142 CBoneState* GetBones() const { return m_Bones; } 143 144 // accessor: get blend data 145 size_t GetNumBlends() const { return m_NumBlends; } 146 SVertexBlend* GetBlends() const { return m_pBlends; } 147 size_t* GetBlendIndices() const { return m_pBlendIndices; } 137 148 138 149 // find and return pointer to prop point matching given name; return … … 146 157 */ 147 158 static CVector3D SkinPoint(const SModelVertex& vtx, 148 const CMatrix3D newPoseMatrices[] , const CMatrix3D inverseBindMatrices[]);159 const CMatrix3D newPoseMatrices[]); 149 160 150 161 /** … … 154 165 */ 155 166 static CVector3D SkinNormal(const SModelVertex& vtx, 156 const CMatrix3D newPoseMatrices[] , const CMatrix3D inverseBindMatrices[]);167 const CMatrix3D newPoseMatrices[]); 157 168 158 169 /** … … 166 177 const VertexArrayIterator<CVector3D>& Normal, 167 178 const SModelVertex* vertices, 168 const CMatrix3D newPoseMatrices[], 169 const CMatrix3D inverseBindMatrices[]); 179 const size_t* blendIndices, 180 const CMatrix3D newPoseMatrices[]); 181 182 /** 183 * Blend bone matrices together to fill bone palette. 184 */ 185 void BlendBoneMatrices(CMatrix3D boneMatrices[]); 170 186 171 187 /** … … 201 217 size_t m_NumBones; 202 218 CBoneState* m_Bones; 219 // blend data 220 size_t m_NumBlends; 221 SVertexBlend *m_pBlends; 222 size_t* m_pBlendIndices; 203 223 // prop point data 204 224 std::vector<SPropPoint> m_PropPoints; -
ps/trunk/source/graphics/ShaderTechnique.cpp
r9362 r9814 22 22 CShaderPass::CShaderPass(const CShaderProgramPtr& shader) : 23 23 m_Shader(shader), 24 m_HasAlpha(false), m_HasBlend(false), m_HasColorMask(false), m_HasDepthMask(false) 24 m_HasAlpha(false), m_HasBlend(false), m_HasColorMask(false), m_HasDepthMask(false), m_HasDepthFunc(false) 25 25 { 26 26 } … … 47 47 if (m_HasDepthMask) 48 48 glDepthMask(m_DepthMask); 49 50 if (m_HasDepthFunc) 51 glDepthFunc(m_DepthFunc); 49 52 } 50 53 … … 68 71 if (m_HasDepthMask) 69 72 glDepthMask(1); 73 74 if (m_HasDepthFunc) 75 glDepthFunc(GL_LEQUAL); 70 76 } 71 77 … … 97 103 m_HasDepthMask = true; 98 104 m_DepthMask = mask; 105 } 106 107 void CShaderPass::DepthFunc(GLenum func) 108 { 109 m_HasDepthFunc = true; 110 m_DepthFunc = func; 99 111 } 100 112 -
ps/trunk/source/graphics/ShaderTechnique.h
r9123 r9814 34 34 void ColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a); 35 35 void DepthMask(GLboolean mask); 36 void DepthFunc(GLenum func); 36 37 37 38 /** … … 66 67 bool m_HasDepthMask; 67 68 GLboolean m_DepthMask; 69 70 bool m_HasDepthFunc; 71 GLenum m_DepthFunc; 68 72 }; 69 73 -
ps/trunk/source/maths/Bound.cpp
r9362 r9814 34 34 35 35 /////////////////////////////////////////////////////////////////////////////// 36 // operator+=: extend this bound to include given bound37 CBound& CBound::operator+=(const CBound& b)38 {39 #define CMPT(c) \40 if (b[0].c < m_Data[0].c) m_Data[0].c = b[0].c; \41 if (b[1].c > m_Data[1].c) m_Data[1].c = b[1].c42 CMPT(X);43 CMPT(Y);44 CMPT(Z);45 #undef CMPT46 47 return *this;48 }49 50 ///////////////////////////////////////////////////////////////////////////////51 // operator+=: extend this bound to include given point52 CBound& CBound::operator+=(const CVector3D& pt)53 {54 #define CMPT(c) \55 if (pt.c < m_Data[0].c) m_Data[0].c = pt.c; \56 if (pt.c > m_Data[1].c) m_Data[1].c = pt.c57 CMPT(X);58 CMPT(Y);59 CMPT(Z);60 #undef CMPT61 62 return *this;63 }64 65 ///////////////////////////////////////////////////////////////////////////////66 36 // RayIntersect: intersect ray with this bound; return true 67 37 // if ray hits (and store entry and exit times), or false … … 157 127 /////////////////////////////////////////////////////////////////////////////// 158 128 // IsEmpty: tests whether this bound is empty 159 bool CBound::IsEmpty() 129 bool CBound::IsEmpty() const 160 130 { 161 131 return (m_Data[0].X == FLT_MAX && m_Data[0].Y == FLT_MAX && m_Data[0].Z == FLT_MAX -
ps/trunk/source/maths/Bound.h
r9345 r9814 45 45 46 46 void SetEmpty(); 47 bool IsEmpty() ;47 bool IsEmpty() const; 48 48 49 CBound& operator+=(const CBound& b); 50 CBound& operator+=(const CVector3D& pt); 49 void Extend(const CVector3D& min, const CVector3D& max) 50 { 51 if (min.X < m_Data[0].X) m_Data[0].X = min.X; 52 if (min.Y < m_Data[0].Y) m_Data[0].Y = min.Y; 53 if (min.Z < m_Data[0].Z) m_Data[0].Z = min.Z; 54 if (max.X > m_Data[1].X) m_Data[1].X = max.X; 55 if (max.Y > m_Data[1].Y) m_Data[1].Y = max.Y; 56 if (max.Z > m_Data[1].Z) m_Data[1].Z = max.Z; 57 } 58 59 // operator+=: extend this bound to include given bound 60 CBound& operator+=(const CBound& b) 61 { 62 Extend(b.m_Data[0], b.m_Data[1]); 63 return *this; 64 } 65 66 // operator+=: extend this bound to include given point 67 CBound& operator+=(const CVector3D& pt) 68 { 69 Extend(pt, pt); 70 return *this; 71 } 51 72 52 73 bool RayIntersect(const CVector3D& origin,const CVector3D& dir,float& tmin,float& tmax) const; … … 55 76 float GetVolume() const { 56 77 CVector3D v=m_Data[1]-m_Data[0]; 57 return v.X*v.Y*v.Z;78 return std::max(v.X, 0.0f)*std::max(v.Y, 0.0f)*std::max(v.Z, 0.0f); 58 79 } 59 80 -
ps/trunk/source/maths/MathUtil.h
r7404 r9814 24 24 25 25 template <typename T> 26 T Interpolate(const T& a, const T& b, float l)26 inline T Interpolate(const T& a, const T& b, float l) 27 27 { 28 28 return a + (b - a) * l; -
ps/trunk/source/maths/Matrix3D.cpp
r9298 r9814 27 27 #include "Vector4D.h" 28 28 29 CMatrix3D::CMatrix3D ()30 {31 }32 33 CMatrix3D::CMatrix3D(34 float a11, float a12, float a13, float a14,35 float a21, float a22, float a23, float a24,36 float a31, float a32, float a33, float a34,37 float a41, float a42, float a43, float a44) :38 _11(a11), _12(a12), _13(a13), _14(a14),39 _21(a21), _22(a22), _23(a23), _24(a24),40 _31(a31), _32(a32), _33(a33), _34(a34),41 _41(a41), _42(a42), _43(a43), _44(a44)42 {43 }44 45 CMatrix3D::CMatrix3D(float data[])46 {47 for(int i=0; i<16; i++)48 {49 _data[i] = data[i];50 }51 }52 53 //Matrix multiplication54 CMatrix3D CMatrix3D::operator*(const CMatrix3D& matrix) const55 {56 return CMatrix3D(57 _11*matrix._11 + _12*matrix._21 + _13*matrix._31 + _14*matrix._41,58 _11*matrix._12 + _12*matrix._22 + _13*matrix._32 + _14*matrix._42,59 _11*matrix._13 + _12*matrix._23 + _13*matrix._33 + _14*matrix._43,60 _11*matrix._14 + _12*matrix._24 + _13*matrix._34 + _14*matrix._44,61 62 _21*matrix._11 + _22*matrix._21 + _23*matrix._31 + _24*matrix._41,63 _21*matrix._12 + _22*matrix._22 + _23*matrix._32 + _24*matrix._42,64 _21*matrix._13 + _22*matrix._23 + _23*matrix._33 + _24*matrix._43,65 _21*matrix._14 + _22*matrix._24 + _23*matrix._34 + _24*matrix._44,66 67 _31*matrix._11 + _32*matrix._21 + _33*matrix._31 + _34*matrix._41,68 _31*matrix._12 + _32*matrix._22 + _33*matrix._32 + _34*matrix._42,69 _31*matrix._13 + _32*matrix._23 + _33*matrix._33 + _34*matrix._43,70 _31*matrix._14 + _32*matrix._24 + _33*matrix._34 + _34*matrix._44,71 72 _41*matrix._11 + _42*matrix._21 + _43*matrix._31 + _44*matrix._41,73 _41*matrix._12 + _42*matrix._22 + _43*matrix._32 + _44*matrix._42,74 _41*matrix._13 + _42*matrix._23 + _43*matrix._33 + _44*matrix._43,75 _41*matrix._14 + _42*matrix._24 + _43*matrix._34 + _44*matrix._4476 );77 }78 79 //Matrix multiplication/assignment80 CMatrix3D& CMatrix3D::operator*=(const CMatrix3D& matrix)81 {82 Concatenate(matrix);83 return *this;84 }85 86 //Matrix scaling87 CMatrix3D CMatrix3D::operator*(float f) const88 {89 CMatrix3D tmp;90 for (int i=0;i<16;i++) {91 tmp._data[i]=_data[i]*f;92 }93 return tmp;94 }95 96 //Matrix scaling/assignment97 CMatrix3D& CMatrix3D::operator*=(float f)98 {99 for (int i=0;i<16;i++) {100 _data[i]*=f;101 }102 return *this;103 }104 105 //Matrix addition106 CMatrix3D CMatrix3D::operator+(const CMatrix3D& m) const107 {108 CMatrix3D tmp;109 for (int i=0;i<16;i++) {110 tmp._data[i]=_data[i]+m._data[i];111 }112 return tmp;113 }114 115 //Matrix addition/assignment116 CMatrix3D& CMatrix3D::operator+=(const CMatrix3D& m)117 {118 for (int i=0;i<16;i++) {119 _data[i]+=m._data[i];120 }121 return *this;122 }123 124 bool CMatrix3D::operator==(const CMatrix3D &matrix) const125 {126 for (int i = 0; i < 16; ++i)127 if (matrix._data[i] != _data[i])128 return false;129 return true;130 }131 132 29 //Sets the identity matrix 133 30 void CMatrix3D::SetIdentity () … … 274 171 _24 += vector.Y; 275 172 _34 += vector.Z; 276 }277 278 void CMatrix3D::Concatenate(const CMatrix3D& m)279 {280 (*this)=m*(*this);281 173 } 282 174 … … 342 234 { 343 235 return CVector3D(_13, _23, _33); 344 }345 346 //Transform a vector by this matrix347 CVector4D CMatrix3D::Transform(const CVector4D &vector) const348 {349 CVector4D result;350 Transform(vector,result);351 return result;352 }353 354 void CMatrix3D::Transform(const CVector4D& vector,CVector4D& result) const355 {356 result[0] = _11*vector[0] + _12*vector[1] + _13*vector[2] + _14*vector[3];357 result[1] = _21*vector[0] + _22*vector[1] + _23*vector[2] + _24*vector[3];358 result[2] = _31*vector[0] + _32*vector[1] + _33*vector[2] + _34*vector[3];359 result[3] = _41*vector[0] + _42*vector[1] + _43*vector[2] + _44*vector[3];360 236 } 361 237 -
ps/trunk/source/maths/Matrix3D.h
r9298 r9814 25 25 26 26 #include "maths/Vector3D.h" 27 28 class CVector4D; 27 #include "maths/Vector4D.h" 28 29 29 class CQuaternion; 30 30 … … 50 50 public: 51 51 // constructors 52 CMatrix3D(); 53 CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24, 54 float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44); 55 CMatrix3D(float data[]); 52 CMatrix3D () 53 { 54 } 55 56 CMatrix3D( 57 float a11, float a12, float a13, float a14, 58 float a21, float a22, float a23, float a24, 59 float a31, float a32, float a33, float a34, 60 float a41, float a42, float a43, float a44) : 61 _11(a11), _12(a12), _13(a13), _14(a14), 62 _21(a21), _22(a22), _23(a23), _24(a24), 63 _31(a31), _32(a32), _33(a33), _34(a34), 64 _41(a41), _42(a42), _43(a43), _44(a44) 65 { 66 } 67 68 CMatrix3D(float data[]) : 69 _11(data[0]), _21(data[1]), _31(data[2]), _41(data[3]), 70 _12(data[4]), _22(data[5]), _32(data[6]), _42(data[7]), 71 _13(data[8]), _23(data[9]), _33(data[10]), _43(data[11]), 72 _14(data[12]), _24(data[13]), _34(data[14]), _44(data[15]) 73 { 74 } 56 75 57 76 // accessors to individual elements of matrix … … 64 83 65 84 // matrix multiplication 66 CMatrix3D operator*(const CMatrix3D &matrix) const; 85 CMatrix3D operator*(const CMatrix3D &matrix) const 86 { 87 return CMatrix3D( 88 _11*matrix._11 + _12*matrix._21 + _13*matrix._31 + _14*matrix._41, 89 _11*matrix._12 + _12*matrix._22 + _13*matrix._32 + _14*matrix._42, 90 _11*matrix._13 + _12*matrix._23 + _13*matrix._33 + _14*matrix._43, 91 _11*matrix._14 + _12*matrix._24 + _13*matrix._34 + _14*matrix._44, 92 93 _21*matrix._11 + _22*matrix._21 + _23*matrix._31 + _24*matrix._41, 94 _21*matrix._12 + _22*matrix._22 + _23*matrix._32 + _24*matrix._42, 95 _21*matrix._13 + _22*matrix._23 + _23*matrix._33 + _24*matrix._43, 96 _21*matrix._14 + _22*matrix._24 + _23*matrix._34 + _24*matrix._44, 97 98 _31*matrix._11 + _32*matrix._21 + _33*matrix._31 + _34*matrix._41, 99 _31*matrix._12 + _32*matrix._22 + _33*matrix._32 + _34*matrix._42, 100 _31*matrix._13 + _32*matrix._23 + _33*matrix._33 + _34*matrix._43, 101 _31*matrix._14 + _32*matrix._24 + _33*matrix._34 + _34*matrix._44, 102 103 _41*matrix._11 + _42*matrix._21 + _43*matrix._31 + _44*matrix._41, 104 _41*matrix._12 + _42*matrix._22 + _43*matrix._32 + _44*matrix._42, 105 _41*matrix._13 + _42*matrix._23 + _43*matrix._33 + _44*matrix._43, 106 _41*matrix._14 + _42*matrix._24 + _43*matrix._34 + _44*matrix._44 107 ); 108 } 109 67 110 // matrix multiplication/assignment 68 CMatrix3D& operator*=(const CMatrix3D &matrix); 111 CMatrix3D& operator*=(const CMatrix3D &matrix) 112 { 113 Concatenate(matrix); 114 return *this; 115 } 116 69 117 // matrix scaling 70 CMatrix3D operator*(float f) const; 71 // matrix scaling/assignment 72 CMatrix3D& operator*=(float f); 118 CMatrix3D operator*(float f) const 119 { 120 return CMatrix3D( 121 _11*f, _12*f, _13*f, _14*f, 122 _21*f, _22*f, _23*f, _24*f, 123 _31*f, _32*f, _33*f, _34*f, 124 _41*f, _42*f, _43*f, _44*f 125 ); 126 } 127 73 128 // matrix addition 74 CMatrix3D operator+(const CMatrix3D &matrix) const; 129 CMatrix3D operator+(const CMatrix3D &m) const 130 { 131 return CMatrix3D( 132 _11+m._11, _12+m._12, _13+m._13, _14+m._14, 133 _21+m._21, _22+m._22, _23+m._23, _24+m._24, 134 _31+m._31, _32+m._32, _33+m._33, _34+m._34, 135 _41+m._41, _42+m._42, _43+m._43, _44+m._44 136 ); 137 } 138 75 139 // matrix addition/assignment 76 CMatrix3D& operator+=(const CMatrix3D &matrix); 140 CMatrix3D& operator+=(const CMatrix3D &m) 141 { 142 _11 += m._11; _21 += m._21; _31 += m._31; _41 += m._41; 143 _12 += m._12; _22 += m._22; _32 += m._32; _42 += m._42; 144 _13 += m._13; _23 += m._23; _33 += m._33; _43 += m._43; 145 _14 += m._14; _24 += m._24; _34 += m._34; _44 += m._44; 146 return *this; 147 } 77 148 78 149 // equality 79 bool operator==(const CMatrix3D &matrix) const; 150 bool operator==(const CMatrix3D &m) const 151 { 152 return _11 == m._11 && _21 == m._21 && _31 == m._31 && _41 == m._41 && 153 _12 == m._12 && _22 == m._22 && _32 == m._32 && _42 == m._42 && 154 _13 == m._13 && _23 == m._23 && _33 == m._33 && _43 == m._43 && 155 _14 == m._14 && _24 == m._24 && _34 == m._34 && _44 == m._44; 156 } 80 157 81 158 // set this matrix to the identity matrix … … 85 162 86 163 // concatenate arbitrary matrix onto this matrix 87 void Concatenate(const CMatrix3D& m); 164 void Concatenate(const CMatrix3D& m) 165 { 166 (*this) = m * (*this); 167 } 168 169 // blend matrix using only 4x3 subset 170 void Blend(const CMatrix3D& m, float f) 171 { 172 _11 = m._11*f; _21 = m._21*f; _31 = m._31*f; 173 _12 = m._12*f; _22 = m._22*f; _32 = m._32*f; 174 _13 = m._13*f; _23 = m._23*f; _33 = m._33*f; 175 _14 = m._14*f; _24 = m._24*f; _34 = m._34*f; 176 } 177 178 // blend matrix using only 4x3 and add onto existing blend 179 void AddBlend(const CMatrix3D& m, float f) 180 { 181 _11 += m._11*f; _21 += m._21*f; _31 += m._31*f; 182 _12 += m._12*f; _22 += m._22*f; _32 += m._32*f; 183 _13 += m._13*f; _23 += m._23*f; _33 += m._33*f; 184 _14 += m._14*f; _24 += m._24*f; _34 += m._34*f; 185 } 88 186 89 187 // set this matrix to a rotation matrix for a rotation about X axis of given angle … … 145 243 146 244 // transform a 3D vector by this matrix 147 CVector3D Transform (const CVector3D &vector) const245 CVector3D Transform(const CVector3D &vector) const 148 246 { 149 247 CVector3D result; … … 159 257 } 160 258 259 // transform a 4D vector by this matrix 260 CVector4D Transform(const CVector4D &vector) const 261 { 262 CVector4D result; 263 Transform(vector, result); 264 return result; 265 } 266 267 void Transform(const CVector4D& vector, CVector4D& result) const 268 { 269 result[0] = _11*vector[0] + _12*vector[1] + _13*vector[2] + _14*vector[3]; 270 result[1] = _21*vector[0] + _22*vector[1] + _23*vector[2] + _24*vector[3]; 271 result[2] = _31*vector[0] + _32*vector[1] + _33*vector[2] + _34*vector[3]; 272 result[3] = _41*vector[0] + _42*vector[1] + _43*vector[2] + _44*vector[3]; 273 } 274 161 275 // rotate a vector by this matrix 162 276 CVector3D Rotate(const CVector3D& vector) const … … 173 287 result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z; 174 288 } 175 176 // transform a 4D vector by this matrix177 void Transform(const CVector4D& vector,CVector4D& result) const;178 CVector4D Transform(const CVector4D& vector) const;179 289 180 290 // rotate a vector by the transpose of this matrix -
ps/trunk/source/maths/Plane.h
r7805 r9814 27 27 28 28 #include "Vector3D.h" 29 #include "Vector4D.h" 29 30 30 31 enum PLANESIDE … … 39 40 public: 40 41 CPlane (); 42 CPlane (const CVector4D& coeffs) : m_Norm(coeffs[0], coeffs[1], coeffs[2]), m_Dist(coeffs[3]) { } 41 43 42 44 //sets the plane equation from 3 points on that plane -
ps/trunk/source/ps/GameSetup/Config.cpp
r9410 r9814 35 35 36 36 bool g_Shadows = false; 37 bool g_ShadowPCF = false; 37 38 bool g_FancyWater = false; 38 39 … … 73 74 CFG_GET_USER_VAL("novbo", Bool, g_NoGLVBO); 74 75 CFG_GET_USER_VAL("shadows", Bool, g_Shadows); 76 CFG_GET_USER_VAL("shadowpcf", Bool, g_ShadowPCF); 75 77 CFG_GET_USER_VAL("fancywater", Bool, g_FancyWater); 76 78 CFG_GET_USER_VAL("renderpath", String, g_RenderPath); -
ps/trunk/source/ps/GameSetup/Config.h
r9189 r9814 46 46 // flag to switch on reflective/refractive water 47 47 extern bool g_FancyWater; 48 // flag to switch on shadow PCF 49 extern bool g_ShadowPCF; 48 50 49 51 extern float g_LodBias; -
ps/trunk/source/ps/GameSetup/GameSetup.cpp
r9768 r9814 550 550 g_Renderer.SetRenderPath(CRenderer::GetRenderPathByName(g_RenderPath)); 551 551 g_Renderer.SetOptionFloat(CRenderer::OPT_LODBIAS, g_LodBias); 552 g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWPCF, g_ShadowPCF); 552 553 553 554 // create terrain related stuff -
ps/trunk/source/ps/GameSetup/HWDetect.cpp
r9556 r9814 116 116 } 117 117 118 void SetDisableShadowPCF(void* UNUSED(cbdata), bool disabled) 119 { 120 if (!IsOverridden("shadowpcf")) 121 g_ShadowPCF = !disabled; 122 } 123 118 124 void SetDisableFancyWater(void* UNUSED(cbdata), bool disabled) 119 125 { … … 137 143 scriptInterface.RegisterFunction<void, bool, &SetDisableS3TC>("SetDisableS3TC"); 138 144 scriptInterface.RegisterFunction<void, bool, &SetDisableShadows>("SetDisableShadows"); 145 scriptInterface.RegisterFunction<void, bool, &SetDisableShadowPCF>("SetDisableShadowPCF"); 139 146 scriptInterface.RegisterFunction<void, bool, &SetDisableFancyWater>("SetDisableFancyWater"); 140 147 scriptInterface.RegisterFunction<void, std::string, &SetRenderPath>("SetRenderPath"); -
ps/trunk/source/renderer/DecalRData.h
r9142 r9814 35 35 void Render(const CShaderProgramPtr& shader); 36 36 37 CModelDecal* GetDecal() { return m_Decal; } 38 37 39 private: 38 40 void BuildArrays(); -
ps/trunk/source/renderer/ModelRenderer.cpp
r9362 r9814 85 85 } 86 86 87 CModelDef::SkinPointsAndNormals(numVertices, Position, Normal, vertices, m odel->GetAnimatedBoneMatrices(), model->GetInverseBindBoneMatrices());87 CModelDef::SkinPointsAndNormals(numVertices, Position, Normal, vertices, mdef->GetBlendIndices(), model->GetAnimatedBoneMatrices()); 88 88 89 89 } … … 254 254 255 255 void RenderAllModels(const RenderModifierPtr& modifier, int filterflags, int pass, int streamflags); 256 void FilterAllModels(CModelFilter& filter, int passed, int filterflags); 256 257 }; 257 258 … … 443 444 ENSURE(bmrdata->GetKey() == this); 444 445 445 if (filterflags && !(model->GetFlags() &filterflags))446 if (filterflags && !(model->GetFlags() & filterflags)) 446 447 continue; 447 448 … … 453 454 } 454 455 455 456 void BatchModelRenderer::Filter(CModelFilter& filter, int passed, int flags) 457 { 458 if (!HaveSubmissions()) 459 return; 460 461 m->FilterAllModels(filter, passed, flags); 462 } 463 464 // Recompute filter flags 465 void BatchModelRendererInternals::FilterAllModels(CModelFilter& filter, int passed, int filterflags) 466 { 467 for(BMRModelDefTracker* mdeftracker = submissions; mdeftracker; mdeftracker = mdeftracker->m_Next) 468 { 469 for(size_t idx = 0; idx < mdeftracker->m_Slots; ++idx) 470 { 471 BMRModelData* bmrdata = mdeftracker->m_ModelSlots[idx]; 472 for(; bmrdata; bmrdata = bmrdata->m_Next) 473 { 474 CModel* model = bmrdata->GetModel(); 475 if (filterflags && !(model->GetFlags() & filterflags)) 476 continue; 477 478 if (filter.Filter(model)) 479 model->SetFlags(model->GetFlags() | passed); 480 else 481 model->SetFlags(model->GetFlags() & ~passed); 482 } 483 } 484 } 485 } -
ps/trunk/source/renderer/ModelRenderer.h
r9187 r9814 43 43 class CModel; 44 44 45 class CModelFilter 46 { 47 public: 48 virtual ~CModelFilter() {} 49 virtual bool Filter(CModel* model) = 0; 50 }; 45 51 46 52 /** … … 168 174 */ 169 175 virtual void Render(const RenderModifierPtr& modifier, int flags) = 0; 176 177 /** 178 * Filter: Filter submitted models, setting the passed flags on any models 179 * that pass the filter, and clearing them from models that fail. 180 * 181 * @param filter Filter to select a subset of models. 182 * @param passed Flags to be set/cleared. 183 * @param flags If non-zero, only models that contain @p flags 184 * have the filter test applied. 185 */ 186 virtual void Filter(CModelFilter& filter, int passed, int flags = 0) = 0; 170 187 171 188 /** … … 269 286 virtual bool HaveSubmissions(); 270 287 virtual void Render(const RenderModifierPtr& modifier, int flags); 288 virtual void Filter(CModelFilter& filter, int passed, int flags); 271 289 272 290 private: -
ps/trunk/source/renderer/PatchRData.cpp
r9635 r9814 58 58 // CPatchRData constructor 59 59 CPatchRData::CPatchRData(CPatch* patch) : 60 m_Patch(patch), m_VBSides(0), m_VBBase(0), m_VBBaseIndices(0), m_VBBlends(0), m_VBBlendIndices(0) 60 m_Patch(patch), m_VBSides(0), 61 m_VBBase(0), m_VBBaseIndices(0), 62 m_VBBlends(0), m_VBBlendIndices(0), 63 m_VBWater(0), m_VBWaterIndices(0) 61 64 { 62 65 ENSURE(patch); … … 74 77 if (m_VBBlends) g_VBMan.Release(m_VBBlends); 75 78 if (m_VBBlendIndices) g_VBMan.Release(m_VBBlendIndices); 79 if (m_VBWater) g_VBMan.Release(m_VBWater); 80 if (m_VBWaterIndices) g_VBMan.Release(m_VBWaterIndices); 76 81 } 77 82 … … 646 651 BuildIndices(); 647 652 BuildBlends(); 653 BuildWater(); 648 654 } 649 655 … … 658 664 BuildIndices(); 659 665 BuildBlends(); 666 BuildWater(); 660 667 661 668 m_UpdateFlags=0; … … 1128 1135 } 1129 1136 } 1137 1138 // 1139 // Water build and rendering 1140 // 1141 1142 // Build vertex buffer for water vertices over our patch 1143 void CPatchRData::BuildWater() 1144 { 1145 // number of vertices in each direction in each patch 1146 ENSURE((PATCH_SIZE % water_cell_size) == 0); 1147 1148 if (m_VBWater) 1149 { 1150 g_VBMan.Release(m_VBWater); 1151 m_VBWater = 0; 1152 } 1153 if (m_VBWaterIndices) 1154 { 1155 g_VBMan.Release(m_VBWaterIndices); 1156 m_VBWaterIndices = 0; 1157 } 1158 m_WaterBounds.SetEmpty(); 1159 1160 // We need to use this to access the water manager or we may not have the 1161 // actual values but some compiled-in defaults 1162 CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); 1163 if (cmpWaterManager.null()) 1164 return; 1165 1166 // Build data for water 1167 std::vector<SWaterVertex> water_vertex_data; 1168 std::vector<GLushort> water_indices; 1169 u16 water_index_map[PATCH_SIZE+1][PATCH_SIZE+1]; 1170 memset(water_index_map, 0xFF, sizeof(water_index_map)); 1171 1172 // TODO: This is not (yet) exported via the ICmp interface so... we stick to these values which can be compiled in defaults 1173 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 1174 1175 CPatch* patch = m_Patch; 1176 CTerrain* terrain = patch->m_Parent; 1177 1178 ssize_t x1 = m_Patch->m_X*PATCH_SIZE; 1179 ssize_t z1 = m_Patch->m_Z*PATCH_SIZE; 1180 1181 // build vertices, uv, and shader varying 1182 for (ssize_t z = 0; z < PATCH_SIZE; z += water_cell_size) 1183 { 1184 for (ssize_t x = 0; x <= PATCH_SIZE; x += water_cell_size) 1185 { 1186 // Check that the edge at x is partially underwater 1187 float startTerrainHeight[2] = { terrain->GetVertexGroundLevel(x+x1, z+z1), terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) }; 1188 float startWaterHeight[2] = { cmpWaterManager->GetExactWaterLevel(x+x1, z+z1), cmpWaterManager->GetExactWaterLevel(x+x1, z+z1 + water_cell_size) }; 1189 if (startTerrainHeight[0] >= startWaterHeight[0] && startTerrainHeight[1] >= startWaterHeight[1]) 1190 continue; 1191 1192 // Move x back one cell (unless at start of patch), then scan rightwards 1193 bool belowWater = true; 1194 ssize_t stripStart; 1195 for (stripStart = x = std::max(x-water_cell_size, (ssize_t)0); x <= PATCH_SIZE; x += water_cell_size) 1196 { 1197 // If this edge is not underwater, and neither is the previous edge 1198 // (i.e. belowWater == false), then stop this strip since we've reached 1199 // a cell that's entirely above water 1200 float terrainHeight[2] = { terrain->GetVertexGroundLevel(x+x1, z+z1), terrain->GetVertexGroundLevel(x+x1, z+z1 + water_cell_size) }; 1201 float waterHeight[2] = { cmpWaterManager->GetExactWaterLevel(x+x1, z+z1), cmpWaterManager->GetExactWaterLevel(x+x1, z+z1 + water_cell_size) }; 1202 if (terrainHeight[0] >= waterHeight[0] && terrainHeight[1] >= waterHeight[1]) 1203 { 1204 if (!belowWater) 1205 break; 1206 belowWater = false; 1207 } 1208 else 1209 belowWater = true; 1210 1211 // Edge (x,z)-(x,z+1) is at least partially underwater, so extend the water plane strip across it 1212 1213 // Compute vertex data for the 2 points on the edge 1214 for (int j = 0; j < 2; j++) 1215 { 1216 // Check if we already computed this vertex from an earlier strip 1217 if (water_index_map[z+j*water_cell_size][x] != 0xFFFF) 1218 continue; 1219 1220 SWaterVertex vertex; 1221 1222 terrain->CalcPosition(x+x1, z+z1 + j*water_cell_size, vertex.m_Position); 1223 float depth = waterHeight[j] - vertex.m_Position.Y; 1224 vertex.m_Position.Y = waterHeight[j]; 1225 m_WaterBounds += vertex.m_Position; 1226 1227 // NB: Usually this factor is view dependent, but for performance reasons 1228 // we do not take it into account with basic non-shader based water. 1229 // Average constant Fresnel effect for non-fancy water 1230 float alpha = clamp(depth / WaterMgr->m_WaterFullDepth + WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha); 1231 1232 // Split the depth data across 24 bits, so the fancy-water shader can reconstruct 1233 // the depth value while the simple-water can just use the precomputed alpha 1234 float depthInt = floor(depth); 1235 float depthFrac = depth - depthInt; 1236 vertex.m_DepthData = SColor4ub( 1237 u8(clamp(depthInt, 0.0f, 255.0f)), 1238 u8(clamp(-depthInt, 0.0f, 255.0f)), 1239 u8(clamp(depthFrac*255.0f, 0.0f, 255.0f)), 1240 u8(clamp(alpha*255.0f, 0.0f, 255.0f))); 1241 1242 water_index_map[z+j*water_cell_size][x] = water_vertex_data.size(); 1243 water_vertex_data.push_back(vertex); 1244 } 1245 1246 // If this was not the first x in the strip, then add a quad 1247 // using the computed vertex data 1248 1249 if (x <= stripStart) 1250 continue; 1251 1252 water_indices.push_back(water_index_map[z + water_cell_size][x - water_cell_size]); 1253 water_indices.push_back(water_index_map[z][x - water_cell_size]); 1254 water_indices.push_back(water_index_map[z][x]); 1255 water_indices.push_back(water_index_map[z + water_cell_size][x]); 1256 } 1257 } 1258 } 1259 1260 // no vertex buffers if no data generated 1261 if (water_indices.size() == 0) 1262 return; 1263 1264 // allocate vertex buffer 1265 m_VBWater = g_VBMan.Allocate(sizeof(SWaterVertex), water_vertex_data.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER); 1266 m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater, &water_vertex_data[0]); 1267 1268 // Construct indices buffer 1269 m_VBWaterIndices = g_VBMan.Allocate(sizeof(GLushort), water_indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); 1270 m_VBWaterIndices->m_Owner->UpdateChunkVertices(m_VBWaterIndices, &water_indices[0]); 1271 } 1272 1273 void CPatchRData::RenderWater() 1274 { 1275 ASSERT(m_UpdateFlags==0); 1276 1277 if (!m_VBWater) 1278 return; 1279 1280 SWaterVertex *base=(SWaterVertex *)m_VBWater->m_Owner->Bind(); 1281 1282 // setup data pointers 1283 GLsizei stride = sizeof(SWaterVertex); 1284 glColorPointer(4, GL_UNSIGNED_BYTE, stride, &base[m_VBWater->m_Index].m_DepthData); 1285 glVertexPointer(3, GL_FLOAT, stride, &base[m_VBWater->m_Index].m_Position); 1286 1287 // render 1288 if (!g_Renderer.m_SkipSubmit) { 1289 u8* indexBase = m_VBWaterIndices->m_Owner->Bind(); 1290 glDrawElements(GL_QUADS, (GLsizei) m_VBWaterIndices->m_Count, 1291 GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_VBWaterIndices->m_Index)); 1292 } 1293 1294 // bump stats 1295 g_Renderer.m_Stats.m_DrawCalls++; 1296 g_Renderer.m_Stats.m_WaterTris += m_VBWaterIndices->m_Count / 2; 1297 1298 CVertexBuffer::Unbind(); 1299 } -
ps/trunk/source/renderer/PatchRData.h
r9132 r9814 42 42 void RenderPriorities(); 43 43 44 void RenderWater(); 45 44 46 static void RenderBases(const std::vector<CPatchRData*>& patches); 45 47 static void RenderBlends(const std::vector<CPatchRData*>& patches); … … 47 49 48 50 CPatch* GetPatch() { return m_Patch; } 51 52 const CBound& GetWaterBounds() const { return m_WaterBounds; } 49 53 50 54 private: … … 94 98 cassert(sizeof(SBlendVertex) == 32); 95 99 100 // Mixed Fancy/Simple water vertex description data structure 101 struct SWaterVertex { 102 // vertex position 103 CVector3D m_Position; 104 // (p,q,r, a) where 105 // p*255 + q*-255 + r = depth of water 106 // a = depth-dependent alpha 107 SColor4ub m_DepthData; 108 }; 109 cassert(sizeof(SWaterVertex) == 16); 110 96 111 // build this renderdata object 97 112 void Build(); … … 129 144 // splats used in blend pass 130 145 std::vector<SSplat> m_BlendSplats; 146 147 // boundary of water in this patch 148 CBound m_WaterBounds; 149 150 // Water vertex buffer 151 CVertexBuffer::VBChunk* m_VBWater; 152 153 // Water indices buffer 154 CVertexBuffer::VBChunk* m_VBWaterIndices; 155 156 // Build water vertices and indices (vertex buffer and data vector) 157 void BuildWater(); 158 159 // parameter allowing a varying number of triangles per patch for LOD 160 // MUST be an exact divisor of PATCH_SIZE 161 // compiled const for the moment until/if dynamic water LOD is offered 162 // savings would be mostly beneficial for GPU or simple water 163 static const ssize_t water_cell_size = 1; 131 164 }; 132 165 -
ps/trunk/source/renderer/RenderModifiers.cpp
r9362 r9814 237 237 shader->BindTexture("shadowTex", GetShadowMap()->GetTexture()); 238 238 shader->Uniform("shadowTransform", GetShadowMap()->GetTextureMatrix()); 239 240 const float* offsets = GetShadowMap()->GetFilterOffsets(); 241 shader->Uniform("shadowOffsets1", offsets[0], offsets[1], offsets[2], offsets[3]); 242 shader->Uniform("shadowOffsets2", offsets[4], offsets[5], offsets[6], offsets[7]); 239 243 } 240 244 -
ps/trunk/source/renderer/Renderer.cpp
r9410 r9814 105 105 Row_DrawCalls = 0, 106 106 Row_TerrainTris, 107 Row_WaterTris, 107 108 Row_ModelTris, 108 109 Row_BlendSplats, … … 161 162 return "# terrain tris"; 162 163 sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_TerrainTris); 164 return buf; 165 166 case Row_WaterTris: 167 if (col == 0) 168 return "# water tris"; 169 sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_WaterTris); 163 170 return buf; 164 171 … … 296 303 RenderModifierPtr ModSolidPlayerInstancing; 297 304 RenderModifierPtr ModTransparent; 305 RenderModifierPtr ModTransparentOpaque; 306 RenderModifierPtr ModTransparentBlend; 298 307 299 308 // Palette of available RenderModifiers … … 301 310 RenderModifierPtr ModPlayerUnlit; 302 311 RenderModifierPtr ModTransparentUnlit; 312 RenderModifierPtr ModTransparentOpaqueUnlit; 313 RenderModifierPtr ModTransparentBlendUnlit; 303 314 304 315 RenderModifierPtr ModShaderSolidColor; … … 312 323 LitRenderModifierPtr ModShaderPlayerInstancing; 313 324 LitRenderModifierPtr ModShaderTransparent; 325 LitRenderModifierPtr ModShaderTransparentOpaque; 326 LitRenderModifierPtr ModShaderTransparentBlend; 314 327 RenderModifierPtr ModShaderTransparentShadow; 315 328 } Model; … … 382 395 Model.PlayerInstancing->Render(modPlayerInstancing, flags); 383 396 } 397 398 /** 399 * Filters all non-transparent models with the given modifiers. 400 */ 401 void FilterModels(CModelFilter& filter, int passed, int flags = 0) 402 { 403 Model.Normal->Filter(filter, passed, flags); 404 if (Model.Normal != Model.NormalInstancing) 405 Model.NormalInstancing->Filter(filter, passed, flags); 406 407 Model.Player->Filter(filter, passed, flags); 408 if (Model.Player != Model.PlayerInstancing) 409 Model.PlayerInstancing->Filter(filter, passed, flags); 410 } 384 411 }; 385 412 … … 413 440 m_Options.m_ShadowAlphaFix = true; 414 441 m_Options.m_ARBProgramShadow = true; 442 m_Options.m_ShadowPCF = false; 415 443 416 444 m_ShadowZBias = 0.02f; … … 515 543 if (m_Caps.m_ARBProgramShadow && m_Options.m_ARBProgramShadow) 516 544 defBasic["USE_FP_SHADOW"] = "1"; 545 if (m_Options.m_ShadowPCF) 546 defBasic["USE_SHADOW_PCF"] = "1"; 517 547 } 518 548 … … 527 557 528 558 // TODO: it'd be nicer to load this technique from an XML file or something 529 CShaderPass passTransparent0(m->shaderManager.LoadProgram("solid_tex", defNull)); 530 passTransparent0.AlphaFunc(GL_GREATER, 0.975f); 531 passTransparent0.ColorMask(0, 0, 0, 0); 532 CShaderPass passTransparent1(m->shaderManager.LoadProgram("model_common", defTransparent)); 533 passTransparent1.AlphaFunc(GL_GREATER, 0.0f); 534 passTransparent1.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 535 passTransparent1.DepthMask(0); 536 CShaderTechnique techTransparent(passTransparent0); 537 techTransparent.AddPass(passTransparent1); 559 CShaderPass passTransparentOpaque(m->shaderManager.LoadProgram("model_common", defTransparent)); 560 passTransparentOpaque.AlphaFunc(GL_GREATER, 0.9375f); 561 passTransparentOpaque.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 562 CShaderTechnique techTransparentOpaque(passTransparentOpaque); 563 564 CShaderPass passTransparentBlend(m->shaderManager.LoadProgram("model_common", defTransparent)); 565 passTransparentBlend.AlphaFunc(GL_GREATER, 0.0f); 566 passTransparentBlend.DepthFunc(GL_LESS); 567 passTransparentBlend.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 568 passTransparentBlend.DepthMask(0); 569 CShaderTechnique techTransparentBlend(passTransparentBlend); 570 571 CShaderTechnique techTransparent(passTransparentOpaque); 572 techTransparent.AddPass(passTransparentBlend); 538 573 539 574 CShaderPass passTransparentShadow(m->shaderManager.LoadProgram("solid_tex", defBasic)); … … 566 601 m->Model.ModShaderTransparent = LitRenderModifierPtr(new ShaderRenderModifier( 567 602 techTransparent)); 603 m->Model.ModShaderTransparentOpaque = LitRenderModifierPtr(new ShaderRenderModifier( 604 techTransparentOpaque)); 605 m->Model.ModShaderTransparentBlend = LitRenderModifierPtr(new ShaderRenderModifier( 606 techTransparentBlend)); 568 607 m->Model.ModShaderTransparentShadow = LitRenderModifierPtr(new ShaderRenderModifier( 569 608 techTransparentShadow)); … … 604 643 m->Model.ModSolidPlayerColor = RenderModifierPtr(new SolidPlayerColorRender); 605 644 m->Model.ModTransparentUnlit = RenderModifierPtr(new TransparentRenderModifier); 645 m->Model.ModTransparentOpaqueUnlit = RenderModifierPtr(new TransparentOpaqueRenderModifier); 646 m->Model.ModTransparentBlendUnlit = RenderModifierPtr(new TransparentBlendRenderModifier); 606 647 m->Model.ModTransparentDepthShadow = RenderModifierPtr(new TransparentDepthShadowModifier); 607 648 … … 660 701 m_Options.m_FancyWater=value; 661 702 break; 703 case OPT_SHADOWPCF: 704 m_Options.m_ShadowPCF=value; 705 break; 662 706 default: 663 707 debug_warn(L"CRenderer::SetOptionBool: unknown option"); … … 677 721 case OPT_FANCYWATER: 678 722 return m_Options.m_FancyWater; 723 case OPT_SHADOWPCF: 724 return m_Options.m_ShadowPCF; 679 725 default: 680 726 debug_warn(L"CRenderer::GetOptionBool: unknown option"); … … 812 858 m->Model.ModShaderTransparent->SetShadowMap(m->shadow); 813 859 m->Model.ModShaderTransparent->SetLightEnv(m_LightEnv); 860 861 m->Model.ModShaderTransparentOpaque->SetShadowMap(m->shadow); 862 m->Model.ModShaderTransparentOpaque->SetLightEnv(m_LightEnv); 863 864 m->Model.ModShaderTransparentBlend->SetShadowMap(m->shadow); 865 m->Model.ModShaderTransparentBlend->SetLightEnv(m_LightEnv); 814 866 815 867 m->Model.ModNormal = m->Model.ModShaderNormal; … … 822 874 m->Model.ModSolidPlayerInstancing = m->Model.ModShaderSolidPlayerColorInstancing; 823 875 m->Model.ModTransparent = m->Model.ModShaderTransparent; 876 m->Model.ModTransparentOpaque = m->Model.ModShaderTransparentOpaque; 877 m->Model.ModTransparentBlend = m->Model.ModShaderTransparentBlend; 824 878 825 879 m->Model.Normal = m->Model.pal_NormalShader; … … 838 892 m->Model.ModPlayerInstancing = m->Model.ModPlayerUnlit; 839 893 m->Model.ModTransparent = m->Model.ModTransparentUnlit; 894 m->Model.ModTransparentOpaque = m->Model.ModTransparentOpaqueUnlit; 895 m->Model.ModTransparentBlend = m->Model.ModTransparentBlendUnlit; 840 896 841 897 m->Model.NormalInstancing = m->Model.pal_NormalFF; … … 920 976 } 921 977 922 void CRenderer::RenderPatches( )978 void CRenderer::RenderPatches(const CFrustum* frustum) 923 979 { 924 980 PROFILE("render patches"); 981 982 bool filtered = false; 983 if (frustum) 984 { 985 if (!m->terrainRenderer->CullPatches(frustum)) 986 return; 987 988 filtered = true; 989 } 925 990 926 991 // switch on wireframe if we need it … … 932 997 // render all the patches, including blend pass 933 998 if (GetRenderPath() == RP_SHADER) 934 m->terrainRenderer->RenderTerrainShader((m_Caps.m_Shadows && m_Options.m_Shadows) ? m->shadow : 0 );999 m->terrainRenderer->RenderTerrainShader((m_Caps.m_Shadows && m_Options.m_Shadows) ? m->shadow : 0, filtered); 935 1000 else 936 m->terrainRenderer->RenderTerrain( );1001 m->terrainRenderer->RenderTerrain(filtered); 937 1002 938 1003 … … 954 1019 955 1020 // render tiles edges 956 m->terrainRenderer->RenderPatches( );1021 m->terrainRenderer->RenderPatches(filtered); 957 1022 958 1023 // set color for outline … … 961 1026 962 1027 // render outline of each patch 963 m->terrainRenderer->RenderOutlines( );1028 m->terrainRenderer->RenderOutlines(filtered); 964 1029 965 1030 // .. and restore the renderstates … … 969 1034 } 970 1035 971 void CRenderer::RenderModels() 1036 class CModelCuller : public CModelFilter 1037 { 1038 public: 1039 CModelCuller(const CFrustum& frustum) : m_Frustum(frustum) { } 1040 1041 bool Filter(CModel *model) 1042 { 1043 return m_Frustum.IsBoxVisible(CVector3D(0, 0, 0), model->GetBoundsRec()); 1044 } 1045 1046 private: 1047 const CFrustum& m_Frustum; 1048 }; 1049 1050 void CRenderer::RenderModels(const CFrustum* frustum) 972 1051 { 973 1052 PROFILE("render models"); 974 1053 1054 int flags = 0; 1055 if (frustum) 1056 { 1057 flags = MODELFLAG_FILTERED; 1058 CModelCuller culler(*frustum); 1059 m->FilterModels(culler, flags); 1060 } 1061 975 1062 if (m_ModelRenderMode == WIREFRAME) 976 1063 { … … 979 1066 980 1067 m->CallModelRenderers(m->Model.ModNormal, m->Model.ModNormalInstancing, 981 m->Model.ModPlayer, m->Model.ModPlayerInstancing, 0);1068 m->Model.ModPlayer, m->Model.ModPlayerInstancing, flags); 982 1069 983 1070 if (m_ModelRenderMode == WIREFRAME) … … 992 1079 993 1080 m->CallModelRenderers(m->Model.ModSolid, m->Model.ModSolidInstancing, 994 m->Model.ModSolid, m->Model.ModSolidInstancing, 0);1081 m->Model.ModSolid, m->Model.ModSolidInstancing, flags); 995 1082 996 1083 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); … … 998 1085 } 999 1086 1000 void CRenderer::RenderTransparentModels( )1087 void CRenderer::RenderTransparentModels(ETransparentMode transparentMode, const CFrustum* frustum) 1001 1088 { 1002 1089 PROFILE("render transparent models"); 1090 1091 int flags = 0; 1092 if (frustum) 1093 { 1094 flags = MODELFLAG_FILTERED; 1095 CModelCuller culler(*frustum); 1096 m->Model.Transp->Filter(culler, flags); 1097 } 1003 1098 1004 1099 // switch on wireframe if we need it … … 1008 1103 } 1009 1104 1010 m->Model.Transp->Render(m->Model.ModTransparent, 0); 1105 if (transparentMode == TRANSPARENT_OPAQUE) 1106 m->Model.Transp->Render(m->Model.ModTransparentOpaque, flags); 1107 else if (transparentMode == TRANSPARENT_BLEND) 1108 m->Model.Transp->Render(m->Model.ModTransparentBlend, flags); 1109 else 1110 m->Model.Transp->Render(m->Model.ModTransparent, flags); 1011 1111 1012 1112 if (m_ModelRenderMode == WIREFRAME) … … 1021 1121 glColor3f(1.0f, 0.0f, 0.0f); 1022 1122 1023 m->Model.Transp->Render(m->Model.ModSolid, 0);1123 m->Model.Transp->Render(m->Model.ModSolid, flags); 1024 1124 1025 1125 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); … … 1035 1135 CMatrix3D view; 1036 1136 1037 glGetFloatv( GL_PROJECTION_MATRIX, &proj._11);1038 glGetFloatv( GL_MODELVIEW_MATRIX, &view._11);1039 1040 return ( proj * view );1137 glGetFloatv(GL_PROJECTION_MATRIX, &proj._11); 1138 glGetFloatv(GL_MODELVIEW_MATRIX, &view._11); 1139 1140 return proj*view; 1041 1141 } 1042 1142 … … 1046 1146 // SetObliqueFrustumClipping: change the near plane to the given clip plane (in world space) 1047 1147 // Based on code from Game Programming Gems 5, from http://www.terathon.com/code/oblique.html 1048 // - cp is a clip plane in camera space (cp.Dot(v) = 0 for any vector v on the plane) 1049 // - sign is 1 or -1, to specify the side to clip on 1050 void CRenderer::SetObliqueFrustumClipping(const CVector4D& cp, int sign) 1051 { 1052 float matrix[16]; 1053 CVector4D q; 1148 // - worldPlane is a clip plane in world space (worldPlane.Dot(v) >= 0 for any vector v passing the clipping test) 1149 void CRenderer::SetObliqueFrustumClipping(const CVector4D& worldPlane) 1150 { 1151 float matrix[16]; 1152 CVector4D q; 1054 1153 1055 1154 // First, we'll convert the given clip plane to camera space, then we'll 1056 1155 // Get the view matrix and normal matrix (top 3x3 part of view matrix) 1057 CMatrix3D viewMatrix; 1058 m_ViewCamera.m_Orientation.GetInverse(viewMatrix); 1059 CMatrix3D normalMatrix = viewMatrix; 1060 normalMatrix._14 = 0; 1061 normalMatrix._24 = 0; 1062 normalMatrix._34 = 0; 1063 normalMatrix._44 = 1; 1064 normalMatrix._41 = 0; 1065 normalMatrix._42 = 0; 1066 normalMatrix._43 = 0; 1067 1068 // Convert the normal to camera space 1069 CVector4D planeNormal(cp.m_X, cp.m_Y, cp.m_Z, 0); 1070 planeNormal = normalMatrix.Transform(planeNormal); 1071 planeNormal.Normalize(); 1072 1073 // Find a point on the plane: we'll take the normal times -D 1074 float oldD = cp.m_W; 1075 CVector4D pointOnPlane(-oldD * cp.m_X, -oldD * cp.m_Y, -oldD * cp.m_Z, 1); 1076 pointOnPlane = viewMatrix.Transform(pointOnPlane); 1077 float newD = -pointOnPlane.Dot(planeNormal); 1078 1079 // Now create a clip plane from the new normal and new D 1080 CVector4D camPlane = planeNormal; 1081 camPlane.m_W = newD; 1082 1083 // Grab the current projection matrix from OpenGL 1084 glGetFloatv(GL_PROJECTION_MATRIX, matrix); 1156 CMatrix3D normalMatrix = m_ViewCamera.m_Orientation.GetTranspose(); 1157 CVector4D camPlane = normalMatrix.Transform(worldPlane); 1158 1159 // Grab the current projection matrix from OpenGL 1160 glGetFloatv(GL_PROJECTION_MATRIX, matrix); 1161 1162 // Calculate the clip-space corner point opposite the clipping plane 1163 // as (sgn(camPlane.x), sgn(camPlane.y), 1, 1) and 1164 // transform it into camera space by multiplying it 1165 // by the inverse of the projection matrix 1085 1166 1086 // Calculate the clip-space corner point opposite the clipping plane 1087 // as (sgn(camPlane.x), sgn(camPlane.y), 1, 1) and 1088 // transform it into camera space by multiplying it 1089 // by the inverse of the projection matrix 1090 1091 q.m_X = (sgn(camPlane.m_X) + matrix[8]) / matrix[0]; 1092 q.m_Y = (sgn(camPlane.m_Y) + matrix[9]) / matrix[5]; 1093 q.m_Z = -1.0f; 1094 q.m_W = (1.0f + matrix[10]) / matrix[14]; 1095 1096 // Calculate the scaled plane vector 1097 CVector4D c = camPlane * (sign * 2.0f / camPlane.Dot(q)); 1098 1099 // Replace the third row of the projection matrix 1100 matrix[2] = c.m_X; 1101 matrix[6] = c.m_Y; 1102 matrix[10] = c.m_Z + 1.0f; 1103 matrix[14] = c.m_W; 1104 1105 // Load it back into OpenGL 1106 glMatrixMode(GL_PROJECTION); 1107 glLoadMatrixf(matrix); 1167 q.m_X = (sgn(camPlane.m_X) - matrix[8]/matrix[11]) / matrix[0]; 1168 q.m_Y = (sgn(camPlane.m_Y) - matrix[9]/matrix[11]) / matrix[5]; 1169 q.m_Z = 1.0f/matrix[11]; 1170 q.m_W = (1.0f - matrix[10]/matrix[11]) / matrix[14]; 1171 1172 // Calculate the scaled plane vector 1173 CVector4D c = camPlane * (2.0f * matrix[11] / camPlane.Dot(q)); 1174 1175 // Replace the third row of the projection matrix 1176 matrix[2] = c.m_X; 1177 matrix[6] = c.m_Y; 1178 matrix[10] = c.m_Z - matrix[11]; 1179 matrix[14] = c.m_W; 1180 1181 // Load it back into OpenGL 1182 glMatrixMode(GL_PROJECTION); 1183 glLoadMatrixf(matrix); 1108 1184 1109 1185 glMatrixMode(GL_MODELVIEW); 1110 1186 } 1111 1112 1187 1113 1188 /////////////////////////////////////////////////////////////////////////////////////////////////// 1114 1189 // RenderReflections: render the water reflections to the reflection texture 1115 void CRenderer::RenderReflections()1190 SScreenRect CRenderer::RenderReflections(const CBound& scissor) 1116 1191 { 1117 1192 PROFILE("render reflections"); … … 1127 1202 // the whole screen despite being rendered into a square, and cover slightly more 1128 1203 // of the view so we can see wavy reflections of slightly off-screen objects. 1129 m_ViewCamera.m_Orientation.Translate(0, -wm.m_WaterHeight, 0);1130 1204 m_ViewCamera.m_Orientation.Scale(1, -1, 1); 1131 m_ViewCamera.m_Orientation.Translate(0, wm.m_WaterHeight, 0); 1205 m_ViewCamera.m_Orientation.Translate(0, 2*wm.m_WaterHeight, 0); 1206 m_ViewCamera.UpdateFrustum(scissor); 1207 m_ViewCamera.ClipFrustum(CVector4D(0, 1, 0, -wm.m_WaterHeight)); 1208 1132 1209 SViewPort vp; 1133 1210 vp.m_Height = wm.m_ReflectionTextureSize; … … 1144 1221 1145 1222 CVector4D camPlane(0, 1, 0, -wm.m_WaterHeight); 1146 SetObliqueFrustumClipping(camPlane , -1);1223 SetObliqueFrustumClipping(camPlane); 1147 1224 1148 1225 // Save the model-view-projection matrix so the shaders can use it for projective texturing 1149 1226 wm.m_ReflectionMatrix = GetModelViewProjectionMatrix(); 1150 1227 1151 // Disable backface culling so trees render properly (it might also be possible to flip 1152 // the culling direction here, but this seems to lead to problems) 1153 glDisable(GL_CULL_FACE); 1154 1155 // Make the depth buffer work backwards; there seems to be some oddness with 1156 // oblique frustum clipping and the "sign" parameter here 1157 glClearDepth(0); 1158 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1159 glDepthFunc(GL_GEQUAL); 1160 1161 // Render sky, terrain and models 1162 m->skyManager.RenderSky(); 1163 ogl_WarnIfError(); 1164 RenderPatches(); 1165 ogl_WarnIfError(); 1166 RenderModels(); 1167 ogl_WarnIfError(); 1168 RenderTransparentModels(); 1169 ogl_WarnIfError(); 1170 1171 // Copy the image to a texture 1172 pglActiveTextureARB(GL_TEXTURE0_ARB); 1173 glEnable(GL_TEXTURE_2D); 1174 glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture); 1175 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1176 (GLsizei)wm.m_ReflectionTextureSize, (GLsizei)wm.m_ReflectionTextureSize); 1177 1178 //Reset old camera and re-enable backface culling 1228 SScreenRect screenScissor; 1229 screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width); 1230 screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height); 1231 screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width); 1232 screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height); 1233 1234 if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2) 1235 { 1236 glEnable(GL_SCISSOR_TEST); 1237 glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1238 1239 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1240 1241 glFrontFace(GL_CW); 1242 1243 // Render sky, terrain and models 1244 m->skyManager.RenderSky(); 1245 ogl_WarnIfError(); 1246 RenderPatches(&m_ViewCamera.GetFrustum()); 1247 ogl_WarnIfError(); 1248 RenderModels(&m_ViewCamera.GetFrustum()); 1249 ogl_WarnIfError(); 1250 RenderTransparentModels(TRANSPARENT_BLEND, &m_ViewCamera.GetFrustum()); 1251 ogl_WarnIfError(); 1252 1253 glFrontFace(GL_CCW); 1254 1255 glDisable(GL_SCISSOR_TEST); 1256 1257 // Copy the image to a texture 1258 pglActiveTextureARB(GL_TEXTURE0_ARB); 1259 glEnable(GL_TEXTURE_2D); 1260 glBindTexture(GL_TEXTURE_2D, wm.m_ReflectionTexture); 1261 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 1262 screenScissor.x1, screenScissor.y1, 1263 screenScissor.x1, screenScissor.y1, 1264 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1265 } 1266 1267 // Reset old camera 1179 1268 m_ViewCamera = normalCamera; 1180 1269 m->SetOpenGLCamera(m_ViewCamera); 1181 1270 1182 glEnable(GL_CULL_FACE); 1183 //glClearDepth(1); 1184 //glClear(GL_DEPTH_BUFFER_BIT); 1185 //glDepthFunc(GL_LEQUAL); 1271 return screenScissor; 1186 1272 } 1187 1273 … … 1189 1275 /////////////////////////////////////////////////////////////////////////////////////////////////// 1190 1276 // RenderRefractions: render the water refractions to the refraction texture 1191 void CRenderer::RenderRefractions()1277 SScreenRect CRenderer::RenderRefractions(const CBound &scissor) 1192 1278 { 1193 1279 PROFILE("render refractions"); … … 1202 1288 // the whole screen despite being rendered into a square, and cover slightly more 1203 1289 // of the view so we can see wavy refractions of slightly off-screen objects. 1290 m_ViewCamera.UpdateFrustum(scissor); 1291 m_ViewCamera.ClipFrustum(CVector4D(0, -1, 0, wm.m_WaterHeight)); 1292 1204 1293 SViewPort vp; 1205 1294 vp.m_Height = wm.m_RefractionTextureSize; … … 1212 1301 scaleMat.SetScaling(m_Height/float(std::max(1, m_Width)), 1.0f, 1.0f); 1213 1302 m_ViewCamera.m_ProjMat = scaleMat * m_ViewCamera.m_ProjMat; 1303 1214 1304 m->SetOpenGLCamera(m_ViewCamera); 1215 1305 1216 CVector4D camPlane(0, 1, 0, -wm.m_WaterHeight);1217 SetObliqueFrustumClipping(camPlane , -1);1306 CVector4D camPlane(0, -1, 0, wm.m_WaterHeight); 1307 SetObliqueFrustumClipping(camPlane); 1218 1308 1219 1309 // Save the model-view-projection matrix so the shaders can use it for projective texturing 1220 1310 wm.m_RefractionMatrix = GetModelViewProjectionMatrix(); 1221 1311 1222 // Make the depth buffer work backwards; there seems to be some oddness with 1223 // oblique frustum clipping and the "sign" parameter here 1224 glClearDepth(0); 1225 glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // a neutral gray to blend in with shores 1226 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1227 glDepthFunc(GL_GEQUAL); 1228 1229 // Render terrain and models 1230 RenderPatches(); 1231 ogl_WarnIfError(); 1232 RenderModels(); 1233 ogl_WarnIfError(); 1234 RenderTransparentModels(); 1235 ogl_WarnIfError(); 1236 1237 // Copy the image to a texture 1238 pglActiveTextureARB(GL_TEXTURE0_ARB); 1239 glEnable(GL_TEXTURE_2D); 1240 glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture); 1241 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1242 (GLsizei)wm.m_RefractionTextureSize, (GLsizei)wm.m_RefractionTextureSize); 1243 1244 //Reset old camera and re-enable backface culling 1312 SScreenRect screenScissor; 1313 screenScissor.x1 = (GLint)floor((scissor[0].X*0.5f+0.5f)*vp.m_Width); 1314 screenScissor.y1 = (GLint)floor((scissor[0].Y*0.5f+0.5f)*vp.m_Height); 1315 screenScissor.x2 = (GLint)ceil((scissor[1].X*0.5f+0.5f)*vp.m_Width); 1316 screenScissor.y2 = (GLint)ceil((scissor[1].Y*0.5f+0.5f)*vp.m_Height); 1317 if (screenScissor.x1 < screenScissor.x2 && screenScissor.y1 < screenScissor.y2) 1318 { 1319 glEnable(GL_SCISSOR_TEST); 1320 glScissor(screenScissor.x1, screenScissor.y1, screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1321 1322 glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // a neutral gray to blend in with shores 1323 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1324 1325 // Render terrain and models 1326 RenderPatches(&m_ViewCamera.GetFrustum()); 1327 ogl_WarnIfError(); 1328 RenderModels(&m_ViewCamera.GetFrustum()); 1329 ogl_WarnIfError(); 1330 RenderTransparentModels(TRANSPARENT_BLEND, &m_ViewCamera.GetFrustum()); 1331 ogl_WarnIfError(); 1332 1333 glDisable(GL_SCISSOR_TEST); 1334 1335 // Copy the image to a texture 1336 pglActiveTextureARB(GL_TEXTURE0_ARB); 1337 glEnable(GL_TEXTURE_2D); 1338 glBindTexture(GL_TEXTURE_2D, wm.m_RefractionTexture); 1339 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 1340 screenScissor.x1, screenScissor.y1, 1341 screenScissor.x1, screenScissor.y1, 1342 screenScissor.x2 - screenScissor.x1, screenScissor.y2 - screenScissor.y1); 1343 } 1344 1345 // Reset old camera 1245 1346 m_ViewCamera = normalCamera; 1246 1347 m->SetOpenGLCamera(m_ViewCamera); 1247 1348 1248 glEnable(GL_CULL_FACE); 1249 glClearDepth(1); 1250 glDepthFunc(GL_LEQUAL); 1349 return screenScissor; 1251 1350 } 1252 1351 … … 1436 1535 ogl_WarnIfError(); 1437 1536 1438 if (m_WaterManager->m_RenderWater && m_WaterManager->WillRenderFancyWater()) 1439 { 1440 // render reflected and refracted scenes, then re-clear the screen 1441 RenderReflections(); 1442 RenderRefractions(); 1443 glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]); 1444 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1537 CBound waterScissor; 1538 if (m_WaterManager->m_RenderWater) 1539 { 1540 waterScissor = m->terrainRenderer->ScissorWater(m_ViewCamera.GetViewProjection()); 1541 if (waterScissor.GetVolume() > 0 && m_WaterManager->WillRenderFancyWater()) 1542 { 1543 SScreenRect reflectionScissor = RenderReflections(waterScissor); 1544 SScreenRect refractionScissor = RenderRefractions(waterScissor); 1545 SScreenRect dirty; 1546 dirty.x1 = std::min(reflectionScissor.x1, refractionScissor.x1); 1547 dirty.y1 = std::min(reflectionScissor.y1, refractionScissor.y1); 1548 dirty.x2 = std::max(reflectionScissor.x2, refractionScissor.x2); 1549 dirty.y2 = std::max(reflectionScissor.y2, refractionScissor.y2); 1550 if (dirty.x1 < dirty.x2 && dirty.y1 < dirty.y2) 1551 { 1552 glEnable(GL_SCISSOR_TEST); 1553 glScissor(dirty.x1, dirty.y1, dirty.x2 - dirty.x1, dirty.y2 - dirty.y1); 1554 glClearColor(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]); 1555 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 1556 glDisable(GL_SCISSOR_TEST); 1557 } 1558 } 1445 1559 } 1446 1560 … … 1468 1582 ogl_WarnIfError(); 1469 1583 1470 // render transparent stuff, so it can overlap models/terrain1471 RenderTransparentModels();1472 ogl_WarnIfError();1473 1474 1584 // render water 1475 if (m_WaterManager->m_RenderWater && g_Game) 1476 { 1585 if (m_WaterManager->m_RenderWater && g_Game && waterScissor.GetVolume() > 0) 1586 { 1587 // render transparent stuff, but only the solid parts that can occlude block water 1588 RenderTransparentModels(TRANSPARENT_OPAQUE); 1589 ogl_WarnIfError(); 1590 1477 1591 m->terrainRenderer->RenderWater(); 1478 1592 ogl_WarnIfError(); 1479 1480 // render transparent stuff again, so it can overlap thewater1481 RenderTransparentModels( );1593 1594 // render transparent stuff again, but only the blended parts that overlap water 1595 RenderTransparentModels(TRANSPARENT_BLEND); 1482 1596 ogl_WarnIfError(); 1483 1484 // TODO: Maybe think of a better way to deal with transparent objects; 1485 // they can appear both under and above water (seaweed vs. trees), but doing 1486 // 2 renders causes (a) inefficiency and (b) darker over-water objects (e.g. 1487 // trees) than usual because the transparent bits get overwritten twice. 1488 // This doesn't look particularly bad, but it is noticeable if you try 1489 // turning the water off. On the other hand every user will have water 1490 // on all the time, so it might not be worth worrying about. 1597 } 1598 else 1599 { 1600 // render transparent stuff, so it can overlap models/terrain 1601 RenderTransparentModels(TRANSPARENT); 1602 ogl_WarnIfError(); 1491 1603 } 1492 1604 … … 1932 2044 } 1933 2045 2046 jsval CRenderer::JSI_GetShadowPCF(JSContext*) 2047 { 2048 return ToJSVal(m_Options.m_ShadowPCF); 2049 } 2050 2051 void CRenderer::JSI_SetShadowPCF(JSContext* ctx, jsval newval) 2052 { 2053 if (!ToPrimitive(ctx, newval, m_Options.m_ShadowPCF)) 2054 return; 2055 2056 ReloadShaders(); 2057 } 2058 1934 2059 jsval CRenderer::JSI_GetSky(JSContext*) 1935 2060 { … … 1956 2081 AddProperty(L"depthTextureBits", &CRenderer::JSI_GetDepthTextureBits, &CRenderer::JSI_SetDepthTextureBits); 1957 2082 AddProperty(L"shadowAlphaFix", &CRenderer::JSI_GetShadowAlphaFix, &CRenderer::JSI_SetShadowAlphaFix); 2083 AddProperty(L"shadowPCF", &CRenderer::JSI_GetShadowPCF, &CRenderer::JSI_SetShadowPCF); 1958 2084 AddProperty(L"skipSubmit", &CRenderer::m_SkipSubmit); 1959 2085 AddProperty(L"skySet", &CRenderer::JSI_GetSky, &CRenderer::JSI_SetSky); -
ps/trunk/source/renderer/Renderer.h
r9410 r9814 50 50 enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES }; 51 51 52 // transparency modes 53 enum ETransparentMode { TRANSPARENT, TRANSPARENT_OPAQUE, TRANSPARENT_BLEND }; 54 52 55 // stream flags 53 56 #define STREAM_POS (1 << 0) … … 66 69 #define g_Renderer CRenderer::GetSingleton() 67 70 71 struct SScreenRect 72 { 73 GLint x1, y1, x2, y2; 74 }; 75 68 76 /////////////////////////////////////////////////////////////////////////////////////////// 69 77 // CRenderer: base renderer class - primary interface to the rendering engine … … 82 90 OPT_SHADOWS, 83 91 OPT_FANCYWATER, 84 OPT_LODBIAS 92 OPT_LODBIAS, 93 OPT_SHADOWPCF 85 94 }; 86 95 … … 105 114 // number of terrain triangles drawn 106 115 size_t m_TerrainTris; 116 // number of water triangles drawn 117 size_t m_WaterTris; 107 118 // number of (non-transparent) model triangles drawn 108 119 size_t m_ModelTris; … … 122 133 bool m_ShadowAlphaFix; 123 134 bool m_ARBProgramShadow; 135 bool m_ShadowPCF; 124 136 } m_Options; 125 137 … … 316 328 jsval JSI_GetShadowAlphaFix(JSContext*); 317 329 void JSI_SetShadowAlphaFix(JSContext* ctx, jsval newval); 330 jsval JSI_GetShadowPCF(JSContext*); 331 void JSI_SetShadowPCF(JSContext* ctx, jsval newval); 318 332 jsval JSI_GetSky(JSContext*); 319 333 void JSI_SetSky(JSContext* ctx, jsval newval); … … 332 346 333 347 // patch rendering stuff 334 void RenderPatches( );348 void RenderPatches(const CFrustum* frustum = 0); 335 349 336 350 // model rendering stuff 337 void RenderModels( );338 void RenderTransparentModels( );351 void RenderModels(const CFrustum* frustum = 0); 352 void RenderTransparentModels(ETransparentMode transparentMode, const CFrustum* frustum = 0); 339 353 340 354 void RenderSilhouettes(); … … 346 360 347 361 // render water reflection and refraction textures 348 void RenderReflections();349 void RenderRefractions();362 SScreenRect RenderReflections(const CBound& scissor); 363 SScreenRect RenderRefractions(const CBound& scissor); 350 364 351 365 // debugging … … 353 367 354 368 // enable oblique frustum clipping with the given clip plane 355 void SetObliqueFrustumClipping(const CVector4D& clipPlane , int sign);369 void SetObliqueFrustumClipping(const CVector4D& clipPlane); 356 370 357 371 void ReloadShaders(); -
ps/trunk/source/renderer/ShadowMap.cpp
r9189 r9814 79 79 GLuint DummyTexture; 80 80 81 float FilterOffsets[8]; 82 81 83 // Helper functions 82 84 void CalcShadowMatrices(); … … 222 224 ShadowBound.IntersectFrustumConservative(LightspaceCamera.GetFrustum()); 223 225 226 // round off the shadow boundaries to sane increments to help reduce swim effect 227 float boundInc = 16.0f; 228 ShadowBound[0].X = floor(ShadowBound[0].X / boundInc) * boundInc; 229 ShadowBound[0].Y = floor(ShadowBound[0].Y / boundInc) * boundInc; 230 ShadowBound[1].X = ceil(ShadowBound[1].X / boundInc) * boundInc; 231 ShadowBound[1].Y = ceil(ShadowBound[1].Y / boundInc) * boundInc; 232 224 233 // minimum Z bound must not be clipped too much, because objects that lie outside 225 234 // the shadow bounds cannot cast shadows either … … 243 252 scale.Z = 2.0 / scale.Z; 244 253 254 // make sure a given world position falls on a consistent shadowmap texel fractional offset 255 float offsetX = fmod(ShadowBound[0].X - LightTransform._14, 2.0f/(scale.X*EffectiveWidth)); 256 float offsetY = fmod(ShadowBound[0].Y - LightTransform._24, 2.0f/(scale.Y*EffectiveHeight)); 257 245 258 LightProjection.SetZero(); 246 259 LightProjection._11 = scale.X; 247 LightProjection._14 = shift.X* scale.X;260 LightProjection._14 = (shift.X + offsetX) * scale.X; 248 261 LightProjection._22 = scale.Y; 249 LightProjection._24 = shift.Y* scale.Y;262 LightProjection._24 = (shift.Y + offsetY) * scale.Y; 250 263 LightProjection._33 = scale.Z; 251 264 LightProjection._34 = shift.Z * scale.Z + renderer.m_ShadowZBias; … … 256 269 // and then concatenating all matrices that have been calculated so far 257 270 CMatrix3D lightToTex; 258 float texscalex = (float)EffectiveWidth / (float)Width; 259 float texscaley = (float)EffectiveHeight / (float)Height; 260 float texscalez = 1.0; 261 262 texscalex = texscalex / (ShadowBound[1].X - ShadowBound[0].X); 263 texscaley = texscaley / (ShadowBound[1].Y - ShadowBound[0].Y); 264 texscalez = texscalez / (ShadowBound[1].Z - ShadowBound[0].Z); 271 float texscalex = scale.X * 0.5f * (float)EffectiveWidth / (float)Width; 272 float texscaley = scale.Y * 0.5f * (float)EffectiveHeight / (float)Height; 273 float texscalez = scale.Z * 0.5f; 265 274 266 275 lightToTex.SetZero(); 267 276 lightToTex._11 = texscalex; 268 lightToTex._14 = -ShadowBound[0].X* texscalex;277 lightToTex._14 = (offsetX - ShadowBound[0].X) * texscalex; 269 278 lightToTex._22 = texscaley; 270 lightToTex._24 = -ShadowBound[0].Y* texscaley;279 lightToTex._24 = (offsetY - ShadowBound[0].Y) * texscaley; 271 280 lightToTex._33 = texscalez; 272 281 lightToTex._34 = -ShadowBound[0].Z * texscalez; … … 360 369 glTexImage2D(GL_TEXTURE_2D, 0, format, Width, Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); 361 370 362 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_ LUMINANCE);371 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); 363 372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); 364 373 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); … … 398 407 g_Renderer.m_Options.m_Shadows = false; 399 408 } 409 410 FilterOffsets[0] = -0.4f/Width; 411 FilterOffsets[1] = 1.0f/Height; 412 413 FilterOffsets[2] = -1.0f/Width; 414 FilterOffsets[3] = -0.4f/Height; 415 416 FilterOffsets[4] = 0.4f/Width; 417 FilterOffsets[5] = -1.0f/Height; 418 419 FilterOffsets[6] = 1.0f/Width; 420 FilterOffsets[7] = 0.4f/Height; 400 421 } 401 422 … … 497 518 } 498 519 520 const float* ShadowMap::GetFilterOffsets() const 521 { 522 return m->FilterOffsets; 523 } 499 524 500 525 ////////////////////////////////////////////////////////////////////////////// -
ps/trunk/source/renderer/ShadowMap.h
r9188 r9814 119 119 void RenderDebugDisplay(); 120 120 121 /** 122 * Get offsets for PCF filtering. 123 */ 124 const float* GetFilterOffsets() const; 125 121 126 private: 122 127 ShadowMapInternals* m; -
ps/trunk/source/renderer/TerrainRenderer.cpp
r9362 r9814 77 77 /// Patches that were submitted for this frame 78 78 std::vector<CPatchRData*> visiblePatches; 79 std::vector<CPatchRData*> filteredPatches; 79 80 80 81 /// Decals that were submitted for this frame 81 82 std::vector<CDecalRData*> visibleDecals; 83 std::vector<CDecalRData*> filteredDecals; 82 84 83 85 /// Fancy water shader … … 165 167 166 168 /////////////////////////////////////////////////////////////////// 169 // Culls patches and decals against a frustum. 170 bool TerrainRenderer::CullPatches(const CFrustum* frustum) 171 { 172 m->filteredPatches.clear(); 173 for (std::vector<CPatchRData*>::iterator it = m->visiblePatches.begin(); it != m->visiblePatches.end(); it++) 174 { 175 if (frustum->IsBoxVisible(CVector3D(0, 0, 0), (*it)->GetPatch()->GetBounds())) 176 m->filteredPatches.push_back(*it); 177 } 178 179 m->filteredDecals.clear(); 180 for (std::vector<CDecalRData*>::iterator it = m->visibleDecals.begin(); it != m->visibleDecals.end(); it++) 181 { 182 if (frustum->IsBoxVisible(CVector3D(0, 0, 0), (*it)->GetDecal()->GetBounds())) 183 m->filteredDecals.push_back(*it); 184 } 185 186 return !m->filteredPatches.empty() || !m->filteredDecals.empty(); 187 } 188 189 /////////////////////////////////////////////////////////////////// 167 190 // Full-featured terrain rendering with blending and everything 168 void TerrainRenderer::RenderTerrain( )191 void TerrainRenderer::RenderTerrain(bool filtered) 169 192 { 170 193 ENSURE(m->phase == Phase_Render); 194 195 std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches; 196 std::vector<CDecalRData*>& visibleDecals = filtered ? m->filteredDecals : m->visibleDecals; 197 if (visiblePatches.empty() && visibleDecals.empty()) 198 return; 171 199 172 200 // render the solid black sides of the map first … … 175 203 glColor3f(0, 0, 0); 176 204 PROFILE_START("render terrain sides"); 177 for (size_t i = 0; i < m->visiblePatches.size(); ++i)178 m->visiblePatches[i]->RenderSides();205 for (size_t i = 0; i < visiblePatches.size(); ++i) 206 visiblePatches[i]->RenderSides(); 179 207 PROFILE_END("render terrain sides"); 180 208 … … 199 227 200 228 PROFILE_START("render terrain base"); 201 CPatchRData::RenderBases( m->visiblePatches);229 CPatchRData::RenderBases(visiblePatches); 202 230 PROFILE_END("render terrain base"); 203 231 … … 232 260 // render blend passes for each patch 233 261 PROFILE_START("render terrain blends"); 234 CPatchRData::RenderBlends( m->visiblePatches);262 CPatchRData::RenderBlends(visiblePatches); 235 263 PROFILE_END("render terrain blends"); 236 264 … … 256 284 257 285 PROFILE_START("render terrain decals"); 258 for (size_t i = 0; i < m->visibleDecals.size(); ++i)259 m->visibleDecals[i]->Render(CShaderProgramPtr());286 for (size_t i = 0; i < visibleDecals.size(); ++i) 287 visibleDecals[i]->Render(CShaderProgramPtr()); 260 288 PROFILE_END("render terrain decals"); 261 289 … … 324 352 325 353 PROFILE_START("render terrain streams"); 326 CPatchRData::RenderStreams( m->visiblePatches, streamflags);354 CPatchRData::RenderStreams(visiblePatches, streamflags); 327 355 PROFILE_END("render terrain streams"); 328 356 … … 364 392 shader->BindTexture("shadowTex", shadow->GetTexture()); 365 393 shader->Uniform("shadowTransform", shadow->GetTextureMatrix()); 394 395 const float* offsets = shadow->GetFilterOffsets(); 396 shader->Uniform("shadowOffsets1", offsets[0], offsets[1], offsets[2], offsets[3]); 397 shader->Uniform("shadowOffsets2", offsets[4], offsets[5], offsets[6], offsets[7]); 366 398 } 367 399 … … 374 406 } 375 407 376 void TerrainRenderer::RenderTerrainShader(ShadowMap* shadow )408 void TerrainRenderer::RenderTerrainShader(ShadowMap* shadow, bool filtered) 377 409 { 378 410 ENSURE(m->phase == Phase_Render); 411 412 std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches; 413 std::vector<CDecalRData*>& visibleDecals = filtered ? m->filteredDecals : m->visibleDecals; 414 if (visiblePatches.empty() && visibleDecals.empty()) 415 return; 379 416 380 417 CShaderManager& shaderManager = g_Renderer.GetShaderManager(); … … 387 424 if (g_Renderer.m_Caps.m_ARBProgramShadow && g_Renderer.m_Options.m_ARBProgramShadow) 388 425 defBasic["USE_FP_SHADOW"] = "1"; 426 if (g_Renderer.m_Options.m_ShadowPCF) 427 defBasic["USE_SHADOW_PCF"] = "1"; 389 428 } 390 429 … … 400 439 glColor3f(0, 0, 0); 401 440 PROFILE_START("render terrain sides"); 402 for (size_t i = 0; i < m->visiblePatches.size(); ++i)403 m->visiblePatches[i]->RenderSides();441 for (size_t i = 0; i < visiblePatches.size(); ++i) 442 visiblePatches[i]->RenderSides(); 404 443 PROFILE_END("render terrain sides"); 405 444 … … 412 451 413 452 PROFILE_START("render terrain base"); 414 CPatchRData::RenderBases( m->visiblePatches);453 CPatchRData::RenderBases(visiblePatches); 415 454 PROFILE_END("render terrain base"); 416 455 … … 438 477 // render blend passes for each patch 439 478 PROFILE_START("render terrain blends"); 440 CPatchRData::RenderBlends( m->visiblePatches);479 CPatchRData::RenderBlends(visiblePatches); 441 480 PROFILE_END("render terrain blends"); 442 481 … … 457 496 458 497 PROFILE_START("render terrain decals"); 459 for (size_t i = 0; i < m->visibleDecals.size(); ++i)460 m->visibleDecals[i]->Render(shaderDecal);498 for (size_t i = 0; i < visibleDecals.size(); ++i) 499 visibleDecals[i]->Render(shaderDecal); 461 500 PROFILE_END("render terrain decals"); 462 501 … … 481 520 /////////////////////////////////////////////////////////////////// 482 521 // Render un-textured patches as polygons 483 void TerrainRenderer::RenderPatches( )522 void TerrainRenderer::RenderPatches(bool filtered) 484 523 { 485 524 ENSURE(m->phase == Phase_Render); 486 525 526 std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches; 527 if (visiblePatches.empty()) 528 return; 529 487 530 glEnableClientState(GL_VERTEX_ARRAY); 488 CPatchRData::RenderStreams( m->visiblePatches, STREAM_POS);531 CPatchRData::RenderStreams(visiblePatches, STREAM_POS); 489 532 glDisableClientState(GL_VERTEX_ARRAY); 490 533 } … … 493 536 /////////////////////////////////////////////////////////////////// 494 537 // Render outlines of submitted patches as lines 495 void TerrainRenderer::RenderOutlines( )538 void TerrainRenderer::RenderOutlines(bool filtered) 496 539 { 497 540 ENSURE(m->phase == Phase_Render); 498 541 542 std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches; 543 if (visiblePatches.empty()) 544 return; 545 499 546 glEnableClientState(GL_VERTEX_ARRAY); 547 for (size_t i = 0; i < visiblePatches.size(); ++i) 548 visiblePatches[i]->RenderOutline(); 549 glDisableClientState(GL_VERTEX_ARRAY); 550 } 551 552 553 /////////////////////////////////////////////////////////////////// 554 // Scissor rectangle of water patches 555 CBound TerrainRenderer::ScissorWater(const CMatrix3D &viewproj) 556 { 557 CBound scissor; 500 558 for (size_t i = 0; i < m->visiblePatches.size(); ++i) 501 m->visiblePatches[i]->RenderOutline(); 502 glDisableClientState(GL_VERTEX_ARRAY); 503 } 504 505 506 /////////////////////////////////////////////////////////////////// 507 // Render water that is part of the terrain 508 void TerrainRenderer::RenderWater() 509 { 510 PROFILE( "render water" ); 511 512 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 513 514 bool fancy = WaterMgr->WillRenderFancyWater(); 559 { 560 CPatchRData* data = m->visiblePatches[i]; 561 const CBound& waterBounds = data->GetWaterBounds(); 562 if (waterBounds.IsEmpty()) 563 continue; 564 565 CVector4D v1 = viewproj.Transform(CVector4D(waterBounds[0].X, waterBounds[1].Y, waterBounds[0].Z, 1.0f)); 566 CVector4D v2 = viewproj.Transform(CVector4D(waterBounds[1].X, waterBounds[1].Y, waterBounds[0].Z, 1.0f)); 567 CVector4D v3 = viewproj.Transform(CVector4D(waterBounds[0].X, waterBounds[1].Y, waterBounds[1].Z, 1.0f)); 568 CVector4D v4 = viewproj.Transform(CVector4D(waterBounds[1].X, waterBounds[1].Y, waterBounds[1].Z, 1.0f)); 569 CBound screenBounds; 570 #define ADDBOUND(v1, v2, v3, v4) \ 571 if (v1[2] >= -v1[3]) \ 572 screenBounds += CVector3D(v1[0], v1[1], v1[2]) * (1.0f / v1[3]); \ 573 else \ 574 { \ 575 float t = v1[2] + v1[3]; \ 576 if (v2[2] > -v2[3]) \ 577 { \ 578 CVector4D c2 = v1 + (v2 - v1) * (t / (t - (v2[2] + v2[3]))); \ 579 screenBounds += CVector3D(c2[0], c2[1], c2[2]) * (1.0f / c2[3]); \ 580 } \ 581 if (v3[2] > -v3[3]) \ 582 { \ 583 CVector4D c3 = v1 + (v3 - v1) * (t / (t - (v3[2] + v3[3]))); \ 584 screenBounds += CVector3D(c3[0], c3[1], c3[2]) * (1.0f / c3[3]); \ 585 } \ 586 if (v4[2] > -v4[3]) \ 587 { \ 588 CVector4D c4 = v1 + (v4 - v1) * (t / (t - (v4[2] + v4[3]))); \ 589 screenBounds += CVector3D(c4[0], c4[1], c4[2]) * (1.0f / c4[3]); \ 590 } \ 591 } 592 ADDBOUND(v1, v2, v3, v4); 593 ADDBOUND(v2, v1, v3, v4); 594 ADDBOUND(v3, v1, v2, v4); 595 ADDBOUND(v4, v1, v2, v3); 596 #undef ADDBOUND 597 if (screenBounds[0].X >= 1.0f || screenBounds[1].X <= -1.0f || screenBounds[0].Y >= 1.0f || screenBounds[1].Y <= -1.0f) 598 continue; 599 scissor += screenBounds; 600 } 601 return CBound(CVector3D(clamp(scissor[0].X, -1.0f, 1.0f), clamp(scissor[0].Y, -1.0f, 1.0f), -1.0f), 602 CVector3D(clamp(scissor[1].X, -1.0f, 1.0f), clamp(scissor[1].Y, -1.0f, 1.0f), 1.0f)); 603 } 604 605 // Render fancy water 606 bool TerrainRenderer::RenderFancyWater() 607 { 608 PROFILE("render fancy water"); 515 609 516 610 // If we're using fancy water, make sure its shader is loaded 517 if (fancy &&!m->fancyWaterShader)611 if (!m->fancyWaterShader) 518 612 { 519 613 Handle h = ogl_program_load(g_VFS, L"shaders/water_high.xml"); … … 522 616 LOGERROR(L"Failed to load water shader. Falling back to non-fancy water.\n"); 523 617 g_Renderer.m_Options.m_FancyWater = false; 524 fancy =false;618 return false; 525 619 } 526 620 else … … 529 623 } 530 624 } 531 CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); // TODO: stop using g_Game 532 625 626 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 533 627 CLOSTexture& losTexture = g_Renderer.GetScene().GetLOSTexture(); 534 628 … … 539 633 540 634 double time = WaterMgr->m_WaterTexTimer; 541 542 635 double period = 1.6; 543 636 int curTex = (int)(time*60/period) % 60; 544 637 545 if(fancy) 546 { 547 WaterMgr->m_NormalMap[curTex]->Bind(); 548 } 549 else 550 { 551 WaterMgr->m_WaterTexture[curTex]->Bind(); 552 } 638 WaterMgr->m_NormalMap[curTex]->Bind(); 553 639 554 640 // Shift the texture coordinates by these amounts to make the water "flow" 555 641 float tx = -fmod(time, 81.0)/81.0; 556 642 float ty = -fmod(time, 34.0)/34.0; 557 558 if(!fancy) 559 { 560 // Perform the shifting by modifying the texture matrix 561 glMatrixMode(GL_TEXTURE); 562 glLoadIdentity(); 563 glTranslatef(tx, ty, 0); 564 565 // Set up texture environment to multiply vertex RGB by texture RGB and use vertex alpha 566 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 567 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 568 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 569 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 570 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); 571 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 572 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 573 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); 574 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 575 576 // Multiply by LOS texture 577 losTexture.BindTexture(1); 578 pglClientActiveTextureARB(GL_TEXTURE1); 579 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 580 581 glLoadMatrixf(losTexture.GetTextureMatrix()); 582 583 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 584 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 585 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); 586 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 587 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); 588 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA); 589 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 590 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); 591 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 592 } 643 float repeatPeriod = WaterMgr->m_RepeatPeriod; 593 644 594 645 // Set the proper LOD bias … … 598 649 CVector3D camPos = camera.m_Orientation.GetTranslation(); 599 650 600 GLint vertexDepth = 0; // water depth attribute, if using fancy water 601 602 if(fancy) 603 { 604 // Bind reflection and refraction textures on texture units 1 and 2 605 pglActiveTextureARB( GL_TEXTURE1_ARB ); 606 glEnable( GL_TEXTURE_2D ); 607 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_ReflectionTexture ); 608 pglActiveTextureARB( GL_TEXTURE2_ARB ); 609 glEnable( GL_TEXTURE_2D ); 610 glBindTexture( GL_TEXTURE_2D, WaterMgr->m_RefractionTexture ); 611 612 losTexture.BindTexture(3); 613 614 // Bind water shader and set arguments 615 ogl_program_use( m->fancyWaterShader ); 616 617 GLint ambient = ogl_program_get_uniform_location( m->fancyWaterShader, "ambient" ); 618 GLint sunDir = ogl_program_get_uniform_location( m->fancyWaterShader, "sunDir" ); 619 GLint sunColor = ogl_program_get_uniform_location( m->fancyWaterShader, "sunColor" ); 620 GLint cameraPos = ogl_program_get_uniform_location( m->fancyWaterShader, "cameraPos" ); 621 GLint shininess = ogl_program_get_uniform_location( m->fancyWaterShader, "shininess" ); 622 GLint specularStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "specularStrength" ); 623 GLint waviness = ogl_program_get_uniform_location( m->fancyWaterShader, "waviness" ); 624 GLint murkiness = ogl_program_get_uniform_location( m->fancyWaterShader, "murkiness" ); 625 GLint fullDepth = ogl_program_get_uniform_location( m->fancyWaterShader, "fullDepth" ); 626 GLint tint = ogl_program_get_uniform_location( m->fancyWaterShader, "tint" ); 627 GLint reflectionTint = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTint" ); 628 GLint reflectionTintStrength = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionTintStrength" ); 629 GLint translation = ogl_program_get_uniform_location( m->fancyWaterShader, "translation" ); 630 GLint reflectionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMatrix" ); 631 GLint refractionMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMatrix" ); 632 GLint losMatrix = ogl_program_get_uniform_location( m->fancyWaterShader, "losMatrix" ); 633 GLint normalMap = ogl_program_get_uniform_location( m->fancyWaterShader, "normalMap" ); 634 GLint reflectionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "reflectionMap" ); 635 GLint refractionMap = ogl_program_get_uniform_location( m->fancyWaterShader, "refractionMap" ); 636 GLint losMap = ogl_program_get_uniform_location( m->fancyWaterShader, "losMap" ); 637 638 const CLightEnv& lightEnv = g_Renderer.GetLightEnv(); 639 pglUniform3fvARB( ambient, 1, &lightEnv.m_TerrainAmbientColor.X ); 640 pglUniform3fvARB( sunDir, 1, &lightEnv.GetSunDir().X ); 641 pglUniform3fvARB( sunColor, 1, &lightEnv.m_SunColor.X ); 642 pglUniform1fARB( shininess, WaterMgr->m_Shininess ); 643 pglUniform1fARB( specularStrength, WaterMgr->m_SpecularStrength ); 644 pglUniform1fARB( waviness, WaterMgr->m_Waviness ); 645 pglUniform1fARB( murkiness, WaterMgr->m_Murkiness ); 646 pglUniform1fARB( fullDepth, WaterMgr->m_WaterFullDepth ); 647 pglUniform3fvARB( tint, 1, WaterMgr->m_WaterTint.FloatArray() ); 648 pglUniform1fARB( reflectionTintStrength, WaterMgr->m_ReflectionTintStrength ); 649 pglUniform3fvARB( reflectionTint, 1, WaterMgr->m_ReflectionTint.FloatArray() ); 650 pglUniform4fARB( translation, tx, ty, 0, 0 ); 651 pglUniformMatrix4fvARB( reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11 ); 652 pglUniformMatrix4fvARB( refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11 ); 653 pglUniformMatrix4fvARB( losMatrix, 1, false, losTexture.GetTextureMatrix() ); 654 pglUniform1iARB( normalMap, 0 ); // texture unit 0 655 pglUniform1iARB( reflectionMap, 1 ); // texture unit 1 656 pglUniform1iARB( refractionMap, 2 ); // texture unit 2 657 pglUniform1iARB( losMap, 3 ); // texture unit 3 658 pglUniform3fvARB( cameraPos, 1, &camPos.X ); 659 660 vertexDepth = ogl_program_get_attrib_location( m->fancyWaterShader, "vertexDepth" ); 661 } 662 663 float repeatPeriod = (fancy ? WaterMgr->m_RepeatPeriod : 16.0f); 664 665 glBegin(GL_QUADS); 666 667 for(size_t i=0; i<m->visiblePatches.size(); i++) 668 { 669 CPatch* patch = m->visiblePatches[i]->GetPatch(); 670 671 for(ssize_t dx=0; dx<PATCH_SIZE; dx++) 672 { 673 for(ssize_t dz=0; dz<PATCH_SIZE; dz++) 674 { 675 ssize_t x = (patch->m_X*PATCH_SIZE + dx); 676 ssize_t z = (patch->m_Z*PATCH_SIZE + dz); 677 678 // Some offsets used to go around counterclockwise while keeping code concise 679 const int DX[] = {1,1,0,0}; 680 const int DZ[] = {0,1,1,0}; 681 682 // is any corner of the tile below the water height? if not, no point rendering it 683 bool shouldRender = false; 684 for (int j = 0; j < 4; j++) 685 { 686 float terrainHeight = terrain->GetVertexGroundLevel(x + DX[j], z + DZ[j]); 687 if (terrainHeight < WaterMgr->m_WaterHeight) 688 { 689 shouldRender = true; 690 break; 691 } 692 } 693 if (!shouldRender) 694 continue; 695 696 for (int j=0; j<4; j++) 697 { 698 ssize_t ix = x + DX[j]; 699 ssize_t iz = z + DZ[j]; 700 701 float vertX = ix * CELL_SIZE; 702 float vertZ = iz * CELL_SIZE; 703 704 float terrainHeight = terrain->GetVertexGroundLevel(ix, iz); 705 706 if (fancy) 707 { 708 pglVertexAttrib1fARB(vertexDepth, WaterMgr->m_WaterHeight - terrainHeight); 709 pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod); 710 glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ); 711 } 712 else 713 { 714 float alpha = clamp( (WaterMgr->m_WaterHeight - terrainHeight) / WaterMgr->m_WaterFullDepth + WaterMgr->m_WaterAlphaOffset, 715 WaterMgr->m_WaterAlphaOffset, WaterMgr->m_WaterMaxAlpha); 716 717 // (Crappy) fresnel effect 718 CVector3D CamFaceVertex=CVector3D(vertX,WaterMgr->m_WaterHeight,vertZ)-camPos; 719 CamFaceVertex.Normalize(); 720 float FresnelScalar = CamFaceVertex.Dot(CVector3D(0.0f, -1.0f, 0.0f)); 721 // Invert and set boundaries 722 FresnelScalar = 1.f - (FresnelScalar * 0.6); 723 724 glColor4f(WaterMgr->m_WaterColor.r, 725 WaterMgr->m_WaterColor.g, 726 WaterMgr->m_WaterColor.b, 727 alpha * FresnelScalar); 728 pglMultiTexCoord2fARB(GL_TEXTURE0, vertX/repeatPeriod, vertZ/repeatPeriod); 729 pglMultiTexCoord3fARB(GL_TEXTURE1, vertX, WaterMgr->m_WaterHeight, vertZ); 730 glVertex3f(vertX, WaterMgr->m_WaterHeight, vertZ); 731 } 732 733 } 734 } //end of x loop 735 } //end of z loop 736 } 737 glEnd(); 738 739 if (fancy) 740 { 741 // Unbind the LOS/refraction/reflection textures and the shader 742 743 g_Renderer.BindTexture(3, 0); 744 g_Renderer.BindTexture(2, 0); 745 g_Renderer.BindTexture(1, 0); 746 747 pglActiveTextureARB(GL_TEXTURE0_ARB); 748 749 ogl_program_use(0); 750 } 751 752 if (!fancy) 753 { 754 g_Renderer.BindTexture(1, 0); 755 pglClientActiveTextureARB(GL_TEXTURE1_ARB); 756 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 757 758 glLoadIdentity(); 759 760 pglActiveTextureARB(GL_TEXTURE0_ARB); 761 pglClientActiveTextureARB(GL_TEXTURE0_ARB); 762 763 // Clean up the texture matrix and blend mode 764 glLoadIdentity(); 765 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 766 } 767 768 glMatrixMode(GL_MODELVIEW); 651 // Bind reflection and refraction textures on texture units 1 and 2 652 pglActiveTextureARB(GL_TEXTURE1_ARB); 653 glEnable(GL_TEXTURE_2D); 654 glBindTexture(GL_TEXTURE_2D, WaterMgr->m_ReflectionTexture); 655 pglActiveTextureARB(GL_TEXTURE2_ARB); 656 glEnable(GL_TEXTURE_2D); 657 glBindTexture(GL_TEXTURE_2D, WaterMgr->m_RefractionTexture); 658 659 losTexture.BindTexture(3); 660 661 // Bind water shader and set arguments 662 ogl_program_use(m->fancyWaterShader); 663 664 GLint ambient = ogl_program_get_uniform_location(m->fancyWaterShader, "ambient"); 665 GLint sunDir = ogl_program_get_uniform_location(m->fancyWaterShader, "sunDir"); 666 GLint sunColor = ogl_program_get_uniform_location(m->fancyWaterShader, "sunColor"); 667 GLint cameraPos = ogl_program_get_uniform_location(m->fancyWaterShader, "cameraPos"); 668 GLint shininess = ogl_program_get_uniform_location(m->fancyWaterShader, "shininess"); 669 GLint specularStrength = ogl_program_get_uniform_location(m->fancyWaterShader, "specularStrength"); 670 GLint waviness = ogl_program_get_uniform_location(m->fancyWaterShader, "waviness"); 671 GLint murkiness = ogl_program_get_uniform_location(m->fancyWaterShader, "murkiness"); 672 GLint fullDepth = ogl_program_get_uniform_location(m->fancyWaterShader, "fullDepth"); 673 GLint tint = ogl_program_get_uniform_location(m->fancyWaterShader, "tint"); 674 GLint reflectionTint = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionTint"); 675 GLint reflectionTintStrength = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionTintStrength"); 676 GLint translation = ogl_program_get_uniform_location(m->fancyWaterShader, "translation"); 677 GLint repeatScale = ogl_program_get_uniform_location(m->fancyWaterShader, "repeatScale"); 678 GLint reflectionMatrix = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionMatrix"); 679 GLint refractionMatrix = ogl_program_get_uniform_location(m->fancyWaterShader, "refractionMatrix"); 680 GLint losMatrix = ogl_program_get_uniform_location(m->fancyWaterShader, "losMatrix"); 681 GLint normalMap = ogl_program_get_uniform_location(m->fancyWaterShader, "normalMap"); 682 GLint reflectionMap = ogl_program_get_uniform_location(m->fancyWaterShader, "reflectionMap"); 683 GLint refractionMap = ogl_program_get_uniform_location(m->fancyWaterShader, "refractionMap"); 684 GLint losMap = ogl_program_get_uniform_location(m->fancyWaterShader, "losMap"); 685 686 const CLightEnv& lightEnv = g_Renderer.GetLightEnv(); 687 pglUniform3fvARB(ambient, 1, &lightEnv.m_TerrainAmbientColor.X); 688 pglUniform3fvARB(sunDir, 1, &lightEnv.GetSunDir().X); 689 pglUniform3fvARB(sunColor, 1, &lightEnv.m_SunColor.X); 690 pglUniform1fARB(shininess, WaterMgr->m_Shininess); 691 pglUniform1fARB(specularStrength, WaterMgr->m_SpecularStrength); 692 pglUniform1fARB(waviness, WaterMgr->m_Waviness); 693 pglUniform1fARB(murkiness, WaterMgr->m_Murkiness); 694 pglUniform1fARB(fullDepth, WaterMgr->m_WaterFullDepth); 695 pglUniform3fvARB(tint, 1, WaterMgr->m_WaterTint.FloatArray()); 696 pglUniform1fARB(reflectionTintStrength, WaterMgr->m_ReflectionTintStrength); 697 pglUniform3fvARB(reflectionTint, 1, WaterMgr->m_ReflectionTint.FloatArray()); 698 pglUniform2fARB(translation, tx, ty); 699 pglUniform1fARB(repeatScale, 1.0f / repeatPeriod); 700 pglUniformMatrix4fvARB(reflectionMatrix, 1, false, &WaterMgr->m_ReflectionMatrix._11); 701 pglUniformMatrix4fvARB(refractionMatrix, 1, false, &WaterMgr->m_RefractionMatrix._11); 702 pglUniformMatrix4fvARB(losMatrix, 1, false, losTexture.GetTextureMatrix()); 703 pglUniform1iARB(normalMap, 0); // texture unit 0 704 pglUniform1iARB(reflectionMap, 1); // texture unit 1 705 pglUniform1iARB(refractionMap, 2); // texture unit 2 706 pglUniform1iARB(losMap, 3); // texture unit 3 707 pglUniform3fvARB(cameraPos, 1, &camPos.X); 708 709 glEnableClientState(GL_VERTEX_ARRAY); 710 glEnableClientState(GL_COLOR_ARRAY); 711 712 for (size_t i = 0; i < m->visiblePatches.size(); ++i) 713 { 714 CPatchRData* data = m->visiblePatches[i]; 715 data->RenderWater(); 716 } 717 718 glDisableClientState(GL_COLOR_ARRAY); 719 glDisableClientState(GL_VERTEX_ARRAY); 720 721 // Unbind the LOS/refraction/reflection textures and the shader 722 g_Renderer.BindTexture(3, 0); 723 g_Renderer.BindTexture(2, 0); 724 g_Renderer.BindTexture(1, 0); 725 726 pglActiveTextureARB(GL_TEXTURE0_ARB); 727 728 ogl_program_use(0); 729 730 glDisable(GL_BLEND); 731 732 return true; 733 } 734 735 void TerrainRenderer::RenderSimpleWater() 736 { 737 PROFILE("render simple water"); 738 739 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 740 CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); 741 742 glEnable(GL_BLEND); 743 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 744 glEnable(GL_DEPTH_TEST); 745 glDepthFunc(GL_LEQUAL); 746 747 double time = WaterMgr->m_WaterTexTimer; 748 double period = 1.6f; 749 int curTex = (int)(time*60/period) % 60; 750 751 WaterMgr->m_WaterTexture[curTex]->Bind(); 752 753 // Shift the texture coordinates by these amounts to make the water "flow" 754 float tx = -fmod(time, 81.0)/81.0; 755 float ty = -fmod(time, 34.0)/34.0; 756 float repeatPeriod = 16.0f; 757 758 // Perform the shifting by using texture coordinate generation 759 GLfloat texgenS0[4] = { 1/repeatPeriod, 0, 0, tx }; 760 GLfloat texgenT0[4] = { 0, 0, 1/repeatPeriod, ty }; 761 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 762 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 763 glTexGenfv(GL_S, GL_OBJECT_PLANE, texgenS0); 764 glTexGenfv(GL_T, GL_OBJECT_PLANE, texgenT0); 765 glEnable(GL_TEXTURE_GEN_S); 766 glEnable(GL_TEXTURE_GEN_T); 767 768 // Set up texture environment to multiply vertex RGB by texture RGB and use vertex alpha 769 GLfloat waterColor[4] = { WaterMgr->m_WaterColor.r, WaterMgr->m_WaterColor.g, WaterMgr->m_WaterColor.b, 1.0f }; 770 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, waterColor); 771 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 772 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 773 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 774 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 775 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT); 776 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 777 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 778 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); 779 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 780 781 // Multiply by LOS texture 782 losTexture.BindTexture(1); 783 const float *losMatrix = losTexture.GetTextureMatrix(); 784 GLfloat texgenS1[4] = { losMatrix[0], losMatrix[4], losMatrix[8], losMatrix[12] }; 785 GLfloat texgenT1[4] = { losMatrix[1], losMatrix[5], losMatrix[9], losMatrix[13] }; 786 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 787 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); 788 glTexGenfv(GL_S, GL_OBJECT_PLANE, texgenS1); 789 glTexGenfv(GL_T, GL_OBJECT_PLANE, texgenT1); 790 glEnable(GL_TEXTURE_GEN_S); 791 glEnable(GL_TEXTURE_GEN_T); 792 793 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 794 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 795 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); 796 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 797 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); 798 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA); 799 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 800 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); 801 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 802 803 // Set the proper LOD bias 804 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 805 806 glEnableClientState(GL_VERTEX_ARRAY); 807 glEnableClientState(GL_COLOR_ARRAY); 808 809 for (size_t i = 0; i < m->visiblePatches.size(); ++i) 810 { 811 CPatchRData* data = m->visiblePatches[i]; 812 data->RenderWater(); 813 } 814 815 glDisableClientState(GL_COLOR_ARRAY); 816 glDisableClientState(GL_VERTEX_ARRAY); 817 818 g_Renderer.BindTexture(1, 0); 819 820 glDisable(GL_TEXTURE_GEN_S); 821 glDisable(GL_TEXTURE_GEN_T); 822 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 823 824 pglActiveTextureARB(GL_TEXTURE0_ARB); 825 826 // Clean up the texture matrix and blend mode 827 glDisable(GL_TEXTURE_GEN_S); 828 glDisable(GL_TEXTURE_GEN_T); 829 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 830 769 831 glDisable(GL_BLEND); 770 832 glDisable(GL_TEXTURE_2D); 771 833 } 772 834 835 /////////////////////////////////////////////////////////////////// 836 // Render water that is part of the terrain 837 void TerrainRenderer::RenderWater() 838 { 839 WaterManager* WaterMgr = g_Renderer.GetWaterManager(); 840 841 if (!WaterMgr->WillRenderFancyWater() || !RenderFancyWater()) 842 RenderSimpleWater(); 843 } 844 773 845 void TerrainRenderer::RenderPriorities() 774 846 { -
ps/trunk/source/renderer/TerrainRenderer.h
r9187 r9814 73 73 74 74 /** 75 * CullPatches: Culls patches and decals against a frustum, 76 * and stores the results in a special filtered list that 77 * is used when calling render functions with @p filtered true. 78 */ 79 bool CullPatches(const CFrustum* frustum); 80 81 /** 75 82 * RenderTerrain: Render textured terrain (including blends between 76 83 * different terrain types). … … 78 85 * preconditions : PrepareForRendering must have been called this 79 86 * frame before calling RenderTerrain. 87 * 88 * @param filtered If true then only render objects that passed CullPatches. 80 89 */ 81 void RenderTerrain( );90 void RenderTerrain(bool filtered = false); 82 91 83 92 /** … … 86 95 * 87 96 * @param shadow A prepared shadow map, in case rendering with shadows is enabled. 97 * @param filtered If true then only render objects that passed CullPatches. 88 98 */ 89 void RenderTerrainShader(ShadowMap* shadow );99 void RenderTerrainShader(ShadowMap* shadow, bool filtered = false); 90 100 91 101 /** … … 94 104 * preconditions : PrepareForRendering must have been called this 95 105 * frame before calling RenderPatches. 106 * 107 * @param filtered If true then only render objects that passed CullPatches. 96 108 */ 97 void RenderPatches( );109 void RenderPatches(bool filtered = false); 98 110 99 111 /** … … 102 114 * preconditions : PrepareForRendering must have been called this 103 115 * frame before calling RenderOutlines. 116 * 117 * @param filtered If true then only render objects that passed CullPatches. 104 118 */ 105 void RenderOutlines( );119 void RenderOutlines(bool filtered = false); 106 120 107 121 /** … … 115 129 116 130 /** 131 * Calculate a scissor rectangle for the visible water patches. 132 */ 133 CBound ScissorWater(const CMatrix3D& viewproj); 134 135 /** 117 136 * Render priority text for all submitted patches, for debugging. 118 137 */ … … 122 141 TerrainRendererInternals* m; 123 142 143 /** 144 * RenderFancyWater: internal rendering method for fancy water. 145 * Returns false if unable to render with fancy water. 146 */ 147 bool RenderFancyWater(); 148 149 /** 150 * RenderSimpleWater: internal rendering method for water 151 */ 152 void RenderSimpleWater(); 153 124 154 void PrepareShader(const CShaderProgramPtr& shader, ShadowMap* shadow); 125 155 }; -
ps/trunk/source/renderer/TransparencyRenderer.cpp
r9362 r9814 541 541 } 542 542 543 543 void SortModelRenderer::Filter(CModelFilter& filter, int passed, int flags) 544 { 545 for (std::vector<SModel*>::iterator it = m->models.begin(); it != m->models.end(); ++it) 546 { 547 SModel* smdl = *it; 548 CModel* mdl = smdl->GetModel(); 549 if (flags && !(mdl->GetFlags() & flags)) 550 continue; 551 552 if (filter.Filter(mdl)) 553 mdl->SetFlags(mdl->GetFlags() | passed); 554 else 555 mdl->SetFlags(mdl->GetFlags() & ~passed); 556 } 557 } 544 558 545 559 /////////////////////////////////////////////////////////////////////////////////////////////////// … … 556 570 int TransparentRenderModifier::BeginPass(int pass) 557 571 { 572 // First pass: opaque areas only. 573 // Second pass: blended areas. 574 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 575 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 576 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 577 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 578 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); 579 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 580 581 // just pass through texture's alpha 582 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 583 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); 584 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 585 586 // Set the proper LOD bias 587 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 588 589 glEnable(GL_BLEND); 590 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 591 592 glEnable(GL_ALPHA_TEST); 558 593 if (pass == 0) 559 594 { 560 // First pass: Put down Z for opaque parts of the model, 561 // don't touch the color buffer. 562 563 glDepthMask(1); 564 565 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 566 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); 567 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT); 568 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 569 570 // just pass through texture's alpha 571 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 572 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); 573 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 574 575 // Set the proper LOD bias 576 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 577 578 glEnable(GL_ALPHA_TEST); 579 glAlphaFunc(GL_GREATER,0.975f); 580 581 // render everything with color writes off to setup depth buffer correctly 582 glColorMask(0,0,0,0); 583 584 return STREAM_POS|STREAM_UV0; 595 glAlphaFunc(GL_GREATER, 0.9375f); 585 596 } 586 597 else 587 598 { 588 // Second pass: Put down color, disable Z write 589 glColorMask(1,1,1,1); 590 599 glAlphaFunc(GL_GREATER, 0.0f); 600 glDepthFunc(GL_LESS); 591 601 glDepthMask(0); 592 593 // setup texture environment to modulate diffuse color with texture color 594 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 595 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 596 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 597 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); 598 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 599 600 glAlphaFunc(GL_GREATER,0); 601 602 glEnable(GL_BLEND); 603 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 604 605 // Set the proper LOD bias 606 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 607 608 return STREAM_POS|STREAM_COLOR|STREAM_UV0; 609 } 602 } 603 604 return STREAM_POS|STREAM_COLOR|STREAM_UV0; 610 605 } 611 606 612 607 bool TransparentRenderModifier::EndPass(int pass) 613 608 { 614 if (pass == 0)615 return false; // multi-pass616 617 609 glDisable(GL_BLEND); 618 610 glDisable(GL_ALPHA_TEST); 611 if (pass == 0) 612 return false; 613 614 glDepthFunc(GL_LEQUAL); 619 615 glDepthMask(1); 620 616 … … 632 628 } 633 629 630 631 /////////////////////////////////////////////////////////////////////////////////////////////////// 632 // TransparentOpaqueRenderModifier implementation 633 634 TransparentOpaqueRenderModifier::TransparentOpaqueRenderModifier() 635 { 636 } 637 638 TransparentOpaqueRenderModifier::~TransparentOpaqueRenderModifier() 639 { 640 } 641 642 int TransparentOpaqueRenderModifier::BeginPass(int pass) 643 { 644 ENSURE(pass == 0); 645 646 // Put down opaque parts of the model only. 647 648 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 649 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 650 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 651 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 652 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); 653 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 654 655 // just pass through texture's alpha 656 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 657 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); 658 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 659 660 // Set the proper LOD bias 661 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 662 663 glEnable(GL_ALPHA_TEST); 664 glAlphaFunc(GL_GREATER, 0.9375f); 665 666 glEnable(GL_BLEND); 667 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 668 669 return STREAM_POS|STREAM_COLOR|STREAM_UV0; 670 } 671 672 bool TransparentOpaqueRenderModifier::EndPass(int UNUSED(pass)) 673 { 674 glDisable(GL_ALPHA_TEST); 675 glDisable(GL_BLEND); 676 677 return true; 678 } 679 680 void TransparentOpaqueRenderModifier::PrepareTexture(int UNUSED(pass), CTexturePtr& texture) 681 { 682 texture->Bind(0); 683 } 684 685 void TransparentOpaqueRenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model)) 686 { 687 // No per-model setup necessary 688 } 689 690 /////////////////////////////////////////////////////////////////////////////////////////////////// 691 // TransparentBlendRenderModifier implementation 692 693 TransparentBlendRenderModifier::TransparentBlendRenderModifier() 694 { 695 } 696 697 TransparentBlendRenderModifier::~TransparentBlendRenderModifier() 698 { 699 } 700 701 int TransparentBlendRenderModifier::BeginPass(int pass) 702 { 703 ENSURE(pass == 0); 704 705 // Put down blended parts of the model only. 706 707 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 708 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); 709 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); 710 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); 711 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); 712 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); 713 714 // just pass through texture's alpha 715 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); 716 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); 717 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); 718 719 // Set the proper LOD bias 720 glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, g_Renderer.m_Options.m_LodBias); 721 722 glEnable(GL_ALPHA_TEST); 723 glAlphaFunc(GL_GREATER,0); 724 725 glEnable(GL_BLEND); 726 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 727 728 glDepthFunc(GL_LESS); 729 glDepthMask(0); 730 731 return STREAM_POS|STREAM_COLOR|STREAM_UV0; 732 } 733 734 bool TransparentBlendRenderModifier::EndPass(int UNUSED(pass)) 735 { 736 glDisable(GL_ALPHA_TEST); 737 glDisable(GL_BLEND); 738 glDepthFunc(GL_LEQUAL); 739 glDepthMask(1); 740 741 return true; 742 } 743 744 void TransparentBlendRenderModifier::PrepareTexture(int UNUSED(pass), CTexturePtr& texture) 745 { 746 texture->Bind(0); 747 } 748 749 void TransparentBlendRenderModifier::PrepareModel(int UNUSED(pass), CModel* UNUSED(model)) 750 { 751 // No per-model setup necessary 752 } 634 753 635 754 /////////////////////////////////////////////////////////////////////////////////////////////////// -
ps/trunk/source/renderer/TransparencyRenderer.h
r9190 r9814 86 86 bool HaveSubmissions(); 87 87 void Render(const RenderModifierPtr& modifier, int flags); 88 void Filter(CModelFilter& filter, int passed, int flags); 88 89 89 90 private: … … 107 108 void PrepareTexture(int pass, CTexturePtr& texture); 108 109 void PrepareModel(int pass, CModel* model); 109 110 110 }; 111 111 112 /** 113 * Class TransparentOpaqueRenderModifier: Modifier for transparent models, 114 * including alpha blending and lighting, Opaque pass only. 115 */ 116 class TransparentOpaqueRenderModifier : public RenderModifier 117 { 118 public: 119 TransparentOpaqueRenderModifier(); 120 ~TransparentOpaqueRenderModifier(); 121 122 // Implementation 123 int BeginPass(int pass); 124 bool EndPass(int pass); 125 void PrepareTexture(int pass, CTexturePtr& texture); 126 void PrepareModel(int pass, CModel* model); 127 }; 128 129 /** 130 * Class TransparentBlendRenderModifier: Modifier for transparent models, 131 * including alpha blending and lighting. Blend pass only. 132 */ 133 class TransparentBlendRenderModifier : public RenderModifier 134 { 135 public: 136 TransparentBlendRenderModifier(); 137 ~TransparentBlendRenderModifier(); 138 139 // Implementation 140 int BeginPass(int pass); 141 bool EndPass(int pass); 142 void PrepareTexture(int pass, CTexturePtr& texture); 143 void PrepareModel(int pass, CModel* model); 144 }; 112 145 113 146 /**
Note:
See TracChangeset
for help on using the changeset viewer.
