[转] DirectX开发的游戏如何使用DirectXTex实现截屏

开场白:最近有很多智能平台的游戏开发者在开发Windows 8和Windows Phone 8的游戏。相对于其他移动技术平台使用的OpenGL,微软的技术平台需要使用DirectX进行图形图像的渲染。很多游戏需要实现“截屏”功能,以帮助玩家保存游戏过程中的成就时刻。如何使用DirectX进行截屏,是游戏开发者问的最多的问题。微软公司总部的技术顾问,Phil Napieralski先生,解答了此问题,并提供了示例代码。这里转发Phil的博客如下:

注:原文地址:http://blog.pnapieralski.com/windows-8/taking-a-screenshot-of-your-directx-game-using-directxtex/

Ever wonder how to allow the user to get a screenshot of your game that’s using DirectX? Let me show you how.

Illustrating this with the Visual Studio Windows Store Direct3D Template

Requirements:

  • Windows 8
  • Visual Studio 2012 Express or higher

I’m going to show you how to do this using the Visual Studio Windows Store Direct3D Template, but you can easily use this on the desktop or anywhere else that is using modern DirectX.

First, let’s create the project. I named mine ScreenshotSample.

Create the Direct3D Windows Store template project

DirectXTex

Now, let’s get the DirectXTex ScreenGrab module and place this in our project.

  1. Navigate to DirectXTex on CodePlex and give it a download.
  2. Extract and copy/paste ScreenGrab.cpp and ScreenGrab.h into your ScreenshotSample project
  3. Every cpp file must have pch.h included at the top of the file. Open up ScreenGrab.cpp and add #include “pch.h” to abide

Plumbing and using the ScreenGrab module

Now, let’s add some code to our CubeRenderer that we can later call to take a screenshot.

Add the following public and private methods and the following private boolean to your CubeRenderer class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ref class CubeRenderer seatled : public Direct3DBase {
public:
   CubeRenderer();
   .
   .
   .
   void TakeScreenshot();
 
private:
   void SaveScreenshot();
    
   bool m_saveScreenshot;
 
   .
   .
   .
};

This way, your view code can simply call TakeScreenshot – then, when the render call is complete, the SaveScreenshot method will kick-in to actually dump the image.

First add the following headers:

1
2
3
4
5
6
7
8
#include "ScreenGrab.h"
#include <wincodec.h>
#include <ppl.h>
#include <ppltasks.h>
#include <collection.h>
 
using namespace Windows::Storage;
using namespace concurrency;

Now let’s define TakeScreenshot() in CubeRenderer.cpp:

1
2
3
4
void CubeRenderer::TakeScreenshot()
{
    m_saveScreenshot = true;
}

Simple – Save screenshot now does the meat of what we want to accomplish:

1
2
3
4
5
6
7
8
void CubeRenderer::SaveScreenshot() {
    auto file = ref new Platform::String(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data()) + "\\Screenshot.png";
 
    ComPtr<ID3D11Texture2D> backBuffer;
    DX::ThrowIfFailed( m_swapChain->GetBuffer(0, __uuidof( ID3D11Texture2D ), (LPVOID*)&backBuffer) );
 
    auto hResult = SaveWICTextureToFile(m_d3dContext.Get(), backBuffer.Get(), GUID_ContainerFormatPng, file->Data());
}

Note that Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data() can be found at %localappdata%/Packages/(your apps folder)/TempState on your hard drive. You can always set a breakpoint at this spot to see the filepath as well.

Now, we’ll run the SaveScreenshot method at the end of our Render loop (so that there is actually an image in the BackBuffer).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void CubeRenderer::Render()
{
        .
        .
        .
    m_d3dContext->DrawIndexed(
        m_indexCount,
        0,
        0
        );
        // Now that we are finished rendering everything (the cube), let's save the scene to an image
    if( m_saveScreenshot ) {
        SaveScreenshot();
        m_saveScreenshot = false;
    }
}

Taking a screenshot!

Finally, let’s make this badboy take a screenshot on a mouse-click. To do this, navigate to the ScreenshotSample::OnPointerPressed method and add the following code:

1
2
3
4
void ScreenshotSample::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
{
    m_renderer->TakeScreenshot();
}

Now run the app, click around and see the magic saved in your apps temporary folder.

Check out the source code on my github

posted @ 2013-05-01 20:12  Tory Xu  阅读(1074)  评论(0编辑  收藏  举报