Sign in to follow this  
23yrold3yrold

[.net] C#, DirectX, XNA, and refusing to redraw

Recommended Posts

This is a semi-repeat of an old thread of mine which I ended with "Gonna have to find a way to deal with that ..." well, I couldn't figure it out so I'm back for round 2. This tilemap utility would actually be nice to have running right now, even with minimal functionality, so I'm determined to give it another run here. Okay, so my window redraws a beat behind all the time. I'm just clearing it to CornflowerBlue right now. If I open a menu, it leaves a giant artifact when it closes. Still there when I open a new menu, and won't refresh until that one closes. I can try to Refresh or Invalidate all day to MouseMove, ReSize, etc., but I can't update on every friggin' event, and I really shouldn't have to. The funny thing is, I've been using DirectX to try to speed up my drawing, and now I'm trying to use XNA in case it fixes my problem (it doesn't) and if I clear the device context to black with either, it still leaves the artifact, but it's the color I'm clearing to in e.Graphics.Clear(), which tells me the update is happening, but I'm screwing up my DirectX/XNA. In DirectX I'm doing this for initialization:
                pps = new PresentParameters(Program.maindevicecontext.PresentationParameters);
                pps.BackBufferCount = 1;
                pps.DeviceWindow = drawingwindow;
                pps.DeviceWindowHandle = drawingwindow.Handle;
                pps.BackBufferWidth = drawingwindow.Width;
                pps.BackBufferHeight = drawingwindow.Height;
                m_mainwindowswap = new SwapChain(Program.maindevicecontext, pps);
                pps = new PresentParameters(Program.maindevicecontext.PresentationParameters);
                pps.BackBufferCount = 1;
                pps.DeviceWindow = currenttiles;
                pps.DeviceWindowHandle = currenttiles.Handle;
                pps.BackBufferWidth  = currenttiles.Width;
                pps.BackBufferHeight = currenttiles.Height;
                m_currtilesswap = new SwapChain(Program.maindevicecontext, pps);

In XNA I'm doing this (haven't bothered with swap chains in XNA yet). I'm setting the SwapEffect to Discard in both cases ...
            PresentationParameters pp = new PresentationParameters();
            pp.BackBufferCount = 1;
            pp.BackBufferFormat = SurfaceFormat.Unknown;
            pp.BackBufferHeight = 600;
            pp.BackBufferWidth = 800;
            pp.DeviceWindowHandle = drawingwindow.Handle;
            pp.IsFullScreen = false;
            pp.SwapEffect = Microsoft.Xna.Framework.Graphics.SwapEffect.Discard;
            device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, Microsoft.Xna.Framework.Graphics.DeviceType.Hardware,
            drawingwindow.Handle, pp);

Doing this in both cases:
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);

Here's how I'm repainting the screen in both cases:
            Surface surf = m_mainwindowswap.GetBackBuffer(0, BackBufferType.Mono);
            surf.Device.SetRenderTarget(0, surf);

            // start drawing
            surf.Device.BeginScene();
            surf.Device.Clear(ClearFlags.Target, System.Drawing.Color.Black, 1.0f, 0);
            surf.Device.EndScene();
            m_mainwindowswap.Present();

            device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);
            device.Present();

Anything else anyone can think of why it wouldn't refresh properly? Am I initializing incorrectly, am I drawing the scene incorrectly, is there something I should be checking for? I can make XNA work in a game engine, but I just can't make it or DirectX play nice in a WinForm ...

Share this post


Link to post
Share on other sites
I guess that was informative, but ultimately unhelpful. What I'm doing it's doing, and what it's doing that I wasn't had zero overall effect on my program when I tried it. So no difference in the end. [sad]

I'm going to keep on this, and I'll post back if I make any headway. But being this frustrated is depressing, and I don't feel like being depressed for Christmas. If anyone else can think of why it wouldn't be updating properly let me know please.

EDIT: BTW, I've tried making the drawing area a regular PictureBox drawn with outside functions, and I've tried making it a derived control with all the drawing in OnPaint; no change either way. And passing the control's invalidate function to Application.Idle as a delegate just makes the control lock onto the background gray color with no XNA or DirectX drawing at all.

EDIT2: graphicsDevice.GraphicsDeviceStatus is always GraphicsDeviceStatus.Normal, btw. Never Lost or NotReset.

[Edited by - 23yrold3yrold on December 23, 2009 11:15:50 PM]

Share this post


Link to post
Share on other sites
Is the problem that your redraw function isn't called, or that the area occupied by the menu is just clipped from redrawing?
It looks as though your draw function isn't called. You could easily check this by adding some animation to your drawing, and see if it stops while using the menu.
Even then, menus are usually handled in a way so that no such artifacts occur. How do you create the menu, is it a control?
Perhaps it's just not compatible with DirectX surfaces. Perhaps they are drawn as overlays or something, and aren't actually redrawn after being clipped. Sounds strange, but hard to say what it could be otherwise, unless the implementation of the menu relies on sending repaint events to the window below it that you don't handle.

Share this post


Link to post
Share on other sites
Do you think you could upload the project so we could check it out using the exact same code you are using? That way, we aren't just throwing blind guesses around, and can determine if it is a problem isolated on your machine or not.

Share this post


Link to post
Share on other sites
I'm pretty sure the drawing function is being called, or else it would be drawing nothing as opposed to drawing everything a beat behind. Anyway, I trimmed the code down to a bare minimum so it's uber-short; if anyone wants to try it out, I appreciate it. This is all XNA at this point, my DirectX system has been removed completely. Guess I need to figure out how XNA does swap chains now too.

Share this post


Link to post
Share on other sites
Works just fine for me. When I move the cursor, the screen flashes, but that is gone when the OnMouseDown code is removed. The menu leaves no artifacts, though.

Have you tried XNA 3.1? Other than that, only thing I can think of is I have the latest .NET, XNA, and Windows 7 x64.

Edit: Also, make sure you build for x86 explicitly, not "Any CPU", otherwise it wont work on x64 machines since XNA has no 64-bit support.

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