问题
I'm working on a school project right now. It's meant to be a 3D editing software, (like a very minimized version of Maya). I have to write it in C#, using the 'Windows Application Project'. I intend to implement all the 3D stuff myself, from projections to shading. My question is, how can I get direct access to a single pixel in the C# windows application? I know I'm going to have a main view port in the window. But I haven't decided yet how it will be made. Is there a built in object that I can use, that will let me define the boundaries of the view port, and then paint each pixel individually? (I'm just shooting in the dark here, I don't know much about C#. I mostly program in C)
Thanks, Malki.
回答1:
Using the CreateGraphics() method, this should work:
Bitmap b = new Bitmap(Width, Height, this.CreateGraphics());
//pixel is:
Color c = b.GetPixel(x, y);
To set a pixel to a specific colour, use this instead of Color c = b.GetPixel(x,y)
:
b.SetPixel(x, y, c); // where c is a Color
If you want a viewport, place a panel or a PictureBox (maybe with Dock: Fill), then use:
Bitmap b = new Bitmap(viewport.Width, viewport.Height, viewport.CreateGraphics());
instead of the first line used previously.
But from what you want to do, I think it would be better to use the OnPaint event:
void pnlViewport_Paint(object sender, PaintEventArgs e) {
if ( e.ClipRectange.Width < 1 || e.ClipRectangle.Height < 1 ) return;
Bitmap b = new Bitmap(e.ClipRectangle.Width, e.ClipRectangle.Height, e.Graphics);
// ...
}
This event fires every time the control needs painted. The first line checks whether the area being drawn is empty - this will not just save CPU time, but your application may crash - you are getting it to make a 0x0 bitmap.
EDIT: Yes, this is resizable, if Dock = DockStyle.Fill; As your window resizes, the control expands to fill the space. It is then repainted - firing the event.
EDIT 2: As pointed out by others, this is still slow. It does sound like it is a requirement to do the 3D drawing yourself, so maybe SDL.NET (which I think can use hardware acceleration) is the way to go. It even has a (slow) SurfaceControl to use.
回答2:
Christian Graus has several good graphic-manipulation articles on www.CodeProject.com. They should answer your questions.
回答3:
A 3D editor application needs not only to draw on the screen - it needs to do it damn fast. The standard approach in .NET would be using Bitmap and Graphics classes, like described by person-b. But this will be slow. You can improve speed by using Bitmap.LockBits() and clever optimizations, but all in all I doubt you will still get the performance you need. You'll eat away all the CPU and will still be stuck with less than some 10-20 FPS (number is a wild guess). Hardware acceleration is the real way to go. shuggycouk has links in the right direction.
Unfortunately the hardware approach will also take away the projections and shading, because that's what the hardware is there for. So I don't know if you can use that... Perhaps seek information on "overlays" in .NET. That's the way all the media player software display movies. It's definately way faster than standard GDI/GDI+ and is still 2D. Or perhaps you could do a tricky workaround with DirectX - use it for drawing 2D shapes you define yourself. ;)
回答4:
If you are doing 3d it would make sense to make use of the hardware acceleration provided by almost every GPU under the sun these days. IF you are happy to stay with windows specific apis then DirectX's 3D API's are exposed via managed wrappers now. Also there is the XNA toolset designed primarily with games in mind but it provides a wealth of examples of how to do Direct-X 3D accelerated drawing from c#.
回答5:
If you have a need for pixel speed, high-speed-graphing-control-for-net-or-mfc, may provide some tips.
来源:https://stackoverflow.com/questions/476255/access-to-a-single-pixel-in-c-sharp