Recording DirectX and OpenGL Rendered Animations(翻译)

记录DirectX和OpenGL渲染的动画
简介
    当我们创建游戏和仿真模拟时,有时我们有必要记录渲染的内容。在某些情况下渲染过于复杂和耗时,这是不可避免的。
     在DirectX中,库函数D3DXSaveSurfaceToFile()保存表面为一张图片文件。对OpenGL,我们用glReadPixels()来读渲染的图像像素然后手动的保存它们为一张图片文件。然而这些表面只是针对单帧记录的,对记录一段连续帧没有简单的方法存在。换句话说,没有库函数来记录我们的完整存在渲染动画效果。
    在这方面,本文提出了几类,这有助于创造电影DirectX的方法和动画。用类CDxToMovie和 CGLToMovie电影可以选择性地或连续的从DirectX和OpenGL渲染帧来创建。一般来说,一个典型的电影创作过程涉及复杂的任务,例如读图的内容,选择帧速率设置,编解码器的设置,初始化媒体流,写媒体流等(详细讨论关于如何创建位图图像序列的电影,请参考这篇文章Create Movie from HBitmap)。类CDxToMovie和CGLToMovie这里介绍的抽象出所有不必要的复杂性和易于使用的界面,提供简单方法解释如下
从DirectX渲染序列记录一个电影
    类CDxToMovie可以记录DirectX渲染序列成电影文件。该类用到DirectX 9.0接口例如LPDIRECT3DSURFACE9,因此你应该用DirectX 9.0 SDK 或者其他的兼容的地方使用这个类 。
      开始从本文中的DirectX代码拷贝文件DxToMovie.h,RenderTarget.h,AviFile.h和AviFile.cpp到你的工程目录下然后添加他们到你的工程中,然后添加vfw.lib,一旦添加到你的工程中,你可以通过#include "DxToMovie.h"访问。CDxToMovie构造函数接受不同的参数如输出电影文件名,电影帧的宽度和高度的要求,每像素比特数等…如下所示,
CDxToMovie(LPCTSTR lpszOutputMovieFileName = _T("Output.avi"),
                
int nFrameWidth = GetSystemMetrics(SM_CXSCREEN),  /*Movie Frame Width*/
                
int nFrameHeight = GetSystemMetrics(SM_CYSCREEN), /*Movie Frame Height*/
                
int nBitsPerPixel = 32,     /*Bits per Pixel*/
                DWORD dwCodec 
= mmioFOURCC('M','P','G','4'),  /*Video Codec for Compression*/
                DWORD dwFrameRate 
= 1)      /*Frame Rate (FPS) setting for the Movie*/
然而,应该注意到的是,这是一个时间设置,后来在电影记录时候不能改变 。每个CDxToMovie对应一个不同的电影文件和再造一个CDxToMovie对象具有相同的输出文件的名字不会追加以前的电影内容,将覆盖它。
CDxToMovie g_MovieRecorder("Output.Avi", 320, 240);
    一旦创建CDxToMovie对象,方法CDxToMovie::OnCreateDevice()在你的程序Direct3D设备创建的时候会被调用。类似的,CDxToMovie::OnLostDevice(),CDxToMovie::OnResetDevice()和CDxToMovie::OnDestroyDevice()也会在设备丢失销毁的时候各自被调用。这些函数的原型显示如下
class CDxToMovie
{
HRESULT OnCreateDevice(LPDIRECT3DDEVICE9 pd3dDevice);
HRESULT OnDestroyDevice(LPDIRECT3DDEVICE9 pd3dDevice);
HRESULT OnLostDevice();
HRESULT OnResetDevice(LPDIRECT3DDEVICE9 pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc);
}
;
函数OnCreateDevice()和OnDestroyDevice()接受一个单单参数,指向你程序的Direct3D设备对象。OnLostDevice()没有参数,但是OnResetDevice()还要有一个指针指向你设备的后缓冲区表面 D3DSURFACE_DESC*。CDxToMovie对象提供一些信息在D3DSURFACE_DESC里 创造一个合适的offscreen渲染目标,可以用来记录你的应用程序的渲染。
真正记录的功能是通过函数CDxToMovie::StartRecordingMovie()和CDxToMovie::PauseRecordingMovie().这两个函数必须每一帧都要在IDirect3DDevice9::BeginScene()IDirect3DDevice9::EndScene()之间。如下所示
g_pd3dDevice->BeginScene();

    
// Capture the Rendering onto CDxToMovie's Render Target
    g_MovieRecorder.StartRecordingMovie(g_pd3dDevice);
        
// Render as usual..    
        g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,200),1,0);
        g_pd3dDevice
->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));
        g_pd3dDevice
->SetFVF(D3DFVF_CUSTOMVERTEX);
        g_pd3dDevice
->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
    g_MovieRecorder.PauseRecordingMovie(g_pd3dDevice);

    
// Copy the CDxToMovie's Render Target content back onto BackBuffer's Surface
    g_pd3dDevice->StretchRect(g_MovieRecorder.RecordingSurface(),
                              NULL,pBackSurface,
                              
0,D3DTEXF_NONE);

    g_pd3dDevice
->EndScene();
在上面的代码段中, g_MovieRecorder.StartRecordingMovie(g_pd3dDevice)将所有随后的渲染在CDxToMovie的内部渲染目标直到g_MovieRecorder.PauseRecordingMovie(g_pd3dDevice)被调用。所有的渲染工作在CDxToMovie的内部渲染目标上做,你的程序back surface将没有任何有效的内容显示在你的应用程序窗口。这不要紧,如果你的申请不只是创作这部电影没有任何动画直接呈现在屏幕上。然而,如果你记录电影从一个互动游戏会话上,它会变坏屏幕不更新到最新的渲染的内容(因为通过重新渲染目标,CDxToMovie内容被偷了)。为了避免它,你可以选择性地复制回CDxToMovie内部的渲染目标的内容到你的应用程序的back surface 使用方法IDirect3DDevice9:StretchRect(),其次是常见的g_pd3dDevice - > EndScene()和g_pd3dDevice - >Present()的要求会更新内容的呈现在屏幕上背缓冲区,使屏幕上更新。
如果你想避免一些帧被选择性记录在这部电影,只是不要叫g_MovieRecorder.StartRecordingMovie和g_MovieRecorder.PauseRecordingMovie()(相应的 g_pd3dDevice - > StretchRect())对那些帧,并会直接渲染动画在屏幕上(没有被重定向到CDxToMovie内部的渲染目标)。
演示代码提供这个项目提供了一个简单的应用程序,使得DirectX屏幕上的一个三角形的动作,鼠标移动窗户上,这将simulatenously被渲染成电影文件和记录(名叫output.avi)。跑演示的可执行程序,确保你有MPG4编解码器的计算机上安装,目录有写权限去创建输出电影文件。详情请设置解码器和平衡,请参考这篇文章Create Movie from HBitmap

Recording a Movie from OpenGL Rendered Sequence
先暂时不翻译了,以后再翻。

注:第一次翻译,水平比较差,还望各位看客见谅。
Reference: Recording DirectX and OpenGL Rendered Animations

posted on 2012-04-28 15:08 Daywei 阅读(1303) 评论(1)  编辑 收藏 引用 所属分类: DirectX


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

导航

统计

常用链接

留言簿

随笔分类

随笔档案

文章档案

牛人博客

搜索

积分与排名

最新评论

阅读排行榜