全景抗混叠是一种减少在渲染的多边形的边时所产生的参差不齐效果的方法。抗混叠物体也会对渲染后的整个场景产生负面影响,尤其是处理动画更是如此。通过实现对像素的本地模糊处理,并在屏幕上显示出一个平均结果而实现全景抗混叠。
在Direct3D中启用多采样实现程序中的抗混叠。多采样将对程序性能的影响很大。这种性能影响取决于所选的样本数,所以在考虑更多的样本数时,一定要牢记着一点。采样数越高,渲染的场景质量越好。样本最大数取决于支持他的硬件。
/*
Demo Name: World Matrix
Author: batman
Date: 03/08/2013
*/
#include<d3d9.h>
#include<d3dx9.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "Batman"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
bool InitializeD3D(HWND hWnd,bool fullscreen);
bool InitializeObjects();
void RenderScene();
void Shutdown();
LPDIRECT3D9 g_D3D=NULL;
LPDIRECT3DDEVICE9 g_D3DDevice=NULL;
D3DXMATRIX g_projection;
D3DXMATRIX g_worldMatrix;
D3DXMATRIX g_translation;
D3DXMATRIX g_rotation;
float g_angle=0.0f;
LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer=NULL;
struct stD3DVertex
{
float x,y,z;
unsigned long color;
};
#define D3DFVF_VERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYUP:
if(wParam == VK_ESCAPE) PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
WINDOW_CLASS, NULL };
RegisterClassEx(&wc);
// Create the application's window
HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, GetDesktopWindow(),
NULL, wc.hInstance, NULL);
// Initialize Direct3D
if(InitializeD3D(hWnd, false))
{
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Enter the message loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}
}
// Release any and all resources.
Shutdown();
// Unregister our window.
UnregisterClass(WINDOW_CLASS, wc.hInstance);
return 0;
}
bool InitializeD3D(HWND hWnd,bool fullscreen)
{
D3DDISPLAYMODE displayMode;
g_D3D=Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D==NULL) return false;
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&displayMode)))
return false;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
D3DMULTISAMPLE_TYPE multiType=D3DMULTISAMPLE_NONE;
if(g_D3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,displayMode.Format,!fullscreen,
D3DMULTISAMPLE_4_SAMPLES,NULL)==D3D_OK)
multiType=D3DMULTISAMPLE_4_SAMPLES;
if(fullscreen)
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = WINDOW_WIDTH;
d3dpp.BackBufferHeight = WINDOW_HEIGHT;
}
else
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
d3dpp.MultiSampleType = multiType;
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING |
D3DCREATE_PUREDEVICE, &d3dpp, &g_D3DDevice))) return false;
// Initialize any objects we will be displaying.
if(!InitializeObjects()) return false;
return true;
}
bool InitializeObjects()
{
// Set the projection matrix.
D3DXMatrixPerspectiveFovLH(&g_projection, D3DX_PI / 4,
WINDOW_WIDTH/WINDOW_HEIGHT, 0.1f, 1000.0f);
g_D3DDevice->SetTransform(D3DTS_PROJECTION, &g_projection);
// Set default rendering states.
g_D3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// Fill in our structure to draw an object.
// x, y, z, color.
stD3DVertex objData[] =
{
{-0.5f, -0.5f, 1.0f, D3DCOLOR_XRGB(255,255,0)},
{0.5f, -0.5f, 1.0f, D3DCOLOR_XRGB(255,0,0)},
{0.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0,0,255)}
};
// Create the vertex buffer.
if(FAILED(g_D3DDevice->CreateVertexBuffer(3 * sizeof(stD3DVertex),
0, D3DFVF_VERTEX, D3DPOOL_DEFAULT, &g_VertexBuffer,
NULL))) return false;
// Fill the vertex buffer.
void *ptr;
if(FAILED(g_VertexBuffer->Lock(0, sizeof(objData),
(void**)&ptr, 0))) return false;
memcpy(ptr, objData, sizeof(objData));
g_VertexBuffer->Unlock();
return true;
}
void RenderScene()
{
g_D3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0),1.0f,0);
g_D3DDevice->BeginScene();
D3DXMatrixTranslation(&g_translation,0.0f,0.0f,3.0f);
D3DXMatrixRotationY(&g_rotation,g_angle);
g_worldMatrix=g_rotation*g_translation;
g_angle+=0.01f;
if(g_angle>=360) g_angle=0.0f;
g_D3DDevice->SetTransform(D3DTS_WORLD, &g_worldMatrix);
g_D3DDevice->SetStreamSource(0, g_VertexBuffer, 0,
sizeof(stD3DVertex));
g_D3DDevice->SetFVF(D3DFVF_VERTEX);
g_D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
g_D3DDevice->EndScene();
g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}
void Shutdown()
{
if(g_D3DDevice != NULL) g_D3DDevice->Release();
if(g_D3D != NULL) g_D3D->Release();
if(g_VertexBuffer != NULL) g_VertexBuffer->Release();
g_D3DDevice = NULL;
g_D3D = NULL;
g_VertexBuffer = NULL;
}