//--------------------------------------------------------------------------------------------------------------------------------------------------- // // Copyright (C)2007 DarkWynter Studios. All rights reserved. // //--------------------------------------------------------------------------------------------------------------------------------------------------- // {Contact : darkwynter.com for licensing information //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace DarkWynter.Stream.PhysicsGpu { #region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using System.Diagnostics; #endregion /// /// Vertex structure for GPU Physics updates /// public struct VertexPosition { /// /// Vertex position /// public Vector3 position; } /// /// GpuProcessor handles the rendering of GpuVariables. /// Supports standard gpgpu "quad" technique to handle gather algorithms. /// Also supports what we call a "quad of points" technique to handle scatter algorithms. /// public class GpuProcessor { public struct GPU_ProcessorSettings { /// /// Indexed viewport target size /// //public int _INDEXED_TARGET_SIZE { get { return INDEXED_TARGET_SIZE; } set { INDEXED_TARGET_SIZE = value; } } //public static int INDEXED_TARGET_SIZE = 128; ///// ///// Spatial viewport target size ///// //public int _SPATIAL_TARGET_SIZE { get { return SPATIAL_TARGET_SIZE; } set { SPATIAL_TARGET_SIZE = value; } } //public static int SPATIAL_TARGET_SIZE = 1024; } //public enum GpuProcessorMode : byte //{ // /// // /// Indexed pass // /// // Indexed, // /// // /// Spatial pass // /// // Spatial //}; // Spatial and Indexed Viewports private Viewport IndexedViewport; // Quad Vertex Buffer ============================================================================= private VertexBuffer quad_vertexBuffer; // Buffer to store vertices private VertexPositionTexture[] quad_vertices; // Array to store vertex Position, Normal and Texture information private VertexDeclaration quad_vertexDeclaration; // Vertex Declaration private int UPDATE_TIME_MILLI = 100; private Stopwatch runUpdateTimer = new Stopwatch(); // Tells the GPU how to format the streams private VertexElement[] Elements = new VertexElement[] { new VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0), }; // ================================\ Methods /===================================================== // ================================================================================================ /// /// GpuProcessor constructor sets up Quad and Quad of Points mechanics. /// public GpuProcessor(GraphicsDevice gd) { // Create geometry used in render passes CreateQuad(gd); runUpdateTimer.Reset(); runUpdateTimer.Start(); } private void CreateQuad(GraphicsDevice gd) { // Set up the Indexed viewport IndexedViewport.X = 0; IndexedViewport.Y = 0; IndexedViewport.Width = GpuVariable.RENDER_TARGET_SIZE; IndexedViewport.Height = GpuVariable.RENDER_TARGET_SIZE; IndexedViewport.MinDepth = gd.Viewport.MinDepth; IndexedViewport.MaxDepth = gd.Viewport.MaxDepth; // Create a 4 point vertex buffer quad_vertices = new VertexPositionTexture[4]; quad_vertexDeclaration = new VertexDeclaration(gd, VertexPositionTexture.VertexElements); quad_vertexBuffer = new VertexBuffer(gd, VertexPositionTexture.SizeInBytes * 4, BufferUsage.WriteOnly); // Create quad with width and height = 1 quad_vertices[0] = new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0), //new Vector3(-0.5f, -0.5f, 1), new Vector2(0, 1.0f)); // 3rd quadrent quad_vertices[1] = new VertexPositionTexture(new Vector3(0.5f, -0.5f, 0), //new Vector3(0.5f, -0.5f, 1), new Vector2(1.0f, 1.0f)); // 4th quadrent quad_vertices[2] = new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0), //new Vector3(0.5f, 0.5f, 1), new Vector2(1.0f, 0)); // 1st quadrent quad_vertices[3] = new VertexPositionTexture(new Vector3(-0.5f, 0.5f, 0), //new Vector3(-0.0f, 1.0f, 1), new Vector2(0, 0)); // 2nd quadrent // Set the data quad_vertexBuffer.SetData(quad_vertices); } /// /// Executes a shader pass on a List of GpuVariables. /// Each GpuVariable has enough information to tell the processor how to execute it. /// Variables are processed in the order in which they occur in the list. /// /// location map /// List of gpu variables // CLEAN: REMOVE BOTH PARAMETERS, REPLACE WITH SINGLE GPU OBJECT public void ExecuteRTT(GraphicsDevice gd, List variables, Effect effect) { // Set Gravity //gravity += objectLibrary.humans[0].playerController.gameInput.GetGPUGravityButton; //ShaderParameters.UpdateFX.gravity.SetValue(gravity); if (runUpdateTimer.ElapsedMilliseconds >= UPDATE_TIME_MILLI) { runUpdateTimer.Reset(); runUpdateTimer.Start(); // Indexed Updates for (int i = 0; i < variables.Count; i++) { if (variables[i].isDynamic) { ////if (variables[i].processorMode == GpuProcessorMode.Indexed) //{ effect.CurrentTechnique = effect.Techniques[variables[i].technique]; ExecuteIndexedRTT(gd, variables[i]._writeRenderTarget, effect); variables[i].SwapBuffers(); //variables[i].WriteToFile(); //} } } gd.SetRenderTarget(0, null); } } private void ExecuteIndexedRTT(GraphicsDevice gd, RenderTarget2D renderTarget, Effect effect) { // Set up Graphics Device gd.Viewport = IndexedViewport; gd.RenderState.DepthBufferEnable = false; // Setup view and projection matrixes Matrix proj = Matrix.CreateOrthographic(1.0f, 1.0f, 1, 5); Matrix view = Matrix.CreateLookAt(Vector3.Backward, Vector3.Zero, new Vector3(0, 1, 1)); effect.Parameters["View"].SetValue(view); effect.Parameters["Projection"].SetValue(proj); // Set Quad Vertex Buffer gd.Vertices[0].SetSource(quad_vertexBuffer, 0, quad_vertexDeclaration.GetVertexStrideSize(0)); // Set and clear RTT texture gd.SetRenderTarget(0, renderTarget); gd.Clear(ClearOptions.Target, Color.TransparentWhite, 1.0f, 0); // Draw Quad effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); gd.VertexDeclaration = quad_vertexDeclaration; gd.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2); pass.End(); } effect.End(); // Gets the Rendered Texture and store it in the RenderTarget variable //g.ResolveRenderTarget(0); gd.SetRenderTarget(0, null); //g.RenderState.DepthBufferEnable = true; // Retrieve the Shadow map from our Render Target //renderTargetTexture = renderTarget.GetTexture(); //renderTargetTexture.Save("indexedTexture.png", ImageFileFormat.Png); } } }