//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// 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);
}
}
}