Archived

This topic is now archived and is closed to further replies.

Direct Draw Pixels

This topic is 5502 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

Greetings, Im curious to whether there is a way to do this or how people have handled it before now. Im working on a Direct Draw Class and everything is fine. But I would like to write a pixel routine and Im facing a puzzling problem. To draw to a 8bit display you need to feed the video buffer a BYTE per pixel? but to draw to a 16bit display mode you need to feed it a WORD and so on. so how would you enter this as a Parameter in your Pixel() function? for instance, if your app is a window app. you cant program your app to draw pixels in one mode because someone else will more than likely be running in a different mode! How do people get around this? Thanks for any advice and I hope my question is clear.

Share this post


Link to post
Share on other sites
You could make a generic Pixel() function that will take 24-bit RGB value and convert it appropriate format.

But that is slow, so you could do is to write at least three member functions that each take a ULONG for the pixel value. Then have a function pointer pointing to the appropriate member function.

Like this:
class DDClass
{
void (DDClass::*Pixel)(int x, int y, ULONG pixel);
void Pixel8(int x, int y, ULONG pixel);
void Pixel16(int x, int y, ULONG pixel);
void Pixel24(int x, int y, ULONG pixel);
void Pixel32(int x, int y, ULONG pixel);
}

DDClass ddclass;

(ddclass->Pixel)(1, 2, RGB(11,22,33));
Then initialize *Pixel to point to correct function when setting or changing mode.

You might consider this, which perhaps is cleaner
class DDClass
{
public:
inline void Pixel(int x, int y, ULONG pixel) { (this->fpPixel)(x, y, pixel); }

private:
void (DDClass::*fpPixel)(int x, int y, ULONG pixel);
void Pixel8(int x, int y, ULONG pixel);
void Pixel16(int x, int y, ULONG pixel);
void Pixel24(int x, int y, ULONG pixel);
void Pixel32(int x, int y, ULONG pixel);
}

DDClass ddclass;

ddclass->Pixel(1, 2, RGB(11,22,33));



Share this post


Link to post
Share on other sites
In the initialization portion of the program I detect what bit depth person is in. And then use a function pointer to set correct plotter.

void (SetPixel *)(int,int,int);

//Use GetPixelFormat or whatever to get bit depth
...
if(MODE == 16) //just being general here
{
SetPixel = SetPixel_16...

Share this post


Link to post
Share on other sites
Thanks for the quick replies!

Thats the idea I had in mind Daerax but I thought a conversion would be better.

I would have thought the *if* statements would be quite slow if I had to plot a lot of pixels?

CWizard's way looks advanced unfortionately I dont really understand it too well. Thanks a lot for taking the time to show me though

[edit] and I dont understand why each pixel is ULONG - why use 3 different functions with the same parameter? sorry if I dont see the obvious

[edited by - redoc on November 19, 2002 11:24:44 PM]

Share this post


Link to post
Share on other sites
The if is only run through once in the begining. WHen you call SetPixel() and say you are in 16bit mode it will call
SetPixel_16() cause SetPixel function is pointing to that function

Share this post


Link to post
Share on other sites
ahh I understand you now! I think..

Thanks a lot for that, I wasnt aware you could even do that with functions!

I still dont understand what cwizard means... espically with the ULONG''s

Share this post


Link to post
Share on other sites
When you''re using function pointers, you must give the pointer a signature (parameter types + return type) and you can only set the function pointer to point to functions with the exact same type.

When you are calling a function via a pointer, the compiler doesn''t know what function is going to be called, so every possible function must take the exact same parameters.

So, all SetPixel functions need the same signature, and the difference is the pixel format. All general formats fit into a ULONG (8, 16, 24 and 32) so that can be used.

Here are examples of 3 of the functions. There might be errors, I haven''t tested it. I''ll leave 24-bit for you

void DDClass::SetPixel8(int x, int y, ULONG pixel)
{
// pSurface is some pointer to the locked surface. perhaps a void*
// lPitch is bytes/row

// Tell the compiler pSurface is a UCHAR pointer, then add the pixel offset, and write the UCHAR "part" of pixel there.
*((UCHAR *)this->pSurface) + y * this->lPitch + x) = (UCHAR)pixel;
}

void DDClass::SetPixel16(int x, int y, ULONG pixel)
{
// lPitch is words/row (== bytes_per_row/2)
*((UWORD *)this->pSurface) + y * this->lPitch + x) = (UWORD)pixel;
}

void DDClass::SetPixel32(int x, int y, ULONG pixel)
{
// lPitch is longs/row (== bytes_per_row/4)
*((ULONG *)this->pSurface) + y * this->lPitch + x) = pixel;
}
Hope it makes sense, and doesn''t contain too many errors. If you''re still not sure, go find any C++ book/tutorial and read the beginning of the chapter about function pointers, and it will clear.

Share this post


Link to post
Share on other sites
Wow! thanks for clearing that up!

Now Im following a little more!

The thing that threw me was the fact I didnt know that you could have a ULONG and extract a UCHAR (byte?) from it..

I really appreciate all the code and explanations from you both.

I''ll continue to learn about pointers and I''ll be sure to have something done soon

Share this post


Link to post
Share on other sites