クライアント領域に残像が残ってしまいます

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

クライアント領域に残像が残ってしまいます

#1

投稿記事 by めんつゆ » 8年前

トピックの投稿ミスがあったため再掲させていただきます。申し訳ありません。
ダイレクトx、ビジュアルC++2010エクスプレスを使用してプログラムを書いています。

ウインドウのサイズを変更した際、画像が表示される領域を一定の比率で保つようにしたのですが、
残像が残ってしまいます。

コールバック関数は以下のようになっています。

コード:

 
    case WM_SIZING://ウインドウサイズの変更中
 
     drawsprite(GraphicDebug);//再描画
     return TRUE;//WM_SIZINGの場合はTRUEを返す
 
 
    case WM_SIZE://ウインドウサイズの変更後
    
        if(!g_pDEV || wParam == SIZE_MINIMIZED)
        {
            break;
        }
        if(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
        {
            
            int WX,WY,FBArea;
 
            FBArea = 0;         //初期化
            WX = LOWORD(lParam);    //横の取得
            WY = HIWORD(lParam);    //縦の取得
 
            WindowDraw(WX,WY,FBArea);////フロントバッファの描画領域の計算
 
            pSprite->OnLostDevice();//スプライトのロスト
            g_pDEV->Reset(&d3dpp);
            InvalidateRgn(hWnd, NULL,TRUE);
 
        }
        break;


仕組みとしては、クライアント領域内のフロントバッファ表示領域をウインドウサイズの変更に応じて変化させているのですが、
フロントバッファの外側に画像が残ってしまいます。

このような状態です(Imgurというサイトです)
http://imgur.com/S6YL5he.jpg

フロントバッファ表示領域外の画像をクリアするにはどうすればいいのでしょうか。
宜しくお願い致します。

Math

Re: クライアント領域に残像が残ってしまいます

#2

投稿記事 by Math » 8年前

DirectXはVer9でしょうか?
http://dixq.net/forum/viewtopic.php?f=3&t=18717
を参考にして動くコードを提示していただけませんか。

めんつゆ

Re: クライアント領域に残像が残ってしまいます

#3

投稿記事 by めんつゆ » 8年前

Mathさん返信ありがとうございます。
DirectX9を使用しています。

チェック用の画像はこちらに用意させていただきました。(Imgurというサイトです)


220行目に使用する画像を決めるコードが書いてあります。
宜しくお願いします。

コード:


#define NAME "DirectX勉強中"
#define INITGUID

#include <Windows.h>
#include <d3dx9.h>
#include <dsound.h>
#include <MMSystem.h>
#include <stdio.h>

// ライブラリのリンク
#pragma once
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"dsound.lib")
#pragma comment(lib,"winmm.lib")



HWND g_hWnd = NULL;      // Window Handle
LPDIRECT3D9             g_pD3D = NULL;     
LPDIRECT3DDEVICE9       g_pDEV = NULL;    

D3DXVECTOR3 Position;//位置(x座標,y座標)キャラクタ
D3DXVECTOR3 haikeiPosition;//背景の座標

BYTE diKeyState[256];

LPD3DXSPRITE pSprite = NULL; 
LPDIRECT3DTEXTURE9 pTexture = NULL; 
LPDIRECT3DTEXTURE9 phaikeiTexture;
LPDIRECT3DTEXTURE9 MapchipTexture;


D3DXMATRIX m_Matrix;//キャラクタの行列
D3DXVECTOR2 m_vec2;//マトリックス自体の座標

RECT B_B_Area = {0,0,0,0}; //バックバッファのサイズ
RECT PaintArea ={0,0,0,0}; //フロントバッファの描画領域


D3DDISPLAYMODE          d3ddm;
D3DPRESENT_PARAMETERS   d3dpp;

//***********************


D3DVIEWPORT9 vp;	

#define wwx 1280
#define wwy 960

//開放のための関数
#define SAFE_RELEASE(x) if(x)  { x->Release(); x=NULL; }
#define DIDEVICE_BUFFERSIZE	100						

RECT W_Size;//ウインドウサイズ
RECT C_Size;//クライアントサイズ
int W_BarX,W_BarY; //ウインドウバー

//初期化処理(デバイスの設定)
HRESULT Init3DDev()
{
    //インターフェイスの取得
    if (NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))    return E_FAIL;

	//アダプタのデータを得る(数、幅、高さ、リフレッシュレート)
    if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))   return E_FAIL;
 
    //D3DPRESENT_PARAMETERS構造体の設定
    ZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.BackBufferWidth = wwx;
	d3dpp.BackBufferHeight =wwy;
    d3dpp.Windowed                  = TRUE;      
    d3dpp.SwapEffect =  D3DSWAPEFFECT_COPY;
    d3dpp.BackBufferFormat          = d3ddm.Format;
    d3dpp.EnableAutoDepthStencil    = TRUE;       
    d3dpp.AutoDepthStencilFormat    = D3DFMT_D16; 
 
    //デバイスの作成:CreateDeviceの実行//復元用
    if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pDEV)))
    return E_FAIL;
    return S_OK;
}

///メモリ開放処理
// DirectX Graphics の終了処理:未開放有り
void Cleanup(void)
{
	SAFE_RELEASE(g_pDEV);	//デバイスの開放
    SAFE_RELEASE(g_pD3D);	//ダイレクトxの開放
}
 


//ウインドウのサイズ関連の調整
void AdjustmentWindow()
{
	//描画領域の指定
	B_B_Area.top = 0;
	B_B_Area.bottom = wwy;
	B_B_Area.left = 0;
	B_B_Area.right = wwx;

	//描画領域の指定
	PaintArea.top = 0;
	PaintArea.bottom = wwy;
	PaintArea.left = 0;
	PaintArea.right = wwx;


	//クライアント領域からウインドウサイズの調整
	GetWindowRect(g_hWnd,&W_Size);//ウインドウのサイズを取得
	GetClientRect(g_hWnd,&C_Size);//クライアント領域のサイズを取得

	int WindowsX,WindowsY,W_X,W_Y;
	//ウインドウのサイズを計算
	W_X = W_Size.right - W_Size.left;
	W_Y = W_Size.bottom - W_Size.top;

	//ウインドウバーのサイズを計算
	W_BarX = W_X - C_Size.right;
	W_BarY = W_Y - C_Size.bottom;

	//正しいウインドウのサイズを計算
	WindowsX = W_X + W_BarX;
	WindowsY = W_Y + W_BarY;

	//ウインドウのサイズを代入
	SetWindowPos(g_hWnd,HWND_TOP,600,300,WindowsX,WindowsY,SWP_SHOWWINDOW);
}

//バックバッファの内容を描画する領域の計算
void WindowDraw(int a,int b,int c)//WX,WY,FBArea;
{

//フロントバッファの表示領域の算出
		if(a>b)
		{
			//領域の高さ開始位置をリセット
			PaintArea.top = 0;		

			//領域の高さを決定
			PaintArea.bottom = b;

			//領域の幅を決定
			c = (b/3)*4;

			if(c < a)//算出されたX軸の描画範囲がウインドウよりも小さい場合
			{
				//領域の横開始位置を決定
				PaintArea.left = (a - c)/2;

				//領域の幅の開始から終点を決定
				PaintArea.right = PaintArea.left + c;
			}
			else if(c > b)//算出されたX軸の描画範囲がウインドウよりも大きい場合
			{
				PaintArea.left = 0;
				PaintArea.right = a;
				c = (a/4)*3;
				PaintArea.top = (b - c)/2;
				PaintArea.bottom = PaintArea.top + c;
			}
		}
		else if(a<b || a == b)
		{
			//領域の高さ開始位置をリセット
			PaintArea.left = 0;

			//領域の幅を決定
			PaintArea.right = a;

			//領域の高さを決定
			c = (a/4)*3;

			if(c < b)//算出されたY軸の描画範囲がウインドウよりも小さい場合
			{
				//領域の高さ開始位置を決定
				PaintArea.top = (b - c)/2;

				//領域の高さの開始から終点を決定
				PaintArea.bottom = PaintArea.top + c;
			}
			else if(c > b)//算出されたY軸の描画範囲がウインドウよりも大きい場合
			{
				PaintArea.top = 0;
				PaintArea.bottom = b;
				c = (b/3)*4;
				PaintArea.left = (a - c)/2;
				PaintArea.bottom = PaintArea.right + c;
			}
		}
}

//ビューポートの作成
HRESULT Viewport()
{
    HRESULT hr;//ハンドル

    //ビューポートの作成
    vp.X = 0;
    vp.Y = 0;
	vp.Width = wwx;
    vp.Height =wwy;
    vp.MinZ = 0.0f;
    vp.MaxZ = 1.0f;
    hr = g_pDEV -> SetViewport(&vp);
    if(FAILED(hr))
    return false;
    return S_OK;
}

//テクスチャの作成
HRESULT textureCreate()
{
	 HRESULT hr;//ハンドル
	//背景3.png
	hr =  D3DXCreateTextureFromFileEx(g_pDEV,"mtkfbxI.png",
									  wwx,wwy,1,0,
									  D3DFMT_UNKNOWN,D3DPOOL_MANAGED,
									  D3DX_DEFAULT,D3DX_DEFAULT,
									  D3DCOLOR_XRGB(0,0,0),
									  NULL,NULL,&phaikeiTexture);

    if(FAILED(hr))
        return false;	
        return S_OK;
}

//スプライトの作成
HRESULT spriteCreate()
{
    HRESULT hr;//ハンドル
    hr = D3DXCreateSprite(g_pDEV,&pSprite);//1.使用するデバイス、2.受け取る変数
    if(FAILED(hr))
    return false;
    return S_OK;
}

//スプライトの描画(キャラクタ)//描画は全てこの中で行う(画像、文字)
HRESULT drawsprite()
{
    HRESULT hr;//ハンドル
	D3DXMatrixTransformation2D(&m_Matrix,0,0,0,NULL,0,&m_vec2);

    //塗りつぶし
	g_pDEV->Clear(0,NULL,(D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER),
					   D3DCOLOR_RGBA(100,150,255,0),1.0f,0);

	g_pDEV->BeginScene();//スプライトシーンの開始---------------------
		pSprite->Begin(D3DXSPRITE_ALPHABLEND|D3DXSPRITE_DONOTSAVESTATE);
		hr = pSprite->SetTransform(&m_Matrix);	

			//背景
			hr = pSprite->Draw(phaikeiTexture,NULL,NULL,&haikeiPosition,0xffffffff);

			if(FAILED(hr))
			return false;

		pSprite->End();//スプライトを描画して終了

    g_pDEV->EndScene();//シーンを終了----------------------------------
	//デバイスの情報を返す
	//ここでバック、フロントバッファの範囲、描画対象のウインドウなどを指定する
	return g_pDEV->Present(&B_B_Area, &PaintArea, g_hWnd, NULL);
	
    return S_OK;
}






////////////////////////////////////////////////////////////////////

/* コールバック関数関連 */

////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam)
{
    switch(msg)
    {   
		case WM_DESTROY://ウインドウの破棄
				Cleanup();
			  PostQuitMessage(0);
					break;
		
		case WM_SIZING://ウインドウサイズの変更中
					drawsprite();
					InvalidateRgn(hWnd, NULL,TRUE);		
					return TRUE;

		case WM_SIZE://ウインドウサイズの変更後
	
				if(!g_pDEV || wParam == SIZE_MINIMIZED)
				{
					break;
				}
				if(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
				{
					//フロントバッファの描画位置と領域を算出
					int WX,WY,FBArea;

					FBArea = 0;				//初期化
					WX = LOWORD(lParam);	//横の取得
					WY = HIWORD(lParam);	//縦の取得

					WindowDraw(WX,WY,FBArea);//描画領域の計算

					pSprite->OnLostDevice();//スプライトのロスト
					g_pDEV->Reset(&d3dpp);
					InvalidateRgn(hWnd, NULL,TRUE);

				}
				break;


        case WM_KEYDOWN://キーを押す
            switch(wParam)
            {   case VK_ESCAPE:
                    DestroyWindow(hWnd);
                    break;
					default:
					diKeyState[wParam] = 1;
            }
            break;

		case WM_KEYUP://キーを放す
			diKeyState[wParam] = 0;
			break;
			
       default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}
 
////////////////////////////////////////////////////////////////////

/* メインコード */

////////////////////////////////////////////////////////////////////
//★ WinMain()
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{   
    MSG msg;

	//ウインドウクラスの登録
    WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,WndProc,0,0,hInst,NULL,NULL,NULL,NULL,NAME,NULL };
    if (!RegisterClassEx(&wc))  return FALSE;

	//メインウインドウ
    g_hWnd= CreateWindowEx(0,NAME,NAME,WS_OVERLAPPEDWINDOW,600,300,640,480,NULL,NULL,hInst,NULL);
    if (!g_hWnd)  return FALSE;

    // DirectX Graphics の初期化
    if (FAILED(Init3DDev()))    return FALSE;

    // ウインドウ表示
    ShowWindow(g_hWnd, SW_SHOWNORMAL);
    UpdateWindow(g_hWnd);

	//ウインドウサイズ等の調整
	AdjustmentWindow();
    ZeroMemory(&msg,sizeof(msg));

	//背景の位置のセット
	haikeiPosition.x = 0.0f;
	haikeiPosition.y = 0.0f;

	//描画関連
    textureCreate();//テクスチャの作成
    spriteCreate();//スプライトの作成
    Viewport();//ビューポートの作成

    //ループ
    while(msg.message!=WM_QUIT)
    {  
        //プロシージャ
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {   
			TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
	    {	 
			drawsprite();
	    }
	}
    UnregisterClass(NAME, hInst);
    return  TRUE;
}




返信

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