Jump to content
  • Advertisement
Sign in to follow this  
Drakkcon

Using surfaces, trying to copy data directly to the screen. Managed, C#.

This topic is 4414 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is my first big project using C#, so I'm a n00b. Basically, I'm trying to make a raycaster using C# and managed DirectX. I'm used to C++, but I'm really enjoying the C# language. Now, I'm not quite used to not using pointers. I think I'm doing something wrong here:
while (caster.Created) //Caster is an instance of the program, which inherits from Form
            {

                caster.device.Clear(ClearFlags.Target, Color.Black, 1, 0);

                int pitch =  SCREEN_RESOLUTION_WIDTH * 4;

                int bufSize = pitch * caster.Height;
                byte[] buf = new byte[bufSize];

                unsafe
                {
                    GraphicsStream screenData = new GraphicsStream(null, pitch * SCREEN_RESOLUTION_HEIGHT, true, true);
                

                screenData = screen.LockRectangle(LockFlags.None);

                for (int i = 0; i < bufSize; i++)
                {
                    buf = 128;
                }

                screenData.Write(buf, 0, bufSize);


                }

                screen.UnlockRectangle();
                

                caster.device.Present();

                Application.DoEvents();
            }

I'm not really sure why I have to use a GraphicsStream. If they're going to go unsafe, why not just return a void pointer to the screen data, that I can cast into an unsigned char*? Anyway, all I'm getting is a black screen. I should be getting a grey screen, because each pixel is getting the value a=128, r=128, b=128, g=128. I think the problem has to do with using a "null" field in the constructor of GraphicsStream, but I'm not sure what to put there. I have thoroughly searched the documentation and cannot find anything to help.

Share this post


Link to post
Share on other sites
Advertisement
(I'm assuming this is MDX 1.1 and not XNA)

1) There is no need to create the GraphicsStream object, the Lock operation will return a new one for you.

2) I have no idea why you are using unsafe code. I have a ton of GraphicsStreams in Doom.Net and not one peice of unsafe code.

3) Where do you actually display the surface?

Share this post


Link to post
Share on other sites
I discovered:
-That the time I got a runtime error was not due to an uninitialized GraphicsStream. [grin]
-That no unsafe tag is needed.

As for number 3, I thought that device.Present() would automatically flip and display the render target, which screen is. What do I do instead?

Share this post


Link to post
Share on other sites
Is the surface named screen your backbuffer? If so, you need to make your backbuffer lockable, by specifying the correct flag in the PresentationParameters.

Hope this helps.

Share this post


Link to post
Share on other sites
Thanks! So, I change my PresentParameters to look like this:


PresentParameters pres = new PresentParameters();
pres.SwapEffect = SwapEffect.Discard;
pres.Windowed = true;
pres.BackBufferCount = 1;
pres.PresentFlag = PresentFlag.LockableBackBuffer;

device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, pres);

this.Size = new System.Drawing.Size
(SCREEN_RESOLUTION_WIDTH, SCREEN_RESOLUTION_HEIGHT);


But the screen is still totally black. Does anyone have a quick link to using DirectX 9 surfaces to display stuff?

Share this post


Link to post
Share on other sites
Okay. I just looked at screenData in the debugger, and it says that "CanWrite" is false for some reason.

So why on earth does Surface.LockRectangle return a non writeable GraphicsStream?

It can't be read either, so it seems totally wortheless.

Am I missing a flag somewhere?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hmm. I haven't used MDX for a while, so I'm not sure. However, I would recommend getting rid of MDX in favor of XNA: it's more modern, it's immensely simplified, and there are no GraphicsStream objects at all, so a problem like this wouldn't occur.

However, I'd say you probably are missing a flag somewhere. I'm not sure where though.

Share this post


Link to post
Share on other sites
Where is your screen object coming from? I'm not 100% sure, but I think you need to fetch your backbuffer from the device each frame with all the flipping & discarding going on behind the scenes. Something like this should work for that:


// using releases the surface when you're done with it
using(Surface screen = caster.device.GetBackBuffer(0, 0, BackBufferType.Mono))
{
GraphicsStream screenData = screen.LockRectangle(LockFlags.None);

// do stuff here

screen.UnlockRectangle();
}


I tried to whip up a small demo, but I ran into a few problems locking the backbuffer. The main one is that when I use the width and height provided in the surface description to loop over the pixels, it doesn't fill a number of rows at the bottom. Might just be my code, but I wouldn't know what's wrong with it.

An alternative might be to set up a plain texture to use for your application, so you don't have to worry about the specifics tied to working with the backbuffer. If you need to render to this texture, you can use the RenderToSurface helper class and device.GetRenderTargetData to copy stuff off this render target. If you need to render the texture itself to the screen, the Sprite helper class might be of use.

Hope this helps :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!