我已经读过DirectX提供最佳速度.但在我开始学习DirectX之前,我想测试一个样本,看看它是否真的那么快.
我发现这个question提供了一个示例代码来做到这一点:
void dump_buffer() { IDirect3DSurface9* pRenderTarget=NULL; IDirect3DSurface9* pDestTarget=NULL; const char file[] = "Pickture.bmp"; // sanity checks. if (Device == NULL) return; // get the render target surface. HRESULT hr = Device->GetRenderTarget(0,&pRenderTarget); // get the current adapter display mode. //hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode); // create a destination surface. hr = Device->CreateOffscreenPlainSurface(DisplayMde.Width,DisplayMde.Height,DisplayMde.Format,D3DPOOL_SYSTEMMEM,&pDestTarget,NULL); //copy the render target to the destination surface. hr = Device->GetRenderTargetData(pRenderTarget,pDestTarget); //save its contents to a bitmap file. hr = D3DXSaveSurfaceToFile(file,D3DXIFF_BMP,pDestTarget,NULL,NULL); // clean up. pRenderTarget->Release(); pDestTarget->Release(); }
我试图包含所需的文件.然而,并非所有这些都可以包括在内(例如#include< D3dx9tex.h>).
任何人都可以提供一个包含所有必需包含的工作示例,或者指出我应该安装哪些库.
我在Windows 7旗舰版(x64)上使用Visual C 2010 Express.
编辑:
此外,此代码不完整,例如什么是设备标识符?!
解决方法
您不必安装任何SDK(Visual Studio附带的标准文件除外,尽管我没有测试过VS 2010).
只需创建一个简单的Win32控制台应用程序,在stdafx.h文件中添加以下内容:
#include <Wincodec.h> // we use WIC for saving images #include <d3d9.h> // DirectX 9 header #pragma comment(lib,"d3d9.lib") // link to DirectX 9 library
以下是示例主要实现
int _tmain(int argc,_TCHAR* argv[]) { HRESULT hr = Direct3D9TakeScreenshots(D3DADAPTER_DEFAULT,10); return 0; }
这将做的是捕获10倍的屏幕,并将“cap%i.png”图像保存在磁盘上.它还将显示此时间(保存图像不计算在该时间内,仅屏幕捕获).
在我的(台式机Windows 8 – 戴尔Precision M2800 / i7-4810MQ-2.80GHz /英特尔HD 4600这是一台非常糟糕的机器……)机器上,它需要在约4秒内完成100次1920×1080捕获,因此大约需要20/25 fps.
HRESULT Direct3D9TakeScreenshots(UINT adapter,UINT count) { HRESULT hr = S_OK; IDirect3D9 *d3d = nullptr; IDirect3DDevice9 *device = nullptr; IDirect3DSurface9 *surface = nullptr; D3DPRESENT_PARAMETERS parameters = { 0 }; D3DDISPLAYMODE mode; D3DLOCKED_RECT rc; UINT pitch; SYSTEMTIME st; LPBYTE *shots = nullptr; // init D3D and get screen size d3d = Direct3DCreate9(D3D_SDK_VERSION); HRCHECK(d3d->GetAdapterDisplayMode(adapter,&mode)); parameters.Windowed = TRUE; parameters.BackBufferCount = 1; parameters.BackBufferHeight = mode.Height; parameters.BackBufferWidth = mode.Width; parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; parameters.hDeviceWindow = NULL; // create device & capture surface HRCHECK(d3d->CreateDevice(adapter,D3DDEVTYPE_HAL,D3DCREATE_SOFTWARE_VERTEXPROCESSING,¶meters,&device)); HRCHECK(device->CreateOffscreenPlainSurface(mode.Width,mode.Height,D3DFMT_A8R8G8B8,&surface,nullptr)); // compute the required buffer size HRCHECK(surface->LockRect(&rc,0)); pitch = rc.Pitch; HRCHECK(surface->UnlockRect()); // allocate screenshots buffers shots = new LPBYTE[count]; for (UINT i = 0; i < count; i++) { shots[i] = new BYTE[pitch * mode.Height]; } GetSystemTime(&st); // measure the time we spend doing <count> captures wprintf(L"%i:%i:%i.%i\n",st.wHour,st.wMinute,st.wSecond,st.wMilliseconds); for (UINT i = 0; i < count; i++) { // get the data HRCHECK(device->GetFrontBufferData(0,surface)); // copy it into our buffers HRCHECK(surface->LockRect(&rc,0)); CopyMemory(shots[i],rc.pBits,rc.Pitch * mode.Height); HRCHECK(surface->UnlockRect()); } GetSystemTime(&st); wprintf(L"%i:%i:%i.%i\n",st.wMilliseconds); // save all screenshots for (UINT i = 0; i < count; i++) { WCHAR file[100]; wsprintf(file,L"cap%i.png",i); HRCHECK(SavePixelsToFile32bppPBGRA(mode.Width,pitch,shots[i],file,GUID_ContainerFormatPng)); } cleanup: if (shots != nullptr) { for (UINT i = 0; i < count; i++) { delete shots[i]; } delete[] shots; } RELEASE(surface); RELEASE(device); RELEASE(d3d); return hr; }
请注意,此代码隐含地链接到WIC(Windows中包含的成像库已有相当长的一段时间)以保存图像文件(因此您不需要需要安装旧版DirectX SDK的着名D3DXSaveSurfaceToFile):
HRESULT SavePixelsToFile32bppPBGRA(UINT width,UINT height,UINT stride,LPBYTE pixels,LPWSTR filePath,const GUID &format) { if (!filePath || !pixels) return E_INVALIDARG; HRESULT hr = S_OK; IWICImagingFactory *factory = nullptr; IWICBitmapEncoder *encoder = nullptr; IWICBitmapFrameEncode *frame = nullptr; IWICStream *stream = nullptr; GUID pf = GUID_WICPixelFormat32bppPBGRA; BOOL coInit = CoInitialize(nullptr); HRCHECK(CoCreateInstance(CLSID_WICImagingFactory,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&factory))); HRCHECK(factory->CreateStream(&stream)); HRCHECK(stream->InitializeFromFilename(filePath,GENERIC_WRITE)); HRCHECK(factory->CreateEncoder(format,&encoder)); HRCHECK(encoder->Initialize(stream,WICBitmapEncoderNoCache)); HRCHECK(encoder->CreateNewFrame(&frame,nullptr)); // we don't use options here HRCHECK(frame->Initialize(nullptr)); // we dont' use any options here HRCHECK(frame->SetSize(width,height)); HRCHECK(frame->SetPixelFormat(&pf)); HRCHECK(frame->WritePixels(height,stride,stride * height,pixels)); HRCHECK(frame->Commit()); HRCHECK(encoder->Commit()); cleanup: RELEASE(stream); RELEASE(frame); RELEASE(encoder); RELEASE(factory); if (coInit) CoUninitialize(); return hr; }
我使用的一些宏:
#define WIDEN2(x) L ## x #define WIDEN(x) WIDEN2(x) #define __WFILE__ WIDEN(__FILE__) #define HRCHECK(__expr) {hr=(__expr);if(FAILED(hr)){wprintf(L"FAILURE 0x%08X (%i)\n\tline: %u file: '%s'\n\texpr: '" WIDEN(#__expr) L"'\n",hr,__LINE__,__WFILE__);goto cleanup;}} #define RELEASE(__p) {if(__p!=nullptr){__p->Release();__p=nullptr;}}
注意:对于Windows 8客户端,应删除所有这些(WIC除外)以支持Desktop Duplication API.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。