namespace ElementalGame { #region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; using System.Xml; #endregion public class GpuVariable : GpuVariableInterface { // Interfacing public Texture2D _read { get { return read; } set { read = value; } } public Texture2D _write { get { return write; } set { write = value; } } public EffectParameter _gpuPointer { get { return gpuPointer; } set { gpuPointer = value; } } public Effect _thisEffect { get { return thisEffect; } set { thisEffect = value; } } public RenderTarget2D _writeRenderTarget { get { return writeRenderTarget; } set { writeRenderTarget = value; } } public RenderTarget2D _readRenderTarget { get { return readRenderTarget; } set { readRenderTarget = value; } } // Standard Variables public Texture2D read; public Texture2D write; public EffectParameter gpuPointer; public Effect thisEffect; public RenderTarget2D writeRenderTarget; public RenderTarget2D readRenderTarget; public string outTexName; public int count; public float minimumValue, scaleRange; public List properties = new List(); public GpuVariable(Effect effect, string gpuParameterName, string debugTextureName) { // Store info outTexName = debugTextureName; thisEffect = effect; GraphicsDevice gd = ElementalGame.graphics.GraphicsDevice; // Create Render Targets writeRenderTarget = new RenderTarget2D(gd, GpuProcessor.INDEXED_TARGET_SIZE, GpuProcessor.INDEXED_TARGET_SIZE, 1, SurfaceFormat.Vector4); readRenderTarget = new RenderTarget2D(gd, GpuProcessor.INDEXED_TARGET_SIZE, GpuProcessor.INDEXED_TARGET_SIZE, 1, SurfaceFormat.Vector4); // Clear out textures gd.SetRenderTarget(0, readRenderTarget); gd.ResolveRenderTarget(0); read = readRenderTarget.GetTexture(); gd.SetRenderTarget(0, writeRenderTarget); gd.ResolveRenderTarget(0); write = writeRenderTarget.GetTexture(); gd.SetRenderTarget(0, null); try { // Set pointer to shader variable gpuPointer = thisEffect.Parameters[gpuParameterName]; } catch { throw new InvalidOperationException("Parameter not found."); } } // Methods public virtual void AddProperty(float value) { properties.Add(new Vector4(value, 1.0f, 1.0f, 1.0f)); } public virtual void AddProperty(Vector2 value) { properties.Add(new Vector4(value.X, value.Y, 1.0f, 1.0f)); } public virtual void AddProperty(Vector3 value) { properties.Add(new Vector4(value.X, value.Y, value.Z, 1.0f)); } public virtual void AddProperty(Vector4 value) { properties.Add(new Vector4(value.X, value.Y, value.Z, value.W)); } public virtual void AddProperty(Quaternion value) { properties.Add(new Vector4( value.X, value.Y, value.Z, value.W )); } public virtual void SetTexData(float minValue, float maxValue) { // Save the min value for decompression minimumValue = minValue; // Get the data range scaleRange = maxValue - minValue; // Vector4 array holds properties that we pass to gpu texture Vector4[] texValues = new Vector4[GpuProcessor.INDEXED_TARGET_SIZE * GpuProcessor.INDEXED_TARGET_SIZE]; // Copy values from properties to texture int texCounter = 0; for (int i = 0; i < properties.Count; i++) { texValues[texCounter].X = (properties[i].X - minValue) / scaleRange; texValues[texCounter].Y = (properties[i].Y - minValue) / scaleRange; texValues[texCounter].Z = (properties[i].Z - minValue) / scaleRange; texValues[texCounter].W = (properties[i].Z - minValue) / scaleRange; texCounter++; } // Initialize both textures with values read.SetData(texValues); write.SetData(texValues); gpuPointer.SetValue(read); } public void SwapBuffers() { // Swap the textures Texture2D temp = read; read = write; write = temp; // Swap the render targets RenderTarget2D tempTarget = readRenderTarget; readRenderTarget = writeRenderTarget; writeRenderTarget = tempTarget; // Reset GPU Variable gpuPointer.SetValue(read); } public virtual Vector3 UnScale(Vector4 input) { Vector3 temp = new Vector3(input.X, input.Y, input.Z); temp *= scaleRange; temp += new Vector3(minimumValue); return temp; } public void WriteToFile() { write.Save(outTexName + "_Write.png", ImageFileFormat.Png); read.Save(outTexName + "_Read.png", ImageFileFormat.Png); } } }