Discussion:
Help: ColorKey In DirectX9
(too old to reply)
cHoIcE lEe
2005-04-07 13:17:09 UTC
Permalink
I have a Image called button.bmp with fomat RGB of 24bit. In the Image, a
button is surrounded by an area in color gray(RGB(125,125,125)).

I want to show the button in my app without the gray area so that firstly I
create a surface named pSurface with function CreateOffscreenPlainSurface()
and secondly I load the Image in with function D3DXLoadSurfaceFromFile().
Finaly, I copy the data in pSurface to BackBuffer with function
D3DXLoadSurfaceFromSurface(). I pass the para ColorKey with value
D3DCOLOR_ARGB(0xff, 125,125,125) .

But the function D3DXLoadSurfaceFromSurface() did not funtioned as I
expected. In my app, The area surround the button was still there which just
turn into BLACK!

I have try several values for para ColorKey in function
D3DXLoadSurfaceFromFile() and D3DXLoadSurfaceFromSurface(), for instance, 0,
D3DCOLOR_ARGB(0, 125,125,125), but it does not help. The area surround the
button is always there in case sometimes it is gray and sometime it is black.

I have read the DirectX9 document which says ColorKey is not directly
surport in DirectX9. Following the document, I have tried a lot of
SetRenderState()s. But it takes no effect.

I am going crazy about this. Who knows how to make the thing work?
cHoIcE lEe
2005-04-07 13:23:08 UTC
Permalink
The March Hare [MVP]
2005-04-07 14:11:51 UTC
Permalink
On Thu, 7 Apr 2005 06:23:08 -0700, cHoIcE lEe wrote:

It is:

microsoft.public.win32.programmer.directx.graphics
--
Please read this before replying:
1. Dshow & posting help: http://tmhare.mvps.org/help.htm
2. Trim & respond inline (please don't top post or snip everything)
3. Benefit others: follow up if you are helped or you found a solution
Eyal Teler
2005-04-07 21:24:20 UTC
Permalink
The D3DX function convert the colour key value to transparent black,
i.e., the value ARGB(0,0,0,0). You need to turn alpha blending or
alpha testing on, and then the value will be drawn as transparent. If
you don't, it will be drawn as black.

Eyal
Post by cHoIcE lEe
I have a Image called button.bmp with fomat RGB of 24bit. In the Image, a
button is surrounded by an area in color gray(RGB(125,125,125)).
I want to show the button in my app without the gray area so that firstly I
create a surface named pSurface with function CreateOffscreenPlainSurface()
and secondly I load the Image in with function D3DXLoadSurfaceFromFile().
Finaly, I copy the data in pSurface to BackBuffer with function
D3DXLoadSurfaceFromSurface(). I pass the para ColorKey with value
D3DCOLOR_ARGB(0xff, 125,125,125) .
But the function D3DXLoadSurfaceFromSurface() did not funtioned as I
expected. In my app, The area surround the button was still there which just
turn into BLACK!
I have try several values for para ColorKey in function
D3DXLoadSurfaceFromFile() and D3DXLoadSurfaceFromSurface(), for instance, 0,
D3DCOLOR_ARGB(0, 125,125,125), but it does not help. The area surround the
button is always there in case sometimes it is gray and sometime it is black.
I have read the DirectX9 document which says ColorKey is not directly
surport in DirectX9. Following the document, I have tried a lot of
SetRenderState()s. But it takes no effect.
I am going crazy about this. Who knows how to make the thing work?
cHoIcE lEe
2005-04-08 03:53:01 UTC
Permalink
Thank you very much for your advice.
It seems that it does not help to set alpha test or to set alpha blending.
Or I was just did it in a wrong way.
The following is my code:

#pragma once
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

HWND InitInstance(HINSTANCE hInstance, int nCmdShow);
ATOM RegisterWindowClass(HINSTANCE hInstance);

HRESULT InitD3D(HWND hWnd);
BOOL InitGame();

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam);

void RenderNormal();
void ReleaseGame();

IDirect3D9* g_pD3D = 0;
LPDIRECT3DDEVICE9 g_pd3dDevice = 0;

HINSTANCE g_hInstance;
HWND g_hMainWnd;

LPDIRECT3DSURFACE9 g_pSurface = 0;
LPDIRECT3DSURFACE9 g_pBackSurface = 0;
D3DXIMAGE_INFO g_ImageInfo;

BOOL InitGame()
{
HRESULT Result = 0;

ZeroMemory( &g_ImageInfo,sizeof(D3DXIMAGE_INFO) );

if( SUCCEEDED( D3DXGetImageInfoFromFile( "Button.bmp", &g_ImageInfo ) ) )
{
Result = g_pd3dDevice->CreateOffscreenPlainSurface( g_ImageInfo.Width,
g_ImageInfo.Height,
D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &g_pSurface, NULL );
}

Result = D3DXLoadSurfaceFromFile( g_pSurface, NULL, NULL, "Button.bmp",
NULL,
D3DX_FILTER_NONE, 0, NULL );
return (Result < 0) ? FALSE : TRUE;
}

HRESULT InitD3D(HWND hWnd)
{
if(NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;//D3DFMT_UNKNOWN;

if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}

g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface);

return S_OK;
}

void RenderNormal()
{
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_ARGB(0,0,0,255),1.0f, 0);

/*g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE ,TRUE );
g_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x01 );
g_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);*/

g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);
// Begin the scene
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
RECT rt;
SetRect( &rt, 200,200, 200+g_ImageInfo.Width, 200+g_ImageInfo.Height);

D3DXLoadSurfaceFromSurface( g_pBackSurface, NULL, &rt, g_pSurface,
NULL, NULL, D3DX_FILTER_NONE, 0xff7d7d7d );

g_pd3dDevice->EndScene();
}
// Present the back buffer contents to the display
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}

void ReleaseGame()
{
if(g_pSurface)
g_pSurface->Release();

if(g_pBackSurface)
g_pBackSurface->Release();

if( g_pd3dDevice )
g_pd3dDevice->Release();

if( g_pD3D )
g_pD3D->Release();
}


HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
{
g_hInstance = hInstance; // Store instance handle in our global variable

RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = 800;
rc.bottom = 600;
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );

#ifndef _DEBUG

g_hMainWnd = CreateWindow( "TestColorKey",
"TestColorKey", /*0,*/WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, 0L,
NULL, hInstance, NULL);
#else

g_hMainWnd = CreateWindow( "TestColorKey",
"TestColorKey", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, 0L,
NULL, hInstance, NULL);

#endif

if (!g_hMainWnd) return FALSE;

ShowWindow(g_hMainWnd, nCmdShow);
UpdateWindow(g_hMainWnd);

return g_hMainWnd;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch(message)
{
case WM_DESTROY:

PostQuitMessage( 0 );
return 0L;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}


ATOM RegisterWindowClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wcex.lpfnWndProc = (WNDPROC) WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);//hInstance;
wcex.hIcon = NULL;//LoadIcon (NULL, IDI_APPLICATION)
;//LoadIcon(hInstance, (LPCTSTR)IDI_MJ);wndclass.hIcon = LoadIcon (NULL,
IDI_APPLICATION) ;
//wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wcex.hIconSm = NULL;//LoadIcon(hInstance, (LPCTSTR)IDI_MJ);
wcex.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "TestColorKey";

return RegisterClassEx(&wcex);
}


int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;

RegisterWindowClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
if( S_OK != InitD3D(g_hMainWnd))
return false;
if(!InitGame())
return false;

while(1)
{
if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if( 0 == GetMessage(&msg, NULL, 0, 0 ) )
{
// WM_QUIT was posted, so exit
return (int)msg.wParam;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
RenderNormal();
}
}

ReleaseGame();

return (int) msg.wParam;
}
Timo Kruse
2005-04-08 04:27:44 UTC
Permalink
Post by cHoIcE lEe
/*g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE ,TRUE );
g_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x01 );
g_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);*/
this would work, if you render something (see below).
Post by cHoIcE lEe
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE );
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);
You are using the colors for blending, from your description i think you did
not mean to do that. If you intend to use ALPHABlending for transparency of
certain parts of a texture, it should be something like this:
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
Post by cHoIcE lEe
D3DXLoadSurfaceFromSurface( g_pBackSurface, NULL, &rt, g_pSurface,
NULL, NULL, D3DX_FILTER_NONE, 0xff7d7d7d );
I am not sure whether D3DXLoadSurfaceFromSurface is making use of
Alphablending, but I seriously doubt it. Renderstates are there for
rendering, so you should try with DrawPrimitive of any kind or with
ID3DXSprite (which is internally rendering 2 triangles) if you are just
interested in 2D.
cHoIcE lEe
2005-04-08 09:09:02 UTC
Permalink
Thank you for your help, but the problem is still there.
I have tried run the program in your way, but it does not work.
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

I am going to try to figure out how to make D3DXLoadSurfaceFromSurface()
function properly in other ways, may be in the way you have mentioned.

Thank you again for your help!
Post by Timo Kruse
......
You are using the colors for blending, from your description i think you did
not mean to do that. If you intend to use ALPHABlending for transparency of
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DXLoadSurfaceFromSurface( g_pBackSurface, NULL, &rt, g_pSurface,
NULL, NULL, D3DX_FILTER_NONE, 0xff7d7d7d );
I am not sure whether D3DXLoadSurfaceFromSurface is making use of
Alphablending, but I seriously doubt it. Renderstates are there for
rendering, so you should try with DrawPrimitive of any kind or with
ID3DXSprite (which is internally rendering 2 triangles) if you are just
interested in 2D.
Eyal Teler
2005-04-08 10:54:09 UTC
Permalink
The loading seems to function properly. Transparency only comes into
effect when you draw using a texture. If you're doing this, and you
don't get transparency, then your problem is when drawing.

Eyal
Post by cHoIcE lEe
Thank you for your help, but the problem is still there.
I have tried run the program in your way, but it does not work.
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
I am going to try to figure out how to make D3DXLoadSurfaceFromSurface()
function properly in other ways, may be in the way you have mentioned.
Thank you again for your help!
Post by Timo Kruse
......
You are using the colors for blending, from your description i think you did
not mean to do that. If you intend to use ALPHABlending for transparency of
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DXLoadSurfaceFromSurface( g_pBackSurface, NULL, &rt, g_pSurface,
NULL, NULL, D3DX_FILTER_NONE, 0xff7d7d7d );
I am not sure whether D3DXLoadSurfaceFromSurface is making use of
Alphablending, but I seriously doubt it. Renderstates are there for
rendering, so you should try with DrawPrimitive of any kind or with
ID3DXSprite (which is internally rendering 2 triangles) if you are just
interested in 2D.
Loading...