D3D中的纹理映射(4)
该例程演示了如何设置纹理寻址模式。
截图:
源程序:
/**************************************************************************************
Allows the user to switch between the different texture address modes to see what they do.
Use the following keys:
'W' - Switches to Wrap mode
'B' - Switches to Border mode
'C' - Switches to Clamp mode
'M' - Switches to Mirror mode
**************************************************************************************/
#include "d3dUtility.h"
#pragma warning(disable : 4100)
const int WIDTH = 640;
const int HEIGHT = 480;
IDirect3DDevice9* g_d3d_device;
IDirect3DVertexBuffer9* g_quad_vb;
IDirect3DTexture9* g_d3d_texture;
class cTextureVertex
{
public:
float m_x, m_y, m_z;
float m_nx, m_ny, m_nz;
float m_u, m_v; // texture coordinates
cTextureVertex() { }
cTextureVertex(float x, float y, float z,
float nx, float ny, float nz,
float u, float v)
{
m_x = x; m_y = y; m_z = z;
m_nx = nx; m_ny = ny; m_nz = nz;
m_u = u; m_v = v;
}
};
const DWORD TEXTURE_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
////////////////////////////////////////////////////////////////////////////////////////////////////
bool setup()
{
// create the quad vertex buffer and fill it with the quad geometry
g_d3d_device->CreateVertexBuffer(6 * sizeof(cTextureVertex), D3DUSAGE_WRITEONLY, TEXTURE_VERTEX_FVF,
D3DPOOL_MANAGED, &g_quad_vb, NULL);
cTextureVertex* vertices;
g_quad_vb->Lock(0, 0, (void**)&vertices, 0);
// quad built from two triangles, note texture coordinate.
vertices[0] = cTextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
vertices[1] = cTextureVertex(-1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
vertices[2] = cTextureVertex( 1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);
vertices[3] = cTextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
vertices[4] = cTextureVertex( 1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);
vertices[5] = cTextureVertex( 1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 3.0f);
g_quad_vb->Unlock();
// create the texture and set filters
D3DXCreateTextureFromFile(g_d3d_device, "dx5_logo.bmp", &g_d3d_texture);
g_d3d_device->SetTexture(0, g_d3d_texture);
g_d3d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_d3d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
g_d3d_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
// don't use lighting for this sample
g_d3d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
// set the projection matrix
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)WIDTH/HEIGHT, 1.0f, 1000.0f);
g_d3d_device->SetTransform(D3DTS_PROJECTION, &proj);
return true;
}
void cleanup()
{
safe_release<IDirect3DVertexBuffer9*>(g_quad_vb);
safe_release<IDirect3DTexture9*>(g_d3d_texture);
}
bool display(float time_delta)
{
// set wrap address mode
if(GetAsyncKeyState('W') & 0x8000f)
{
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
}
// set border color address mode
if(GetAsyncKeyState('B') & 0x8000f)
{
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
g_d3d_device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x000000ff);
}
// set clamp address mode
if(GetAsyncKeyState('C') & 0x8000f)
{
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
}
// set mirror address mode
if(GetAsyncKeyState('M') & 0x8000f)
{
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
g_d3d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
}
// draw the scene
g_d3d_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
g_d3d_device->BeginScene();
g_d3d_device->SetStreamSource(0, g_quad_vb, 0, sizeof(cTextureVertex));
g_d3d_device->SetFVF(TEXTURE_VERTEX_FVF);
g_d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
g_d3d_device->EndScene();
g_d3d_device->Present(NULL, NULL, NULL, NULL);
return true;
}
LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(word_param == VK_ESCAPE)
DestroyWindow(hwnd);
break;
}
return DefWindowProc(hwnd, msg, word_param, long_param);
}
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
{
if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_d3d_device))
{
MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
return 0;
}
if(! setup())
{
MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
return 0;
}
enter_msg_loop(display);
cleanup();
g_d3d_device->Release();
return 0;
}