DX 绘制位图

简单地学习了四个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 }
原文地址:https://www.cnblogs.com/lc-cnblong/p/3361467.html