Direct3D成長日記(07):紋理貼圖(二):Texture Addressing Modes
//////////////////////////////////////////////////////////////////////////
//說明 :Direct3D成長日記(07):紋理貼圖(二):Texture Addressing Modes
//作者 :shenzi
//完成時間 :2009.05.15
//描述 :Texture Addressing Modes:F1:WRARP;F2:CLMAP;F3:MIRROR;
// F4:BORDER;F5:MIRRORONCE
//////////////////////////////////////////////////////////////////////////
//包含頭文件,相應庫:
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
//全局變量聲明:
LPDIRECT3D9 g_pD3D = NULL; //Direct3D接口指針
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;//Direct3D設備指針
LPDIRECT3DVERTEXBUFFER9 g_pVBuffer = NULL; //頂點緩存
LPDIRECT3DTEXTURE9 g_pTexture = NULL; //紋理
#define WINDOW_CLASS_NAME L"Direct3D"
#define WINDOW_NAME L"Texture Addressing Modes: F1:WRARP;F2:CLMAP;F3:MIRROR;F4:BORDER;F5:MIRRORONCE"
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
bool g_bUseIndexedGeometry = true;
//鼠標移動控制的旋轉
float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;
//頂點結構
struct CUSTOMVERTEX
{
FLOAT X, Y ,Z;
FLOAT U, V;
};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_TEX1)
//函數聲明:
HRESULT InitD3D( HWND); //初始化Direct3D
void RenderFrame( void); //場景渲染
void CleanD3D( void); //釋放資源
HRESULT InitGraphics(void); //初始化圖形
void SetupMatrices(void); //模型視圖投影矩陣設置
//WINDOWS 消息處理函數:
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM);
//WinMain函數:
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hprevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//變量聲明:
HWND hwnd;
MSG msg;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
//創建窗口類
wc.cbClsExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor( NULL, IDC_ARROW);
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = WINDOW_CLASS_NAME;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
//註冊窗口類
RegisterClassEx(&wc);
//初始化窗口
hwnd = CreateWindowEx( NULL,
WINDOW_CLASS_NAME,
WINDOW_NAME,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
SCREEN_WIDTH,
SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);
//顯示,更新窗口:
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
if (SUCCEEDED(InitD3D(hwnd)))
{
if (SUCCEEDED(InitGraphics()))
{
ZeroMemory(&msg, sizeof(MSG));
//消息循環:
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
RenderFrame();
}
}
}
UnregisterClass( WINDOW_CLASS_NAME, wc.hInstance );
return 0;
}
LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static POINT ptLastMousePosit;
static POINT ptCurrentMousePosit;
static bool bMousing;
switch( msg )
{
case WM_DESTROY:
CleanD3D();
PostQuitMessage( 0 );
return 0;
case WM_LBUTTONDOWN:
{
ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
bMousing = true;
}
break;
case WM_LBUTTONUP:
{
bMousing = false;
}
break;
case WM_MOUSEMOVE:
{
ptCurrentMousePosit.x = LOWORD (lParam);
ptCurrentMousePosit.y = HIWORD (lParam);
if( bMousing )
{
g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
}
ptLastMousePosit.x = ptCurrentMousePosit.x;
ptLastMousePosit.y = ptCurrentMousePosit.y;
}
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_F1:
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
break;
case VK_F2:
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
break;
case VK_F3:
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
break;
case VK_F4:
g_pD3DDevice->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x00ff00ff );
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER );
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER );
break;
case VK_F5:
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRRORONCE );
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRRORONCE );
break;
}
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
HRESULT InitD3D(HWND hwnd)
{
//創建D3D對象:
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
{
return E_FAIL;
}
//定義窗口的顯示信息:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.EnableAutoDepthStencil = TRUE;
//創建D3D設備:
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
{
return E_FAIL;
}
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
return S_OK;
}
void RenderFrame(void)
{
if(NULL == g_pD3DDevice)
return;
//清空背景緩衝區:
g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
if(SUCCEEDED(g_pD3DDevice->BeginScene()))
{
//渲染場景:
//設置頂點結構:
g_pD3DDevice->SetFVF(CUSTOMFVF);
SetupMatrices();
D3DXMATRIX matTrans;
D3DXMATRIX matRot;
D3DXMATRIX matWorld;
D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, 5.0f );
D3DXMatrixRotationYawPitchRoll( &matRot,
D3DXToRadian(g_fSpinX),
D3DXToRadian(g_fSpinY),
0.0f );
matWorld = matRot * matTrans;
g_pD3DDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pD3DDevice->SetTexture(0, g_pTexture);
g_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_pD3DDevice->SetStreamSource( 0, g_pVBuffer, 0, sizeof(CUSTOMVERTEX) );
g_pD3DDevice->SetFVF( CUSTOMFVF );
g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pD3DDevice->EndScene();
}
//把渲染的場景顯示在窗口:
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
void CleanD3D(void)
{
//釋放資源
if (NULL != g_pVBuffer)
{
g_pVBuffer->Release();
}
if(NULL != g_pD3DDevice)
g_pD3DDevice->Release();
if(NULL != g_pD3D)
g_pD3D->Release();
g_pVBuffer = NULL;
g_pD3DDevice = NULL;
g_pD3D = NULL;
}
HRESULT InitGraphics(void)
{
//讀入紋理
D3DXCreateTextureFromFile(g_pD3DDevice, L"smile.jpg", &g_pTexture);
//定義頂點數組
CUSTOMVERTEX vertices[] =
{
// Quad 0
{-1.0f, 1.0f, 0.0f, 0.0f,0.0f },
{ 1.0f, 1.0f, 0.0f, 3.0f,0.0f },
{-1.0f,-1.0f, 0.0f, 0.0f,3.0f },
{ 1.0f,-1.0f, 0.0f, 3.0f,3.0f }
};
//建立頂點緩存
if (FAILED(g_pD3DDevice->CreateVertexBuffer(sizeof(vertices),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&g_pVBuffer,
NULL)))
{
return E_FAIL;
}
//通過Lock,Unlock 爲頂點緩存填充數據(頂點信息):
VOID * pV;
if(FAILED(g_pVBuffer->Lock(0,
sizeof(vertices),
(void**)&pV,
0)))
{
return E_FAIL;
}
memcpy(pV, vertices, sizeof(vertices));
g_pVBuffer->Unlock();
}
void SetupMatrices(void)
{
//投影變換
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DX_PI/4,
(FLOAT)SCREEN_WIDTH/(FLOAT)SCREEN_HEIGHT,
0.1f,
100.0f);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection);
}