• ベストアンサー

描画を透明にする方法

Directxの質問なのですがある色だけ透明にするにはどうしたらいいのでしょうか? void Draw(ID3DXSprite* g_pSprite,DDXTEX* g_pTexture) { // クリア g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, g_clrBackgroundColor, 1.0f, 0); // 描画開始 if (FAILED(g_pd3dDevice->BeginScene())) { g_pd3dDevice->Present(NULL, NULL, NULL, NULL); return; } // スプライトを描画 g_pSprite->Begin(D3DXSPRITE_ALPHABLEND); g_pSprite->Draw( g_pTexture->m_pTexture, // LPDIRECT3DTEXTURE9 pTexture NULL, // CONST RECT *pSrcRect &g_vCenter, // CONST D3DXVECTOR3 *pCenter NULL, // CONST D3DXVECTOR3 *pPosition g_pTexture->m_clrAlpha // D3DCOLOR Color ); g_pSprite->SetTransform(&g_mat); g_pSprite->End(); // シーン描画の終了とバックバッファからの表示 g_pd3dDevice->EndScene(); g_pd3dDevice->Present(NULL, NULL, NULL, NULL); } g_pTexture->m_clrAlphaで半透明するはずだとは思うのですが。できません。わかる方いらしたらご教授のほどよろしくお願いします。

  • 79562
  • お礼率68% (164/239)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

 こんばんは。 ・g_pSprite->Drawの5番目の引数は透明化するわけではないのですね。そこで質問なのですが、g_pSprite->Drawの5番目の引数は何の意味があるのでしょうか?  此れはアルファブレンディングと言って、テクスチャ全体(スプライト)とシーンの色彩を半透明で合成する為の物です(幽霊みたいに透ける)。 ・::D3DXCreateTextureFromFile(g_pd3dDevice, g_pTexture->m_Filename, &g_pTexture->m_pTexture);ではなぜ駄目だったのでしょうか。  此れに関しては「簡易版の関数で詳細設定が出来ない代わりにパラメータが少なくて呼び出しやすい」程度に捕らえておけば良いと思います。  windows系関数の幾つかには、簡易版と詳細版(関数名の先頭か末尾にExが付く)の二つが存在します。

79562
質問者

お礼

そうだったんですか!回答ありがとうございました。

その他の回答 (4)

回答No.4

 こんにちは。  要はカラーキーを指定したいのでしょうか。  http://msdn.microsoft.com/ja-jp/library/cc372753.aspx  テクスチャをロードする時、透明にしたい色彩を指定しないと出来ない様です。  右から4番目のパラメータに、0xFFRRGGBBでもって消したい色彩を指定します。  例えば、緑色を消したければ、0xFF00FF00と言う事です。  以下の例はサイズが640x480、黒が透明の1枚から成るテクスチャを作成します。  ::D3DXCreateTextureFromFileEx(g_pd3dDevice, lpszFilename, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &g_pTexture);

79562
質問者

お礼

できました!感動的です!g_pSprite->Drawの5番目の引数は透明化するわけではないのですね。そこで質問なのですが、g_pSprite->Drawの5番目の引数は何の意味があるのでしょうか? あと::D3DXCreateTextureFromFile(g_pd3dDevice, g_pTexture->m_Filename, &g_pTexture->m_pTexture); ではなぜ駄目だったのでしょうか。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

そういえば、g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE,TRUE); が必要かも知れません。 BeginScene()の後に入れてみてください。

79562
質問者

お礼

入れてみたのですが、駄目でした。 RECT rect={0,0,1020,480}; とやるとうまくいくのですが、サイズは 描画本体は680X460なのでおかしいのですが・・・描画の透明化も変わらずです。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

うーん。分りません。 とりあえず、SetTransform()を止めてみるとか、g_pTexture->m_clrAlphaを止めて直接D3DCOLOR_ARGB(30,0,0,0)を書いてみるとか。色々試してみてください。 シンプルな形でもし表示できたら逆にたどってうまくいかない原因をつぶすのがバグ退治の基本です。 それと、SetTransform()の位置が変じゃないでしょうか? Begin()前じゃないとTransformが即反映されない気がするんですが。

79562
質問者

補足

試したり探してみたのですが、見つかりませんでした。SetTransform()もやってみたのですが駄目でした。 // デバイス初期化 HRESULT InitializeD3D(HWND hWnd) { HRESULT hr; D3DPRESENT_PARAMETERS d3dpp; D3DDISPLAYMODE dmode; // D3Dオブジェクトの作成 g_pD3D = ::Direct3DCreate9(D3D_SDK_VERSION); // 現在のディスプレイモードを取得 ::ZeroMemory(&d3dpp, sizeof(d3dpp)); hr = g_pD3D->GetAdapterDisplayMode(g_nAdapter, &dmode); if (FAILED(hr)) return hr; // パラメータの設定 d3dpp.Windowed = TRUE; // ウィンドウモードで表示 d3dpp.SwapEffect = g_dwSwapEffect; d3dpp.BackBufferFormat = dmode.Format; // デスクトップのフォーマットを使用 d3dpp.BackBufferCount = 2; // トリプルバッファリングを行う d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // 16Bit Zバッファ作成 // IDirect3DDevice9オブジェクトの作成 hr = g_pD3D->CreateDevice(g_nAdapter, g_dwDeviceType, hWnd, g_dwBehaviorFlags, &d3dpp, &g_pd3dDevice); if (FAILED(hr)) return hr; return S_OK; } // デバイスの解放 void FinalizeD3D() { // IDirect3DDevice9オブジェクトの解放 if (g_pd3dDevice != NULL) g_pd3dDevice->Release(); g_pd3dDevice = NULL; // IDirect3D9オブジェクトの解放 if (g_pD3D != NULL) g_pD3D->Release(); g_pD3D = NULL; } HRESULT ReadBMP(ID3DXSprite** g_pSprite,LPCTSTRlpszFilename,DDXTEX* g_pTexture) {  /*省略*/ } // スプライト破棄 void DestroySplite(ID3DXSprite* g_pSprite,DDXTEX* g_pTexture) { if (g_pTexture->m_pTexture != NULL) g_pTexture->m_pTexture->Release(); g_pTexture = NULL; if (g_pSprite != NULL) g_pSprite->Release(); g_pSprite = NULL; } // 変換行列の設定 void SetMatrix(HWND hWnd) { RECT rc={0,0,0,0}; FLOAT x, y; ::D3DXMatrixIdentity(&g_mat); // ウィンドウサイズにスプライトの大きさをあわせる ::GetWindowRect(hWnd, &rc); x = (FLOAT)(rc.right - rc.left) / g_sSurfaceInfo.Width; y = (FLOAT)(rc.bottom - rc.top) / g_sSurfaceInfo.Height; // 拡縮させる ::D3DXMatrixScaling(&g_mat, x, y, 0.0f); }

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

最近のDirectXを触っていないので間違っているかもしれませんが。 g_pTexture->m_clrAlphaは、D3DCOLOR型ですよね。 値は、D3DCOLOR_ARGB()マクロ等で設定していますか? D3DCOLOR_ARGB(30,0,0,0)とかすればスプライトは殆ど透明化するはずですが。

79562
質問者

補足

D3DCOLOR_XRGBマクロはしていました。 D3DCOLOR_ARGB(30,0,0,0)をやっても透明化しませんでした。 HRESULT ReadBMP(ID3DXSprite** g_pSprite,LPCTSTR lpszFilename,DDXTEX* g_pTexture) { HRESULT hr = S_FALSE; UINT uLevel = 0; IDirect3DSurface9* pSurface = NULL; lstrcpy(g_pTexture->m_Filename,lpszFilename); g_pTexture->m_clrAlpha=g_colorKey; g_pTexture->m_pTexture=NULL; // スプライト情報の生成 if (SUCCEEDED(hr)) hr = ::D3DXCreateSprite(g_pd3dDevice, g_pSprite); if (SUCCEEDED(hr)) hr = ::D3DXCreateTextureFromFile(g_pd3dDevice, g_pTexture->m_Filename, &g_pTexture->m_pTexture); if (SUCCEEDED(hr)) hr = g_pTexture->m_pTexture->GetSurfaceLevel(uLevel, &pSurface); // サーフェイス取得 if (SUCCEEDED(hr)) hr = pSurface->GetDesc(&g_sSurfaceInfo); if (pSurface != NULL) pSurface->Release(); pSurface = NULL; // 失敗したら破棄 if (FAILED(hr)) DestroySplite(*g_pSprite,g_pTexture); return hr; } のどこかがいけないのでしょうか?

関連するQ&A

  • 描画位置について

    描画を透明化する質問をしたものですが、もう1つ教えていただきたいことがあります。 void Draw(ID3DXSprite* g_pSprite,DDXTEX* g_pTexture) { // クリア g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, g_clrBackgroundColor, 1.0f, 0); // 描画開始 if (FAILED(g_pd3dDevice->BeginScene())) { g_pd3dDevice->Present(NULL, NULL, NULL, NULL); return; } // スプライトを描画 g_pSprite->Begin(D3DXSPRITE_ALPHABLEND); g_pSprite->Draw( g_pTexture->m_pTexture, // LPDIRECT3DTEXTURE9 pTexture NULL, // CONST RECT *pSrcRect &g_vCenter, // CONST D3DXVECTOR3 *pCenter NULL, // CONST D3DXVECTOR3 *pPosition g_pTexture->m_clrAlpha // D3DCOLOR Color ); g_pSprite->SetTransform(&g_mat); g_pSprite->End(); で描画範囲がCONST RECT *pSrcRectで、描画中心がCONST D3DXVECTOR3 *pPosition、描画位置がCONST D3DXVECTOR3 *pPositionのはずなのですが描画範囲も描画中心、描画位置も思い通りいきません。 描画範囲、中心、位置を指定するにはどうすればいいのでしょうか?

  • 描画について

    今DirectXでゲームを作ろうとしてるものですが、描画しようと思い打ったのですが位置が思い通りにならない(描画が範囲を下回っている)描画されなくて困っています。ソースはこれです。 HRESULT Render(void) { g_pD3DDevice->Clear(0, NULL,NULL, D3DCOLOR_XRGB(0, 255, 255), 1.0f, 0); // シーンの描画開始 if (SUCCEEDED(g_pD3DDevice->BeginScene())) { // スプライトの描画開始(アルファ・ブレンディング有効&デバイス状態を保存も復元もしない) pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DONOTSAVESTATE); // シーンの描画(2D画像の描画) RECT SrcRect = { 0,0,640,480 }; // テクスチャ内でスプライトに使う範囲(0,0)-(512,64) D3DXVECTOR3 Center(320,240,0); // スプライト内の中心の位置(256,32,0) D3DXVECTOR3 Position(320,240,0); // スプライトを表示する位置(0,0,0)+(320,240,0) static int alpha=0; pSprite->Draw(pTexture.m_texture, // スプライトに使うテクスチャ &SrcRect, // 描画範囲 &Center, // スプライト内の中心の位置 &Position, // スプライトを表示する位置 D3DCOLOR_ARGB(alpha>255?511-alpha:alpha,255,255,255)); //alpha++; alpha &= 0x1FF; //pTexture.m_colorKey); // スプライトの描画終了 pSprite->End(); // シーンの描画終了 g_pD3DDevice->EndScene(); } // シーンの表示 return g_pD3DDevice->Present(NULL, NULL, NULL, NULL); }どうしたらきちんとした位置に描画できるのでしょうか。

  • ローディング画面をマルチスレッドで動かせません。

    ローディング画面をマルチスレッドで動かせません。 DirectXとC++をVisualStudio2010でゲームを制作しています。 ローディング画面を動かせるようにマルチスレッドにしているんですが、パソコンによってはローディング画面から動かなくなってしまいます。(開発環境では、問題なく動きます) スレッドの呼び出し部分は以下のようになっています。 HANDLE thread; CScene gamen; //タイトル画面やメインゲーム画面などのシーンを管理 void Loading() { SetDrawLoading( true ); delete gamen; gamen = new CTitleGamen(); thread = (HANDLE)_beginthreadex(NULL,0,DrawLoading,NULL,0,NULL); gamen->LoadData(); //クラス内の画像や音楽データを読み込み effect->SetDrawLoading(false); WaitForSingleObject( thread, INFINITE ); CloseHandle(thread); } マルチスレッド部分は以下のように、 drawLoading変数がtrueの間、ローディング画面を描画するようにしています。 D3DXMATRIX m_world; unsigned __stdcall DrawLoading(void *p){ LPDIRECT3DTEXTURE9 pTexture; D3DXCreateTextureFromFileEx(m_pD3DDevice, TEXT("texture.png"),16, 16, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, D3DCOLOR_XRGB(255,255,0), NULL, NULL, &pTexture)) do{ m_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); if( SUCCEEDED( m_pD3DDevice->BeginScene() ) ) { D3DXMatrixIdentity( &m_world ); m_pD3DDevice->SetTransform( D3DTS_WORLD, &m_world ); m_pSprite->Begin( D3DXSPRITE_ALPHABLEND ); m_pSprite->Draw( pTexture, NULL, NULL, &D3DXVECTOR3( timeGetTime()%800), 550, 0 ), 0xffffffff ); m_pSprite->End(); m_pD3DDevice->EndScene(); } m_pD3DDevice->Present( 0, 0, 0, 0 ); }while( effect->GetDrawLoading() ); pTexture->Release(); _endthreadex(0); return 0; } どなたか、ご教授お願い致します。

  • 描画について

    サイズを綺麗に描画したいのですが(サイズの範囲(rightとbottom)が微妙にずれている)どうしたら描画できるでしょうか? ここら辺かな?と思うところを載せます。 HRESULT ReadBMP(ID3DXSprite** g_pSprite,LPCTSTR lpszFilename,DDXTEX* g_pTexture) { HRESULT hr = S_FALSE; UINT uLevel = 0; IDirect3DSurface9* pSurface = NULL; lstrcpy(g_pTexture->m_Filename,lpszFilename); g_pTexture->m_clrAlpha=g_colorKey; g_pTexture->m_pTexture=NULL; // スプライト情報の生成 if (SUCCEEDED(hr)) hr = ::D3DXCreateSprite(g_pd3dDevice, g_pSprite); if (SUCCEEDED(hr)) hr = ::D3DXCreateTextureFromFileEx(g_pd3dDevice, g_pTexture->m_Filename, 680, 460, 1, D3DUSAGE_RENDERTARGET, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, g_pTexture->m_clrAlpha, NULL, NULL, &g_pTexture->m_pTexture); if (SUCCEEDED(hr)) hr = g_pTexture->m_pTexture->GetSurfaceLevel(uLevel, &pSurface); // サーフェイス取得 if (SUCCEEDED(hr)) hr = pSurface->GetDesc(&g_sSurfaceInfo); if (pSurface != NULL) pSurface->Release(); pSurface = NULL; // 失敗したら破棄 if (FAILED(hr)) DestroySplite(*g_pSprite,g_pTexture); return hr; } よろしくお願いします。

  • DirectXのSpriteについて

    現在DirectXを使ってプログラムを書いています。 スプライトを使って画像を描画しようと思ったのですが、 LPD3DXSPRITE pSprite;//スプライト LPDIRECT3DTEXTURE9 texture;//適当な画像 pSprite->Begin( 0 ); pSprite->Draw( texture, 0,0,0,0xffffffff ); pSprite->End(); というように使って画像を描画するようですが、これを見ると pSpriteはアプリケーション内に1つ存在すればいいような気がするのですが複数用意する意味はあるのでしょうか? 教えてください。

  • DirectXでの半透明PNG画像について

    半分が半透明で、もう半分は透明でない単色のPNG画像(128×128サイズ)を作成しました。 ソフトはAdobe Photoshop Elements 6.0で、アルファ設定されている「PNG-24」です。 D3DXCreateTextureFromFileEx関数で、そのPNG画像を読み込んで描画したのですが、半透明の部分は描画されず、透明にしていない片方しか描画されませんでした。 半透明の部分も描画されるようにするにはどうすればよいでしょうか? 自分でもいろいろ調べてみたのですが、原因がよく分からないので質問させていただきます。 一応、参考程度に… // スプライトオブジェクトの作成 if ( FAILED( D3DXCreateSprite( g_pd3dDevice, &m_pSprite ) ) ) {     // エラー処理 } D3DXIMAGE_INFO info; // テクスチャの読み込み if( FAILED( D3DXCreateTextureFromFileExA( g_pd3dDevice,                                FileName,                                D3DX_DEFAULT,                                D3DX_DEFAULT,                                D3DX_DEFAULT,                                0,                                D3DFMT_A1R5G5B5,                                D3DPOOL_MANAGED,                                D3DX_FILTER_NONE,                                D3DX_FILTER_NONE,                                0,                                &info,                                NULL,                                &g_pd3dTexture) ) ) {     // エラー処理 }

  • DirectXで画像表示

    DirextXでゲームを作ってるんですがわからないことがあるんで教えてください。 背景として640×640(ピクセル)の画像を表示したくて(ウィンドウはサイズ640,640で作成) RECT from; D3DXVECTOR3 to; D3DCOLOR color; from = makeRect(0,0,640,640); to = D3DXVECTOR3(0,0,0); color = D3DCOLOR_ARGB(255,255,255,255); if(g_pTexture != NULL) g_pSprite->Draw(g_pTexture, &from, NULL, &to, color); RECT makeRect(int x, int y, int w, int h) { RECT box; box.left = x; box.top = y; box.right = w; box.bottom = h; return (box); } //g_pTexture = D3DXCreateTextureFromFileEx関数で作成したテクスチャオブジェクト。 //g_pSprite = スプライトオブジェクト。 大体こんな感じの流れで背景画像を表示したらウィンドウ全体に画像の一部分だけが拡大されて表示されました。なぜ画像全体がうまく表示されないんでしょうか? 例えば64×64のキャラクタ画像を from = makeRect(0,0,64,64); to = D3DXVECTOR3(0,0,0); で表示したら画面左上にうまく表示されました。 初心者なんであまりうまく説明できないんでかなりわかりにくいかもしれませんが、わかる方よろしくお願いします。

  • テクスチャに半透明ポリゴンを描画すると透ける??

    DirectX9で不透明なテクスチャに半透明ポリゴンを描画すると、ポリゴンを描画した部分が透けてしまうのはなぜですか? 1.「D3DUSAGE_RENDERTARGET」指定したテクスチャを作成して白でクリア 2.そのテクスチャに半透明の青いポリゴンをDrawPrimitiveUPで描画 3.そのテクスチャをD3DXSaveTextureToFileでPNG等で保存 とした場合、私のイメージでは白地に薄い青の四角が描かれた不透明な画像ファイルができると思ったんですが、青の部分が半透明になりました。 なぜ不透明なテクスチャに半透明ポリゴンを描くと半透明になるのでしょうか・・・? ―――――――――――――――――――――――――――――――――――― //レンダリング用テクスチャの準備 { global.pDevice->CreateTexture( 512, 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTarget, NULL); pTarget->GetSurfaceLevel(0, &pSurface); global.pDevice->GetRenderTarget(0, &pBackBuffer); //バックバッファの取得 global.pDevice->SetRenderTarget(0, pSurface); //ターゲットの切り替え //白(不透明)にクリア global.pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 255, 255, 255), 1.0f, 0 ); } //テクスチャに半透明ポリゴンを描画 { VERTEX point[4] ={ D3DXVECTOR3(100, 200, 1), 1.0f, D3DCOLOR_ARGB(128, 0, 0, 255), D3DXVECTOR3(100, 100, 0), 1.0f, D3DCOLOR_ARGB(128, 0, 0, 255), D3DXVECTOR3(200, 200, 0), 1.0f, D3DCOLOR_ARGB(128, 0, 0, 255), D3DXVECTOR3(200, 100, 0), 1.0f, D3DCOLOR_ARGB(128, 0, 0, 255) }; global.pDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); global.pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, point, sizeof(VERTEX)); global.pDevice->SetRenderTarget(0, pBackBuffer); //レンダリングターゲット戻す } //テクスチャを保存 { D3DXSaveTextureToFile("d:\\hoge.png", D3DXIFF_PNG, pTarget, NULL); } ―――――――――――――――――――――――――――――――― D3DTSS_ALPHAOPをADDにしてみたりしたのですが、変化がありません。 テクスチャが透ける理屈と、こうならないようにする手段(アルファ値は加算したい)を教えてもらえると助かります。

  • Directxについて

    1つご教授お願い申したいのですが、 HRESULT DrowInitialize(HWND hWnd) { LPDIRECT3D9 g_pD3D; D3DPRESENT_PARAMETERS g_D3DPP; g_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if(g_pD3D==NULL) { return S_FALSE; } ZeroMemory(&g_D3DPP,sizeof(g_D3DPP)); g_D3DPP.Windowed =TRUE; g_D3DPP.SwapEffect =D3DSWAPEFFECT_DISCARD; g_D3DPP.BackBufferFormat = D3DFMT_UNKNOWN; HRESULT hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,&g_D3DPP,&pd3dDevice); if(FAILED(hr)) { hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,&g_D3DPP,&pd3dDevice); if(FAILED(hr)) { hr =g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,&g_D3DPP,&pd3dDevice); if(FAILED(hr)) { return S_FALSE; } } } return S_OK; } なのですが、これが通らなくて困っています。(S_FALSEを通ってしまいます)S_OKを通るにはどうしたらいいのでしょうか。わかる方いらしたらよろしくお願いします。

  • DIRECTXのスプライト描画で質問です

    いつもお世話になってます。 DIRECTX9.0、VC++6.0を使っています。 DIRECTXでLPDIRECT3DTEXTURE9(テクスチャ)とLPD3DXSPRITE(スプライト)を使って描画しています。 ですが、テクスチャの縦と横のサイズが256*256を超えたものが正常に表示できません。 色々調べてみると、縦と横のピクセル数が2の乗数以外の中途半端なサイズのテクスチャは、キリの良いサイズに変換されるみたいですが、一応縦横共に2の乗数のテクスチャなのにうまく表示できません。 例:768*512ピクセルのTGA形式のファイル 大きな画像ファイルを表示する方法はないでしょうか? どうぞ宜しくお願いします。

専門家に質問してみよう