Archived

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

Ivko

DirectDraw fading

Recommended Posts

Ivko    203
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?

Share this post


Link to post
Share on other sites
Goku705    122
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

Share this post


Link to post
Share on other sites
Ivko    203
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

Share this post


Link to post
Share on other sites
CrazedGenius    156
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...)

Share this post


Link to post
Share on other sites
Ivko    203
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

Share this post


Link to post
Share on other sites
Ivko    203
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.

Share this post


Link to post
Share on other sites
CrazedGenius    156
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...

Share this post


Link to post
Share on other sites
Ivko    203
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.

Share this post


Link to post
Share on other sites
Ruseneca    122
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[i] = 0;
ddGamRam.blue[i] = 0;
break;

case ''g'':
ddGamRam.red[i] = 0;
ddGamRam.green[i] = m_wGamma;
ddGamRam.blue[i] = 0;
break;

case ''b'':
ddGamRam.red[i] = 0;
ddGamRam.green[i] = 0;
ddGamRam.blue[i] = m_wGamma;
break;

case ''0'':
ddGamRam.red[i] = m_wGamma;
ddGamRam.green[i] = m_wGamma;
ddGamRam.blue[i] = m_wGamma;
break;
}


m_wGamma += (WORD) m_lGammaRamp;
}

if(FAILED(hr = m_pGammaControl->SetGammaRamp(0, &ddGamRam)))
{
TRACE("FAIELD TO SET GammaRamp\n");
SAFERELEASE(m_pGammaControl);
return E_FAIL;
}

SAFERELEASE(m_pGammaControl);
return S_OK;

}


Rusenec

Share this post


Link to post
Share on other sites
Rusenec    126
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

Share this post


Link to post
Share on other sites