DIrectXでウィンドウの透明化

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
manntera

DIrectXでウィンドウの透明化

#1

投稿記事 by manntera » 10年前

今回の質問は、DirectXを用いたウィンドウの透明化です!

色々調べては見たのですが、書いてる事が何がなにやらわからないので、ここで質問させて頂きましたー。

やりたいのは、デスクトップ上にキャラクターを動かさせたいって言う感じです。
キャラクターをアニメーションで走らせる事までは出来ました><
何方か教えて下さい…><

現在のソースコード
★comon.h★

コード:

 
#include<windows.h>
#include<d3dx9.h>
#include<MMSystem.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")

//////////////////////
//グローバル変数定義//
//////////////////////
LPDIRECT3D9       g_pD3D       = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
LPDIRECT3DTEXTURE9 g_pTex1=NULL;
LPDIRECT3DTEXTURE9 g_pTex2=NULL;
////////////////
//【定数設定】//
////////////////
#define FVF_sTlvertex (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#define WINDOW_WIDTH (1280)
#define WINDOW_HEIGHT (960)
#define WINDOW_NAME ("エレマスを動かすプログラム")

#define FALSE (0)
#define TURE (1)

#define INUP (1)
#define INRIGHT (2)
#define INDOWN (3)
#define INLEFT (4)
#define INNULL (0)

#define ERE_OFFSET_DASH (1.25)
//パラメーター設定
#define ERE_SPPED_X (8.0f)	//エレマスのX軸移動速度指定
#define ERE_SPPED_Y (4.0f)	//エレマスのY軸移動速度指定
#define ERE_SIZE_X (200.0f)	//エレマスのX軸サイズ
#define ERE_SIZE_Y (400.0f)	//エレマスのY軸サイズ

#define ERE_WALL_OFFSET_MAX_X (-40.0f)
#define ERE_WALL_OFFSET_MIN_X (-10.0f)
#define ERE_WALL_OFFSET_MAX_Y (10.0f)
#define ERE_WALL_OFFSET_MIN_Y (30.0f)
//キャラクターモーション連番指定
enum character_motion
{
	STAND,
	DASH,
	WALK,
	ATTACK,
	RECEIVE
};

//////////////////
//【構造体定義】//
//////////////////
//---頂点情報構造体---//
typedef struct _sTlvertex{
	float x,y,z;	//座標
	float rhw;		//射影フラグ
	D3DCOLOR deffuse;
	float tu,tv;
}sTlvertex;

typedef struct _sCharacterPos
{
	float posX;
	float posY;
}sCharacterPos;

////////////////////////
//【プロトタイプ宣言】//
////////////////////////
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HRESULT          InitD3D(HWND);
void             DrawD3D(void);
void             DestroyD3D(void);
void AsciiFontDraw(int,int,int,int,char,DWORD);
void StringDraw(int,int,int,int,char*,DWORD);
void GameMain(void);
void Action(void);
int PushKey(void);
void MoveCharacter(sCharacterPos*,float,float);
void TouchWall(sCharacterPos*,float,float,float,float);



★main.cpp★

コード:

 
////////////////////////
//【インクルード宣言】//
////////////////////////
#include"common.h"

int g_frameCount;
int g_nowPosition;
///////////////
//【WINMAIN】//
///////////////

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	HWND hWnd;
	MSG msg;
	DWORD oldTime;
	DWORD nowTime;
	
	wc.cbSize=sizeof(WNDCLASSEX);
	wc.style=CS_HREDRAW|CS_VREDRAW;
	wc.hInstance=hInstance;
	wc.lpszClassName="DX21";
	wc.lpfnWndProc=(WNDPROC)WndProc;
	wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
	wc.hCursor=LoadCursor(NULL,IDC_ARROW);
	wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName=NULL;
	wc.cbClsExtra=0;
	wc.cbWndExtra=0;

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL,"ウィンドウクラスの構造体の初期化エラー","",MB_OK);
	}
		hWnd = CreateWindowEx(NULL,	//常に最前面=WS_EX_TOPMOST
							wc.lpszClassName,
							WINDOW_NAME,
							WS_CAPTION | WS_SYSMENU|WS_MINIMIZEBOX,
							0,
							0,
							WINDOW_WIDTH,
							WINDOW_HEIGHT,
							NULL,
							NULL,
							hInstance,
							NULL);
	//DirextX初期化関数
	if(FAILED(InitD3D(hWnd))) return -1;
	ShowWindow(hWnd,nCmdShow);
	UpdateWindow(hWnd);

	//DirectX描画関数(本来はゲームループで実行する関数だが今はループ前に一回だけ実行
	DrawD3D();

	//メインループ
	timeBeginPeriod(1);
	oldTime=timeGetTime();
	while(1)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
		{
			if(GetMessage(&msg,NULL,0,0)==0)
			{
				break;
			}
			TranslateMessage(&msg);	//Windowsメッセージの処理キーボードからの入力を文字列入力に変換
			DispatchMessage(&msg);	//メッセージを解放(?)
		}
		nowTime=timeGetTime();
		if((nowTime-oldTime)>=16)
		{
			oldTime=nowTime;
//			DrawD3D();
			GameMain();
			//メッセージの翻訳と送出
			
		}
	}
	timeEndPeriod(1);
	//DirectX終了処理関数
	DestroyD3D();
	return (int)msg.wParam;
}

///////////////
//WndProc関数//
///////////////
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch(message){
		case WM_DESTROY:
			PostQuitMessage(0);
			if(g_pTex1!=NULL)
			{
				g_pTex1->Release();
				
			}
			if(g_pTex2!=NULL)
			{
				g_pTex2->Release();
			}
			g_pd3dDevice->Release();
			break;

		default:
			return DefWindowProc(hWnd,message,wParam,lParam);
	}
	return 0;
}

/////////////////////
//DirectX初期化関数//
/////////////////////
HRESULT InitD3D(HWND hWnd)
{
	g_frameCount=0;
	g_nowPosition=0;

	D3DPRESENT_PARAMETERS d3dpp;

	if(NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
	{
		return E_FAIL;
	}

	ZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.Windowed  =TRUE;
	d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.EnableAutoDepthStencil=TRUE;
	d3dpp.AutoDepthStencilFormat =D3DFMT_D16;

	if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
									D3DDEVTYPE_HAL,
									hWnd,
									D3DCREATE_HARDWARE_VERTEXPROCESSING,
									&d3dpp,
									&g_pd3dDevice)))
	{
		return E_FAIL;
	}
	g_pd3dDevice->SetRenderState(D3DRS_ZENABLE,TRUE);
	g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
	g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
	g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
	g_pd3dDevice->LightEnable(0,FALSE);
	g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
	g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
	g_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
	g_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
	g_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);
	g_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
	HRESULT thr=D3DXCreateTextureFromFile(g_pd3dDevice,"ere_stand__TEX.png",&g_pTex1);
	HRESULT thr2=D3DXCreateTextureFromFile(g_pd3dDevice,"sysfont.tga",&g_pTex2);
	if(FAILED(thr))
	{
		return E_FAIL;
	}
	if(FAILED(thr2))
	{
		return E_FAIL;
	}
	return S_OK;
}

///////////////////
//directX描画関数//
///////////////////
void DrawD3D(void)
{
	g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,255),1.0f,0);
	LPDIRECT3DTEXTURE9 fontTex;
	LPDIRECT3DTEXTURE9 ereTex;

	static int characterMotion=STAND;			//キャラクターモーション取得
	static int NowKey=4;						//押下されているキーを取得
	static sCharacterPos sErePos={0.0f,0.0f};	//エレマスの座標
	static int characterWayLeft=0;				//キャラクター方向左
	static int characterWayRight=1;				//キャラクター方向右
	
	D3DXCreateTextureFromFile(g_pd3dDevice,"sysfont.tga",&fontTex);	//フォントテクスチャ読み込み
	
	switch(characterMotion)	//モーションによって読み込むテクスチャーを変更
	{
		case STAND:D3DXCreateTextureFromFile(g_pd3dDevice,"ere_stand__TEX.png",&ereTex);
			break;
		case DASH:D3DXCreateTextureFromFile(g_pd3dDevice,"ere_dash__TEX.png",&ereTex);
			break;
	}
	
	TouchWall(&sErePos,WINDOW_WIDTH-ERE_SIZE_X+ERE_WALL_OFFSET_MAX_X,WINDOW_HEIGHT-ERE_SIZE_Y+ERE_WALL_OFFSET_MAX_Y,ERE_WALL_OFFSET_MIN_X,ERE_WALL_OFFSET_MIN_Y);	//壁衝突判定

	if(SUCCEEDED(g_pd3dDevice->BeginScene()))	//描画開始
	{
		g_pd3dDevice->EndScene();
		//=====頂点データの作成
		sTlvertex vertex[4];	//頂点配列
		vertex[0].rhw=vertex[1].rhw=vertex[2].rhw=vertex[3].rhw=1.0f;
		vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.0f;
		//---x,yの設定---//
		switch(characterMotion)	//モーションによってテクスチャー座標を変更
		{
			//立ち状態
			case STAND:	
				vertex[0].x=0.0f+sErePos.posX;
				vertex[0].y=ERE_SIZE_Y+sErePos.posY;
				vertex[0].tu = 0.250f*(g_nowPosition+characterWayLeft);
				vertex[0].tv = 1.0f*1;
				vertex[0].deffuse=D3DCOLOR_RGBA(255,255,255,255);
		
				vertex[1].x=0.0f+sErePos.posX;
				vertex[1].y=0.0f+sErePos.posY;
				vertex[1].tu = 0.250f*(g_nowPosition+characterWayLeft);
				vertex[1].tv = 1.0f*0;
				vertex[1].deffuse=D3DCOLOR_RGBA(255,255,255,255);
		
				vertex[2].x=ERE_SIZE_X+sErePos.posX;
				vertex[2].y=0.0f+sErePos.posY;
				vertex[2].tu = 0.250f*(g_nowPosition+characterWayRight);
				vertex[2].tv = 1.0f*0;
				vertex[2].deffuse=D3DCOLOR_RGBA(255,255,255,255);
		
				vertex[3].x=ERE_SIZE_X+sErePos.posX;
				vertex[3].y=ERE_SIZE_Y+sErePos.posY;
				vertex[3].tu = 0.250f*(g_nowPosition+characterWayRight);
				vertex[3].tv = 1.0f*1;
				vertex[3].deffuse=D3DCOLOR_RGBA(255,255,255,255);
				
				//ボタンを押すとダッシュ状態へ
				NowKey=PushKey();
				if(NowKey!=INNULL)
				{
					//フレームリセット
					g_nowPosition=0;
					g_frameCount=0;
					characterMotion=DASH;
				}
					break;
			//ダッシュ状態
			case DASH:
				vertex[0].x=0.0f+sErePos.posX;
				vertex[0].y=400.0f+sErePos.posY;
				vertex[0].tu = 0.250f*(g_nowPosition+characterWayLeft);
				vertex[0].tv = 1.0f*1;
				vertex[0].deffuse=D3DCOLOR_RGBA(255,255,255,255);
		
				vertex[1].x=0.0f+sErePos.posX;
				vertex[1].y=0.0f+sErePos.posY;
				vertex[1].tu = 0.250f*(g_nowPosition+characterWayLeft);
				vertex[1].tv = 1.0f*0;
				vertex[1].deffuse=D3DCOLOR_RGBA(255,255,255,255);
		
				vertex[2].x=200.0f*ERE_OFFSET_DASH+sErePos.posX;
				vertex[2].y=0.0f+sErePos.posY;
				vertex[2].tu = 0.250f*(g_nowPosition+characterWayRight);
				vertex[2].tv = 1.0f*0;
				vertex[2].deffuse=D3DCOLOR_RGBA(255,255,255,255);
		
				vertex[3].x=200.0f*ERE_OFFSET_DASH+sErePos.posX;
				vertex[3].y=400.0f+sErePos.posY;
				vertex[3].tu = 0.250f*(g_nowPosition+characterWayRight);
				vertex[3].tv = 1.0f*1;
				vertex[3].deffuse=D3DCOLOR_RGBA(255,255,255,255);

				MoveCharacter(&sErePos,ERE_SPPED_X,ERE_SPPED_Y);
				//キャラクター方向指定
				if(GetAsyncKeyState(VK_RIGHT))
				{
					if(!GetAsyncKeyState(VK_LEFT))
					{
						characterWayLeft=0;
						characterWayRight=1;
					}
				}
				if(GetAsyncKeyState(VK_LEFT))
				{
					if(!GetAsyncKeyState(VK_RIGHT))
					{
						characterWayLeft=1;
						characterWayRight=0;
					}
				}
				//ボタンを押していない時は立ち状態に戻る
				if(PushKey()==NULL)
				{
					g_nowPosition=0;
					g_frameCount=0;
					characterMotion=STAND;
						break;
				}
		}
		
		if(SUCCEEDED(g_pd3dDevice->BeginScene()))
		{
			g_pd3dDevice->SetFVF(FVF_sTlvertex);	//頂点フォーマットのフラグを伝える
			g_pd3dDevice->SetRenderState(		//カリング
						D3DRS_CULLMODE,
						D3DCULL_CCW);
			g_pd3dDevice->SetTexture(0,ereTex);
			g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,	//頂点データーをビデオカードに送る
											2,
											vertex,
											sizeof(sTlvertex));
			g_pd3dDevice->SetTexture(0,g_pTex1);
			g_pd3dDevice->SetTexture(0,g_pTex2);
			g_pd3dDevice->EndScene();
		}
	}
	StringDraw(300,10,32,32,"manntera's program",D3DCOLOR_RGBA(255,255,255,255));
	ereTex->Release();
	fontTex->Release();
	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}

//////////////////////////////////////////////////////////////////////
//【文字画像出力関数】                                              //
//(引数:初期X座標,Y座標、文字の大きさwidth,height,文字,色指定RGB)//
//(返し値:無し)                                                  //
//////////////////////////////////////////////////////////////////////
		/////////////////////////////
		///char型は8ビットであり、//
		///前半の4ビットをcodex   //
		///後半の4ビットをcodey   //
		///へ当てる。              //
		/////////////////////////////
void AsciiFontDraw(int x,int y,int width,int height,char code,DWORD color)
{
	sTlvertex v[4];
	v[0].z=v[1].z=v[2].z=v[3].z=0.0f;
	v[0].rhw=v[1].rhw=v[2].rhw=v[3].rhw=1.0f;
	int codex,codey;	//文字位置
	float tu,tv;	//テクスチャ左上座標
	codex=code&0x0f;
	codey=code>>4;
	codey=codey-2;
	tu=0.0625f*codex;
	tv=0.0625f*codey;
	
	v[0].x=x;
	v[0].y=y;
	v[0].tu=tu;
	v[0].tv=tv;

	v[1].x=x+width;
	v[1].y=y;
	v[1].tu=tu+0.0625;
	v[1].tv=tv;

	v[2].x=x;
	v[2].y=y+height;
	v[2].tu=tu;
	v[2].tv=tv+0.0625f;
	
	v[3].x=x+width;
	v[3].y=y+height;
	v[3].tu=tu+0.0625;
	v[3].tv=tv+0.0625;

	v[0].deffuse=v[1].deffuse=v[2].deffuse=v[3].deffuse=color;
	g_pd3dDevice->SetFVF(FVF_sTlvertex);
	g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,v,sizeof(sTlvertex));
}

////////////////////////////////////////////////////////////////////////
//【文字列画像出力関数】                       //
//(引数:初期X座標,Y座標、文字の大きさwidth,height,文字列.色指定RGB)//
//(返し値:無し)                                                    //
////////////////////////////////////////////////////////////////////////
void StringDraw(int x,int y,int width,int height,char* str,DWORD color)
{
	for(int i=0;str[i]!='\0';i++)
	{
		AsciiFontDraw(x+(width*i),y,width,height,str[i],color);
	}
}

///////////////////////////
//【DirextX終了処理関数】//
//(引数:なし)     //
//(返し値:なし)       //
///////////////////////////
void DestroyD3D(void)
{
	if(g_pd3dDevice !=NULL)
	{
		g_pd3dDevice->Release();
	}
	if(g_pD3D !=NULL)
	{
		g_pD3D->Release();
	}
}

////////////////////
//【ゲームメイン】//
////////////////////
void GameMain(void)
{
	Action();
	DrawD3D();
}

//////////////////////
//【アクション関数】//
//////////////////////
void Action(void)
{
	g_frameCount++;
	switch(g_frameCount)
	{
		case 15:g_nowPosition++;
			break;
		case 30:g_nowPosition++;
			break;
		case 45:g_nowPosition++;
			break;
		case 59:g_nowPosition=0;
				g_frameCount=0;
			break;
	}
}

/////////////////////////////////
//【キー入力関数】             //
// 引数:無し                 //
// 返し値:↑=1,→=2,↓=3,←=4//
//  何も押されていない=0       //
/////////////////////////////////
int PushKey(void)
{
	if(GetAsyncKeyState(VK_UP))
	{
		return 1;
	}
	if(GetAsyncKeyState(VK_RIGHT))
	{
		return 2;
	}
	if(GetAsyncKeyState(VK_DOWN))
	{
		return 3;
	}
	if(GetAsyncKeyState(VK_LEFT))
	{
		return 4;
	}
	return 0;
}

/////////////////////////////////
//【キャラクター移動関数】     //
// 引数:キャラ座標           //
//戻り値:キャラ座標ポインター //
/////////////////////////////////
void MoveCharacter(sCharacterPos* sCharacterPos,float MoveSpeedX,float MoveSpeedY)
{

	if(GetAsyncKeyState(VK_UP))
	{
		sCharacterPos->posY-=MoveSpeedY;
	}
	if(GetAsyncKeyState(VK_RIGHT))
	{
		sCharacterPos->posX+=MoveSpeedX;
	}
	if(GetAsyncKeyState(VK_DOWN))
	{
		sCharacterPos->posY+=MoveSpeedY;
	}
	if(GetAsyncKeyState(VK_LEFT))
	{
		sCharacterPos->posX-=MoveSpeedX;
	}
}

///////////////////////////////////////////////////////////////////////////////
//【キャラクター壁衝突判定】                                                 //
// 引数:キャラクター座標のポインター,X軸MAXオフセット値,Y軸MAXオフセット値 //
//        X軸MINオフセット値,X軸MINオフセット値                              //
//返し値:キャラクター座標のポインター                                       //
///////////////////////////////////////////////////////////////////////////////
void TouchWall(sCharacterPos *sCharacterPos,float offsetMaxX,float offsetMaxY,float offsetMinX,float offsetMinY)
{
	if(sCharacterPos->posX>offsetMaxX)
	{
		sCharacterPos->posX=offsetMaxX;
	}
	if(sCharacterPos->posX<offsetMinX)
	{
		sCharacterPos->posX=offsetMinX;
	}
	if(sCharacterPos->posY>offsetMaxY)
	{
		sCharacterPos->posY=offsetMaxY;
	}
	if(sCharacterPos->posY<0-offsetMinY)
	{
		sCharacterPos->posY=0-offsetMinY;
	}
}

“C言語何でも質問掲示板” へ戻る