Hey folks,

Apparently, DirectDraw won't let me draw 24-bit plain surfaces to a 16-bit rendered screen, so I need some algorithm to convert a 8-8-8 24-bit RGB pixel to a 5-6-5 (and 5-5-5) RGB pixel. I need something that's accurate rather than fast.

How is this usually done (i.e., by the Windows API)? Do they simply truncate the least significant bits for each color, or are there other calculations involved?

Thanks, and btw, new forum is nice; great job guys.
Posted on 2006-05-12 07:48:37 by Big Red
Truncation is the way to go... but use then next most significant bit to round it.

Ossa
Posted on 2006-05-12 08:02:10 by Ossa
You obviously understand binary.
You have answered your own question :P
Isn't it weird, the more succinctly you define a query, the more obvious the answer is? ;)
Posted on 2006-05-12 08:31:42 by Homer
You might want to take a look at http://www.clanlib.org/hermes/ :)
Posted on 2006-05-12 09:37:00 by f0dder
Which DX are you using? I remember that DDraw7.0 does the color-space conversion - in hardware (if supported) and in software. You just create an offscreen surface and blit it to the primary surface or its back-buffer.
Posted on 2006-05-12 12:52:35 by ti_mo_n
Truncation is the way to go... but use then next most significant bit to round it.


Oh okay then... thanks.

Which DX are you using? I remember that DDraw7.0 does the color-space conversion - in hardware (if supported) and in software. You just create an offscreen surface and blit it to the primary surface or its back-buffer.


I'm doing the blittling from within an application designed for DX 5-6.1 with a system install of 9.0c. I've had incredible problems so far, from DX completely refusing to create client memory surfaces to not implementing SetSurfaceDesc altogether (weird stuff - null method pointers).

I've been trying to blit 24-bit RGB surfaces (from bmps) to a 5-6-5 16-bit screen back buffer. It either gives me a RECT error (which doesn't make much sense) or a 'not implemented' error. I figured that 'not implemented' refers to the color conversion because I have been able to blit from screen (back buffer) to a compatible off-screen surface (5-6-5 16 bit), and there aren't any other important effects involved. I tried everything suggested in the Directx 6.1 manual and none of it works, especially client memory surfaces (which were what I was first hoping to use). In fact, I debugged DDRAW.dll and found that whenever the lpSurface member of DDSURFACEDESC was enabled, ddraw would automatically nullify the lpPitch flag and jump to a piece of code that returns an error if it isn't set. Frankly I've stopped trying to understand it, it's becoming a real waste of time.


Posted on 2006-05-12 14:55:57 by Big Red
Well switch to DDraw7.0. It doesn't matter which version you have installed -- you still use ddraw4 interface, which is 'quite' old :P ddraw interfaces are: 1.0, 2.0, 4.0, 7.0, and 9.0 (but this one is used only internally).

The attached file is the ddraw include you need in order to use the ddraw7 interface. It's in TASM format - quite easy to translate to anything else. Make sure that you use the correct guids/iids/structures.
Attachments:
Posted on 2006-05-12 22:19:45 by ti_mo_n
Well thanks, but it's in fact a good thing that DirectX is being so picky with my setup, because it ensures I use the simplest tactics, which will in turn keep compatibility at its best (which is essential considering the running environment of this project). I have to say though, I got so pissed off at it I almost dropped it completely and settled for software algorithms. At some point you stop caring how fast it's supposed to be, because it doesn't frickin work in the first place.

Anyway, I have finally gotten things to generally work with DX. The RECT problem was my mistake, but everything else was about correct. The blitting started working as soon as I added conversion to 16-bit prior to the blits (for same format blitting), as well as the color keying. So thanks for that. The colors look fine when truncating; didn't even care to round.

Client surfaces still refuse to work, but they would've been only for performance (i.e., no mem copy). Also, oddly enough, the types of structures required for some of the calls seem to depend on the 3D video mode used, despite it all being 2D draws over a final render, which the DX 6.1 docs completely failed to mention (i.e., software mode required DDSURFACEDESC while hardware mode required DDSURFACEDESC2, or calls would fail due to struct size). Thanks Microsoft!

And thanks for the include file! I will keep it for future reference (even though the project is in FASM).
Posted on 2006-05-23 14:18:14 by Big Red