[MDX] DirectDraw Overlay and Pixelformat help

Started by
7 comments, last by Muhammad Haggag 18 years, 3 months ago
Heyas, I've had a play around with the MDX C# Overlay sample. It works flawlessly on any ATI based card, however, it errors out with "InvalidPixelFormatException" on any nVidia based cards. After doing a bit of research i've verified (through the use of the C++ version of this code) that nVidia cards need to have their overlay surface initialised in the "UYVY" or "YYY2" pixel formats. When i added the following formats to the C++ sample, the overlay layer initialised (in either of the formats), however is was full of garbage. On an ATI, the overlay created and was just a black square (no text). case PIXEL_FORMAT_UYVY: dd_format.dwFlags = DDPF_FOURCC; dd_format.dwFourCC = MAKEFOURCC ('U', 'Y', 'V', 'Y'); break; case PIXEL_FORMAT_YUY2: dd_format.dwFlags = DDPF_FOURCC; dd_format.dwFourCC = MAKEFOURCC ('Y', 'U', 'Y', '2'); break; I'm trying for figure out how to get these formats into C#. I just assumed that the following would work: case BitsPerPixel.PixelFormat_UYVY: pixelFormat.FourCC = 0x59565955; pixelFormat.FourCcIsValid = true; break; case BitsPerPixel.PixelFormat_YUY2: pixelFormat.FourCC = 0x32595559; pixelFormat.FourCcIsValid = true; break; However, these 2 formats error out with "InvalidPixelFormatException" on both the ATI and nVidia cards, so i'm obviously doing something wrong. Anyhelp anyone can provide would be greatly appreciated. The C# sample i am refering to is: http://www.gamedev.net/community/forums/topic.asp?topic_id=367591 The C++ sample i am refering to is: http://www.gamedev.net/community/forums/topic.asp?topic_id=359319 Cheers, Matt
Advertisement
You might be getting exceptions because OverlayManager.GetPixelFormat sets pixelFormat.Rgb to true before entering the switch case. Make sure you move that statement into the relevant switch cases if you haven't already.

You can use the following function to create FourCC codes:
static int MakeFourCC(int ch0, int ch1, int ch2, int ch3){   return ((int)(byte)(ch0)|((int)(byte)(ch1) << 8)| ((int)(byte)(ch2) << 16) | ((int)(byte)(ch3) << 24));}


Instead of manually adding in formats like the sample does, take a look at the documentation for IDirectDraw7::GetFourCCCodes (Managed equivalent: DirectDraw.Device.FourCCCodes) and IDirectDraw7::EnumSurfaces (Managed equivalent: Couldn't find it!). You should check for a number of pre-defined formats first (e.g. 16 and 32 bits per pixel), then check for all FourCC formats supported by the device.

I'll be away for a while, so I won't be able to modify the original sample to reflect the above method as soon as I want to. In the meantime, feel free to do so yourself [smile].

Heyas again,

Yep, i'm a moron for not seeing that one.

The overlay surface initialises now no probs, but getting anything to appear on it is a different kettle of fish altogether.

It appears that because the overlaySurface and overlayBackSurface are both in UYVY format, i can't use the GetDC function as it returns "CantCreateDeviceContext".

I was using the GetDC to do my drawing to the surface. The .DrawText .DrawRectangle etc function also appear to attempt to use GetDC internally as they throw the same error.

It would appear i have to do my drawing elsewhere then somehow get the contents into the overlayBackSurface before i Flip and UpdateOverlay. Am i correct in assuming this?

Towards that end, i'm now drawing onto a separate OffScreenPlain (in RGB format) and have no problems.

I just can't work out how to get the contents of the new RGB drawSurface converted to UYVY and onto the overlayBackSurface.

I've managed to stumble upon a ddraw sample called mosquito, that has a function that takes the contents of an RGB surface, converts and writes to the overlay surface. Unfortunately i'm no that great of a C++ programmer and can't really follow what's going on. I can post the function if needed.

Am i sort of moving in the right direction?

Any help anyone can provide would be greatly appreciated.

Thanks again,
Matt
Quote:Original post by McNubblet
Towards that end, i'm now drawing onto a separate OffScreenPlain (in RGB format) and have no problems.

I just can't work out how to get the contents of the new RGB drawSurface converted to UYVY and onto the overlayBackSurface.

Tried doing an IDirectDraw7::Blt? I seem to recall blit can do format conversions.

Quote:I've managed to stumble upon a ddraw sample called mosquito, that has a function that takes the contents of an RGB surface, converts and writes to the overlay surface. Unfortunately i'm no that great of a C++ programmer and can't really follow what's going on. I can post the function if needed.

I recall that sample. Post the function if IDirectDraw7::Blt doesn't work.

Hey again,

Thanks again for all the help you're providing, it's much appreciated :)

The MDX Blt/BltFast equivalent is Draw/Drawfast as far as i can tell. Neither of these methods work, throwing a NotSupported exception.

Some good news though, after strenuously excercising my powers of google-fu, I stumbled accross something else, which almost works :)

When setting the pixelFormat up, i'm now using:

case BitsPerPixel.PixelFormat_UYVY:
pixelFormat.FourCC = 0x59565955;
pixelFormat.FourCcIsValid = true;
pixelFormat.Rgb = true;
pixelFormat.RgbToYuv = true;
pixelFormat.RgbBitCount = 32;
pixelFormat.RBitMask = 0x00FF0000;
pixelFormat.GBitMask = 0x0000FF00;
pixelFormat.BBitMask = 0x000000FF;
break;

As i said it *almost* works, what comes up on the overlay surface is of the correct colour, but it looks kinda wacky.

I can't take a screenie of it to show you, so i've just dodgied this up in photoshop.

What it should look like:
http://www.mcnubblet.net/upload/overlay-good.gif

What it turns out looking like:
http://www.mcnubblet.net/upload/overlay-bad.gif

Thanks again,
Matt

Just doing a bit of experimentation :)

If i set the rgbbits in the UYVY pixelformat to 16 (and set the appropriate bit masks), it only draws 2 copies of what it's supposed to, as oppoesed to 4 in the example gif above (which is set at rgbbits = 32).

Could this be something to do with "pitch" or "stride"?

The pitch of the UYVY overlay surface is 256, the pitch of a 16bit rgb surface is 512 and the pitch of a 32bit rgb surface is 960.

Just a thought. But if i'm on the right track, is it possible to fix this?

Thanks again,
Matt
Quote:The pitch of the UYVY overlay surface is 256, the pitch of a 16bit rgb surface is 512 and the pitch of a 32bit rgb surface is 960.

Well, given that you're not doing any conversions explicitly, the runtime and/or driver should be the ones compensating for pitch differences.

Anyway, I don't have time to experiment with this right now. Also, experimentation isn't the best way to do this stuff - please start a thread in DIRECTXDEV about this problem. I'll follow up here or there when I get the time.

The different pixel format doesn't work on nvidia cards :(

Just about ready to throw in the towel and put this in the to hard basket.

DIRECTXDEV, is that the microsoft mailing list?

Thanks again,
Matt
Quote:Original post by McNubblet
DIRECTXDEV, is that the microsoft mailing list?

DIRECTXDEV.

This topic is closed to new replies.

Advertisement