注:1:一般使用多个窗口,都觉得对应一个device比较好做,但是这样一来,texture,vertex....在不同device之间不能共享,造成很大的浪费. 2: SetViewport是个重点.#include "windows.h" #include "d3d9.h" #include "d3dx9.h" #ifdef _DEBUG #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9d.lib") #else #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") #endif HINSTANCE g_3DhInst; ATOM g_3DWinClass; HWND g_3DWindow=0; HWND g_3DFocusWindow=0; DWORD g_3DWindowStyleWin; DWORD g_3DWindowStyleFullScreen; DWORD g_3DWindowStyleExWin; DWORD g_3DWindowStyleExFullScreen; D3DPRESENT_PARAMETERS g_d3dpp; LPDIRECT3D9 g_pD3D=0; LPDIRECT3DDEVICE9 g_pDev=0; bool g_bResetDevice = false; char g_strWinClass[] = "QuickDX9"; char g_strWinTitle[] = "TestApp"; LRESULT WINAPI TestWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {  if (msg==WM_CLOSE)  {   PostQuitMessage(0);  }  else if (msg==WM_SIZE)  {   g_bResetDevice = true;  }  else if (msg==WM_KEYDOWN && wParam == VK_ESCAPE)  {   PostQuitMessage(0);  }  return DefWindowProc(hWnd, msg, wParam, lParam); } bool RegisterWin() {  WNDCLASSEX wndclass;  memset(&wndclass, 0, sizeof(wndclass));  wndclass.cbSize = sizeof(WNDCLASSEX);  wndclass.style = CS_OWNDC;  wndclass.lpfnWndProc = TestWinProc;  wndclass.hInstance = g_3DhInst;  wndclass.lpszClassName = g_strWinClass;  g_3DWinClass = RegisterClassEx(&wndclass);  return g_3DWinClass != 0; } bool CreateWin() {  RECT rc;  g_3DWindowStyleFullScreen = g_3DWindowStyleWin = WS_OVERLAPPEDWINDOW | WS_VISIBLE;  g_3DWindowStyleExFullScreen = g_3DWindowStyleExWin = WS_EX_OVERLAPPEDWINDOW;  rc.left = 0;  rc.top = 0;  rc.right = 800;  rc.bottom = 600;  AdjustWindowRectEx(&rc, g_3DWindowStyleWin, false, g_3DWindowStyleExWin);  g_3DFocusWindow = CreateWindowEx(g_3DWindowStyleExWin, g_strWinClass, g_strWinTitle, g_3DWindowStyleWin,  0, 0, rc.right - rc.left, rc.bottom - rc.top, 0, 0, g_3DhInst, 0);  g_3DWindow = g_3DFocusWindow;  return g_3DWindow != 0; } bool MsgPump() {  MSG msg;  static bool exit = false;  if (exit)   return false;  while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))  {   if (msg.message == WM_QUIT)   {    exit = true;    return false;   }   TranslateMessage(&msg);   DispatchMessage(&msg);  }  return true; } void Cleanup() {  if (g_pDev)   g_pDev->Release();  if (g_pD3D)   g_pD3D->Release();  if (g_3DWindow)   DestroyWindow(g_3DWindow); }  bool CreateD3D() {  g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);  return g_pD3D != 0; }
 bool CreateDevice() {  RECT rc;  GetClientRect(g_3DWindow, &rc);  memset(&g_d3dpp, 0, sizeof(g_d3dpp));  g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;  g_d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;  g_d3dpp.EnableAutoDepthStencil = true;  g_d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;  g_d3dpp.hDeviceWindow = g_3DWindow;  g_d3dpp.BackBufferWidth = rc.right - rc.left;  g_d3dpp.BackBufferHeight = rc.bottom - rc.top;  g_d3dpp.BackBufferCount = 1;  g_d3dpp.Windowed = true;  g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE ;  if (FAILED(g_pD3D->CreateDevice(0, D3DDEVTYPE_HAL, g_3DFocusWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,  &g_d3dpp, &g_pDev)))   return false;  return true; } void TestPreReset(); bool TestPostReset(); bool ResetDevice() {  TestPreReset();  if (FAILED(g_pDev->Reset(&g_d3dpp)))   return false;  return TestPostReset(); } bool TestDevice() {  HRESULT hr = g_pDev->TestCooperativeLevel();  if (hr == D3DERR_DEVICENOTRESET || (hr == S_OK && g_bResetDevice))  {   g_bResetDevice = false;   if (!ResetDevice())    return false;  }  else if (hr == D3DERR_DEVICELOST)   return false;  return true; } HWND g_swapwnd = 0; LPDIRECT3DSWAPCHAIN9 g_pSwap = 0; D3DPRESENT_PARAMETERS g_scparam; LPDIRECT3DSURFACE9 g_pSwapDepthSurf = 0; LPDIRECT3DSURFACE9 g_pSwapRenderSurf = 0; LPDIRECT3DSURFACE9 g_pDevDepthSurf = 0; LPDIRECT3DSURFACE9 g_pDevRenderSurf = 0; bool TestSetup() {  RECT rc;  rc.left = 0;  rc.top = 0;  rc.right = 400;  rc.bottom = 400;  AdjustWindowRectEx(&rc, g_3DWindowStyleWin, false, g_3DWindowStyleExWin);  g_swapwnd = CreateWindowEx(g_3DWindowStyleExWin, g_strWinClass, "ChainWnd", g_3DWindowStyleWin, 800, 0,  rc.right - rc.left, rc.bottom - rc.top, 0, 0, g_3DhInst, 0);  return TestPostReset(); } void TestCleanup() {  TestPreReset();  if (g_swapwnd)   DestroyWindow(g_swapwnd); } void TestPreReset() {  if (g_pSwapDepthSurf)   g_pSwapDepthSurf->Release();  g_pSwapDepthSurf = 0;  if (g_pSwapRenderSurf)   g_pSwapRenderSurf->Release();  g_pSwapRenderSurf = 0;  if (g_pSwap)   g_pSwap->Release();  g_pSwap = 0;  if (g_pDevRenderSurf)   g_pDevRenderSurf->Release();  g_pDevRenderSurf = 0;  if (g_pDevDepthSurf)   g_pDevDepthSurf->Release();  g_pDevDepthSurf = 0; } bool TestPostReset() {  memset(&g_scparam, 0, sizeof(g_scparam));  g_scparam.BackBufferCount = 1;  g_scparam.BackBufferFormat = D3DFMT_X8R8G8B8;  g_scparam.BackBufferHeight = 400;  g_scparam.BackBufferWidth = 400;  g_scparam.hDeviceWindow = g_swapwnd;  g_scparam.SwapEffect = D3DSWAPEFFECT_DISCARD;  g_scparam.Windowed = true;  g_scparam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;  g_pDev->CreateAdditionalSwapChain(&g_scparam, &g_pSwap);  g_pSwap->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &g_pSwapRenderSurf);  g_pDev->CreateDepthStencilSurface(400,400,D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, false, &g_pSwapDepthSurf,  0);  g_pDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pDevRenderSurf);  g_pDev->GetDepthStencilSurface(&g_pDevDepthSurf);  return true; } class TestVert { public:  float x,y,z;  DWORD color; }; TestVert g_aoVerts[4]; D3DXMATRIX w,v,p; void TestUpdate() {  g_aoVerts[0].x = -1;   g_aoVerts[0].y = -1;   g_aoVerts[0].z =  0;  g_aoVerts[0].color = 0xFFFF0000;  g_aoVerts[1].x = -1;   g_aoVerts[1].y =  1;   g_aoVerts[1].z =  0;  g_aoVerts[1].color = 0xFFFFFF00;  g_aoVerts[2].x =  1;   g_aoVerts[2].y = -1;   g_aoVerts[2].z =  0;  g_aoVerts[2].color = 0xFFFF00FF;  g_aoVerts[3].x =  1;   g_aoVerts[3].y =  1;   g_aoVerts[3].z =  0;  g_aoVerts[3].color = 0xFFFFFFFF;  POINT pt;  GetCursorPos(&pt);  D3DXMatrixRotationYawPitchRoll(&w, (pt.x - 800.0f) / 800 * D3DX_PI / 2, (pt.y - 600.0f) / 600 * D3DX_PI /  2, 0);  w._43 = 2;  D3DXMatrixPerspectiveFovLH(&p, D3DX_PI/4, 1.0, 0.1f, 500.0f);  g_pDev->SetTransform(D3DTS_WORLD, &w);  g_pDev->SetTransform(D3DTS_PROJECTION, &p);  D3DXMatrixIdentity(&w);  g_pDev->SetTransform(D3DTS_VIEW, &w); } void TestRender() {  g_pDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);  g_pDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);  g_pDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);  g_pDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);  g_pDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);  g_pDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);  g_pDev->SetRenderState(D3DRS_LIGHTING, false);  g_pDev->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE);  g_pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);  g_pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_aoVerts, sizeof(TestVert)); } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdLine, int cmdShow) {  g_3DhInst = hInst;  do  {   if (!RegisterWin())    break;   if (!CreateWin())    break;   if (!CreateD3D())    break;   if (!CreateDevice())    break;   if (!TestSetup())    break;   while (MsgPump())   {    if (TestDevice())    {     D3DVIEWPORT9 vp;     vp.X = 0;     vp.Y = 0;     vp.Width = 800;     vp.Height = 600;     vp.MinZ = 0;     vp.MaxZ = 1;     TestUpdate();     g_pDev->SetRenderTarget(0, g_pDevRenderSurf);     g_pDev->SetDepthStencilSurface(g_pDevDepthSurf);     g_pDev->SetViewport(&vp);     g_pDev->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x456789, 1.0f, 0);     g_pDev->BeginScene();     TestRender();     g_pDev->EndScene();     g_pDev-> resent(0,0,0,0);     g_pDev->SetRenderTarget(0, g_pSwapRenderSurf);     g_pDev->SetDepthStencilSurface(g_pSwapDepthSurf);     vp.Width = 400;     vp.Height = 400;     g_pDev->SetViewport(&vp);     g_pDev->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x654321, 1.0f, 0);     g_pDev->BeginScene();     TestRender();     g_pDev->EndScene();     g_pSwap-> resent(0, 0, 0, 0, 0);    }   };  } while (0);  TestCleanup();  Cleanup();  return 0; }  |