特效--多采樣

露水上的青蛙發表於2013-08-03

全景抗混疊是一種減少在渲染的多邊形的邊時所產生的參差不齊效果的方法。抗混疊物體也會對渲染後的整個場景產生負面影響,尤其是處理動畫更是如此。通過實現對畫素的本地模糊處理,並在螢幕上顯示出一個平均結果而實現全景抗混疊。

在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;
}

相關文章