Jump to content
xisto Community
Sign in to follow this  
bob3695

How To: Render Loop C#

Recommended Posts

The Source code for this tutorial is here http://www.alcedosoftware.com/users/sign_in

Introduction

This tutorial will explain how to create a Tick based Render Loop in C#.

All Source Code and Multimedia.dll is included in the .zip package at the top of the tutorial.

Everything about timers
One issue with this type of loop is that fact that the speed in which the computer can accomplish the tasks in the render loop varies from computer to computer. It even varies on the same computer according to how much memory and CPU time is available for the game at any given moment. We need to have some way of accounting for these differences to make sure that we animate consistently. So instead of treating each frame the same, we are going to calculate the time elapsed between frames and apply that value to our calculations.
There are a couple of different ways of keeping track of time in Windows:
1. System.Windows.Forms.Timer: This is the most common timer used in Windows programming. While it is easy to use, it only has a resolution of 1/18th of a second. Since we could have up to a thousand frames per second this resolution is not good enough for a game program.
2. timeGetTime: This Windows DLL provides a resolution of 1 microsecond on some versions of Windows and 5 microseconds on Windows NT. This is too variable, and we really donât want to check the operating system our game is running on to see if we need to adjust the timer values.
3. System.TickCount: This managed call returns the number of ticks that indicate the number of milliseconds. This is close to what we want, but we can do better.
4. QueryPerformanceCounter: This is the preferred timer to use; it has a resolution of less than 1 microsecond. This is the timer most often used in game development.

Multimedia.dll is a High Resolution Timer Based on The QueryPerformanceCounter that comes with Windows. We will be using it as it is more accurate and reliable than the System.Windows.Forms Timer.

The Code

To use the Multimedia Timer to do is:

1: Create a Timer Object

private Multimedia.Timer PaceTimer;

2: Create a Callback Method for it

private void Timer_Tick(object state){	//put any physics, AI and game play code here            //Clean Up      GC.Collect(); 	//render loop rerender every 10ms	this.Invalidate();}

3: In The Class Constructor Initialize the PaceTimer

PaceTimer = new Multimedia.Timer(new Multimedia.TimerCallback(Timer_Tick),null,Peroid,1);

4: Start the timer in any method you want but if you are drawing graphics putting the Start code in the Constructor does not work well so my advice is to put it in the Load Event of the Form

PaceTimer.Start();

That is the Loop Started but now we want to actually render something

Double Buffering and Drawing

All Drawing should be done in the OnPaint method, and to stop flickering we will use 2 methods

1: Add this line of code to the constructor of the class

this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

This line says that all Painting will happen in the OnPaint() function, and that the screen is Opaque, the true bit just says that we want to enable these settings now.

The Second one is Double Buffering.

protected override void OnPaint(PaintEventArgs e){	e.Graphics.DrawLine(new Pen(Color.Red),50,50,100,100);}

Drawing like this just using the Graphics object from e object draws straight to the screen which causes flickering

If we implement Double Buffering it should stop the screen from flickering.

Double Buffering is drawing what we want to draw to an in memory Bitmap, and then drawing the Bitmap to the screen.

To implement Double Buffering we must create a Bitmap, Create a graphics object from the Bitmap, Draw everything to the Bitmap using the Graphics object we just created then drawing the Bitmap to the screen using the graphics object in e. below is an example.


protected override void OnPaint(PaintEventArgs e){	// It will be double buffered to stop flickering	//Create Temporary Canvas	System.Drawing.Bitmap timage = new Bitmap(800,600);	//Create our Graphics Objects	System.Drawing.Graphics g = Graphics.FromImage(timage);	//Draw anything to the bitmap eg.	g.FillRectangle(new SolidBrush(Color.LightBlue),0,0,800,600);	e.Graphics.DrawImageUnscaled(timage,0,0,800,600);	g.Dispose();            GC.Collect(); }  

We have used DrawImageUnscaled() because it is more efficient and give use better performance than DrawImage() does.

The Sample Application show a Frame Counter which counts the number of times the screen has been rendered, also 2 Boxes that move towards each other, and pass just to show some simple animation.


Written By Lloyd Sparkes. Part of the CyberWarfare Dev Team.
Edited by infamousflame (see edit history)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.