Archived

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

Colors messed up on ATI cards

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

Guest Anonymous Poster
You must use the GetPixelFormat() function of DDraw. I'm not sure how it works exactly, because I have never used it, so just look in ddraw.doc for it. You should always use this function, because you never know what kind of format the pixels will be in 16bpp.

Good luck

Share this post


Link to post
Share on other sites
to beat a dead horse....

for maximum compatibility, be SURE to check either the pixel format or the surface description(which also contains the pixel format) of your surfaces.

most(not all) ATI cards use 555 in 16 bit mode.

also, there are some cards out there that store their pixels as BGR instead of RGB, and thus, checking the pixel format is paramount.

Share this post


Link to post
Share on other sites
BGR yuck! Why do hardware guys make it so tough. I have a 565 RGB card and have been able to test using some bit-shifting for speedy conversion, and it works great my problem is testing on every graphic card could get rough. I also have some general functions that use all of the pixel format for a slower but always accurate picture. Since I don't want to test for every possible combination and most cards are 565 RGB I am going to test for 16 bits with 6 green bits and if that is the case use my bit-shift routine otherwise I will use the slower general routine.

Does anybody have a better approach or good bit-shift macros for 555 and BGR?

------------------
Glen Martin
Dynamic Adventures Inc.
http://www.dynamicadventures.com

Share this post


Link to post
Share on other sites
just have a set of functions for every pixel format (RGB 555, RGB 565, BGR 555, BGR 565) and when you check the card's pixel format, set a function pointer to the right function.

Your code will be a bit bigger, but thats the price you pay for good compatibility.

Note that i'm not saying to call a function every time you want to work with a pixel. Use macros (or inline functions) inside more general functions, and have function pointers pointing to these more general functions (4 diff functions, 4 times the code, but you can just copy/paste).

Also note that this is a solution off the top of my head, because I havent really dived into supporting all 16bit formats yet.. right now I just support RGB 565 which my card uses..

Share this post


Link to post
Share on other sites
I use this macro from LaMothe's Tricks of the Windows Game Programming Gurus for RGB 565 mode...

#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 6) + ((r & 31) << 11))

It is much faster than the other code I was using. But I tried is 555 macro on an ATI card and it didn't work. Could have been a non-RGB mode.

------------------
Glen Martin
Dynamic Adventures Inc.
http://www.dynamicadventures.com

Share this post


Link to post
Share on other sites
D3DXCreateTextureFromFile() or D3DXCreateTextureFromMemory() will automatically do any color conversion you need.

I usually don't use these functions because they do not allow as much control over texture creation (opaque, static, dynamic flags, etc.)

I usually handle this problem like this: I store all textures on disk in a known format (usually 32-bit or 24-bit RGB, or DXT compressed) I then have quick, optimized routines for common 16-bit formats (565, 555 RGB, haven't seen BGR, but it could happen), a simple copy when source format matches the hardware's format (32-bit textures, or support for DXTn compression,) and a slower, generic, "everything else," fallback.

Share this post


Link to post
Share on other sites
GetPixelFormat is your best bet.

Structures and globals for holding the RGB info
// Container structure for RGB masks
typedef struct _RGBMASK
{
ULONG rgbRed;
ULONG rgbGreen;
ULONG rgbBlue;
} RGBMASK;

// Container structure for (5,6,5 or 5,5,5 and masking)
typedef struct _RGB16
{
RGBQUAD depth;
RGBQUAD amount;
RGBQUAD position;
RGBMASK mask;
} RGB16;

RGB16 rgb16;

extern int RedMask, GreenMask, BlueMask; // RGB Masks
RedPos, GreenPos, BluePos; // RGB Positions

Macros that will make a RGB pixel wheter the card is 555 or 565 or any other excentric format.

#define RED(p) (p >> RedPos) // Extracts Red color
#define GREEN(p) ((p & GreenMask) >> GreenPos) // Extracts Green color
#define BLUE(p) (p & BlueMask) // Extracts Blue color
#define RGB16(r, g, b) ((r << RedPos) | (g << GreenPos) | b) // Creates RGB pixel

void DDGetPixelFormat()
{
DDSURFACEDESC2 ddsd; // DirectDraw Surface Description
BYTE shiftcount; // Shift Counter

// Get a surface despriction.
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_PIXELFORMAT;
FrontSurf->Surface->GetSurfaceDesc(&ddsd);
// Fill in the masking values for extracting colors.
rgb16.mask.rgbRed = ddsd.ddpfPixelFormat.dwRBitMask;
rgb16.mask.rgbGreen = ddsd.ddpfPixelFormat.dwGBitMask;
rgb16.mask.rgbBlue = ddsd.ddpfPixelFormat.dwBBitMask;

// Get red surface information.
shiftcount = 0;
while(!(ddsd.ddpfPixelFormat.dwRBitMask & 1))
{
ddsd.ddpfPixelFormat.dwRBitMask >>= 1;
shiftcount++;
}
rgb16.depth.rgbRed = (BYTE)ddsd.ddpfPixelFormat.dwRBitMask;
rgb16.position.rgbRed = shiftcount;
rgb16.amount.rgbRed = (ddsd.ddpfPixelFormat.dwRBitMask == 0x1f) ? 3 : 2;

// Get green surface information.
shiftcount = 0;
while(!(ddsd.ddpfPixelFormat.dwGBitMask & 1))
{
ddsd.ddpfPixelFormat.dwGBitMask >>= 1;
shiftcount++;
}
rgb16.depth.rgbGreen =(BYTE)ddsd.ddpfPixelFormat.dwGBitMask;
rgb16.position.rgbGreen = shiftcount;
rgb16.amount.rgbGreen = (ddsd.ddpfPixelFormat.dwGBitMask == 0x1f) ? 3 : 2;

// Get Blue surface information.
shiftcount = 0;
while(!(ddsd.ddpfPixelFormat.dwBBitMask & 1))
{
ddsd.ddpfPixelFormat.dwBBitMask >>= 1;
shiftcount++;
}
rgb16.depth.rgbBlue =(BYTE)ddsd.ddpfPixelFormat.dwBBitMask;
rgb16.position.rgbBlue = shiftcount;
rgb16.amount.rgbBlue = (ddsd.ddpfPixelFormat.dwBBitMask == 0x1f) ? 3 : 2;
// Fill in variables so we dont' have to access the structure anymore.
RedMask = rgb16.mask.rgbRed; // Red Mask
GreenMask = rgb16.mask.rgbGreen; // Green Mask
BlueMask = rgb16.mask.rgbBlue; // Blue Mask
RedPos = rgb16.position.rgbRed; // Red Position
GreenPos = rgb16.position.rgbGreen; // Green Position
BluePos = rgb16.position.rgbBlue; // Blue Position
}

Sorry if it all messy. E-mail me and I wil send it to you properley.

Share this post


Link to post
Share on other sites
Thanx alot folks
But I'm asking myself: Why does no function come with DirectDraw that does this job?

WORD IDirectDraw::GetPixelValue (BYTE red, BYTE green, BYTE blue)

Bye

Share this post


Link to post
Share on other sites
Cause the whole point of direct Draw is give you easier access to hardware thats all after that it's up to you to write you on pixel plotting functions

Share this post


Link to post
Share on other sites
I've written my own Alpha routine for a GUI and I'm wondering, because it works on every Machine of my friends, except those, that are fitted with ATI cards. The colors are messed up! Do these cards have an exotic pixel-format? I think it's not 5-6-5 or 5-5-5...

Share this post


Link to post
Share on other sites