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 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值