DirectDraw fading

Started by
8 comments, last by Ivko 22 years, 3 months ago
How do I make the screen fade in or out in DirectDraw? Preferably by changing the brightness/gamma and not by changing the actual color values of the pixels. I''m using 16bit color and page flipping. I guess what I''m asking is how do I adjust the screen/surface brightness?
Advertisement
You can use the gamma ramps but that''s supported on so few video cards and it won''t be handled in software for you. So you have two options: switch your program to 8 bit, where fades are too easy to do; or do it manually by changing every pixel. I''ve also heard something else about using Direct3D to draw an alpha-blended black rectangle over the whole screen, since it''s supported in hardware.

None of the solutions are all that great unfortunately.

-Goku
Well, at Aeon Software's tutorials it says something along the lines of ".. this isn't the best way to do it, you could use D3D alpha blending or gamma controls in DirectDraw". I tried the example function that they have in the pixels/palletes tutorial but it's horribly slow (about 1fps on my 1.2ghz tbird) and it doesnt work right, i can get a slight fading distance then any higher than that it just warps the colors like I was changing the pallete randomly.

Here's the code I'm talking about (modified a bit):
    void Fade(float pct, USHORT *buffer, int pitch) {	int x, y;	UCHAR r, g, b;	USHORT color;	USHORT *temp = buffer;	int jump = pitch - 1024;	for (y=0; y<SCREENH; y++) {        for (x=0; x<SCREENW; x++, temp++) {// move pointer to next pixel each time            // first, get the pixel            color = *temp;            // now extract red, green, and blue            r = (color & 0xF800) >> 11;            g = (color & 0x0730) >> 5;            b = (color & 0x001F);            // apply the fade            r = (UCHAR)((float)r * pct);            g = (UCHAR)((float)g * pct);            b = (UCHAR)((float)b * pct);            // write the new color back to the buffer            *temp = FROMRGB16(r, g, b);        }        // move pointer to beginning of next line        temp += jump;    }}  


I think there is an easy way to change the gamma in directdraw, but I don't know where to look for it (I can never find anything at msdn)

Edited by - Ivko on January 3, 2002 7:29:38 PM
Just to give you some ideas - this is the sort of thing that runs at 100+ fps on a GF2 MX with DX8 (D3D)...

For instance, a GF2 MX runs about $80, which is roughly in the same ballpark as a good programming book. An alpha blended background runs at about 160+ fps using a smallish texture. Right around 100 fps with a 1024x1024 texture. Actual results will depend on the size of your texture and your implementation.

The point is, if there is any way in the world for you to buy this bottom of the line card, you shouldn''t be spending alot of time ( = money) figuring out how to do this in DirectDraw unless you think you think you can do better than 100 fps...

Best Buy here in the states was offering Ti 200s at ~$100. I bet the performance would be even better...

(stepping off the soapbox...)
Author, "Real Time Rendering Tricks and Techniques in DirectX", "Focus on Curves and Surfaces", A third book on advanced lighting and materials
System specs:
1200mhz 266fsb athlon thunderbird
GeForce2 GTS 32mb
256MB PC2100 DDR ram

Anyways I got the fading to actually work instead of screwing up the colors, but that still doesn't help the 1-2 FPS. It has to do 786432 runs of the inner loop each frame (1024x768). That explain a few things?

Still looking for that magic function that directdraw has
Keep in mind I can't use D3D because this project is largely to learn how to use directdraw, when I started it I had no clue how to even make a DDraw instance.

Edited by - Ivko on January 3, 2002 7:58:55 PM
Hmm, I found an article here on GDev.net that explains exactly how to do so. I''m gonna go through it but it says you can only adjust the gamma of the primary surface. Shouldn''t be a problem though, gonna try it out and see what happens.
quote:Original post by Ivko
Keep in mind I can''t use D3D because this project is largely to learn how to use directdraw.


Just my opinion, but...

You are choosing not to learn a new API because you want to learn the old version of the API??? If you were supporting legacy code, that might make sense, but otherwise this seems like a extremely faulty logic.

Yes yes yes, you can still use the old interfaces, but this is for legacy support. The whole methodology is outdated by the current hardware. Given you are not constrained by old code or old hardware, I''d very much recommend you devote your energy to the current state of the art...

This seems to be the opinion of the DX team as well...
Author, "Real Time Rendering Tricks and Techniques in DirectX", "Focus on Curves and Surfaces", A third book on advanced lighting and materials
I''ll just scrap the fading. The gamma controlling isn''t doing anything. When I''m basically done the game I''ll convert it do D3D.
Why don''t you try something like this. It works perfectly, in fact that here is fading in r,g,b and normal, you may not need the r,g,b fading but i practcally copied and pased it from my working code and was too lasy to throw away the stuf you may not need
You can change the step of fading if you want here it is with 2.
It''s blazing fast, using DDraw. For sure any normal card nowadays supports such a feature, so don''t bother inmplementing things ppl have already done good, just use them wisely.

HRESULT CHistogram::ChangeGamma(IDirectDrawSurface7* pdds, char col, bool bLight)
{

hr = g_pddsPrimary->QueryInterface(IID_IDirectDrawGammaControl, (LPVOID*)&m_pGammaControl);
if(!m_pGammaControl)
{
switch(hr)
{
case E_NOINTERFACE :
TRACE("E_NOINTERFACE \n");
break;
case E_POINTER:
TRACE("E_POINTER\n");
break;
}
return false;
}

if(bLight)
{
m_lGammaRamp += 2;
if(m_lGammaRamp > 256)
m_lGammaRamp = 256;
}
else
{
m_lGammaRamp -= 2;
if(m_lGammaRamp < 0)
m_lGammaRamp = 0;
}


DDGAMMARAMP ddGamRam = {sizeof(ddGamRam)};

if( FAILED( hr = m_pGammaControl->GetGammaRamp( 0, &ddGamRam)))
return E_FAIL;

m_wGamma = 0;

for(int i = 0; i < 256; ++i)
{
switch(col)
{
case ''r'':
ddGamRam.red = m_wGamma;
ddGamRam.green = 0;<br> ddGamRam.blue = 0;<br> break;<br><br> case ''g'':<br> ddGamRam.red = 0;<br> ddGamRam.green = m_wGamma;<br> ddGamRam.blue = 0;<br> break;<br><br> case ''b'':<br> ddGamRam.red = 0;<br> ddGamRam.green = 0;<br> ddGamRam.blue = m_wGamma;<br> break;<br><br> case ''0'':<br> ddGamRam.red = m_wGamma;<br> ddGamRam.green = m_wGamma;<br> ddGamRam.blue = m_wGamma;<br> break;<br> }<br> <br><br> m_wGamma += (WORD) m_lGammaRamp;<br> }<br><br> if(FAILED(hr = m_pGammaControl->SetGammaRamp(0, &ddGamRam)))<br> {<br> TRACE("FAIELD TO SET GammaRamp\n");<br> SAFERELEASE(m_pGammaControl);<br> return E_FAIL;<br> }<br> <br> SAFERELEASE(m_pGammaControl);<br> return S_OK;<br><br>} </i> <br><br>Rusenec
Rusenec
It''s a quick on funk so you may need to throw or change some things basically it wokrs fine. (replace the one returning "false" with E_FAIL, hehe, may be too lazy i am

Rusenec
Rusenec

This topic is closed to new replies.

Advertisement