Thread: Help! something about transparency

  1. #1
    Registered User Hermisky's Avatar
    Join Date
    Feb 2006
    Location
    Nanjing
    Posts
    16

    Question Help! something about transparency

    I am using directx9 to do a little 2d program.

    Much like the way in direct draw, i use "CreateOffscreenPlainSurface()" to create an offsceen surface, then call "D3DXLoadSurfaceFromFile()" to load a map into this offscreen surface. after copy some curtain part from this surface to backbuffer by calling "StretchRect()", the "Present()" is used to draw the backbuffer.

    so far, these worked well. but these is color in the map i want it to be transparent, like pink : RGB(255,0,255). so i set the "Colorkey" param in function "D3DXLoadSurfaceFromFile()" to value 0x00FF00FF, then call some "SetRenderState" function to set alpha blending before the "StretchRect()" copy contents from offsurface to backbuffer(detail code is attached below). And it dosen't work, the pink is still there.

    maybe i didn't use these function right, can someone check my code, and tell me what should i do to make it work?

    any help would be greatly appreciated.....

    init and load the map file
    Code:
    myPainter.InitDirect3D(hwnd, clientRect.right, clientRect.bottom);
    myPainter.CreateOffScrSurfaceFromFile("res\\chess.bmp", 0x00ff00ff);
    code in msg loop
    Code:
    if(myPainter.BeginRender())
    {
    				
    	myPainter.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
    	myPainter.m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    	myPainter.m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    
    
    	// also tried these way
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCCOLOR);
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
    
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_ALPHAREF, 0x01);
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
    
    
    	myPainter.Render(chessman1);//chessman has the source rect and dest rect in it.
    
    	myPainter.Render(chessman2);
    				
    
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    
    	//myPainter.m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    
    	myPainter.EndRender();
    }

    code of myPainter definition
    Code:
    bool KD3D9Painter::InitDirect3D(HWND hWnd, UINT nWidth, UINT nHeight)
    {
    	Clean();//for safety
    
    	//create d3d9 object
    	if((m_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
    		return false;
    
    	//set d3d presentation parameters struct
    	D3DPRESENT_PARAMETERS d3dpp;
    	ZeroMemory(&d3dpp, sizeof(d3dpp));
    	d3dpp.Windowed = true;
    	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
    	d3dpp.BackBufferCount = BACKBUF_COUNT;
    	d3dpp.BackBufferHeight = nHeight;
    	d3dpp.BackBufferWidth = nWidth;
    	d3dpp.hDeviceWindow = hWnd;
    
    	//create d3d device here
    	if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice)))
    		return false;
    	return true;
    }
    
    bool KD3D9Painter::CreateOffScrSurfaceFromFile(LPCTSTR pFile, D3DCOLOR ColorKey)
    {
    	if(m_pD3DDevice == NULL)
    		return false;
    	D3DXIMAGE_INFO imageInfo;
    	if(FAILED(D3DXGetImageInfoFromFile(pFile, &imageInfo)))
    		return false;
    	if(FAILED(m_pD3DDevice->CreateOffscreenPlainSurface(imageInfo.Width, imageInfo.Height, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pOffScrSurface, NULL)))
    		return false;
    	if(FAILED(D3DXLoadSurfaceFromFile(m_pOffScrSurface, NULL, NULL, pFile, NULL, D3DX_DEFAULT, ColorKey, NULL)))
    		return false;
    	return true;
    }
    
    bool KD3D9Painter::BeginRender()
    {
    	if(m_pD3DDevice == NULL)
    		return true;
    
    	if(FAILED(m_pD3DDevice->BeginScene()))
    		return false;
    
    	if(FAILED(m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 255), 1.0f, 0)))
    		return false;
    	if(FAILED(m_pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackbuf)))
    		return false;
    	return true;
    }
    
    void KD3D9Painter::Render(const KSprite& kSpr)
    {
    	if(m_pD3DDevice == NULL)
    		return;
    	m_pD3DDevice->StretchRect(m_pOffScrSurface, &(kSpr.srcRect), m_pBackbuf, &(kSpr.pos), D3DTEXF_NONE);
    }
    
    bool KD3D9Painter::EndRender()
    {
    	if(m_pD3DDevice == NULL)
    		return false;
    
    	if(FAILED(m_pD3DDevice->EndScene()))
    		return false;
    
    	if(FAILED(m_pD3DDevice->Present(NULL, NULL, NULL, NULL)))
    		return false;
    	return true;
    }

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    myPainter.CreateOffScrSurfaceFromFile("res\\chess.bmp", 0x00ff00ff);
    From the MDSN page for D3DXLoadSurfaceFromFile():

    ColorKey
    [in] D3DCOLOR value to replace with transparent black, or 0 to disable the colorkey. This is always a 32-bit ARGB color, independent of the source image format. Alpha is significant and should usually be set to FF for opaque color keys Thus, for opaque black, the value would be equal to 0xFF000000.
    In other words, I think it goes ARGB, not RGBA.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User Hermisky's Avatar
    Join Date
    Feb 2006
    Location
    Nanjing
    Posts
    16
    thanks for reply, dwks.

    but i never mean RGBA, the value i used "0x00ff00ff" means ARGB(0,255,0,255), transparent pink.

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    That's what I'm telling you -- I don't think it does. Try
    Code:
    0xff00ff00
    instead.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User Hermisky's Avatar
    Join Date
    Feb 2006
    Location
    Nanjing
    Posts
    16
    it dosen't work, and why do you suggest 0xff00ff00 ? i don't understand~~

    the funny thing is , if i set the colorkey to 0xffff00ff, all my pink color turned to be black. It totally confused me, maybe i misunderstand the meaning of "colorkey"?

  6. #6
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    I guess you were loading a 24 bit image? With an absence of alpha information it is very likely that the loader automatically set the images to having full alpha. Otherwise the images you load would all be invisible until you set the alpha on them.

    Anyway congrats; it sounds like you successfully masked your image. Just thought I'd let you know why it works that way. Had me confused for a while once too.

  7. #7
    Registered User Hermisky's Avatar
    Join Date
    Feb 2006
    Location
    Nanjing
    Posts
    16
    no, it didn't work out yet.... the ugly pink (or opaque black if i use 0xffff00ff) is still on my screen, it's killing me~

    missing you, DirectDraw~~

  8. #8
    Registered User Hermisky's Avatar
    Join Date
    Feb 2006
    Location
    Nanjing
    Posts
    16
    Quote Originally Posted by mike_g View Post
    I guess you were loading a 24 bit image? With an absence of alpha information it is very likely that the loader automatically set the images to having full alpha. Otherwise the images you load would all be invisible until you set the alpha on them.

    Anyway congrats; it sounds like you successfully masked your image. Just thought I'd let you know why it works that way. Had me confused for a while once too.

    and? you got solution ?

  9. #9
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    From googling it seems the direct draw 'colourkey' is not the same as a mask. with a colour key you should be setting a high and low bounds for colours to mask out, yet you do not seem to be doing this. Dont know if thats any help tho. Never used DD myself.

  10. #10
    Registered User Hermisky's Avatar
    Join Date
    Feb 2006
    Location
    Nanjing
    Posts
    16
    but i am not using directdraw, it is d3d9 i am using here.

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    There is no such thing as a colorkey in Direct3D. It is not supported nor implemented in any form.

    Two options:

    Alpha masks
    You must create an alpha channel mask for the image and set your render states as follows. Please note that because levels of transparency are supported you must Z-sort the quads and billboards to render or the resulting render will not look correct. This may or may not apply to your 2D system depending on how you are using Direct3D to do 2D.

    Code:
    ...
    //Enable alpha blending via alpha masks
    m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
    m_pDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
    m_pDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
    ...
    Alpha testing
    Optionally you can use alpha testing which does not support levels of transparency by deciding on a threshhold value. Depending on your settings and the alpha test type Direct3D will not render pixels that are less than/greater than/equal to the threshhold value.
    Code:
    ...
    DWORD threshhold=0x0000007f
    m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE,TRUE);
    m_pDevice->SetRenderState(D3DRS_ALPHAREF, threshhold);
    m_pDevice->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATER);
    ...
    This turns on alpha testing, sets the threshhold to 127, and then sets the compare function to be greater than. Any pixels with alpha's greater than 127 will be rendered and all other pixels will not be rendered. Please note that because the frame buffer is completely untouched for pixels that fail the test you can render unsorted billboards and textured quads.

    You should use state blocks to record the state for this type of rendering. Record the state block at application startup and prior to rendering alpha test dependent objects apply the state block. After applying the state block then you can restore the previous state block and render the rest of your objects. State blocks ease the pain of having 50 thousand SetRenderState calls jammed between renders and also eases the pain of knowing which states were set by what object and the current status of all the states.
    Last edited by VirtualAce; 11-07-2007 at 07:06 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 06-17-2008, 04:00 PM
  2. Are these possible - transparency and colors
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 05-17-2007, 12:57 AM
  3. How do you print on a transparency ?
    By Zeeshan in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 02-25-2003, 02:29 PM
  4. Transparency
    By Hunter2 in forum Windows Programming
    Replies: 25
    Last Post: 07-29-2002, 10:58 AM
  5. GIF Transparency
    By dbaryl in forum A Brief History of Cprogramming.com
    Replies: 17
    Last Post: 04-20-2002, 05:46 PM