pixels in c(++)

Started by
7 comments, last by [disabled] 20 years ago
I recently finished (successfully) a 3D screen saver I wrote in Visual Basic (yes, 3D in VB, it''s possible). I used the Polygon API call to draw my polygons for me. However, this API function is very restrictive. It''s only of use for flat-shaded polygons. I want to further develop my 3D programming skills. To do that I want to write both a more advanced shading algorithm (I''m thinking Gourad or perhaps Phong) and a texture mapping routine. Gourad and texture mapping are easy to implement save for one little detail: you need to access individual pixels. Although the Windows GDI provides the SetPixel and GetPixel calls for manipulating pixels in a bitmap object, I''ve found they''re very slow which isn''t that surprising since you have to call a procedure for every single pixel and that involves passing parameters and return addresses. VB also provides two procedures, Point and PSet, but they''re even slower than their API equivalents. Now, I''m no fool (in my humble opinion anyway) so I switched to C (Visual C++ more specifically) for my next project. I have some experience writing in C but that experience doesn''t include manipulating a bitmap on a pixel level and that''s why I''ve come here: to tap into the amazing knowlegde base that is GameDev.net. I would like to know how to access pixels in a bitmap the fastest way possible, i.e. without the help of GDI. I''ve come across a few examples but none of them worked for me because Visual C++ doesn''t provide either the graphics.h or mem.h header files. From what I understand by reading through the example code I need functions like memset or putpixel to write a pixel but like I said Visual C++ lacks the necessary header files. Another thing I would like to know is how to draw a bitmap to the screen without the BitBlt API. You see, for my next project I want full control over the entire rendering process, including the screen output. If this requires assembly, so be it, I fear no low-level code.
Advertisement
Well there are several ways to do it. You can use something like mode 13h (google it) which will restrict you to 320x240 and 256-bit palleted colour. It may also not work too well under 2k and XP as it'll have to run under their DOS emulation also you may have trouble doing 13h mode stuff using visual C++. If you don't mind having direct access to the hardware (and I don't see any good reason why you should) have a look at DirectX or SDL. SDL is basically a wrapper for DX when using windows but it'll be simpler to use.

[edited by - Monder on March 27, 2004 10:00:58 AM]
You can still use the Windows API and be faster than Get/SetPixel. I haven''t tried it myself, since I moved to DirectX to get faster graphics when the simple API stuff became too slow, but the idea is to draw to your own bitmap in memory, and then bitblt it to the screen using the GDI. That bitmap would be your backbuffer, just like you''d find in DirectX or OpenGL or most other graphics stuff. And since it is simply memory that you can read from and write to, it''ll be pretty darn quick. And you''ll only be making a few calls to the GDI. In fact, I think that GetDIBits and SetDIBits might be used quite a bit in more quickly drawn Windows apps. I was about to start playing with those functions when I instead moved to DirectX.

But just explore the MSDN Bitmap Reference and the GDI reference to get an idea for all the different functions available.

int Agony() { return *((int*)0); } Mwahaha... >8)
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
SDL is probably the best option. It''s designed for games so it''s fast. It will give you direct access to the pixels of "surfaces" (which are like Bitmaps). SDL is also cross platform so that''s a plus. You shouldn''t need to use any assembly, the speed gained would barely be noticable.

http://www.libsdl.org
Thanks for your replies but what you''re suggesting is exactly what I''m trying to avoid. You see, I want to build my own engine from the ground up. That means no DirectX or OpenGL or what have ya. There''s no point in writing a gourad shading procedure or a texture mapping routine if DirectX already provides both. Also, I did some testing with SetDIBitsToDevice and GetDIBits a while back and it turns out they''re both rediculously slow. Both functions copy(!) a bitbuffer to or from a bitmap. So instead of directly manipulating pixels you have to first work on the bits in the bitbuffer and second copy this buffer to the bitmap. I suppose I can''t avoid using the Windows GDI all together so I''ve adjusted my original plans. Now my goal is to minimize the dependency on GDI of my engine-to-be. Let''s say I create a bitmap the GDI-way by setting up a device context and a bitmap object. I want to manipulate the bitmap''s pixels directly by declaring a pointer which points to the actual memory area where the bitmap''s bits are stored and moving this pointer from pixel to pixel (e.g. by stepping 3 bytes for a 24bit bitmap). To draw the bitmap to the screen I can use the BitBlt call. I understand I can''t control the actual screen output (=video mem) unless I write my own drivers and that''s a little too advanced for me so I''ll just settle for BitBlt...for now. That just leaves on more problem: setting up a pointer to a bitmap. I''m not sure this is possible but I would really like to know.
I''d use CreateDIBSection and use the pointer to the bitmap data. You won''t escape double buffering, but you can manipulate your pixel data as you want (plus all different color depths).

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

I think directdraw would probebly be perfectly suited for you if i understand you correctly. There you have the hardware blitter and direct access to the graphics memory for plotting pixels, but without any 3d functionality, which you want to implement yourself.
Shields up! Rrrrred alert!
Yes, CreateDIBSection sounds interesting. I looked it up in the MSDN library and apparently I can manipulate pixels directly without any function calls! But how does it compare in speed to other methods? I''m not too sure what too make of a ''device independent bitmap''. How is it any different from a regular bitmap created by calling the CreateBitmap or CreateCompatibleBitmap functions, besides the fact you can directly access a DIB''s pixels?
Don''t quote me on this, but i think Device independent bitmaps keep their color depth (therefore it''s possible to have a pointer to the pixel data).

BitBlt will take care of the color conversion.

The speed is only affected by your pixel methods, plus one BitBlt to put the image to the wanted HDC.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

This topic is closed to new replies.

Advertisement