Jump to content
  • Advertisement
Sign in to follow this  
nchannon

How do I copy a texture to a surface with transparency

This topic is 2589 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I am trying to copy hopfully a transparant texture to a off screen surface then copy that offscreen surface to another offscreen surface which contains an image while keeping the first surface transparent overlayed ontop of the second surface.

I have included my source so you can see what im trying to do
What the code is doing:
GetOvrData(..) calls
CreateMatrixView(uiW, uiH); this creates a 2x2 matrix please see attachement:
2x2 matrix created from CreateMatrixViewbackbuff.JPG I then create an off screen surface from a YUY2 buffer streams this works fine
I then need to copy the textured surface that should be transparent except for the the white grids and using black as the transparent color onto my YUY2 surface. then present it to the front buffer.
Both surfaces display fine except g_ScreenMatrixSurface is not transparent and hides tempbuffSurf

My code:

HRESULT CMainDX::CreateMatrixView(int nWidth, int nHeight){
HDC hDC;
HRESULT hr;
RECT rect,rc;
rect.right = m_RectOverlaySrc.right;
rect.bottom = m_RectOverlaySrc.bottom;
rect.top = 0;
rect.left = 0;
//Enable alpha blending via alpha masks
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,true);//alpha
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);//alpha
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);//alpha
if(g_pd3dDevice->CreateTexture(nWidth, nHeight,0,0,D3DFMT_A8R8G8B8 ,D3DPOOL_MANAGED,&g_Texture,NULL) != D3D_OK)
{
g_Texture->Release();
return DT_ERROR;
}
if (g_pd3dDevice->CreateOffscreenPlainSurface(nWidth, nHeight, D3DFMT_YUY2 , D3DPOOL_SYSTEMMEM, &tempSurf, NULL) != D3D_OK)
{
tempSurf->Release();
return DT_ERROR;
}
LPDIRECT3DSURFACE9 tempBkSurf;
//g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET , D3DCOLOR_ARGB(255,0, 0, 0), 1.0f, 0);// remove to make transparent g_pd3dDevice->GetBackBuffer(0,0, D3DBACKBUFFER_TYPE_MONO, &tempBkSurf);
hr=tempBkSurf->GetDC(&hDC);
::SelectObject(hDC, m_hGridLinesPen);
m_SplitInfo.scSplitConf = *(views[m_MatrixView]);
double gridX = (double)(rect.right-rect.left)/m_SplitInfo.scSplitConf.szBoundSize.cx;
double gridY = (double)(rect.bottom-rect.top)/m_SplitInfo.scSplitConf.szBoundSize.cy;
for(int j=0;j<(signed)m_SplitInfo.scSplitConf.uNumRects;j++){
rc = m_SplitInfo.scSplitConf.rcRect[j];
//## Top Line ##//
::MoveToEx(hDC, rc.left*gridX-0, rc.top*gridY-1, NULL);
::LineTo(hDC, rc.right*gridX-1, rc.top*gridY-0);
//## Right Line ##//
::MoveToEx(hDC, rc.right*gridX-1, rc.top*gridY-0, NULL);
::LineTo(hDC, rc.right*gridX-1, rc.bottom*gridY-0);
//## Left Line ##//
::MoveToEx(hDC, rc.left*gridX-0, rc.top*gridY-0, NULL);
::LineTo(hDC, rc.left*gridX-0, rc.bottom*gridY-0);
//## Bottom Line ##//
::MoveToEx(hDC, rc.left*gridX-0, rc.bottom*gridY-0, NULL);
::LineTo(hDC, rc.right*gridX-1, rc.bottom*gridY-0);
}
tempBkSurf->ReleaseDC(hDC);
D3DSURFACE_DESC sdesc;
tempBkSurf->GetDesc(&sdesc);
if (g_pd3dDevice->CreateOffscreenPlainSurface(nWidth, nHeight,D3DFMT_A8R8G8B8 , D3DPOOL_DEFAULT, &g_ScreenMatrixSurface, NULL) != D3D_OK)
{
g_ScreenMatrixSurface->Release();
return DT_ERROR;
}
hr=g_Texture->GetSurfaceLevel(0,&g_ScreenMatrixSurface);
hr = D3DXLoadSurfaceFromSurface(g_ScreenMatrixSurface, NULL, NULL, tempBkSurf, NULL, NULL, D3DX_FILTER_LINEAR, D3DCOLOR_ARGB(255,0, 0, 0));
//hr = D3DXLoadSurfaceFromSurface(tempSurf, NULL, NULL, g_ScreenMatrixSurface, NULL, NULL, D3DX_FILTER_LINEAR, D3DCOLOR_ARGB(255,0, 0, 0));
//tempSurf->GetDesc(&sdesc);
MatrixSetup = true;
//g_ScreenMatrixSurface->GetDesc(&sdesc);
// tempBkSurf->GetDesc(&sdesc);
// hr = g_pd3dDevice->UpdateSurface(tempSurf,&m_RectMainWindowDest,g_ScreenMatrixSurface,0);
hr= D3DXSaveSurfaceToFile(_T("backbuf.bmp"), D3DXIFF_BMP, g_ScreenMatrixSurface, NULL, NULL);
tempBkSurf->Release();
return S_OK;
}

BOOL CMainDX::GetOvrData(BYTE *btAddr, UINT uiW, UINT uiH, UINT bdid, UINT bdCount){
if(!Setup) if(!OvrCap)
{
if( NULL == g_pd3dDevice )
return true;
if(!MatrixSetup)
CreateMatrixView(uiW, uiH);
HRESULT hr;
D3DSURFACE_DESC sdesc;
g_StreamSurface->GetDesc(&sdesc);
RECT rect;
rect.bottom = uiH;
rect.right = uiW;
rect.left = 0;
rect.top = 0;
g_BackBuffer->GetDesc(&sdesc);
RECT bkRect;
bkRect.bottom = sdesc.Height;
bkRect.right = sdesc.Width;
bkRect.left = 0;
bkRect.top = 0;
DWORD start = ::GetTickCount();
//RenderMatrix();
int StepSize;
StepSize = uiW * 2;
LPDIRECT3DSURFACE9 tempBkSurf;
if (g_pd3dDevice->CreateOffscreenPlainSurface(rect.right, rect.bottom, D3DFMT_YUY2, D3DPOOL_SYSTEMMEM, &tempBkSurf, NULL) != D3D_OK)
{
tempBkSurf->Release();
return DT_ERROR;
}
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();
LPDIRECT3DSURFACE9 tempbuffSurf;
if (g_pd3dDevice->CreateOffscreenPlainSurface(rect.right, rect.bottom, D3DFMT_YUY2 , D3DPOOL_DEFAULT, &tempbuffSurf, NULL) != D3D_OK)
{
tempbuffSurf->Release();
return DT_ERROR;
}
g_ScreenMatrixSurface->GetDesc(&sdesc);
tempbuffSurf->GetDesc(&sdesc);
// g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0 ,0 , 0, 0), 1.0f, 0); g_pd3dDevice->GetBackBuffer(0,0, D3DBACKBUFFER_TYPE_MONO, &g_BackBuffer);
//g_pd3dDevice->BeginScene();
hr = g_pd3dDevice->UpdateSurface(tempBkSurf,NULL,tempbuffSurf,NULL);
//hr = g_pd3dDevice->UpdateSurface(g_ScreenMatrixSurface,NULL,tempbuffSurf,NULL);
//hr = g_pd3dDevice->StretchRect(tempSurf,NULL,tempbuffSurf,NULL,D3DTEXF_LINEAR );
hr = D3DXLoadSurfaceFromSurface(tempbuffSurf, NULL, NULL, g_ScreenMatrixSurface, NULL, NULL, D3DX_FILTER_NONE, D3DCOLOR_ARGB(255,0, 0, 0));
//g_pd3dDevice->EndScene();
hr = g_pd3dDevice->StretchRect(tempbuffSurf,&rect,g_BackBuffer,NULL,D3DTEXF_LINEAR );
//hr= D3DXSaveSurfaceToFile(_T("backbuf.bmp"), D3DXIFF_BMP, g_ScreenMatrixSurface, NULL, NULL);
// g_ScreenMatrixSurface->GetDesc(&sdesc);
g_BackBuffer->GetDesc(&sdesc);
//hr= D3DXSaveSurfaceToFile(_T("backbuf.bmp"), D3DXIFF_BMP, temp, NULL, NULL);
g_BackBuffer->Release();
tempBkSurf->Release();
tempbuffSurf->Release();
DWORD elapsed = ::GetTickCount() - start;
_RPT1 ( _CRT_WARN, "Elapsed time %lu\r\n", elapsed );
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
return 0;
}
Edited by nchannon

Share this post


Link to post
Share on other sites
Advertisement
I'm thinking color blending.... Since I'm not sure alpha values can be preserved with render targets.

Share this post


Link to post
Share on other sites
Hi Thanks for the reply color blending this is new to me could you post a sample or point me into the right direction
Thanks

Share this post


Link to post
Share on other sites
Your original description is hard to read. Can you describe the specific effect you want. Is this several copies of the same screen and you are overlaying to make like a drunken camera that sees cross eyed? Do you have it some images showing where it goes wrong? Your original image is 4 separate black copies and I don't know what they are actually supposed to be.

Share this post


Link to post
Share on other sites
Hi I dont want the four black copy's that are in the sample I want the blank to be transparent overlay over a background, I only want to see the white lines on top of the back ground image but my problem is the background image is in YUY2 format on a YUY2 surface color space which dosnt support the alpha channel I can convert the YUY2 data to RGB32 before copying the pixels to a surface that support alpha blending D3DFMT_A8R8G8B8.
But im not sure how to copy the RGB32 byte array to a locked textured surface where I can make sure I have an alpha channel that is black any sample on how to copy the byte array to the locked textured surface.
I think its done something like this but i think this is not correct.
BYTE *RGB32; // already holds the original RGB32 byte array
BYTE * newRGB = new newRGB[HEIGHT * WIDTH * 4];
for(int i =0;i<HEIGHT;i++)
{
for(int j=0;j<WIDTH,j++)
{
// this is where im a Little unsure
newRGB[j * 4 + 0] = RGB32; //alpha
newRGB[j * 4 + 1] = RGB32; //Blue
newRGB[j * 4 + 2] = RGB32; //Green
newRGB[j * 4 + 3] = RGB32; //Red
}
}

Share this post


Link to post
Share on other sites
You can use blending that work based off colour. So you can set a colour that will be a transparency mask, which means it doesn't write, when you do some rendering to an offscreen surface or to your game surface to get what you want. Or you can set a blending mode that effectively makes the black transparent.

See here for openGL implementation: http://nehe.gamedev.net/tutorial/moving_bitmaps_in_3d_space/17001/

DirectX method: http://www.directxtutorial.com/tutorial9/b-direct3dbasics/dx9B11.aspx

I'm not sure if the second tutorial explains the theory of using black as a transparent color or not. So best read the first one first regardless of the fact you're using direct X

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!