Archived

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

EmpyrealHell

Direct Draw Transparency

Recommended Posts

EmpyrealHell    125
I was wondering how you draw a surface at a set transparency. I am trying to create a menu screen with marble walls, and I want to draw reflections of the menu select icon on the walls at 50% opacity, so I just need to know how to draw a surface semi-transparent on top of another surface. Links to articles or examples would be very helpful, thanks

Share this post


Link to post
Share on other sites
evillive2    779
you won''t get hardware acceleration in direct draw or any other 2d API for alpha blending which is what you want to do. There are articles in the articles and resources section here that deal with software alpha blending in 2d. Even if you decide to go with a 3d API that supports hardware alpha blending like d3d or OpenGL, I still recomend looking at the articles so you know what is going on behind the scenes.

Share this post


Link to post
Share on other sites
bilsa    157
Hello!

I''m not sure if there is any way of making a surface transparent with directdraw by just setting a value or something like that...

But I know that you can simply access the primary surface pixelbuffer, extract the colorvalues for each pixel. Then add the color of the pixel that is supposed to be on top of this, and then divide the value by two. This will look transparent.

Here is some code for making 32 bit surface transparent:


  
int LoadFromSurfaceWithTrancparency(LPDIRECTDRAWSURFACE7 lpddsSrc, LPDIRECTDRAWSURFACE7 lpddsDest, int x, int y, int w, int h, int pct)
{

DDSURFACEDESC2 ddsdSrc; //This will hold information about the source surface

DDSURFACEDESC2 ddsdDest; //This will hold information about the destination surface

DD_INIT(ddsdSrc); //Initialize them... dunno what you use.

DD_INIT(ddsdDest);

int r,g,b; //Wil hold information about colors

int r2,g2,b2;

//Now lock the surface you want to read from!

if (FAILED(lpddsSrc->Lock(NULL, &ddsdSrc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL)))
{
//Errorhandling!

}

UINT* buffer = (UINT*)ddsdSrc.lpSurface; //This will get the pixelbuffer of the source surface

UINT nPitch = ddsdSrc.lPitch >> 2; //Getting the pitch... different for 16 bit colors


if (FAILED(lpddsBitmap->Lock(NULL, &ddsdDest, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL)))
{
//Errorhandling!

}

UINT* buffer2 = (UINT*)ddsdDest.lpSurface; //Getting the pixelbuffer from the surface you want to be transparent!

UINT nPitch2 = ddsdDest.lPitch >> 2; //Getting the pitch...


//Now we start manipulating the colors!!

for(int iX = x; iX < (x+w); iX++) //From the x position u specify, until the width you want....

{
for(int iY = y; iY < (y+h); iY++) //From the y position u specify, until the height you want...

{
UINT color = buffer[iY*nPitch + iX]; //Extract the pixelcolor at position iY, iX from the source surface!

UINT color2 = buffer2[iY*nPitch2 + iX]; //Extract the pixelcolor at position iY, iX from the surface you want to be transparent!


r = ((color & 0xFF0000) >> 16); //Get the colors!... this is for 32 bit colors!

g = ((color & 0xFF00) >> 8);
b = ((color & 0xFF));

r2 = ((color2 & 0xFF0000) >> 16); //Get the colors!... this is for 32 bit colors!

g2 = ((color2 & 0xFF00) >> 8);
b2 = ((color2 & 0xFF));

(r += r2) *= pct; //Add the colors and multiply with the percentage of transparency you want!

(g += g2) *= pct;
(b += b2) *= pct;

r /= 100; //Divide with 100 since we specify the percentage from 1 - 100 !

g /= 100;
b /= 100;

buffer2[iY*nPitch + iX] = RGB32(r,g,b); //Set the "transparent" color at position x, y in the desired surface!

}
}

lpddsDest->Unlock(NULL); //Remember unlocking the surfaces!

lpddsSrc->Unlock(NULL);

return EXIT_SUCCESS;
}


Well... I know the code is kinda ugly but I have never put any work on it, cuz I only needed it occasionally.
This is how you would call the function:


  
//This is how you would make a surface transparent!

//I''m assuming you already have created a surface of yours that can handle the desired size.

//The function I use is not very optimized and not dynamical, because when I want to achieve this effect

//I alwasy print all my stuff on usually the backbuffer and call this function on it

//If you have different size on the destination surface can easily get out of size...

//But You could easily change this if you need...

//Anyhow...


//This would make your surface lpddsDestination transparent for 50% at position 0,0 with the size 100x100


LoadFromSurfaceWithTrancparency(lpddsPrimary, lpddsDestination, 0, 0, 100, 100, 50);


Hope this helps!

Gl!

Share this post


Link to post
Share on other sites
rtw1701    114
bilsa,

Can you send me that transparency code? I''ve tried copy and paste and its gets really screwed up in notepad and doesn''t seam to paste at all into ms c++. Would this code be able to work with 24bit files with changes or only 32bit cause of the alpha channel? Thanks for your time.

Share this post


Link to post
Share on other sites