Tom Miller's Blog

The Ramblings of Miller. These postings are provided "AS IS" with no warranties, and confer no rights.

My last post on render loops (hopefully)..

My last post on render loops (hopefully)..

  • Comments 29

The most common topic on my blog returns again.  This time it will be brief as all I'm going to to do now is show you the render loop the June'05 SDK will be using.  A coworker in another group came up with this markedly simple, yet deceptively effective loop for that groups projects.  I liked it so much, i'm sharing it with everyone else. =)

The basic loop (slightly modified from his original version and the version in the new SDK for ease of reading):

public void MainLoop()
{
        // Hook the application's idle event
        System.Windows.Forms.Application.Idle += new EventHandler(OnApplicationIdle);
        System.Windows.Forms.Application.Run(myForm);
}

private void OnApplicationIdle(object sender, EventArgs e)
{
    while (AppStillIdle)
    {
         // Render a frame during idle time (no messages are waiting)
         UpdateEnvironment();
         Render3DEnvironment();
    }
}

private bool AppStillIdle
{
     get
    {
        NativeMethods.Message msg;
        return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
     }
}

And the declarations for those two native methods members:

[StructLayout(LayoutKind.Sequential)]
public struct Message
{
    public IntPtr hWnd;
    public WindowMessage msg;
    public IntPtr wParam;
    public IntPtr lParam;
    public uint time;
    public System.Drawing.Point p;
}

[System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously
[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);

------

Simple, elegant, effective.  No extra allocations, no extra collections, it just works..  The Idle event fires when there's no messages in the queue, and then the handler keeps looping continuously until a message does appear, in which case it stops..  Once all the messages are handled, the idle event is fired again, and the process starts over.

  • The PeekMessage loop has been in use for ages by game programmers who code in unmanaged DirectX and even OpenGL. What surprises me is that it took such a long before someone was able to figure it out for managed dx!
  • I put the using directive System.Runtime.InteropServices and that solved all of the errors except for one that says:

    The type or namespace name 'WindowMessage' could not be found (are you missing a using directive or an assembly reference?)

    I've looked in the MSDN and all over the web, and I cannot find the namespace it is in. Thank you for your help.
  • I can only guess this works - since I cannot get it to run. Reason for this being that I - as an average programmer - simply have no idea what namespaces / references to include.

    What type is WindowMessage? IntPtr? (I tried looking for WindowMessage in MSDN to no avail).

    System.Drawing.NativeMethods seems to be an internal class. Consequently I get compilation errors when trying to compile the code. What am I missing?

    Might be I am the only one that plays around with MDX without a complete understanding and knowledge of the .net framework, at least to my very limited mind a complete code sample would be extremely helpful.

    Don't get me wrong, I am not critizing here. It's just that I have very limited ressources (both time and brain ;) )
  • I have made a sample framework app using the loop you have suggested here. It does work better than the original SDK loop. It is located <a href="http://photongl.blogspot.com">here</a>.
  • I'm wondering how much of a performance difference will be if I take out the AppStillIdle while loop and just call the update and render methods within OnApplicationIdle.

    Tom, do you have any figures on this?
  • That looks great. I am new to DirectX, but I remember back when doing OpenGL that the main render loop was the most difficult part- especially trying to balance always redrawing without overworking the CPU.

    Could you provide the source for the C# version of the WindowMessage struct as well? I am having difficulty getting this to compile since I assume that structure is defined else where in your code. (Is it defined somewhere in the managed source for the April MDX SDK update?)

    Thanks,
    -Chris
  • Simply put: Yuck. That's not simple nor elegant. :/
  • Hrm. The Message struct is already defined by the .NET libraries as:

    System.Windows.Forms.Message
  • I have checked in a new initial version of the Client UI which is based on the OnApplicationIdle style...
  • PingBack from http://www.stynet.co.uk/blog/archives/31
  • PingBack from http://www.zaknafein.hjcrusaders.com/?p=15

  • PingBack from http://www.zaknafein.hjcrusaders.com/?p=14

  • PingBack from http://paidsurveyshub.info/story.php?title=tom-miller-s-blog-my-last-post-on-render-loops-hopefully

  • PingBack from http://insomniacuresite.info/story.php?id=8983

Page 2 of 2 (29 items) 12