[.net] Framebuffer-like graphics in C#?
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
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:
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.
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.
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
Popular Topics
Advertisement