RenderTargetクラスを作る
テクスチャに対してレンダリングするためには、
- Usage.RenderTarget、Pool.Defaultを指定して作ったテクスチャ
- 3D描画を行う場合の深度バッファ
- 実際の描画先となるテクスチャのサーフェイス
の3つが必要になります。
さらに、デバイスのResizingイベント時の再生成やDispose()、デバイスへの設定など、そのまま使うと結構面倒です。
ということでRenderTargetクラスを作ってみます。
RenderTargetクラス
using System; using System.ComponentModel; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace WindowsFormsApplication1 { public class RenderTarget : IDisposable { private Texture texture_; private Surface depth_; private Surface surface_; private Viewport viewport_; private Format format_; public RenderTarget( Device device ) { texture_ = null; surface_ = device.GetRenderTarget(0); depth_ = device.DepthStencilSurface; viewport_ = device.Viewport; format_ = device.PresentationParameters.BackBufferFormat; } public RenderTarget( Device device, int width, int height, Format format ) { texture_ = new Texture(device, width, height, 1, Usage.RenderTarget, format, Pool.Default); depth_ = device.CreateDepthStencilSurface( width, height, device.PresentationParameters.AutoDepthStencilFormat, MultiSampleType.None, 0, true); surface_ = texture_.GetSurfaceLevel(0); viewport_.X = 0; viewport_.Y = 0; viewport_.Width = width; viewport_.Height = height; viewport_.MinZ = 0.0f; viewport_.MaxZ = 1.0f; format_ = format; } public void Dispose() { if (depth_ != null) { depth_.Dispose(); depth_ = null; } if (surface_ != null) { surface_.Dispose(); surface_ = null; } if (texture_ != null) { texture_.Dispose(); texture_ = null; } } public void DeviceResizing( object sender, CancelEventArgs e ) { Device device = ( Device )sender; Dispose(); texture_ = new Texture(device, viewport_.Width, viewport_.Height, 1, Usage.RenderTarget, format_, Pool.Default); depth_ = device.CreateDepthStencilSurface( viewport_.Width, viewport_.Height, device.PresentationParameters.AutoDepthStencilFormat, MultiSampleType.None, 0, true); surface_ = texture_.GetSurfaceLevel(0); } public Texture texture { get{ return texture_; } } public Surface surface { get{ return surface_; } } public Surface depth { get{ return depth_; } } public Viewport viewport { get{ return viewport_; } } public float aspect { get{ return ( float )viewport_.Width / viewport_.Height; } } public void Set( Device device ) { device.SetRenderTarget(0, surface); device.DepthStencilSurface = depth; device.Viewport = viewport; } } }
使い方
private RenderTarget shadow_map;
shadow_map = new RenderTarget( device, 512, 512, Format.A8R8G8B8 ); device.DeviceResizing += new CancelEventHandler( shadow_map.DeviceResizing );
if (shadow_map != null) { shadow_map.Dispose(); shadow_map = null; }
//バックバッファへのレンダーターゲットを生成 using( RenderTarget backbuffer = new RenderTarget( device ) ) { //レンダーターゲットの切り替え shadow_map.Set( device ); /*shadow_mapへの描画*/ //レンダーターゲットをバックバッファに戻す backbuffer.Set( device ); }