[.net] Framebuffer-like graphics in C#?

Started by
2 comments, last by RenZimE 18 years ago
I want to do some lowlevel drawing, demoscene mid-90's style. Is there any way to get an area that's drawable at pixel level, so I can go: buffer[100] = 0x223311; // set pixel at {100, 0} to color 0x223311 flip(buffer); If this could be done on a Forms control, well that would be peachy! :D
Advertisement
You can use a Bitmap to do this.
For example, define Bitmap BackBuffer; in your form somewhere, and in the load BackBuffer = new Bitmap(640, 480);
Then set it as the background of the form, using Form.BackgroundImage = BackBuffer;
To draw to it, you can use BackBuffer.SetPixel(); - which is extremely slow. The fastest way is to use an unsafe block of code that locks the surface and writes to it, like this:
// Nota bene: reading a bitmap's width/height is extremely slow.// I'll read it only once into the following variables.int Width = BackBuffer.Width;int Height = BackBuffer.Height;BitmapData Locked =     BackBuffer.LockBits(        new Rectangle(0, 0, Width, Height),        ImageLockMode.Write, PixelFormat.Format32bppRgb);Random R = new Random(); // Let's draw random pixels.unsafe {    // Get an int pointer to the start of the bitmap:    int* p = (int*)Locked.Scan0.ToPointer();    // Write away to your heart's content...    for (int y = 0; y < Height; ++y) {        for (int x = 0; x < Width; ++x) {              *p++ = R.Next(0xFFFFFF);        }    }}BackBuffer.UnlockBits(Locked);Form.Refresh();

Setting your form's DoubleBuffered property to true is also useful.
Disclaimer: Above code was written off the top of my head sans compiler. It should work, though.

[Website] [+++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++]

Wow, that's a really nice and thorough explanation. Thanks dude!
or you can do it with out an unsafe block, which is possibly just as slow with all the copying.

// Nota bene: reading a bitmap's width/height is extremely slow.// I'll read it only once into the following variables.        int Width = BackBuffer.Width;        int Height = BackBuffer.Height;        BitmapData Locked =            BackBuffer.LockBits(                new Rectangle(0, 0, Width, Height),                ImageLockMode.Write, PixelFormat.Format32bppRgb);        Random R = new Random(); // Let's draw random pixels.        // -- Changed from original post        int[] buffer = new int[Width * Height];        Marshal.Copy(Locked.Scan0, buffer, 0, buffer.Length);        for (int y = 0; y < Height; y++)        {            for (int x = 0; x < Width; x++)            {                buffer[y * x] = R.Next(0xFFFFFF);            }        }        Marshal.Copy(buffer, 0, Locked.Scan0, buffer.Length);        // -- End Changed        BackBuffer.UnlockBits(Locked);        Form.Refresh();


This topic is closed to new replies.

Advertisement