Advertisement
Guest User

Untitled

a guest
Apr 26th, 2012
407
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.22 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System.Windows.Forms;
  3. using SlimDX.Direct3D9;
  4. using SlimDX;
  5. using System.Drawing;
  6. using System.Runtime.InteropServices;
  7. static class Program
  8. {
  9.     static void Main(string[] args)
  10.     {
  11.         gui = new Model();
  12.         gui.BackColor = System.Drawing.Color.Wheat;
  13.         //gui.Objects.Add(GetMessyBox());
  14.         gui.Objects.Add(GetMess());
  15.         gui.ShowDialog();
  16.     }
  17.     private static Model gui;
  18.     private static ModelObject GetMess()
  19.     {/*Create a lot of objects to demonstrate flashing.*/
  20.         const int messcount = 10000;
  21.         var r = new System.Random();
  22.         var verts = new Vertex[messcount];
  23.         for (int i = 0; i < messcount; i++)
  24.             verts[i] = getvert(r.NextDouble(), r.NextDouble(), r.NextDouble(), 1500);
  25.         return new ModelObject(GetBuff(verts), messcount / 2, PrimitiveType.LineList);
  26.     }
  27.     private static VertexBuffer GetBuff(Vertex[] verts)
  28.     {
  29.         var ret = new VertexBuffer(gui.device, Vertex.Size * verts.Length, Usage.None, VertexFormat.PositionNormal, Pool.Managed);
  30.         var l = ret.Lock(0, 0, LockFlags.None);
  31.         l.WriteRange(verts);
  32.         ret.Unlock();
  33.         return ret;
  34.     }
  35.     private static ModelObject GetMessyBox()
  36.     {
  37.         List<Vertex> verts = new List<Vertex>();
  38.         verts.Add(getvert(0, 0, 0, 200));
  39.         for (int x = 0; x < 3; x++)
  40.         {
  41.             for (int y = 0; y < 3; y++)
  42.             {
  43.                 for (int Z = 0; Z < 3; Z++)
  44.                 {
  45.                     verts.Add(getvert(x, y, Z, 200));
  46.                     verts.Add(getvert(x, y, Z, 200));
  47.                 }
  48.             }
  49.         }
  50.         verts.Add(getvert(2, 2, 2, 200));
  51.         return new ModelObject(GetBuff(verts.ToArray()), verts.Count / 2, PrimitiveType.LineList);
  52.     }
  53.     private static Vertex getvert(double x, double y, double z, double magnitude)
  54.     {
  55.         return new Vertex(new SlimDX.Vector3((float)(x * magnitude), (float)(y * magnitude), (float)(z * magnitude)), SlimDX.Vector3.Zero);
  56.     }
  57. }
  58. //#define PROFILING
  59. public class Model : Form
  60. {
  61.     public Model()
  62.     {
  63.         Objects = new List<ModelObject>();
  64.         d3d = new Direct3D();
  65.         device = new Device(d3d, 0, DeviceType.Hardware, Handle,
  66.             CreateFlags.HardwareVertexProcessing, GetPresentParameters());
  67.  
  68.         vdecl = new VertexDeclaration(device, Vertex.GetVertexElements());
  69.  
  70.         Camera = new CameraHandler(this);
  71.         lastsize = ClientSize;
  72.         SetPerspective();
  73.         ResetDevice();
  74.     }
  75.     protected override void OnClosed(System.EventArgs e)
  76.     {
  77.         d3d.Dispose();
  78.         device.Dispose();
  79.         vdecl.Dispose();
  80.         foreach (var o in Objects)
  81.             o.buff.Dispose();
  82.         base.OnClosed(e);
  83.     }
  84.     protected override void Dispose(bool disposing)
  85.     {
  86.         if (disposing)
  87.             foreach (var item in ObjectTable.Objects)
  88.                 item.Dispose();
  89.  
  90.         base.Dispose(disposing);
  91.     }
  92.     private void SetPerspective()
  93.     {
  94.         this.p = Matrix.PerspectiveFovRH(3.1415f / 4, this.ClientSize.Width / (float)this.ClientSize.Height,
  95.             .1f, 100000);
  96.     }
  97.     protected override void OnResize(System.EventArgs eventargs)
  98.     {
  99.         if (lastsize == this.ClientSize ||
  100.             this.ClientSize.IsEmpty)
  101.             return;
  102.         lastsize = this.ClientSize;
  103.         SetPerspective();
  104.         ResetDevice();
  105.     }
  106.     private PresentParameters GetPresentParameters()
  107.     {
  108.         var ret = new PresentParameters();
  109.         ret.BackBufferCount = 1;
  110.         ret.SwapEffect = SwapEffect.Flip;
  111.         ret.Windowed = true;
  112.         ret.BackBufferFormat = Format.Unknown;
  113.         ret.BackBufferHeight = ClientSize.Height - 100;
  114.         ret.BackBufferWidth = ClientSize.Width;
  115.         ret.PresentationInterval = PresentInterval.Immediate;
  116.         return ret;
  117.     }
  118.     private void ResetDevice()
  119.     {
  120.         device.Reset(GetPresentParameters());
  121.  
  122. #if DEBUG
  123.         device.SetRenderState(RenderState.FillMode, FillMode.Wireframe);
  124.         //device.SetRenderState(RenderState.FillMode, FillMode.Solid);
  125. #endif
  126.         device.SetRenderState(RenderState.Ambient, AmbientLight.ToArgb());
  127.  
  128.         device.VertexDeclaration = vdecl;
  129.     }
  130.  
  131.     protected override void OnPaint(PaintEventArgs e)
  132.     {
  133.         Draw();
  134.     }
  135.     public void Draw()
  136.     {
  137.  
  138.         device.SetTransform(TransformState.View, Camera.GetRHCamMatrix());
  139.         device.SetTransform(TransformState.Projection, p);
  140.  
  141.         device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, this.BackColor, 1.0f, 0);
  142. #if BADSPOT
  143.         System.Threading.Thread.Sleep(700);
  144. #endif
  145.         device.BeginScene();
  146.  
  147.         //System.Diagnostics.Debug.Print("{0} objects", objects.Count);
  148.         foreach (var o in Objects)
  149.         {
  150.             device.SetStreamSource(0, o.buff, 0, Vertex.Size);
  151.             device.DrawPrimitives(o.type, 0, o.primitivecount);
  152.         }
  153.  
  154.         device.EndScene();
  155. #if BADSPOT2
  156.         System.Threading.Thread.Sleep(500);
  157. #endif
  158.         device.Present();
  159. #if GOODSPOT
  160.         System.Threading.Thread.Sleep(500);
  161. #endif
  162.     }
  163.     public Color4 AmbientLight
  164.     {
  165.         get { return ambient; }
  166.         set
  167.         {
  168.             ambient = value;
  169.             device.SetRenderState(RenderState.Ambient, ambient.ToArgb());
  170. #if !CONSTANTREDRAW
  171.             this.Invalidate(true);
  172. #endif
  173.         }
  174.     }
  175.     /// <summary>Sets the ambient light color.  Default is gray.</summary>
  176.     private Color4 ambient = new Color4(0x020202);
  177.     private Size lastsize;
  178. #if PROFILING
  179.     private int primitives = 0;
  180.     private System.Diagnostics.Stopwatch fpsclock = System.Diagnostics.Stopwatch.StartNew();
  181.    
  182.     private int frames = 0;
  183.    
  184.     private System.Diagnostics.Stopwatch insidedraw = new System.Diagnostics.Stopwatch(),
  185.         outsidedraw = new System.Diagnostics.Stopwatch();
  186. #endif
  187.     public readonly Device device;
  188.     private readonly Direct3D d3d;
  189.     private readonly VertexDeclaration vdecl;
  190.     public readonly List<ModelObject> Objects;
  191.  
  192.     public readonly CameraHandler Camera;
  193.     /// <summary>Perspective matrix</summary>
  194.     private Matrix p;
  195. }
  196.  
  197. public delegate void FrameUpdate(System.TimeSpan totaltime, System.TimeSpan timesincelastframe);
  198. [StructLayout(LayoutKind.Sequential)]
  199. public struct Vertex
  200. {
  201.     public Vertex(Vector3 position)
  202.         : this(position, Vector3.Zero) { }
  203.     public Vertex(Vector3 position, Vector3 normal)
  204.     {
  205.         this.Position = position;
  206.         this.Normal = normal;
  207.     }
  208.     public static VertexElement[] GetVertexElements()
  209.     {
  210.         return new[] {
  211.                 new VertexElement(0, 0, DeclarationType.Float3,
  212.                     DeclarationMethod.Default, DeclarationUsage.Position, 0),
  213.                 new VertexElement(0,(short)(sizeof(float)*3), DeclarationType.Float3,
  214.                     DeclarationMethod.Default, DeclarationUsage.Normal,0),
  215.                 VertexElement.VertexDeclarationEnd
  216.             };
  217.     }
  218.     public static short Size { get { return (short)Marshal.SizeOf(typeof(Vertex)); } }
  219.     public Vector3 Position;
  220.     public Vector3 Normal;
  221.  
  222. }
  223.  
  224. public class ModelObject
  225. {
  226.     public ModelObject(VertexBuffer buffer, int primitivecount, PrimitiveType type)
  227.     {
  228.         this.primitivecount = primitivecount;
  229.         this.type = type;
  230.         this.buff = buffer;
  231.     }
  232.     public readonly int primitivecount;
  233.     public readonly PrimitiveType type;
  234.     public readonly VertexBuffer buff;
  235. }
  236. public class CameraHandler
  237. {
  238.     public CameraHandler(Control rendertarget)
  239.     {
  240.         this.rendertarget = rendertarget;
  241.         rendertarget.MouseDown += rendertarget_MouseDown;
  242.         rendertarget.MouseUp += rendertarget_MouseUp;
  243.         rendertarget.MouseMove += rendertarget_MouseMove;
  244.         rendertarget.MouseWheel += rendertarget_MouseWheel;
  245.         rendertarget.MouseEnter += rendertarget_MouseEnter;
  246.  
  247.         up = Vector3.UnitZ;
  248.         target = Vector3.Zero;
  249.         Vector3 camoffset = new Vector3(1);
  250.         camoffset.Normalize();
  251.         camoffset *= dist;
  252.         cam = target + camoffset;
  253.     }
  254.  
  255.     private void rendertarget_MouseEnter(object sender, System.EventArgs e)
  256.     {
  257.         (sender as Control).Focus();
  258.     }
  259.     /// <summary>Hold shift to change distance, otherwise, we just
  260.     /// move the camera.</summary>
  261.     private void rendertarget_MouseWheel(object sender, MouseEventArgs e)
  262.     {
  263.         float delta = System.Math.Sign(e.Delta) * wheelfactor;
  264.         if ((Control.ModifierKeys & Keys.Shift) > 0)
  265.         {
  266.             Vector3 camvec = cam - target;
  267.             camvec.Normalize();
  268.             Vector3 add = camvec * delta;
  269.             cam += add;
  270.             target += add;
  271.         }
  272.         else
  273.         {
  274.             Distance += delta;
  275.         }
  276.     }
  277.     public Matrix GetRHCamMatrix()
  278.     {
  279.         return Matrix.LookAtRH(cam, target, up);
  280.     }
  281.     private bool GoAhead()
  282.     {
  283.  
  284. #if WAIT
  285.         var now = System.DateTime.Now;
  286.         if ((now - lastgoahead).TotalMilliseconds > msbetweengoahead)
  287.         {   //go ahead
  288.             lastgoahead = now;
  289.             return true;
  290.         }
  291.         return false;
  292. #else
  293.         return true;
  294. #endif
  295.     }
  296.     private const double msbetweengoahead = 500;
  297.     private System.DateTime lastgoahead = System.DateTime.MinValue;
  298.     private void rendertarget_MouseMove(object sender, MouseEventArgs e)
  299.     {
  300.         if (mousedown)
  301.         {
  302.             if (!GoAhead())
  303.                 return;
  304.             //System.Diagnostics.Debug.Print("Mouse moved.");
  305.             MoveCamera(new Size(Point.Subtract(e.Location, new Size(downspot))), movetarget);
  306.             downspot = e.Location;
  307.         }
  308.     }
  309.  
  310.     private void rendertarget_MouseUp(object sender, MouseEventArgs e)
  311.     {
  312.         mousedown = false;
  313.     }
  314.  
  315.     private void rendertarget_MouseDown(object sender, MouseEventArgs e)
  316.     {
  317.         mousedown = true;
  318.         movetarget = e.Button == MouseButtons.Right;
  319.         downspot = e.Location;
  320.     }
  321.     private void MoveCamera(Size s, bool movetarget)
  322.     {
  323.         //System.Diagnostics.Debug.WriteLine(string.Format(            "Moving by {0}", s));
  324.  
  325.         if (movetarget)
  326.         {
  327.             MoveTarget(new Vector2(s.Width * cameramovefactor, s.Height * cameramovefactor));
  328.         }
  329.         else
  330.         {
  331.             RotateCamera(new Vector2(-s.Width * camerarotfactor, s.Height * camerarotfactor));
  332.         }
  333.     }
  334.     /// <param name="mousemovement">The movement that the mouse
  335.     /// made with the scaling factor already present.</param>
  336.     private void RotateCamera(Vector2 mousemovement)
  337.     {
  338.         //if (!GoAhead())
  339.         //    return;
  340.         /*We will be rotating the camera position and the up vector about
  341.          * the target.  First, bring the target to zero (and the up and
  342.          * camera vectors with it), then do the rotation, then come back.*/
  343.  
  344.         /*the camera vec with relation to the target*/
  345.         var camtarvec = cam - target;
  346.  
  347.         var camtarvecn = camtarvec;
  348.         camtarvecn.Normalize();
  349.  
  350.         var upn = up;
  351.         upn.Normalize();
  352.  
  353.         /*The vector about which updown mouse movements are rotated*/
  354.         var updownaxis = Vector3.Cross(-upn, camtarvecn);
  355.  
  356.         /*this matrix will rotate the camera according to the updown mouse movements.*/
  357.         var updownmatrix = Matrix.RotationAxis(updownaxis, mousemovement.Y);
  358.  
  359.         /*The up vector is already at 0*/
  360.         var lraxis = up;
  361.  
  362.         var lrmatrix = Matrix.RotationAxis(lraxis, mousemovement.X);
  363.  
  364.         /*the composition of matrices*/
  365.         var finalmatrix = updownmatrix * lrmatrix;
  366.  
  367.         /*now, finally, rotate the up vector and the camera*/
  368.         var up4 = Vector3.Transform(up, finalmatrix);
  369.         /*we need to move the camera so that it is rotating about
  370.          * target (so we need to move target back to zero taking
  371.          * the camera with it), then move it back.  That is
  372.          * We need to conjugate camera by target's translation.*/
  373.         var cam4 = Vector3.Transform(cam - target, finalmatrix) + new Vector4(target, 0);
  374.  
  375.         //System.Diagnostics.Debug.WriteLine(string.Format("Up was {0}", up));            
  376.         up = new Vector3(up4.X, up4.Y, up4.Z);
  377.         //System.Diagnostics.Debug.WriteLine(string.Format("Up is  {0}", up));
  378.  
  379.         //System.Diagnostics.Debug.WriteLine(string.Format("cam was {0}", cam));
  380.         cam = new Vector3(cam4.X, cam4.Y, cam4.Z);
  381.         //System.Diagnostics.Debug.WriteLine(string.Format("cam is  {0}", cam));
  382. #if !CONSTANTREDRAW
  383.         rendertarget.Invalidate();
  384. #endif
  385.     }
  386.     /// <param name="mousemovent">The movement that the mouse made with the
  387.     /// scaling factor already in it.</param>
  388.     private void MoveTarget(Vector2 mousemovent)
  389.     {
  390.         //if (!GoAhead())
  391.         //    return;
  392.  
  393.         /*the camera vector in relation to the target.*/
  394.         var camtarvec = cam - target;/*or target - cam*/
  395.  
  396.         /*pick up some normalized vectors*/
  397.         var camtarvecn = camtarvec;
  398.         camtarvecn.Normalize();
  399.         var upn = up;
  400.         upn.Normalize();
  401.  
  402.         /*the vector about which z must be rotated to get up*/
  403.         var xchange = Vector3.Cross(upn, camtarvecn);
  404.         /*xchange.normalize should be unnecessary since we used two
  405.          * normalized vectors*/
  406.  
  407.         var movevec = up * mousemovent.Y - xchange * mousemovent.X;
  408.  
  409.         target += movevec;
  410.         cam += movevec;
  411. #if !CONSTANTREDRAW
  412.         rendertarget.Invalidate();
  413. #endif
  414.     }
  415.     private Control rendertarget;
  416.     private bool mousedown = false;
  417.     private bool movetarget = false;
  418.     private float cameramovefactor = 4, wheelfactor = -100;
  419.     /*The camera will rotate a number of degrees per pixel moved on screen.
  420.      This number is in radians.*/
  421.     private float camerarotfactor = 2f * (float)System.Math.PI / 180;
  422.     private float dist = 8000;
  423.     public Vector3 CameraUp { get { return up; } }
  424.     /// <summary>
  425.     /// Keeps the same CameraUp value.  Moves the target and the camera
  426.     /// to the specified spot.
  427.     /// </summary>
  428.     public Vector3 Target
  429.     {
  430.         get
  431.         {
  432.             return target;
  433.         }
  434.         set
  435.         {
  436.             //target = new Vector3(1) * 1000;
  437.             Vector3 camoffset = cam - target;
  438.             camoffset.Normalize();
  439.             camoffset *= dist;
  440.             cam = target + camoffset;
  441.  
  442. #if !CONSTANTREDRAW
  443.             rendertarget.Invalidate();
  444. #endif
  445.         }
  446.     }
  447.     /// <summary>Sets the camer's distance from the target. The
  448.     /// default is 8000</summary>
  449.     public float Distance
  450.     {
  451.         get
  452.         {
  453.             return dist;
  454.         }
  455.         set
  456.         {
  457.             if (value == dist)
  458.                 return;
  459.             dist = System.Math.Max(1, value);
  460.             var targetcamvec = cam - target;
  461.             targetcamvec.Normalize();
  462.             targetcamvec *= dist;
  463.             cam = target + targetcamvec;
  464. #if !CONSTANTREDRAW
  465.             rendertarget.Invalidate();
  466. #endif
  467.         }
  468.     }
  469.     public Vector3 CameraPos { get { return cam; } }
  470.     private Vector3 up, target, cam;
  471.     /*The spot at which the mouse was seen to go "down"*/
  472.     private Point downspot;
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement