Archived

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

kitson

How to darken a surface of DX? HELP!!!!

Recommended Posts

Hi everybody. Is there anyone know how to darken a surface? I am currently using a method, get the value of a pixel, shift it with red, green and blue mask, all these process is done pixel by pixel. It is quite slow, so is there anybody can help me? Thanks for your attention.

Share this post


Link to post
Share on other sites
A few methods:

Gamma ramping: Only works in fullscreen. Only on cards which support it (a fair few, but nowhere near all)

Stippled fade: Very cheap, and can look it too (depends on your graphics). Basically, you blt a checkerboard of black/transparent over the whole screen.

Pseudo-fade: For this, you use the GDI commands, don''t worry, it will still be quite fast, just 1 or 2 bitblts per frame. Basically, you use the SRC_AND raster op, to mask out the different bits of the colour. The order you do this is again dictated by the graphics you are using, and remember that because this is GDI, it is 32bit (which makes it easier). I would try masking with values like binary 11110000. If you need to do a fade, it can get a bit trickier, but for just darkening, this will be fine.

Dark Quad: I thought you were using DirectDraw, now I''ve realised that you didn''t specify. If you are using 3d stuff, then put a big black quad alphablended over the entire screen.

There are a few other tricks, but those are probably the better of them.


Trying is the first step towards failure.

Share this post


Link to post
Share on other sites
Also remember that if you are modifying a locked surface it will be way faster to have it in sysmem than in vidmem.
Always have your manually blitted/modified surfaces in sysmem.

Share this post


Link to post
Share on other sites
I think we could have a better discussion with my code posted here:

// lock it
HRESULT hResult = suf->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
if(hResult == DD_OK)
{ // lock ok

// get the pixel format
DDPIXELFORMAT ddpf;
memset(&ddpf, 0, sizeof(DDPIXELFORMAT));
ddpf.dwSize = sizeof(DDPIXELFORMAT);
suf->GetPixelFormat(&ddpf);

// create mask
WORD rmask = (WORD)((ddpf.dwRBitMask>>1) & ddpf.dwRBitMask);
WORD gmask = (WORD)((ddpf.dwGBitMask>>1) & ddpf.dwGBitMask);
WORD bmask = (WORD)((ddpf.dwBBitMask>>1) & ddpf.dwBBitMask);

// calculate number of pixel need to darken
int pixelsperrow = ddsd.lPitch / (DisplayMode_ColorDeep/8);
int total = pixelsperrow * DisplayMode_Height;

register WORD mask = rmask | gmask | bmask;
register WORD* surfptr = (WORD*) ddsd.lpSurface;
register WORD* final = surfptr+total;
while(surfptr < final)
{
(*surfptr) = (*surfptr++)>>1 & mask;
}

// unlock
suf->Unlock(NULL);
}

It''s long enough, isn''t it. But all the code are preparation, only the while loop is time consuming (I believe). I will be great if I could have any comment, thanks.

Share this post


Link to post
Share on other sites