2枚のスプライトの描画がうまくいかない

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

2枚のスプライトの描画がうまくいかない

#1

投稿記事 by bonbo » 13年前

早速ですが質問させていただきます
ストライプを2つ用意し、それぞれに異なるテクスチャを貼り付け、それぞれ描画するプログラムを組んだのですが、うまくいきません。
どこがおかしいのでしょうか。
長くなりますが、一応すべて貼っておきます。
(この順にコピーコンパイルすればうまくいくはずです)
上から、
・インクルード
・デバイス作成解放
・スプライトの設定
・変換行列
・プロシージャとメイン関数
となっています。

各種インクルード

コード:


#include <windows.h>
#include <tchar.h>
//インクルードは9のやつでもいけると思います
#include <d3dx9core.h>
#include <d3d10_1.h>
#include <d3d10.h>
#include <d3dx10.h>


// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

// DirectX関連
IDirect3D9*         g_pD3D;                // D3Dオブジェクト
IDirect3DDevice9*   g_pd3dDevice;          // D3DDeviceオブジェクト
UINT                g_nAdapter;
D3DDEVTYPE          g_dwDeviceType;        // デバイスの種類
DWORD               g_dwBehaviorFlags;     // デバイスの動作モード
D3DSWAPEFFECT       g_dwSwapEffect;
D3DCOLOR            g_clrBackgroundColor;  // 背景色

// スプライト関連
ID3DXSprite*        g_pSprite;        // スプライト
ID3DXSprite*        g_pSprite2;        // スプライト
IDirect3DTexture9*  g_pTexture;       // テクスチャ
D3DSURFACE_DESC     g_sSurfaceInfo;   // サーフェイス情報
D3DXVECTOR3         g_vCenter;        // 描画中心点
D3DCOLOR            g_clrAlpha;       // アルファチャンネル
D3DXMATRIX          g_mat;            // 変換行列
D3DXMATRIX          g_mat2;           // 変換行列2
//プロトタイプ宣言
HRESULT InitializeD3D(HWND hWnd);
void FinalizeD3D();
HRESULT CreateSplite(LPCTSTR lpszFilename);
HRESULT CreateSplite2(LPCTSTR lpszFilename);
void DestroySplite();
void Draw();

デバイス作成、解放関数

コード:

// デバイス初期化(ほぼ固定)
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 CreateSplite(LPCTSTR lpszFilename)
{
	HRESULT hr = S_FALSE;
	UINT uLevel = 0;
	IDirect3DSurface9* pSurface = NULL;

	// スプライト情報の生成
	if (SUCCEEDED(hr))
		hr = ::D3DXCreateSprite(g_pd3dDevice, &g_pSprite);
	if (SUCCEEDED(hr))
		hr = ::D3DXCreateTextureFromFile(g_pd3dDevice, lpszFilename, &g_pTexture);
	if (SUCCEEDED(hr))
		hr = g_pTexture->GetSurfaceLevel(uLevel, &pSurface);

	// サーフェイス取得
	if (SUCCEEDED(hr))
		hr = pSurface->GetDesc(&g_sSurfaceInfo);
	if (pSurface != NULL)
		pSurface->Release();
	pSurface = NULL;

	// 失敗したら破棄
	if (FAILED(hr))
		DestroySplite();

	return hr;
}
HRESULT CreateSplite2(LPCTSTR lpszFilename)
{
	HRESULT hr = S_FALSE;
	UINT uLevel = 0;
	IDirect3DSurface9* pSurface = NULL;

	// スプライト情報の生成
	if (SUCCEEDED(hr))
		hr = ::D3DXCreateSprite(g_pd3dDevice, &g_pSprite2);
	if (SUCCEEDED(hr))
		hr = ::D3DXCreateTextureFromFile(g_pd3dDevice, lpszFilename, &g_pTexture);
	if (SUCCEEDED(hr))
		hr = g_pTexture->GetSurfaceLevel(uLevel, &pSurface);

	// サーフェイス取得
	if (SUCCEEDED(hr))
		hr = pSurface->GetDesc(&g_sSurfaceInfo);
	if (pSurface != NULL)
		pSurface->Release();
	pSurface = NULL;

	// 失敗したら破棄
	if (FAILED(hr))
		DestroySplite();

	return hr;
}
// スプライト破棄
void DestroySplite()
{
	if (g_pTexture != NULL)
		g_pTexture->Release();
	g_pTexture = NULL;
	if (g_pSprite != NULL)
		g_pSprite->Release();
	if (g_pSprite2 != NULL)
		g_pSprite2->Release();
	g_pSprite = NULL;
}
変換行列2つ

コード:

// 変換行列の設定
void SetMatrix(HWND hWnd)45°回転
{
	RECT rc;
	FLOAT x=0, y=0;
	::D3DXMatrixIdentity(&g_mat);
	::D3DXMatrixScaling(&g_mat, x, y, 0.0f);
	::D3DXMatrixRotationZ(&g_mat, D3DXToRadian(45.0f));

}
void SetMatrix2(HWND hWnd)//0°回転
{
	RECT rc;
	FLOAT x=0, y=0;

	::D3DXMatrixIdentity(&g_mat2);
	::D3DXMatrixScaling(&g_mat2, x, y, 0.0f);
	::D3DXMatrixRotationZ(&g_mat, D3DXToRadian(0.0f));

}
描画処理

コード:

// 描画
void Draw()
{
	// クリア
	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;
	}
	// 1つ目のスプライトを描画
	g_pSprite2->Begin(D3DXSPRITE_ALPHABLEND);
	g_pSprite2->SetTransform(&g_mat2);
	g_pSprite2->Draw(
		g_pTexture,      // LPDIRECT3DTEXTURE9 pTexture
		NULL,            // CONST RECT *pSrcRect
		&g_vCenter,      // CONST D3DXVECTOR3 *pCenter
		NULL,            // CONST D3DXVECTOR3 *pPosition
		g_clrAlpha       // D3DCOLOR Color
	);
	
	g_pSprite2->End();
	// 2つ目のスプライトを描画

	g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
	g_pSprite->Draw(
		g_pTexture,      // LPDIRECT3DTEXTURE9 pTexture
		NULL,            // CONST RECT *pSrcRect
		&g_vCenter,      // CONST D3DXVECTOR3 *pCenter
		NULL,            // CONST D3DXVECTOR3 *pPosition
		g_clrAlpha       // D3DCOLOR Color
	);
	g_pSprite->SetTransform(&g_mat);
	g_pSprite->End();

	// シーン描画の終了とバックバッファからの表示
	g_pd3dDevice->EndScene();
	g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
プロシージャーとメイン関数です

コード:

int APIENTRY
_tWinMain(HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          LPTSTR    lpCmdLine,
          int       nCmdShow)
{
	MSG msg;
	msg.message=NULL;
	HWND hWnd;
	HRESULT hr;
	LPCTSTR lpszFilename = _T("colorbar.png");
	WNDCLASSEX wcex;
	LPCTSTR szWindowClass = _T("{45320057-ECD4-4c79-BE64-009DCBD6AEF6}");

	// ウィンドウクラス登録
	::ZeroMemory(&wcex, sizeof(WNDCLASSEX));
	wcex.cbSize             = sizeof(WNDCLASSEX);
	wcex.style              = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc        = WndProc;
	wcex.hInstance          = hInstance;
	wcex.hIcon              = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
	wcex.hIconSm            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
	wcex.hCursor            = LoadCursor (NULL, IDC_ARROW);
	wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszClassName      = szWindowClass;
	if (!RegisterClassEx(&wcex))
		return FALSE;

	// ウィンドウ作成
	hWnd = CreateWindow(szWindowClass, _T(""),
	                    WS_OVERLAPPEDWINDOW,
	                    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
	                    NULL, NULL, hInstance, NULL);
	if (!hWnd)
		return FALSE;

	// パラメータのセット
	g_dwDeviceType    = D3DDEVTYPE_HAL;
	g_nAdapter        = D3DADAPTER_DEFAULT;
	g_dwBehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	g_dwSwapEffect    = D3DSWAPEFFECT_DISCARD;

	g_vCenter = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	g_clrBackgroundColor = D3DCOLOR_XRGB(0xcc,0xcc,0xcc);
	g_clrAlpha = D3DCOLOR_RGBA(0xff,0xff,0xff,0xff);

	// 初期化
	hr = InitializeD3D(hWnd);
	if (FAILED(hr))
		return FALSE;
	hr = CreateSplite(lpszFilename);
	if (FAILED(hr))
		return FALSE;
	hr = CreateSplite2(lpszFilename);
	if (FAILED(hr))
		return FALSE;
	SetMatrix(hWnd);
	SetMatrix2(hWnd);
	// 一回再描画してウィンドウ表示
	Draw();
	SetWindowPos(hWnd, NULL, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW);

	// メイン メッセージ ループ:
	while (msg.message!=WM_QUIT) {
		if (PeekMessageA( &msg , NULL , 0 , 0 , PM_REMOVE )) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else{
			Draw();
		}
		Sleep( 1 );
	}

	// 後処理
	DestroySplite();
	FinalizeD3D();

	return (int) msg.wParam;
}

// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{

	case WM_ERASEBKGND:
		return FALSE;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}

以上です。よろしくおねがいします。

Ryo

Re: 2枚のストライプの描画がうまくいかない

#2

投稿記事 by Ryo » 13年前

「うまくいかない」とは?

#縞模様はどこにあるんだろう?と一瞬思った

bonbo

Re: 2枚のストライプの描画がうまくいかない

#3

投稿記事 by bonbo » 13年前

>Ryoさん
ありがとうございます
すみません…目的を書いていませんでしたね…
やりたいことは2枚の画像(傾いてない画像と45°に傾いた画像)を重ねて表示したいということなのですが
なぜか1方しか表示されないのです

bonbo

Re: 2枚のスプライトの描画がうまくいかない

#4

投稿記事 by bonbo » 13年前

>縞模様
ストライプじゃなくてスプライトでした…すみません…
トピック名かえられないでしょうか…

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 2枚のスプライトの描画がうまくいかない

#5

投稿記事 by softya(ソフト屋) » 13年前

タイトル名は変えておきますが、再現確認のために何処かのアップローダにソースと画像ファイルをアップロードできませんか?
このままだと確認に手間がかかりすぎると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

bonbo

Re: 2枚のスプライトの描画がうまくいかない

#6

投稿記事 by bonbo » 13年前

>soft屋さん
ありがとうございます
http://www1.axfc.net/uploader/so/2681997
です
ご迷惑おかけしました

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 2枚のスプライトの描画がうまくいかない

#7

投稿記事 by softya(ソフト屋) » 13年前

間違ってますね。修正版です。

コード:

	::D3DXMatrixIdentity(&g_mat2);
	::D3DXMatrixScaling(&g_mat2, x, y, 0.0f);
	::D3DXMatrixRotationZ(&g_mat2, D3DXToRadian(0.0f));
どう違うかは見比べてみてください。

ちなみに同じような処理関数をコピペで作っているのが原因です。
こういうのは、引数を工夫して関数を共通化すれば防ぐ事が可能です。
バグを出さないための基本的な手法ですので手を抜かないことが自分のためになります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

bonbo

Re: 2枚のスプライトの描画がうまくいかない

#8

投稿記事 by bonbo » 13年前

>soft屋さん
ありがとうございます。できました
>引数を工夫して関数を共通化すれば防ぐ事が可能です
サボらないようにします…すみません…
連日トピックをたてつづけに立ててしまい申し訳ありませんでした。
また何かありましたらよろしくお願いします。

閉鎖

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