DirectDraw(C#) Fullscreen Clipping Problems

Started by
4 comments, last by Krisc 19 years, 1 month ago
I have tried time and time again to get fullscreen clipping to work but each time I have been bet with "InvalidRectangleException". It is starting to piss me off. http://www.gamedev.net/community/forums/topic.asp?topic_id=288300&whichpage=1? That idea has not worked. My code : Click here! Also when I hit Alt-F4 the program returns an error of surface lost...grr, don't know how to take care of that either. Any ideas? Thanks! [Edited by - Krisc on February 15, 2005 6:42:08 AM]
Advertisement
Anyone?
These look to be the offending lines:

Rectangle[] ScreenClip = new Rectangle[1];ScreenClip[0]=new Rectangle(-100,-100,1124,868);//m_clipper.Window = this;m_clipper.ClipList = ScreenClip;m_front.Clipper = m_clipper;


First off, your clip region rectangle size is borked. The purpose of clipping is to keep things in the window's client area. -100,-100 won't help you do that. Secondly, there's no need to use clip regions unless you want to clip to one or more subrectangles of the client area, and not the entire window at once. Third, you are attaching the clipper to the primary surface, but have page flipping enabled and aren't attaching to the back buffer. Page flipping means that each time you call Present, the front and back surfaces effectively swap places (back becomes front and vice versa).

To clip to the entire window, you should be able to do something like this (note that I'm taking what I know of the C++ version of DDraw and translating that to C# - should be the same):

// associate the window with the clipper. This will set the clipRect automatically - when the window is resized the clipper will adjust to its new boundsm_clipper.Window = this;// attach the clipper to the surfaces you want to clipm_front.Clipper = m_clipper;m_back.Clipper = m_clipper;


That should do it.
Awesome, that did it. I guess my original problem was that I was using DrawFast. Anyone know why I am getting this error when I hit Alt-F4?

"An unhandled exception of type 'Microsoft.DirectX.DirectDraw.SurfaceLostException' occurred in microsoft.directx.directdraw.dll

Additional information: Error in the application."

I think it is because the loop is still running despite the application having been quit but I am not sure how to solve this.
Sometimes it is possible that you will call blit on a surface after the internal representation of that surface has been destroyed. Technically this can happen at any time, but often happens when alt-tabbing between windows or sometimes, as in your case, when closing the window. The solution is to wrap your blitting code in a try..catch block and handle the exception appropriately. If the window is closing, you can just ignore the caught exception and let everything shutdown (but this shouldn't be happening - see below). Otherwise, you will need to recreate the lost surface and any other hardware surfaces that have been lost (surfaces in system memory won't have this problem). If you have lost a surface you are using for a sprite, you will need to reload it the sprite image.

Realistically, you should not be attempting to do any blitting if the window is closing. But because of the asynhronous event mechanism of Windows Forms, you really don't have a choice. What I suggest is that you create an event delegate to handle Closing events, add a boolean member to the form called 'isclosing' or 'bclosing' or whatever, initialize it to false, and set it to true in your event handler. Then, in your main loop (adapted from the code you posted earlier):

public void Run(){   x = y = 200;   while(brun)   {        try        {	   m_back.ColorFill(0);           m_back.Draw(new Rectangle(new Point(x, y), new Size(200,200)), m_surf, DrawFlags.DoNotWait);                      // Don't do this. This is what you do in windowed mode.           // m_front.Draw(m_back, DrawFlags.DoNotWait);                      // Since you are in full screen mode with page flipping enabled, do this           m_front.Flip();        }        catch(SurfaceLostException)        {           // if the surface was lost because the window was closing, then bclosing will be true - restore surfaces if it is false because the app is still running           if(!bclosing)           {              m_device.RestoreAllSurfaces();              // reload any image data you need              reloadImages();           }        }        catch(GraphicsException ge)        {           // Some other exception was thrown - handle it        }}


Again, this is all from what I know of the C++ version. I've never used Mangaged DX with C#, but the concepts still apply. I suggest you hit Google and look for any DirectX resources you can find (specifically DX 7). Even if any samples you find are in C or C++, you can still translate it to C# as the functionality is still there, just in a different guise. Always catch Exceptions, and always keep in mind that window events are asynchronous.
Thank you much for your help! I have wrapped all the DirectDraw stuff into a class now that is handling exceptions like no other! ;) On a more serious note, in my drawing class restoring the surfaces is simple. What should I do about surfaces outside the class? Not worry about them? Note: I am writing this class to be 100% modular; does this mean I should only worry about the front and back surfaces? Also, I have the class written so I can alt-tab without any problems out of the application but when I give focus back to the application it does not recreate surfaces. It is just giving a form coloured background at the resolution previously defined when the device was created. If you want to see the class: Click Here... Another problem I just noticed was that when Alt-F4 is hit the application does not exit out completely. The form never gets disposed or anything...

Again, thanks for all the help! I appreciate it!

[Edited by - Krisc on February 16, 2005 4:58:14 AM]

This topic is closed to new replies.

Advertisement