简单地学习了四个API:
1 HRESULT CreateOffscreenPlainSurface( 2 [in] UINT Width, // 宽度 3 [in] UINT Height, // 高度 4 [in] D3DFORMAT Format, // 像素格式 5 [in] D3DPOOL Pool, // 内存池类型 6 [out, retval] IDirect3DSurface9 **ppSurface, // 返回的表面的指针 7 [in] HANDLE *pSharedHandle // 一般为NULL 8 );
1 HRESULT GetBackBuffer( 2 [in] UINT iSwapChain, // 交换链索引,0为默认的交换链 3 [in] UINT BackBuffer, // 后备缓冲索引,从0开始,指定要得到的后备缓冲 4 [in] D3DBACKBUFFER_TYPE Type, // DX只支持D3DBACKBUFFER_TYPE_MONO 5 [out, retval] IDirect3DSurface9 **ppBackBuffer// 返回的指针 6 );
1 HRESULT ColorFill( 2 [in] IDirect3DSurface9 *pSurface, // 要填充的表面 3 [in] const RECT *pRect, // 填充的矩形 4 [in] D3DCOLOR color // 填充的颜色 5 );
1 HRESULT StretchRect( 2 [in] IDirect3DSurface9 *pSourceSurface, // 源表面 3 [in] const RECT *pSourceRect, // 源表面的矩形 4 [in] IDirect3DSurface9 *pDestSurface, // 目的表面 5 [in] const RECT *pDestRect, // 目的表面的矩形 6 [in] D3DTEXTUREFILTERTYPE Filter // 过滤 7 );
1 #include <windows.h> 2 #include <d3dx9.h> 3 4 #define SCREEN_W 800 5 #define SCREEN_H 600 6 #define APPNAME "myGame" 7 #define CLASSNAME "wndClass" 8 9 10 IDirect3D9 *pD3D = NULL; 11 IDirect3DDevice9 *pD3DDev = NULL; 12 IDirect3DSurface9* pSur = NULL; 13 IDirect3DSurface9* pBackSur = NULL; 14 15 #define SAFE_RELEASE(p) 16 if (p) { 17 p->Release(); 18 p = NULL; 19 } 20 21 LRESULT WINAPI WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) 22 { 23 PAINTSTRUCT ps; 24 switch (msg) 25 { 26 // case WM_PAINT: 27 // { 28 // BeginPaint(hWnd,&ps); 29 // EndPaint(hWnd,&ps); 30 // return 0; 31 // } 32 case WM_DESTROY: 33 { 34 PostQuitMessage(0); 35 return 0; 36 } 37 } 38 39 return DefWindowProc(hWnd,msg,wParam,lParam); 40 } 41 void initWndClass(HINSTANCE hInstance,WNDCLASSEX &wndClass) 42 { 43 wndClass.cbSize = sizeof(WNDCLASSEX); 44 wndClass.style = CS_HREDRAW | CS_VREDRAW; 45 wndClass.lpfnWndProc = WndProc; 46 wndClass.cbClsExtra = 0; 47 wndClass.cbWndExtra = 0; 48 wndClass.hInstance = hInstance; 49 wndClass.hIcon = LoadIcon(NULL,IDI_APPLICATION); 50 wndClass.hCursor = LoadCursor(NULL,IDC_ARROW); 51 wndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); 52 wndClass.lpszClassName = TEXT(CLASSNAME); 53 wndClass.lpszMenuName = NULL; 54 wndClass.hIconSm = LoadIcon(NULL,IDI_WINLOGO); 55 } 56 57 bool initD3D(HWND hWnd) 58 { 59 60 // 主要目的是获取设备,为调用下面的函数做很多准备。 61 // 比如 获取IDirect3D9 ,获取支持的顶点处理,填充后备缓冲相关参数等。 62 63 // IDirect3D9::CreateDevice( 64 //UINT Adapter, 65 //D3DDEVTYPE DeviceType, 66 //HWND hFocusWindow, 67 //DWORD BehaviorFlags, 68 //D3DPRESENT_PARAMETERS *pPresentationParameters, 69 //IDirect3DDevice9 ** ppReturnDeviceInterface 70 //); 71 72 // 第一步 获取 IDirect3D9 接口 73 // Direct3DCreate9(D3D_SDK_VERSION); 74 pD3D = Direct3DCreate9(D3D_SDK_VERSION); 75 if (NULL == pD3D) 76 { 77 MessageBox(NULL,TEXT("NULL == pD3D"),NULL,MB_OK); 78 return false; 79 } 80 // 第二步 确定显卡是否支持顶点转换和光照 81 // 通过获取设备性能,里面包含顶点处理,纹理,shader等信息。 82 // pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps) 83 // caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT 84 D3DCAPS9 caps; 85 pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps); 86 87 int vp = 0; 88 if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) 89 { 90 vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 91 } 92 else 93 { 94 vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; 95 } 96 97 98 // 第三步 填充显示参数,主要是和后备缓冲相关的设置。 99 D3DPRESENT_PARAMETERS d3dpp; 100 d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; 101 d3dpp.BackBufferCount = 1; 102 d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; 103 d3dpp.BackBufferHeight = SCREEN_H; 104 d3dpp.BackBufferWidth = SCREEN_W; 105 d3dpp.EnableAutoDepthStencil = true; 106 //d3dpp.FullScreen_RefreshRateInHz = 0; // 屏幕刷新频率,默认值即可 107 d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; // 屏幕刷新频率,默认值即可 108 d3dpp.Windowed = true; 109 d3dpp.hDeviceWindow = hWnd; // 窗口句柄。 110 d3dpp.MultiSampleQuality = 0; 111 d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; 112 //d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 113 d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; 114 // D3DPRESENT_INTERVAL_IMMEDIATE 图形绘制完后立即显示,实时的,可以提高帧率,但过快会产生图形撕裂。 115 // D3DPRESENT_INTERVAL_DEFAULT 则需等待屏幕刷新完后绘制 116 d3dpp.Flags = 0; // 附加特性一般为0. 117 118 // d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 这个一定要赋值(即使初始化为0),枚举值从1开始 119 d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; // 这个一定要赋值(即使初始化为0),枚举值从1开始 120 //d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP; // 这个一定要赋值(即使初始化为0),枚举值从1开始 121 // 使用FLIP 屏幕有很强的抖动,难道是交换链的切换和显示不同步所致??。 122 // 123 124 125 // 第四步 创建设备。 126 127 // IDirect3D9::CreateDevice( 128 //UINT Adapter, 129 //D3DDEVTYPE DeviceType, 130 //HWND hFocusWindow, 131 //DWORD BehaviorFlags, 132 //D3DPRESENT_PARAMETERS *pPresentationParameters, 133 //IDirect3DDevice9 ** ppReturnDeviceInterface 134 //); 135 136 pD3D->CreateDevice( 137 D3DADAPTER_DEFAULT, 138 D3DDEVTYPE_HAL, 139 hWnd, 140 vp, 141 &d3dpp, 142 &pD3DDev 143 ); 144 145 if (NULL == pD3DDev) 146 { 147 MessageBox(NULL,TEXT("NULL == pD3DDev"),NULL,MB_OK); 148 return false; 149 } 150 151 return true; 152 } 153 154 void Release() 155 { 156 SAFE_RELEASE(pD3D); 157 SAFE_RELEASE(pD3DDev); 158 SAFE_RELEASE(pSur); 159 SAFE_RELEASE(pBackSur); 160 } 161 162 void initSurface() 163 { 164 if (pD3DDev) 165 { 166 pD3DDev->CreateOffscreenPlainSurface( 167 100,100,D3DFMT_A8R8G8B8, 168 D3DPOOL_DEFAULT, 169 &pSur, 170 NULL); 171 pD3DDev->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackSur); 172 // GetBackBuffer()得到的是后备缓冲表面的指针。 173 pD3DDev->Clear(0,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_ARGB(0,0,0,0),1.0,0 ); 174 } 175 } 176 void Render() 177 { 178 if (pD3DDev) 179 { 180 //pD3DDev->Clear(0,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_ARGB(0,0,0,0),1.0,0 ); 181 182 pD3DDev->ColorFill(pSur,NULL,D3DCOLOR_ARGB(0,rand() % 255,rand() % 255,rand() % 255)); 183 184 // 目的表面随机一个矩形 185 RECT rect; 186 rect.left = rand() % SCREEN_W; 187 rect.top = rand() % SCREEN_H; 188 rect.right = rect.left + rand() % (SCREEN_W - rect.left); 189 rect.bottom = rect.top + rand() % (SCREEN_H - rect.top); 190 191 pD3DDev->BeginScene(); 192 193 if (pSur && pBackSur) 194 { 195 pD3DDev->StretchRect(pSur,NULL,pBackSur,&rect,D3DTEXF_NONE); 196 // StretchRect() 197 // 它要求源和目的表面的内存池类型为D3DPOOL_DEFAULT。 198 // 并且不能再同一表面操作:。 199 } 200 201 pD3DDev->EndScene(); 202 pD3DDev->Present(0,0,0,0); 203 } 204 } 205 206 int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) 207 { 208 HWND hWnd; 209 210 WNDCLASSEX wndClass; 211 initWndClass(hInstance,wndClass); 212 213 RegisterClassEx(&wndClass); 214 215 hWnd = CreateWindow( 216 TEXT(CLASSNAME), 217 TEXT(APPNAME), 218 WS_OVERLAPPEDWINDOW, 219 CW_USEDEFAULT, 220 CW_USEDEFAULT, 221 SCREEN_W, 222 SCREEN_H, 223 NULL, 224 NULL, 225 hInstance, 226 NULL 227 ); 228 229 if (NULL == hWnd) 230 { 231 MessageBox(NULL,TEXT("NULL == hWnd"),NULL,MB_OK); 232 return 0; 233 } 234 235 if (!initD3D(hWnd)) 236 { 237 MessageBox(NULL,TEXT("initD3D"),NULL,MB_OK); 238 Release(); 239 return 0; 240 } 241 242 initSurface(); 243 244 UpdateWindow(hWnd); 245 ShowWindow(hWnd,nShowCmd); 246 MSG msg; 247 while (true) 248 { 249 if ( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ) 250 { 251 if (WM_QUIT == msg.message) 252 { 253 break; 254 } 255 TranslateMessage(&msg); 256 DispatchMessage(&msg); 257 } 258 else 259 { 260 Render(); 261 } 262 } 263 Release(); 264 return msg.lParam; 265 }