Problem with Transparent surface

Started by
8 comments, last by nchannon 12 years, 5 months ago
Hi,
I am trying to copy a transparent texture to a YUY2 surface and keep the textures transparent alpha channel.
I know my texture has the transparent alpha channel but it looses it when I copy it to the YUY2 surface.
EG:

D3DXCreateTextureFromFileExA(g_pd3dDevice,"leaf.png"D3DX_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT,NULL,D3DFMT_UNKNOWN,D3DPOOL_MANAGED,D3DX_DEFAULT,D3DX_DEFAULT,D3DCOLOR_ARGB(255 ,0 , 0, 0),NULL,NULL,&pLeafTexture);
LPDIRECT3DSURFACE9 tempBkSurf;
//Create ofscreen surface with alpha channel
if (g_pd3dDevice->CreateOffscreenPlainSurface(256, 256, D3DFMT_A8R8G8B8 , D3DPOOL_DEFAULT, &tempBkSurf, NULL) != D3D_OK)
{
templeafSurf->Release();
return DT_ERROR;
}
if (g_pd3dDevice->CreateOffscreenPlainSurface(256, 256, D3DFMT_YUY2 , D3DPOOL_SYSTEMMEM, &templeafSurf, NULL) != D3D_OK)
{
templeafSurf->Release();
return DT_ERROR;
}
//copy texture to offscreen surface
hr = pLeafTexture->GetSurfaceLevel( 0 ,&tempBkSurf);
hr = D3DXLoadSurfaceFromSurface(templeafSurf, NULL, NULL, tempBkSurf, NULL, NULL, D3DX_FILTER_NONE, D3DCOLOR_ARGB(255 ,0, 0, 0));
//Test to see if offscreen surface is transparent
hr= D3DXSaveSurfaceToFile(_T("backLeafSurface.png"), D3DXIFF_PNG, templeafSurf, NULL, NULL);
tempBkSurf->Release();


Problem is I am loosing the alpha channel when I load tempBkSurf to templeafSurf and I have to use YUY2 surface because I am tring to copy the transparent image ontop of a YUY2 frame.
Any help would be muc appreciated
Thanks
Advertisement
I couldn't find much information on the YUY2 Format, but one reference said it was a 16bit format, does it even support per pixel alpha channels?
As yewbie said D3DFMT_YUY2 is not a format with an alpha channel, so you'll lose that information when you copy a surface with an alpha channel to it.
Hi thanks for the replys,
Yes YUY2 is 16bit aligned.
Ok I figured that D3DFMT_YUY2 has no alpha channel so I converted the YUY2 data stream to RGB32 and created the offscreensurface using [font="Consolas"][font="Consolas"]D3DFMT_A8R8G8B8 [/font][/font]still had the same problem so Im guessing I still have no alpha channel due to the source data having no alpha channel maybe im wrong.
Is there a formula that I can use for example if I lock my surface and loop though the pixels from the RGB32 buffer array could I add the alpha channel this way?
Originally I was using DirectDraw with YUY2 surfaces and created transparent surfaces like this

DDBLTFX ddbfx;
ddbfx.dwSize = sizeof( ddbfx );

DDCOLORKEY ck;

ddbfx.dwFillColor = (DWORD)RGB( 0,0,0 );

ck.dwColorSpaceLowValue = RGB( 0,0,0 );

ck.dwColorSpaceHighValue = RGB(0,0,0 );

g_FaceRecBkBufferDDS[chid-1]->SetColorKey(DDCKEY_SRCBLT, &ck);

hr = g_BackBufferDDS->Blt(&m_dstrect[ch-1],g_FaceRecBkBufferDDS[chid-1],&m_dstrect[0],DDBLT_WAIT,NULL);



and all was fine but this same approch in dx9 dosnt work can you help with with a work around to port the same approch to DX9
Thanks
Just for my reference, what exactly are you trying to do here?

1) Load a texture from a file
2) Copy that texture to a surface of the same size
3) Copy that surface back to a file

Is the purpose of this to make changes to the texture and save it?
Hi
first off all im just loading a png image as a test via
[font="Consolas"][font="Consolas"]D3DXCreateTextureFromFileExA(..) img size 256 x 256

I then have created 2 offscreen surfaces one to load the texture to and one to convert the color space from [font="Consolas"][font="Consolas"]D3DFMT_A8R8G8B8 to [font="Consolas"][font="Consolas"]D3DFMT_YUY2[/font][/font][/font][/font]
[font="Consolas"][font="Consolas"]g_pd3dDevice->CreateOffscreenPlainSurface(...) both surfaces are size 256 x 256

I then copy my texture to the first off screen surface D3DFMT_A8R8G8B8 I still have my img with its alpha channel so all is good to this point
[font="Consolas"][font="Consolas"]pLeafTexture->GetSurfaceLevel( 0 ,&tempBkSurf)

I then copy surface D3DFMT_A8R8G8B8 to [font="Consolas"][font="Consolas"]D3DFMT_YUY2 using [font="Consolas"][font="Consolas"][font="Consolas"][font="Consolas"]D3DXLoadSurfaceFromSurface(..) with the color space paramater [font="Consolas"][font="Consolas"]D3DCOLOR_ARGB(255 , 0, 0, 0)
[/font][/font][/font][/font][/font][/font][/font][/font]But this makes no difference due the the YUY2 surface not supporting the Alpha channel.
I now copy this YUY2 surface that now contains the png img data to another YUY2 surface that holds the background img which at the moment is YUY2 data. The reason my background is in YUY2 colorspace is because im receiving 30 FPS from a frame grabber card that is sending a byte array of YUY2 data bits.
I copy this using
[font="Consolas"][font="Consolas"]UpdateSurface(templeafSurf,NULL,tempbuffSurf,&pt); tempbuffSurf being the YUY2 surface containing the background img.
[/font][/font]Finally I use
[font="Consolas"][font="Consolas"]StretchRect(tempbuffSurf,&rect,g_BackBuffer,NULL,D3DTEXF_LINEAR )
and flip it to the back buffer which is also D3DFMT_A8R8G8B8 then present it to the screen
This works but no alpha channel on the png image anymore so I get the black background of the png img ontop of my YUY2 background

This basically sums up what im trying to do.[/font][/font]
[/font][/font]



[/font][/font][/font][/font]
Are you forced to use the YU2U format for your backbuffer?

If you are you may want to consider just using a color key when loading your texture instead of using an alpha channel.
Hi no im not forced to use YUY2 surface I can convert the color space to either RGB24 or RGB32 but im not sure of the formula to use when I lock the surface to copy the RGB byte array I think I should use RGB32 as it has the alpha channel.
currently I am copying the YUY2 byte array to the surface this way. I dont want to use D3DXLoadSurfaceFromMemory(..) as it is to resource hungry unless im using it wrong.

D3DLOCKED_RECT slRect;

int i;

BYTE *dst;

hr=tempBkSurf->LockRect(&slRect, &rect, D3DLOCK_READONLY );

dst = (BYTE *)slRect.pBits;

for(i=0; i<uiH; i++)
{
CopyMemory(dst, btAddr, StepSize);
btAddr+= StepSize;
dst += slRect.Pitch;
}

tempBkSurf->UnlockRect();



if you have a sample that will copy the RGB32 byte array with an alpha channel that would be very helpful.
As for color key I thought this was removed from DX9 as I use the color key in DirectDraw that works fine for what im trying to do.
A sample using color key under DX9 would be great
Thanks

A sample using color key under DX9 would be great
Thanks


http://www.directxtu...ics/dx9B12.aspx

This tutorial is for 3d but the same basic concept applies.
When you load your texture you specify the color key and it makes that the transparency color.

I know it works because I use it =)

edit:
Once you commit things to a surface I don't think colorkeying applies though.
Especially with stretchrect etc.

If you could keep your stuff in a texture instead of loading it to a surface that would be the easiest.


edit edit:
Oh I think I get it now, your trying to use directx9 like how you used directdraw as a 2d renderer, I think there is a much better way of doing things.
basically you render your texture to (a) quad(s)

tutorial: (ugh I couldn't find the really good once since the gamedev overhaul but here is one for dx8)
http://archive.gamedev.net/archive/reference/programming/features/2ddx8/index.html
Hi Thanks for the help I finally worked out what I needed to do by following the sample from this link http://www.codesampler.com/dx9src/dx9src_4.htm#dx9_alpha_blending_framebuffer

This topic is closed to new replies.

Advertisement