Jump to content

  • Log In with Google      Sign In   
  • Create Account


CdrTomalak

Member Since 12 Mar 2012
Offline Last Active Aug 01 2014 04:19 PM

#5037573 How many draw calls per frame are possible without awful performance?

Posted by CdrTomalak on 28 February 2013 - 06:30 AM

I have just completed attempts to write my own sprite batch class in C# using SlimDX, in direct response to performance problems in my game.

 

Basically I draw the game area (pacman) in tiles, with each tile drawn using a draw call to the sprite renderer object. I am now using a decent sprite renderer (http://sdxspritetext.codeplex.com/wikipage?title=Concepts%20of%20the%20SpriteRenderer) but find that my performance problem remains the same!

 

Basically I was fine with a 10x10 tile game area, but after scaling up to 30x15, the performance is terrble. Literally 5 frames per second.

 

How should I be handling the drawing of game tiles in this scenario? Or could there be something else wrong with the way in which I've got things set up?

 

My graphics device set-up code is as follows (excuse the mess):

 

		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// START: Method InitialiseGraphics
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		public void InitialiseGraphics()
		{
			bool debug=false;
			
			if(debug){MessageBox.Show( "InitialiseGraphics()...");}
			
			description = new SlimDX.DXGI.SwapChainDescription()
            {
                BufferCount = 2,
                Usage = SlimDX.DXGI.Usage.RenderTargetOutput,
                OutputHandle = this.Handle,
                IsWindowed = true,
                ModeDescription = new SlimDX.DXGI.ModeDescription(0, 0, new SlimDX.Rational(60, 1), SlimDX.DXGI.Format.R8G8B8A8_UNorm),
                SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0),
                Flags = SlimDX.DXGI.SwapChainFlags.AllowModeSwitch,
                SwapEffect = SlimDX.DXGI.SwapEffect.Discard
            };
		
			if(debug){MessageBox.Show( "InitialiseGraphics()...1");}
			
			SlimDX.Direct3D11.FeatureLevel[] featureLevels = new SlimDX.Direct3D11.FeatureLevel[] { SlimDX.Direct3D11.FeatureLevel.Level_10_1 };

			if(debug){MessageBox.Show( "InitialiseGraphics()...2");}
	
			// 02/09/12: Change constructor to enable text writing!
			SlimDX.Direct3D11.Device.CreateWithSwapChain(
				adapter1, 
				SlimDX.Direct3D11.DeviceCreationFlags.Debug, 
				featureLevels,
				description, 
				out graphics, 
				out swapChain
			);	
			
			if(debug){MessageBox.Show( "InitialiseGraphics()...3");}
			
			// create a view of our render target, which is the backbuffer of the swap chain we just created
			using (var resource = SlimDX.Direct3D11.Resource.FromSwapChain<SlimDX.Direct3D11.Texture2D>(swapChain, 0))
                renderTarget = new SlimDX.Direct3D11.RenderTargetView(graphics, resource);

				if(debug){MessageBox.Show( "InitialiseGraphics()...4");}
				
			// setting a viewport is required if you want to actually see anything
            context = graphics.ImmediateContext;
            var viewport = new SlimDX.Direct3D11.Viewport(0.0f, 0.0f, this.ClientSize.Width, this.ClientSize.Height);
            context.OutputMerger.SetTargets(renderTarget);
            context.Rasterizer.SetViewports(viewport);
			
			if(debug){MessageBox.Show( "InitialiseGraphics()...5");}
			
			bsd = new SlimDX.Direct3D11.BlendStateDescription();
			bsd.RenderTargets[0].BlendEnable = true;
			bsd.RenderTargets[0].SourceBlend = SlimDX.Direct3D11.BlendOption.SourceAlpha;
			bsd.RenderTargets[0].DestinationBlend = SlimDX.Direct3D11.BlendOption.InverseSourceAlpha;
			bsd.RenderTargets[0].BlendOperation = SlimDX.Direct3D11.BlendOperation.Add;
			bsd.RenderTargets[0].SourceBlendAlpha = SlimDX.Direct3D11.BlendOption.One;
			bsd.RenderTargets[0].DestinationBlendAlpha = SlimDX.Direct3D11.BlendOption.Zero;
			bsd.RenderTargets[0].BlendOperationAlpha = SlimDX.Direct3D11.BlendOperation.Add;
			bsd.RenderTargets[0].RenderTargetWriteMask = SlimDX.Direct3D11.ColorWriteMaskFlags.All;
			BlendState_Transparent = SlimDX.Direct3D11.BlendState.FromDescription(graphics, bsd);
			
			context.OutputMerger.BlendState = BlendState_Transparent;
			
			// ... END
			// ---------------------------------------------------------------------------------------------------------------------------
			
			if(debug){MessageBox.Show( "InitialiseGraphics()...5.5");}
			
			SlimDX.Direct3D11.RasterizerStateDescription rasterizerStateDescription = new SlimDX.Direct3D11.RasterizerStateDescription 
			{
				CullMode = SlimDX.Direct3D11.CullMode.None, 
				FillMode = SlimDX.Direct3D11.FillMode.Solid
			};
 
			context.Rasterizer.State = SlimDX.Direct3D11.RasterizerState.FromDescription(graphics, rasterizerStateDescription);
			
			if(debug){MessageBox.Show( "InitialiseGraphics()...6");}

			// load and compile the vertex shader (from the FX file)
            using (var bytecode = SlimDX.D3DCompiler.ShaderBytecode.CompileFromFile("D:\\Programming\\SharpDevelop_Projects\\SlimDX_StartOver\\BasicWindow_1\\BasicWindow_1\\triangle8.fx", "TextVS", "vs_4_0", SlimDX.D3DCompiler.ShaderFlags.None, SlimDX.D3DCompiler.EffectFlags.None))
            {
                inputSignature = SlimDX.D3DCompiler.ShaderSignature.GetInputSignature(bytecode);
                vertexShader = new SlimDX.Direct3D11.VertexShader(graphics, bytecode);
            } 
			
			if(debug){MessageBox.Show( "InitialiseGraphics()...7");}
			
			// load and compile the pixel shader (from the FX file)
            using (var bytecode = SlimDX.D3DCompiler.ShaderBytecode.CompileFromFile("D:\\Programming\\SharpDevelop_Projects\\SlimDX_StartOver\\BasicWindow_1\\BasicWindow_1\\triangle8.fx", "TextPS", "ps_4_0", SlimDX.D3DCompiler.ShaderFlags.None, SlimDX.D3DCompiler.EffectFlags.None))
                pixelShader = new SlimDX.Direct3D11.PixelShader(graphics, bytecode);
				
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....2");}
			// SamplerDescription
			// GT 17/07/12: Check this against the DX11 book!!!!
			// 
			samplerDescription = new SlimDX.Direct3D11.SamplerDescription();
            samplerDescription.AddressU = SlimDX.Direct3D11.TextureAddressMode.Wrap;
            samplerDescription.AddressV = SlimDX.Direct3D11.TextureAddressMode.Wrap;
            samplerDescription.AddressW = SlimDX.Direct3D11.TextureAddressMode.Wrap;
			samplerDescription.ComparisonFunction = SlimDX.Direct3D11.Comparison.Never;
			samplerDescription.Filter = SlimDX.Direct3D11.Filter.MinPointMagMipLinear;
					
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....3");}
			// SamplerState
			SlimDX.Direct3D11.SamplerState samplerState = SlimDX.Direct3D11.SamplerState.FromDescription(graphics, samplerDescription);
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....4");}

            context.PixelShader.SetSampler(samplerState,0);
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....7");}
			
			// 26/08/12: START
			// --------------------
			// INPUT ELEMENTS
			// ----------------------
			var elements = new[] { 
				new SlimDX.Direct3D11.InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32_Float, 0),
				new SlimDX.Direct3D11.InputElement("TEXCOORD", 0, SlimDX.DXGI.Format.R32G32_Float, 0)
			};
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....8");}
            
			layout = new SlimDX.Direct3D11.InputLayout(graphics, inputSignature, elements);
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....9");}
			// --------------------------------------------------------------------------------------------------------------------
			
			// -------------------------------------------
			// INPUT ASSEMBLER: Layout & PrimitiveTopology
			// -------------------------------------------
			context.InputAssembler.InputLayout = layout;
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....10");}

			context.InputAssembler.PrimitiveTopology = SlimDX.Direct3D11.PrimitiveTopology.TriangleStrip;
			// -----------------------------------------------------------------------
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....11");}
			
			// Added these because of the awful crashing incident. Might fix it?
			// set the shaders
            context.VertexShader.Set(vertexShader);
            context.PixelShader.Set(pixelShader);
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....12");}
			
			// Clear the screen...
			context.ClearRenderTargetView(renderTarget, new SlimDX.Color4(0.0f, 0.0f, 0.0f));
			// 26/08/12: END
			
			if(debug){MessageBox.Show( "InitialiseGraphics()... TEXTURE CODE....13");}
		}
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// END: Method InitialiseGraphics
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

I'm slightly baffled, as I didn't think I'd hit this problem what with the power of hardware these days. Wierd. Clearly I'm doing something very silly.

 

blink.png




#4980056 About to enter the world of 2d animation under SlimDX...

Posted by CdrTomalak on 14 September 2012 - 08:03 AM

I think I know what to do now.

http://spritesheetpacker.codeplex.com/

This will allow me to build a sprite sheet from separate images, which I can generate in GIMP easily enough. I would then need to map the texture using the texture coordinate attributes for each CustomVertex object (instance variable of a sprite) in my game.

I'll set the vectors as per the rectangle definitions in the spritesheet config file, and transform them through an orthogonal matrix.

I think this is the principle anyways.Posted Image


#4977230 being realistic

Posted by CdrTomalak on 06 September 2012 - 09:15 AM

Hey igna92ts - I'm learning 2D game programming at the moment, but using C# and SlimDX (API around DX11).

Eveything people have said about just 'starting' is true, and you have to build yourself up gradually. Learning the basics of programming can be tackled at the same time as writing games, but you could tackle them separately.

Being an existing coder I needed to refresh before learning the principles behind 2d game design. I did this by identifying a number of C# tutorials that I would go through, to master the key concepts - or at least get closer to mastering them.

With this foundation in place you can kick-on to creating a game. This approach worked for me.

One thing I have found is that making a command line driven game (I made a fruit machine game drawing the machine in ASCII characters) was much easier than a 2d game. The reason is, graphics programming is science (yes another one) in itself - but this can be made eaiser depending on the APIs you use. In my case I took a slightly mental approach by going for DX11 via SlimDX - but if you use XNA you'll get results quicker than I did.

But it depends what you want out of the experience really. If you want results ASAP then go for higher level APIs, or even game engines. If you want the thrill of learning then lower level might be more of an option.

Right now I'm starting with a basic 2d game - a pacman clone. It's seriously good fun.

Hope this helps! Posted Image


#4946500 Making SlimDX tutorial code compatible with old graphics hardware...

Posted by CdrTomalak on 05 June 2012 - 10:26 AM

You might have seen me post about this problem before, but basically I have just merged the SlimDX tutorial code with Ron Pentons game framework as per his C# Game Programming book.

The problem is, this won't run on my Dell Latitude D600 (DXGI ERROR UNSUPPORTED), whilst is fine on my slightly old gaming rig with an Nvidia 9800GT. All it's doing is displaying a triangle.

The quesiton is, how can I alter the code to make it compatible with the ATI Radeon Mobility 9000 graphics hardware on the D600? The specificaiton for this GPU says it doesn't even officically support DirectX9!

Here's the code anyways (excuse the lack of comments - I've stripped most of them out shorten this post).

using System;
using System.ComponentModel;
using SlimDX;
using SlimDX.Windows;
using System.Windows.Forms;
namespace BasicWindow_1
{
public class Game : Form
{
	 // --------------------------------------------------------------------
		// static variables
		// --------------------------------------------------------------------
		static string gametitle  = "Test";
		static int screenwidth   = 640;
		static int screenheight  = 480;
  static bool windowed	 = true;
		static bool graphicslost = false;
  static bool paused	   = false;
  // --------------------------------------------------------------------

  // --------------------------------------------------------------------
  // Direct3D9 object
  // --------------------------------------------------------------------
  SlimDX.Direct3D9.Direct3D myD3D;
  // --------------------------------------------------------------------

  // --------------------------------------------------------------------
		// Devices
  // --------------------------------------------------------------------

  SlimDX.Direct3D11.Device graphics		= null;
  SlimDX.DXGI.SwapChain swapChain = null;

  SlimDX.D3DCompiler.ShaderSignature inputSignature = null;
		SlimDX.Direct3D11.VertexShader vertexShader = null;
		SlimDX.Direct3D11.PixelShader pixelShader = null;

  SlimDX.Direct3D11.RenderTargetView renderTarget = null;

  SlimDX.Direct3D11.DeviceContext context = null;

  // KEYBOARD ...
  SlimDX.DirectInput.DirectInput directInput = null;
  SlimDX.DirectInput.Keyboard keyboard = null;

  // MOUSE ...
  SlimDX.DirectInput.Mouse mouse		= null;

  // SOUND ...
		SlimDX.DirectSound.DirectSound sound		= null;
	  
	  
  // --------------------------------------------------------------------

  // --------------------------------------------------------------------
  // Vertex Object
  // --------------------------------------------------------------------
  SlimDX.DataStream vertices = new DataStream(12 * 3, true, true);
  SlimDX.Direct3D11.Buffer vertexBuffer = null; // This is set in init geom.
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


  // ********************************************************************
  // Game Constructor!
  public Game()
  {
	  ClientSize = new System.Drawing.Size( screenwidth, screenheight );
  
			Text = gametitle;

  }
  // ********************************************************************


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // START: Method InitialiseGraphics
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  public void InitialiseGraphics()
  {
  
   var description = new SlimDX.DXGI.SwapChainDescription()
			{
				BufferCount = 2,
				Usage = SlimDX.DXGI.Usage.RenderTargetOutput,
				OutputHandle = this.Handle,
				IsWindowed = true,
				ModeDescription = new SlimDX.DXGI.ModeDescription(0, 0, new SlimDX.Rational(60, 1), SlimDX.DXGI.Format.R8G8B8A8_UNorm),
				SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0),
				Flags = SlimDX.DXGI.SwapChainFlags.AllowModeSwitch,
				SwapEffect = SlimDX.DXGI.SwapEffect.Discard
			};
  
   SlimDX.Direct3D11.Device.CreateWithSwapChain(
	SlimDX.Direct3D11.DriverType.Hardware,
	SlimDX.Direct3D11.DeviceCreationFlags.Debug,
	description,
	out graphics,
	out swapChain
   );
  
   // create a view of our render target, which is the backbuffer of the swap chain we just created
   using (var resource = SlimDX.Direct3D11.Resource.FromSwapChain<SlimDX.Direct3D11.Texture2D>(swapChain, 0))
				renderTarget = new SlimDX.Direct3D11.RenderTargetView(graphics, resource);
   // setting a viewport is required if you want to actually see anything
			context = graphics.ImmediateContext;
			var viewport = new SlimDX.Direct3D11.Viewport(0.0f, 0.0f, this.ClientSize.Width, this.ClientSize.Height);
			context.OutputMerger.SetTargets(renderTarget);
			context.Rasterizer.SetViewports(viewport);
   // load and compile the vertex shader  
			using (var bytecode = SlimDX.D3DCompiler.ShaderBytecode.CompileFromFile("E:\\MY_AREA\\SharpDevelop_Projects\\SlimDX_StartOver\\BasicWindow_1\\BasicWindow_1\	riangle.fx", "VShader", "vs_4_0", SlimDX.D3DCompiler.ShaderFlags.None, SlimDX.D3DCompiler.EffectFlags.None))
			{
				inputSignature = SlimDX.D3DCompiler.ShaderSignature.GetInputSignature(bytecode);
				vertexShader = new SlimDX.Direct3D11.VertexShader(graphics, bytecode);
			}
  
   // load and compile the pixel shader
			using (var bytecode = SlimDX.D3DCompiler.ShaderBytecode.CompileFromFile("E:\\MY_AREA\\SharpDevelop_Projects\\SlimDX_StartOver\\BasicWindow_1\\BasicWindow_1\	riangle.fx", "PShader", "ps_4_0", SlimDX.D3DCompiler.ShaderFlags.None, SlimDX.D3DCompiler.EffectFlags.None))
				pixelShader = new SlimDX.Direct3D11.PixelShader(graphics, bytecode);
  
  
   // -----------------------------------------------------------------------
  }
  // END: Method InitialiseGraphics


		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // ***************** InitializeSound START ****************************
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// Initialize the DirectSound subsystem
		public void InitialiseSound()
		{
			// set up a device
			sound = new SlimDX.DirectSound.DirectSound();

   sound.SetCooperativeLevel( this.Handle, SlimDX.DirectSound.CooperativeLevel.Normal );
		}
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // ********************************************************************
  // *************** InitializeInput START ******************************
  // ********************************************************************
		// Initialize the DirectInput subsystem
		public void InitialiseInput()
		{
			// set up the keyboard
   directInput = new SlimDX.DirectInput.DirectInput();
			keyboard = new SlimDX.DirectInput.Keyboard(directInput);
  
   keyboard.SetCooperativeLevel(
				this,
				SlimDX.DirectInput.CooperativeLevel.Background |
				SlimDX.DirectInput.CooperativeLevel.Nonexclusive );
			keyboard.Acquire();
			// set up the mouse
			mouse = new SlimDX.DirectInput.Mouse(directInput);
			mouse.SetCooperativeLevel(
				this,
				SlimDX.DirectInput.CooperativeLevel.Background |
				SlimDX.DirectInput.CooperativeLevel.Nonexclusive );
			mouse.Acquire();
		}
  // ********************************************************************

  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // Method InitialiseGeometry
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  public void InitialiseGeometry()
  {
   vertices.Write(new Vector3(0.0f, 0.5f, 0.5f));
   vertices.Write(new Vector3(0.5f, -0.5f, 0.5f));
   vertices.Write(new Vector3(-0.5f, -0.5f, 0.5f));
   vertices.Position = 0;  // Rewind the position after we're done.
			// create the vertex layout and buffer
			var elements = new[] { new SlimDX.Direct3D11.InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32_Float, 0) };
			var layout = new SlimDX.Direct3D11.InputLayout(graphics, inputSignature, elements);
  
   // Once we have our vertex data in memory, we need to load it into
   // a Direct3D vertex buffer, which can then be passed into the graphics pipeline.
   vertexBuffer = new SlimDX.Direct3D11.Buffer(
   graphics,
   vertices,
   12 * 3,
   SlimDX.Direct3D11.ResourceUsage.Default,
   SlimDX.Direct3D11.BindFlags.VertexBuffer,
   SlimDX.Direct3D11.CpuAccessFlags.None,
   SlimDX.Direct3D11.ResourceOptionFlags.None,
   0);
  
			// configure the Input Assembler portion of the pipeline with the vertex data
			context.InputAssembler.InputLayout = layout;
			context.InputAssembler.PrimitiveTopology = SlimDX.Direct3D11.PrimitiveTopology.TriangleList;
			context.InputAssembler.SetVertexBuffers(0, new SlimDX.Direct3D11.VertexBufferBinding(vertexBuffer, 12, 0));
			// set the shaders
			context.VertexShader.Set(vertexShader);
			context.PixelShader.Set(pixelShader);
  }
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // START: Method RenderFrame
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  public void RenderFrame()
  {
   // GT 01/06/12:
   // From what I can tell, the render frame method
  }
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // END: Method RenderFrame
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // ************** ProcessFrame START **********************************
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// Process one iteration of the game loop
		protected virtual void ProcessFrame()
		{
			// process the game only while it's not paused
			if( !paused )
			{

			}
			else
				System.Threading.Thread.Sleep( 1 );
		}
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // Render....
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		protected virtual void Render()
		{
			if( graphics != null )
			{
	context.ClearRenderTargetView(renderTarget, new SlimDX.Color4(0.5f, 0.5f, 1.0f));
  
	// draw the triangle
	context.Draw(3, 0);
	swapChain.Present(0, SlimDX.DXGI.PresentFlags.None);
  
			}
		}
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // ******************** Run START *************************************
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// Run the game
		public void Run()
		{
			while( this.Created )
			{
				// Process one frame of the game
				ProcessFrame();
				// Render the current scene
	// I.e. display graphics to the user in the game form.
				Render();
				// Handle all events
				Application.DoEvents();
			}
		}
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


		// ********************************************************************
  // **************** HANDLE WINDOWS EVENTS *****************************
  // ********************************************************************
		// Handle windows events
		protected override void OnLostFocus( EventArgs e )
		{
			base.OnLostFocus( e );
			Paused = true;
		}
		protected override void OnKeyDown( KeyEventArgs e )
		{
			base.OnKeyDown( e );
			if( e.KeyCode == System.Windows.Forms.Keys.Escape )
			{
				this.Close();
			}
			if ( e.KeyCode == System.Windows.Forms.Keys.P )
			{
				Paused = !Paused;
			}
		}
  // ********************************************************************
  // ********************************************************************
		// Property to pause/unpause the game, or get its pause state
		public bool Paused
		{
			get { return paused; }
			set
			{
				// pause the game
				if( value == true && paused == false )
				{
	 // TO DO
	 //
					//gametimer.Pause();
					paused = true;
				}
				// unpause the game
				if( value == false && paused == true )
				{
	 // TO DO
	 //
					//gametimer.Unpause();
					paused = false;
				}
			}
		}
  // ********************************************************************

  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  // START: MAIN
  [STAThread]
  private static void Main(string[] args)
  {
   Game game;
  
   try
   {
	game = new Game();
  
	// Initialise Gfx, Sound, Input, Geometry
				game.InitialiseGraphics();
				game.InitialiseSound();
				game.InitialiseInput();
  
	game.InitialiseGeometry();
	game.Show();
	game.Run();
   }
   catch( Exception e )
			{
				MessageBox.Show( "Error: " + e.Message );
			}
  }
  // END: MAIN
}
}

EDIT: I might have found something in the SlimDX tutorial. One of the parameters to the SlimDX.Direct3D11.Device.CreateWithSwapChain() method is for Feature Levels:

"The third parameter to the device creation function is an array of feature levels. Feature levels provide a unified method by which Direct3D 11 can run on lower end hardware. Each feature level mandates a specific set of functionality that an adapter must expose, enabling application developers to reliably scale their applications depending on the hardware a user might have. The array allows you to specify a set of feature levels that you’d like Direct3D to try to use. It will try them in order and create a device with the first one that works. You can use the Device.GetSupportedFeatureLevel method to get the highest feature level currently supported by the primary adapter. If you don’t care to specify a set and just want to use the highest available, you can skip the parameter and use the less generic overload. Once the device has been created, you can access the Device.FeatureLevel property to see which feature level is currently active. The 10Level9 reference on MSDN gives in-depth details about exactly which portions of the API are available on which feature levels."

I don't actually use this in my program, but perhaps this is the key to making my program compatible with the old D600?

EDIT: I think I've concluded something, although it's not good.

On my 9800GT rig the following works fine:

SlimDX.Direct3D11.FeatureLevel[] featureLevels = new SlimDX.Direct3D11.FeatureLevel[] { SlimDX.Direct3D11.FeatureLevel.Level_10_0 };
   SlimDX.Direct3D11.Device.CreateWithSwapChain(
    SlimDX.Direct3D11.DriverType.Hardware,
    SlimDX.Direct3D11.DeviceCreationFlags.Debug,
    featureLevels,
    description,
    out graphics,
    out swapChain
   );  

But when I use FeatureLevel.Level_10_1 or above, I get DXGI ERROR UNSUPPORTED, because this card doesn't support DX11.

I dropped down to FeatureLevel.Level_9_1 on the D600 laptop, but to no avail. Apparently the GPU supports DX8.1 and Shader 1.4, where as the requirements for Level_9_1 are shader model 2.

Oh dear. Still, it was interesting finding out.


#4944038 Game Engine

Posted by CdrTomalak on 28 May 2012 - 09:04 AM

Ah yes, thanks for the tip on terminology. I was equating a game-engine to a game-framework (i.e. like for a 2d platformer or shoot-em-up). That could definitely be confusing. Interesting post that.


#4942263 What I should know / learn to pursue a career in Programming?

Posted by CdrTomalak on 22 May 2012 - 11:21 AM

Hi GKANG - interesting post!

I've been in the I.T (Software) industry professionally for almost 13 years now so thought I'd share my thoughts with you.

It is true (I think) that having a grasp of maths is useful. I enjoyed maths as a kid, and studied pure maths at college (A-level) along with Computing. I went on to study Computing at university, and this worked well for me. When I graduated I started as a developer, and went on to work in a number of different roles. Having a mind which can grapple with maths, formulas, problem solving, is really useful in the programming discipline.

If it is definitely feasible for you to progress to university, I'd say studying computing is a good idea - or something similar. You'll be introduced into the principles of programming lanaguages, OOD, databases, architecture, the software engineering process etc. This will put you in good stead. There will probably be more technical purist degrees, such as computer architecture, which will focus on low-level programming - it really depends what you are looking to do. It might be worth picking up a prospectus for a university, and looking at course profiles. Then look at the prerequisites to that course, and decide to fulfill those prerequisites. Think about what type of developer you want to be - what kind of technical job you would want to be doing in 10 years time. It's worth a thought.

I find employers prefer degree eductated programmers, but that's not to say you MUST have one. You can get lighter qualifications and still get a developer job - in which case studying in your own time will really help during an interview. Employers love to see enthusiasm, as I'm sure you know. Good luck with your current application by the way! 8D

It's hard to understand what your current qualifications are, but as you've been into music production you are probably technically minded. I find programming very similar to maths, in that the priciples of elegance and structure apply. They also apply to music.

I picked up the points in replies saying that modern languages like C# and Java do a lot for you, and they're right. For example, if you want to search through an array for a particular item, whereas years ago you'd knock up your own algorithm and function for this, now you don't have to. However, as has been alluded to, there can be a certain discomfort when you don't really know what the function is doing (binary searches for example) to achieve the result. Laying foundations of knowledge, such as learning about how programming languages evolved to their current point, and learning about algorithm design - will both help you familiarise yourself with the world of programming.

It's worth thinking carefully about your learning strategy - the sequence of events, and not trying to take huge steps at once - but rather gradual ones. I tip my hat to you taking on C++, as this is something I could not face - mind you, I studied C and Java at university, and chose to learn c# due the syntax similarity with Java plus the OO aspect. C++ is a more difficult language to master I think. If you're a total beginner it might be worth starting with C, mastering that, then stepping up to C++.

Anyway, hopefully something I've rambled on about might be useful to you. Feel free to give me a shout about anything - although there are countless people on here with better coding skills and in depth knowledge than I.


PARTNERS