static void TestFloat4x4() { if ( System.Runtime.InteropServices.Marshal.SizeOf(typeof(float4x4)) != 64 ) throw new Exception( "Not the appropriate size!" ); float4x4 test1 = new float4x4( new float[16] { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 } ); float4x4 test2 = new float4x4( new float4( 1, 0, 0, 0 ), new float4( 0, 1, 0, 0 ), new float4( 0, 0, 1, 0 ), new float4( 0, 0, 0, 1 ) ); float4x4 test3 = new float4x4( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ); float4x4 test0; test0 = test3; test2.Scale( new float3( 2, 2, 2 ) ); float3x3 cast = (float3x3) test3; float4x4 mul0 = test1 * test2; float4x4 mul1 = 3.0f * test2; float4 mul2 = new float4( 1, 1, 1, 1 ) * test3; float4 access0 = test3[2]; test3[1] = new float4( 12, 13, 14, 15 ); float access1 = test3[1,2]; test3[1,2] = 18; float coFactor = test3.CoFactor( 0, 2 ); float det = test3.Determinant; float4x4 inv = test2.Inverse; float4x4 id = float4x4.Identity; test3.BuildRotLeftHanded( float3.UnitZ, float3.Zero, float3.UnitY ); test3.BuildRotRightHanded( float3.UnitZ, float3.Zero, float3.UnitY ); test3.BuildProjectionPerspective( 1.2f, 2.0f, 0.01f, 10.0f ); test3.BuildRotationX( 0.5f ); test3.BuildRotationY( 0.5f ); test3.BuildRotationZ( 0.5f ); test3.BuildFromAngleAxis( 0.5f, float3.UnitY ); }
void Application_Idle( object sender, EventArgs e ) { if ( m_Device == null ) return; // Setup global data m_CB_Main.m.iResolution = new float3( panelOutput.Width, panelOutput.Height, 0 ); if ( checkBoxAnimate.Checked ) m_CB_Main.m.iGlobalTime = GetGameTime() - m_StartTime; m_CB_Main.UpdateData(); // Setup area light buffer float LighOffsetX = 1.2f; float SizeX = floatTrackbarControlLightScaleX.Value; float SizeY = 1.0f; float RollAngle = (float) (Math.PI * floatTrackbarControlLightRoll.Value / 180.0); float3 LightPosition = new float3( LighOffsetX + floatTrackbarControlLightPosX.Value, 1.0f + floatTrackbarControlLightPosY.Value, -1.0f + floatTrackbarControlLightPosZ.Value ); float3 LightTarget = new float3( LightPosition.x + floatTrackbarControlLightTargetX.Value, LightPosition.y + floatTrackbarControlLightTargetY.Value, LightPosition.z + 2.0f + floatTrackbarControlLightTargetZ.Value ); float3 LightUp = new float3( (float) Math.Sin( -RollAngle ), (float) Math.Cos( RollAngle ), 0.0f ); float4x4 AreaLight2World = new float4x4(); AreaLight2World.BuildRotRightHanded( LightPosition, LightTarget, LightUp ); float4x4 World2AreaLight = AreaLight2World.Inverse; double Phi = Math.PI * floatTrackbarControlProjectionPhi.Value / 180.0; double Theta = Math.PI * floatTrackbarControlProjectionTheta.Value / 180.0; float3 Direction = new float3( (float) (Math.Sin(Theta) * Math.Sin(Phi)), (float) (Math.Sin(Theta) * Math.Cos(Phi)), (float) Math.Cos( Theta ) ); const float DiffusionMin = 1e-2f; const float DiffusionMax = 1000.0f; // float Diffusion_Diffuse = DiffusionMin / (DiffusionMin / DiffusionMax + floatTrackbarControlProjectionDiffusion.Value); float Diffusion_Diffuse = DiffusionMax + (DiffusionMin - DiffusionMax) * (float) Math.Pow( floatTrackbarControlProjectionDiffusion.Value, 0.01f ); // float3 LocalDirection_Diffuse = (float3) (new float4( Diffusion_Diffuse * Direction, 0 ) * World2AreaLight); float3 LocalDirection_Diffuse = Diffusion_Diffuse * Direction; m_CB_Light.m._AreaLightX = (float3) AreaLight2World[0]; m_CB_Light.m._AreaLightY = (float3) AreaLight2World[1]; m_CB_Light.m._AreaLightZ = (float3) AreaLight2World[2]; m_CB_Light.m._AreaLightT = (float3) AreaLight2World[3]; m_CB_Light.m._AreaLightScaleX = SizeX; m_CB_Light.m._AreaLightScaleY = SizeY; m_CB_Light.m._AreaLightDiffusion = floatTrackbarControlProjectionDiffusion.Value; m_CB_Light.m._AreaLightIntensity = floatTrackbarControlLightIntensity.Value; m_CB_Light.m._AreaLightTexDimensions = new float4( m_Tex_AreaLightSAT.Width, m_Tex_AreaLightSAT.Height, 1.0f / m_Tex_AreaLightSAT.Width, 1.0f / m_Tex_AreaLightSAT.Height ); m_CB_Light.m._ProjectionDirectionDiff = LocalDirection_Diffuse; m_CB_Light.UpdateData(); // =========== Render shadow map =========== // float KernelSize = 16.0f * floatTrackbarControlProjectionDiffusion.Value; float KernelSize = floatTrackbarControlKernelSize.Value; // float ShadowZFar = (float) Math.Sqrt( 2.0 ) * m_Camera.Far; float ShadowZFar = 10.0f; m_CB_ShadowMap.m._ShadowOffsetXY = (float2) Direction; m_CB_ShadowMap.m._ShadowZFar = new float2( ShadowZFar, 1.0f / ShadowZFar ); m_CB_ShadowMap.m._KernelSize = KernelSize; m_CB_ShadowMap.m._InvShadowMapSize = 1.0f / m_Tex_ShadowMap.Width; m_CB_ShadowMap.m._HardeningFactor = new float2( floatTrackbarControlHardeningFactor.Value, floatTrackbarControlHardeningFactor2.Value ); m_CB_ShadowMap.UpdateData(); if ( m_Shader_RenderShadowMap != null && m_Shader_RenderShadowMap.Use() ) { m_Tex_ShadowMap.RemoveFromLastAssignedSlots(); m_Device.SetRenderTargets( m_Tex_ShadowMap.Width, m_Tex_ShadowMap.Height, new View2D[0], m_Tex_ShadowMap ); #if FILTER_EXP_SHADOW_MAP // m_Device.ClearDepthStencil( m_Tex_ShadowMap, 0.0f, 0, true, false ); // m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_GREATER, BLEND_STATE.DISABLED ); // For exp shadow map, the Z order is reversed m_Device.ClearDepthStencil( m_Tex_ShadowMap, 1.0f, 0, true, false ); m_Device.SetRenderStates( checkBoxCullFront.Checked ? RASTERIZER_STATE.CULL_BACK : RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_LESS, BLEND_STATE.DISABLED ); // For exp shadow map, the Z order is reversed #else m_Device.ClearDepthStencil( m_Tex_ShadowMap, 1.0f, 0, true, false ); m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_LESS, BLEND_STATE.DISABLED ); #endif RenderScene( m_Shader_RenderShadowMap ); m_Device.RemoveRenderTargets(); m_Tex_ShadowMap.SetPS( 2 ); } #if FILTER_EXP_SHADOW_MAP if ( m_Shader_FilterShadowMapH != null ) { // m_Tex_ShadowMapFiltered[1].RemoveFromLastAssignedSlots(); m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.DISABLED, BLEND_STATE.DISABLED ); // Filter horizontally m_Device.SetRenderTarget( m_Tex_ShadowMapFiltered[0], null ); m_Shader_FilterShadowMapH.Use(); m_Prim_Quad.Render( m_Shader_FilterShadowMapH ); // Filter vertically m_Device.SetRenderTarget( m_Tex_ShadowMapFiltered[1], null ); m_Tex_ShadowMapFiltered[0].SetPS( 2 ); m_Shader_FilterShadowMapV.Use(); m_Prim_Quad.Render( m_Shader_FilterShadowMapV ); m_Device.RemoveRenderTargets(); m_Tex_ShadowMapFiltered[1].SetPS( 2 ); } #else if ( m_Shader_BuildSmoothie != null && m_Shader_BuildSmoothie.Use() ) { m_Tex_ShadowSmoothie.RemoveFromLastAssignedSlots(); m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.DISABLED, BLEND_STATE.DISABLED ); // Render the (silhouette + Z) RG16 buffer m_Device.SetRenderTarget( m_Tex_ShadowSmoothie, null ); m_Prim_Quad.Render( m_Shader_BuildSmoothie ); m_Device.RemoveRenderTargets(); m_Tex_ShadowSmoothie.SetPS( 3 ); // Build distance field m_Device.SetRenderTarget( m_Tex_ShadowSmoothiePou[0], null ); m_Shader_BuildSmoothieDistanceFieldH.Use(); m_Prim_Quad.Render( m_Shader_BuildSmoothieDistanceFieldH ); // m_Device.RemoveRenderTargets(); // m_Tex_ShadowSmoothiePou[0].SetPS( 3 ); m_Device.SetRenderTarget( m_Tex_ShadowSmoothiePou[1], null ); m_Tex_ShadowSmoothiePou[0].SetPS( 0 ); m_Shader_BuildSmoothieDistanceFieldV.Use(); m_Prim_Quad.Render( m_Shader_BuildSmoothieDistanceFieldV ); m_Device.RemoveRenderTargets(); m_Tex_ShadowSmoothiePou[1].SetPS( 3 ); } #endif // =========== Render scene =========== m_Device.SetRenderTarget( m_Device.DefaultTarget, m_Device.DefaultDepthStencil ); m_Device.Clear( m_Device.DefaultTarget, float4.Zero ); m_Device.ClearDepthStencil( m_Device.DefaultDepthStencil, 1.0f, 0, true, false ); m_Tex_AreaLightSAT.SetPS( 0 ); // m_Tex_AreaLight3D.SetPS( 0 ); m_Tex_AreaLightSATFade.SetPS( 1 ); m_Tex_AreaLight.SetPS( 4 ); m_Tex_FalseColors.SetPS( 6 ); // m_Tex_GlossMap.SetPS( 7 ); // m_Tex_Normal.SetPS( 8 ); // Render the area light itself m_Device.SetRenderStates( RASTERIZER_STATE.CULL_NONE, DEPTHSTENCIL_STATE.READ_WRITE_DEPTH_LESS, BLEND_STATE.DISABLED ); if ( m_Shader_RenderAreaLight != null && m_Shader_RenderAreaLight.Use() ) { m_CB_Object.m._Local2World = AreaLight2World; m_CB_Object.m._Local2World.Scale( new float3( SizeX, SizeY, 1.0f ) ); m_CB_Object.m._World2Local = m_CB_Object.m._Local2World.Inverse; m_CB_Object.m._UseTexture = checkBoxUseTexture.Checked ? 1U : 0U; m_CB_Object.m._FalseColors = checkBoxFalseColors.Checked ? 1U : 0U; m_CB_Object.m._FalseColorsMaxRange = floatTrackbarControlFalseColorsRange.Value; m_CB_Object.UpdateData(); m_Prim_Rectangle.Render( m_Shader_RenderAreaLight ); } else { m_Device.Clear( new float4( 1, 0, 0, 0 ) ); } // Render the scene m_Device.SetRenderStates( RASTERIZER_STATE.CULL_BACK, DEPTHSTENCIL_STATE.NOCHANGE, BLEND_STATE.NOCHANGE ); if ( m_Shader_RenderScene != null && m_Shader_RenderScene.Use() ) { RenderScene( m_Shader_RenderScene ); } else { m_Device.Clear( new float4( 1, 1, 0, 0 ) ); } // Show! m_Device.Present( false ); // Update window text // Text = "Zombizous Prototype - " + m_Game.m_CurrentGameTime.ToString( "G5" ) + "s"; }