Framework should be good to go...
779
0
Advertisement
Well the D3DApp framework appears to be totally ported at this point. Font stretch bug is fixed. I just last night fixed a bug that was causing the timer to occasionally hang up temporarily on resizing. This was due to the fact that I was not properly handling window states. A few boolean flags latter and it appears as if the bug is squashed. I also went ahead and implemented IDisposable. This was a suggestion in one of the comments from a previous entry. I feel this is the better way to go and will make deriving from the class safer.
It definitely feels good to be away from C++. I still find my self trying to get out of the ruts the language put me in. When using C++ we all know there are certain things you do a certain way for a good reason. In C# things are done differently and take a whole new mind set. C# for sure seems to push better programming practices on the developer. With C++ it is always finding the right workaround in C# I only encountered one workaround I needed and that was to handle window states. C# does not expose a Restore event for the window. So you need to keep track of whether or not the window was previously minimized or maximized so you can properly Reset your DirectX Views and SwapChain to new sizes.
Even with my positive experience thus far I find my self wanting to fall back to C++. It grew on me almost like a child. I could write C++ code as fast as a lot of people can write C#, Python, or even Java. That comes with experience.
Overall I am very pleased with C# it is like a fresh breeze in the air. Will I go back to C++... Not sure lets give C# some time I am sure it will grow on me.
Before I forget CODE:
It definitely feels good to be away from C++. I still find my self trying to get out of the ruts the language put me in. When using C++ we all know there are certain things you do a certain way for a good reason. In C# things are done differently and take a whole new mind set. C# for sure seems to push better programming practices on the developer. With C++ it is always finding the right workaround in C# I only encountered one workaround I needed and that was to handle window states. C# does not expose a Restore event for the window. So you need to keep track of whether or not the window was previously minimized or maximized so you can properly Reset your DirectX Views and SwapChain to new sizes.
Even with my positive experience thus far I find my self wanting to fall back to C++. It grew on me almost like a child. I could write C++ code as fast as a lot of people can write C#, Python, or even Java. That comes with experience.
Overall I am very pleased with C# it is like a fresh breeze in the air. Will I go back to C++... Not sure lets give C# some time I am sure it will grow on me.
Before I forget CODE:
using System;using System.Drawing;using System.Windows.Forms;using SlimDX;using D3D10 = SlimDX.Direct3D10;using DXGI = SlimDX.DXGI;using SlimDX.Windows;using System.Text;namespace InitDirect3D{ class D3DApp : IDisposable { protected RenderForm m_Window; protected D3D10.Device m_D3DDevice; protected DXGI.SwapChain m_SwapChain; protected D3D10.RenderTargetView m_RenderTargetView; protected D3D10.DepthStencilView m_DepthStencilView; protected D3D10.Texture2D m_DepthStencilBuffer; protected D3D10.Font m_Font; protected int m_VSync; protected bool m_AppPaused; protected string m_FrameStats; protected GameTimer m_Timer; private int frameCnt; private float t_base; private bool minimized; private bool maximized; public D3DApp() { m_Window = null; m_D3DDevice = null; m_SwapChain = null; m_RenderTargetView = null; m_DepthStencilView = null; m_DepthStencilBuffer = null; m_Font = null; m_VSync = 0; m_FrameStats = ""; m_AppPaused = false; minimized = false; maximized = false; frameCnt = 0; t_base = 0.0f; } ~D3DApp() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { // release managed resources m_Window.Dispose(); } // Release unmanaged resources m_D3DDevice.ClearState(); m_RenderTargetView.Dispose(); m_DepthStencilView.Dispose(); m_DepthStencilBuffer.Dispose(); m_D3DDevice.Dispose(); m_SwapChain.Dispose(); m_Font.Dispose(); } public virtual void Initialize(string windowCaption) { m_Window = new RenderForm(windowCaption); m_Timer = new GameTimer(); // This sets up the SwapChain's Mode Description DXGI.ModeDescription modeDesc = new DXGI.ModeDescription() { Width = m_Window.ClientSize.Width, Height = m_Window.ClientSize.Height, RefreshRate = new Rational(60, 1), Format = DXGI.Format.R8G8B8A8_UNorm, ScanlineOrdering = DXGI.DisplayModeScanlineOrdering.Unspecified, Scaling = DXGI.DisplayModeScaling.Unspecified }; // Setup the SwapChain and Device DXGI.SwapChainDescription swapDesc = new DXGI.SwapChainDescription() { BufferCount = 1, ModeDescription = modeDesc, IsWindowed = true, OutputHandle = m_Window.Handle, SampleDescription = new DXGI.SampleDescription(1, 0), Usage = DXGI.Usage.RenderTargetOutput, Flags = DXGI.SwapChainFlags.None, SwapEffect = DXGI.SwapEffect.Discard }; D3D10.Device.CreateWithSwapChain(null, D3D10.DriverType.Hardware, D3D10.DeviceCreationFlags.Debug, swapDesc, out m_D3DDevice, out m_SwapChain); // Once the device is created we need to Call on resize to setup our buffers and resize our swapchain. OnResize(); // Disable Alt+Enter FullScreen DXGI.Factory factory = m_SwapChain.GetParent(); factory.SetWindowAssociation(m_Window.Handle, DXGI.WindowAssociationFlags.IgnoreAll); // The font that will display our Performance information. m_Font = new D3D10.Font(m_D3DDevice, 20, 0, D3D10.FontWeight.Normal, 1, false, D3D10.FontCharacterSet.Default, D3D10.FontPrecision.Default, D3D10.FontQuality.Default, D3D10.FontPitchAndFamily.Default | D3D10.FontPitchAndFamily.DontCare, "Fixedsys"); // Hook to our window event handlers. m_Window.ResizeBegin += new EventHandler(m_Window_ResizeBegin); m_Window.ResizeEnd += new EventHandler(m_Window_ResizeEnd); m_Window.Resize += new EventHandler(m_Window_Resize); m_Window.KeyDown += new KeyEventHandler(m_Window_KeyDown); } private void m_Window_Resize(object sender, EventArgs e) { // Make sure we properly handle resizing and pausing through different window states. // This will allow for proper freeing of CPU cycles and making sure our views and swapchain // are the right dimensions. if (m_Window.WindowState == FormWindowState.Minimized) { m_AppPaused = true; m_Timer.Stop(); minimized = true; } else if (m_Window.WindowState == FormWindowState.Maximized) { if (minimized) { m_AppPaused = false; m_Timer.Start(); OnResize(); maximized = true; minimized = false; } else { m_AppPaused = false; OnResize(); maximized = true; } } else { if(minimized) { m_AppPaused = false; m_Timer.Start(); OnResize(); minimized = false; } if(maximized) { m_AppPaused = false; OnResize(); maximized = false; } } } private void m_Window_ResizeBegin(object sender, EventArgs e) { m_AppPaused = true; m_Timer.Stop(); } private void m_Window_ResizeEnd(object sender, EventArgs e) { m_AppPaused = false; m_Timer.Start(); OnResize(); } private void m_Window_KeyDown(object sender, KeyEventArgs e) { // When the V-Key is pressed we will force SwapChain to // Present at the Vertical Refresh Rate of our monitor. // Under most circumstances this will be 60 FPS. if (e.KeyCode == Keys.V) { if (m_VSync == 0) { m_VSync = 1; } else { m_VSync = 0; } } } public virtual void Run() { m_Timer.Reset(); MessagePump.Run(m_Window, () => { m_Timer.Tick(); if (!m_AppPaused) { UpdateScene(m_Timer.GetDeltaTime()); } else { System.Threading.Thread.Sleep(50); } DrawScene(); m_SwapChain.Present(m_VSync, DXGI.PresentFlags.None); }); } public virtual void OnResize() { // Release our resources as long as we are not null. This will prevent // Internal reference counts from accumulating. Put here to be on the safe side. // Not 100% sure if neccessary. if (m_RenderTargetView != null) { m_RenderTargetView.Dispose(); } if (m_DepthStencilView != null) { m_DepthStencilView.Dispose(); } if (m_DepthStencilBuffer != null) { m_DepthStencilBuffer.Dispose(); } // Resize our SwapChain Buffers and then setup our new RenderTargetView and DepthStencilBuffer/View m_SwapChain.ResizeBuffers(1, m_Window.ClientSize.Width, m_Window.ClientSize.Height, DXGI.Format.R8G8B8A8_UNorm, DXGI.SwapChainFlags.None); D3D10.Texture2D backbuffer = D3D10.Texture2D.FromSwapChain3D10.Texture2D>(m_SwapChain, 0); m_RenderTargetView = new D3D10.RenderTargetView(m_D3DDevice, backbuffer); backbuffer.Dispose(); D3D10.Texture2DDescription depthStencilDesc = new D3D10.Texture2DDescription() { Width = m_Window.ClientSize.Width, Height = m_Window.ClientSize.Height, MipLevels = 1, ArraySize = 1, Format = DXGI.Format.D24_UNorm_S8_UInt, SampleDescription = new DXGI.SampleDescription(1, 0), Usage = D3D10.ResourceUsage.Default, BindFlags = D3D10.BindFlags.DepthStencil, CpuAccessFlags = D3D10.CpuAccessFlags.None, OptionFlags = D3D10.ResourceOptionFlags.None }; m_DepthStencilBuffer = new D3D10.Texture2D(m_D3DDevice, depthStencilDesc); m_DepthStencilView = new D3D10.DepthStencilView(m_D3DDevice, m_DepthStencilBuffer); // Bind views to OutputMerger stage of the rendering pipeline m_D3DDevice.OutputMerger.SetTargets(m_DepthStencilView, m_RenderTargetView); // Now we will recreate our viewport and bind it to the Raster stage. D3D10.Viewport vp = new D3D10.Viewport(0, 0, m_Window.ClientSize.Width, m_Window.ClientSize.Height, 0.0f, 1.0f); m_D3DDevice.Rasterizer.SetViewports(vp); } public virtual void UpdateScene(float dt) { frameCnt++; if ((m_Timer.GetGameTime() - t_base) >= 1.0f) { float fps = (float)frameCnt; float mspf = 1000.0f / fps; StringBuilder output = new StringBuilder(); if (m_VSync == 0) { output.Append("VSync: Off \n"); } else { output.Append("VSync: On \n"); } output.AppendFormat("FPS: {0} \n", fps); output.AppendFormat("Milliseconds Per Frame: {0:0.000000}", mspf); m_FrameStats = output.ToString(); frameCnt = 0; t_base += 1.0f; } } public virtual void DrawScene() { // Clear our Views. m_D3DDevice.ClearRenderTargetView(m_RenderTargetView, new Color4(1.0f, 0.0f, 0.0f, 1.0f)); m_D3DDevice.ClearDepthStencilView(m_DepthStencilView, D3D10.DepthStencilClearFlags.Depth | D3D10.DepthStencilClearFlags.Stencil, 1.0f, 0); m_Font.Draw(null, m_FrameStats, new Rectangle(0,0,5,5), D3D10.FontDrawFlags.NoClip, 0xff000000); } }}Advertisement
Advertisement
Advertisement
Discussion