#include <windows.h>
#include <tchar.h>
#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; // スプライト
IDirect3DTexture9* g_pTexture; // テクスチャ
D3DSURFACE_DESC g_sSurfaceInfo; // サーフェイス情報
D3DXVECTOR3 g_vCenter; // 描画中心点
D3DCOLOR g_clrAlpha; // アルファチャンネル
D3DXMATRIX g_mat; // 変換行列
HRESULT InitializeD3D(HWND hWnd);
void FinalizeD3D();
HRESULT CreateSplite(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;
}
// スプライト破棄
void DestroySplite()
{
if (g_pTexture != NULL)
g_pTexture->Release();
g_pTexture = NULL;
if (g_pSprite != NULL)
g_pSprite->Release();
g_pSprite = NULL;
}
// 変換行列の設定
void SetMatrix(HWND hWnd)
{
RECT rc;
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);
}
// 描画
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;
}
// スプライトを描画
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;
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;
SetMatrix(hWnd);
// 一回再描画してウィンドウ表示
Draw();
SetWindowPos(hWnd, NULL, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW);
// メイン メッセージ ループ:
while (GetMessage(&msg, NULL, 0, 0)) {
if (!TranslateAccelerator(msg.hwnd, NULL, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// 後処理
DestroySplite();
FinalizeD3D();
return (int) msg.wParam;
}
// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
Draw();
break;
case WM_ERASEBKGND:
return FALSE;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}