texturestateapplication.cpp
来自「real-time(实时渲染技术DirectX)13-18」· C++ 代码 · 共 264 行
CPP
264 行
/***************************************************************
* TextureApplication.cpp *
* *
* This file contains the implementation of the *
* CTextureStateApplication class. *
* To compile correctly, this file must be linked with: *
* kernel32.lib *
* user32.lib *
* d3dx8dt.lib *
* d3d8.lib *
* gdi32.lib *
* advapi32.lib *
* *
***************************************************************/
#include "TextureStateApplication.h"
#define D3DFVF_TEXTUREVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
struct TEXTURE_VERTEX
{
float x, y, z;
float u, v;
};
CTextureStateApplication::CTextureStateApplication()
{
//Initialize everything
m_pVertexBuffer = NULL;
m_pCheckerTexture = NULL;
//Set the default modes
m_CurrentFilterMode = 1;
m_CurrentAddressMode = 1;
}
CTextureStateApplication::~CTextureStateApplication()
{
DestroyGeometry();
}
BOOL CTextureStateApplication::PostInitialize()
{
if (FAILED(EasyCreateWindowed(m_hWnd, D3DDEVTYPE_HAL,
D3DCREATE_HARDWARE_VERTEXPROCESSING)))
return FALSE;
SetupDevice();
if (!CreateGeometry())
return FALSE;
//All of our textures are in managed memory, so no need to
//initialize them more than once.
if (FAILED(D3DXCreateTextureFromFile(m_pD3DDevice,
"..\\media\\Big_Checker.bmp",
&m_pCheckerTexture)))
return FALSE;
VerifyModes();
return TRUE;
}
void CTextureStateApplication::SetupDevice()
{
D3DXMatrixLookAtLH(&m_ViewMatrix, &D3DXVECTOR3(0.0f, 0.25f, 2.0f),
&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));
m_pD3DDevice->SetTransform(D3DTS_VIEW, &m_ViewMatrix);
RECT WindowRect;
GetClientRect(m_hWnd, &WindowRect);
D3DXMatrixPerspectiveFovLH(&m_ProjectionMatrix,
D3DX_PI / 4,
(float)(WindowRect.right - WindowRect.left) /
(float)(WindowRect.bottom - WindowRect.top),
1.0f, 100.0f);
m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &m_ProjectionMatrix);
m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
}
BOOL CTextureStateApplication::HandleMessage(MSG *pMessage)
{
//Handle user input. F1 sets the current addressing mode.
if (pMessage->message == WM_KEYDOWN && pMessage->wParam == VK_F1)
{
if (++m_CurrentAddressMode > 5)
m_CurrentAddressMode = 1;
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSU,
(D3DTEXTUREADDRESS)m_CurrentAddressMode);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_ADDRESSV,
(D3DTEXTUREADDRESS)m_CurrentAddressMode);
}
//F2 runs through the different filtering modes
if (pMessage->message == WM_KEYDOWN && pMessage->wParam == VK_F2)
{
if (++m_CurrentFilterMode > 5)
m_CurrentFilterMode = 1;
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER,
(D3DTEXTUREFILTERTYPE)m_CurrentFilterMode);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER,
(D3DTEXTUREFILTERTYPE)m_CurrentFilterMode);
m_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER,
(D3DTEXTUREFILTERTYPE)m_CurrentFilterMode);
}
//Mke sure the base class receives any messages
return CHostApplication::HandleMessage(pMessage);
}
BOOL CTextureStateApplication::PreReset()
{
DestroyGeometry();
return TRUE;
}
BOOL CTextureStateApplication::PostReset()
{
SetupDevice();
return CreateGeometry();
}
BOOL CTextureStateApplication::PreTerminate()
{
DestroyGeometry();
//Make sure a texture is not in use
m_pD3DDevice->SetTexture(0, NULL);
if (m_pCheckerTexture)
m_pCheckerTexture->Release();
return TRUE;
}
BOOL CTextureStateApplication::CreateGeometry()
{
//Same old drill... Create, lock, fill unlock.
if (FAILED(m_pD3DDevice->CreateVertexBuffer(6 * sizeof(TEXTURE_VERTEX),
D3DUSAGE_WRITEONLY,
D3DFVF_TEXTUREVERTEX,
D3DPOOL_DEFAULT,
&m_pVertexBuffer)))
return FALSE;
TEXTURE_VERTEX *pVertices;
if (FAILED(m_pVertexBuffer->Lock(0, 6 * sizeof(TEXTURE_VERTEX),
(BYTE **)&pVertices,
0)))
{
DestroyGeometry();
return FALSE;
}
//we are creating a "floor and wall" arrangement that will be rendered with a
//triangle strip. First set their position.
pVertices[0].x = -1.0f; pVertices[0].y = 0.0f; pVertices[0].z = 1.0f;
pVertices[1].x = 1.0f; pVertices[1].y = 0.0f; pVertices[1].z = 1.0f;
pVertices[2].x = -1.0f; pVertices[2].y = 0.0f; pVertices[2].z = -1.0f;
pVertices[3].x = 1.0f; pVertices[3].y = 0.0f; pVertices[3].z = -1.0f;
pVertices[4].x = -1.0f; pVertices[4].y = 1.0f; pVertices[4].z = -1.0f;
pVertices[5].x = 1.0f; pVertices[5].y = 1.0f; pVertices[5].z = -1.0f;
//Now set the texture coordinates.
pVertices[0].u = -10.0f; pVertices[0].v = -10.0f;
pVertices[1].u = 10.0f; pVertices[1].v = -10.0f;
pVertices[2].u = -10.0f; pVertices[2].v = 10.0f;
pVertices[3].u = 10.0f; pVertices[3].v = 10.0f;
pVertices[4].u = -10.0f; pVertices[4].v = -10.0f;
pVertices[5].u = 10.0f; pVertices[5].v = -10.0f;
m_pVertexBuffer->Unlock();
//Since we are not going to use another source...
m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(TEXTURE_VERTEX));
m_pD3DDevice->SetVertexShader(D3DFVF_TEXTUREVERTEX);
return TRUE;
}
void CTextureStateApplication::DestroyGeometry()
{
if (m_pVertexBuffer)
{
m_pVertexBuffer->Release();
m_pVertexBuffer = NULL;
}
}
void CTextureStateApplication::PreRender()
{
//We have overridden PreRender so that we can change the clear color,
//but make sure you call BeginScene!!!!
//Clear the device
m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
//Call BeginScene to set up the device
m_pD3DDevice->BeginScene();
}
void CTextureStateApplication::Render()
{
m_pD3DDevice->SetTexture(0, m_pCheckerTexture);
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 4);
}
void CTextureStateApplication::VerifyModes()
{
//Get the device caps
D3DCAPS8 Caps;
m_pD3DDevice->GetDeviceCaps(&Caps);
//This is a fairly sloppy way to do this, but we don't have
//a better method to do UI (yet). You may want to comment
//these lines out once you understand the limitations of your device.
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER))
MessageBox(m_hWnd, "The Border Addressing mode is not available.", "", MB_OK);
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP))
MessageBox(m_hWnd, "The Clamp Addressing mode is not available.", "", MB_OK);
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR))
MessageBox(m_hWnd, "The Mirror Addressing mode is not available.", "", MB_OK);
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE))
MessageBox(m_hWnd, "The Mirror Once Addressing mode is not available.", "", MB_OK);
if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP))
MessageBox(m_hWnd, "The Wrap Addressing mode is not available.", "", MB_OK);
//We are going to assume that if the device supports a given filter
//type for the magnification filter that it will support it for the
//minification and mip map filters as well. THIS IS NOT NECESSARILY
//GUARANTEED TO BE TRUE, but it should give you a general feel for
//what your device is capable of. If you need to check, replicate these
//lines replacing MAG with MIN and/or MIP.
if (!(Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFPOINT))
MessageBox(m_hWnd, "The Point Filtering mode is not available.", "", MB_OK);
if (!(Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR))
MessageBox(m_hWnd, "The Linear Filtering mode is not available.", "", MB_OK);
if (!(Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC))
MessageBox(m_hWnd, "The Anisotropic Filtering mode is not available.", "", MB_OK);
if (!(Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFAFLATCUBIC))
MessageBox(m_hWnd, "The Cubic Filtering mode is not available.", "", MB_OK);
if (!(Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC))
MessageBox(m_hWnd, "The Gaussian Cubic Filtering mode is not available.", "", MB_OK);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?