Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

CdrTomalak

Member Since 12 Mar 2012
Offline Last Active Yesterday, 03:21 PM
-----

Topics I've Started

Controlling game loop speed

04 May 2013 - 10:09 AM

My pacman clone is progressing, and I am now at the point where I need to slow down the game loop.

 

However, there are points where I switch textures which causes a subtle slow-down (I think - it's hard to tell), so my thoughts turn to regulating the game loop speed - i.e. I don't want to see any slowdown whatsoever.

 

Rather than putting a wait command in the loop, what other techniques are there? I'm sure there are loads out there, so please feel free to point in the way of your favourite article. I'm basically doing research at the moment before going ahead with anything.

 

Essentially I want to choose a game speed which means there will always be room for a little extra processing overhead, and the user will not notice a thing. It's running too fast at the moment! On average about 350 FPS.

 

Thanks in advance! cool.png


Tacking performance degradation

21 April 2013 - 03:10 PM

Hi,

 

I'm at a stage where my 2D game engine (starting with pacman) is fairly stable. What I've not done though is looked into performance.

 

By running the profiler, I have optimised my render method quite well, but I still get a degradation in performance after say 30 seconds of game-play.

 

My first question is, will the profiler pick up things like degradation, or does it take an average of the ticks per function? I am using SharpDevelop by the way.

 

The second question is, what is the recommended strategy for tackling performance problems? My current understanding is that due to garbage collection, I don't need to worry about unreferenced objects too much. But is it not the case that even the garbage collector might not be able to keep up if one is too inefficient?

 

I could opt for a full code-review, function by function, to ensure that things are running efficiently. For example, I have not taken care to dispose of objects when they are clearly not of use. Presumably this will help? I have been concentrating on core functionality actually working up to this point, and game logic - but the time has come to make this thing run as slick and efficiently as possible.

 

Any comments are most welcome. It would just be interesting to hear how people go about such things if they notice a degradation in performance in a language that has garbage collection.

 

Thanks in advance! biggrin.png


Sudden E_FAIL graphics initialisation error...

01 March 2013 - 04:36 AM

Although this might sound implausible, this morning when compiling my game I got a run-time error: E_FAIL: An undetermined error ocurred (-2147467259).

 

The sequence of code is:

 

			// DirectX DXGI 1.1 factory
			factory1 = new SlimDX.DXGI.Factory1();
			
			// The 1st graphics adapter
			adapter1 = factory1.GetAdapter1(0);

			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.FeatureLevel[] featureLevels = new SlimDX.Direct3D11.FeatureLevel[] { SlimDX.Direct3D11.FeatureLevel.Level_10_1 };
			
			if(debug){MessageBox.Show( "InitialiseGraphics()...2");}
	
			SlimDX.Direct3D11.Device.CreateWithSwapChain(
				adapter1, 
				SlimDX.Direct3D11.DeviceCreationFlags.Debug, 
				featureLevels,
				description, 
				out graphics, 
				out swapChain
			);	

The swapChain creation code is failing, whereas yesterday is was fine. Nothing has been changed here at all, so I'm completely stumped. I've tried changing the feature level back down to 9_1 but this doesn't work. I'm baffled. Any ideas?sad.png


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

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


Problem coding own SpriteBatchRenderer class

18 February 2013 - 12:37 PM

Hi,

 

As an exercise I have put togther a really basic SpriteBatchRenderer class, but what I've found is that far from improving performance when rendering, I have actually gone backwards. Oh no!

 

I am basing it on the following principles:

 

Constructor(Direct3D11.Device graphicsIn, Direct3D11.DeviceContext contextIn):

- Create empty indices and vertices data streams

- Create Index Buffer

- Set standard texture positions (I'm drawing simple textures for now on all sprites)

- Create Vertex Buffer

- Create otho matrix

- Create an array of textures for each sprite

 

Begin()

- Rewind data stream positions to 0

 

Add(vector3[] positionIn, string texturePath)

- Transform vectors passed in

- Write vectors to vertices data stream

- Write indices array to indices data stream

- Store texture for this sprite

- noOfSprites++;

 

End()

- Rewind data stream positions to 0

 

Draw()

- Set index buffer binding

- Set vertex buffer binding

- Draw each sprite in sprite array using corresponding texture in texture array

 

ResetSpriteCount()

- noOfSprites = 0;

 

Dispose()

- Does nothing at present

 

When I use this class, calling Begin(), a series of Add() calls, then End(), Draw(), and then ResetSpriteCount(), nothing appears at all. I've debugged this to see if even one frame is drawn, and it is not.

 

As an experiement I created another version of the SpriteBatchRenderer() class, which doesn't create the index or vertex buffers in the Constructor. Instead it creates them, and sets the bindings, in the End() method. This WORKS, but is apallingly slow, as each frame new vertex buffers are created - which I think is what is slowing things down.

 

What I am trying to do is just create the index and vertex data streams ONCE, and the same for the index and vertex buffers, as I thought that it is the declaration of these structures that causes a performance hit. I want to work with the same vertex buffer for the entire lifetime of the game.

 

Clearly I'm doing something very wrong indeed.


PARTNERS