2011-09-11 11 views
3

nVidia 3D Vision Kitの立体化プロセスを制御するためにSlimDXとDirectX10または11を使用しようとしています。このquestionのおかげで、DirectX 9で動作させることができました。しかし、いくつかの方法がないため、DirectX 10または11で動作させることができませんでした。NV_STEREO_IMAGE_SIGNATUREとDirectX 10/11(nVidia 3D Vision)

アルゴリズムは次のようになります。

  1. 書き込み
  2. (SOテクスチャサイズは、2 *幅、高さ+ 1であろう)は、左眼用画像
  3. はそれらの両方を含むことができるテクスチャーPLUS余分な行を作成し、右眼用画像
  4. レンダリングレンダリングこのNV_STEREO_IMAGE_SIGNATURE値
  5. は、私はすでにステレオ質感を持っているように私のテストコードは、最初の2つのステップをスキップし

画面にこのテクスチャをレンダリングします。これは以前の.JPSファイルで、特にnvidia 3Dキットに付属しているサンプル画像に含まれるファイルの1つです。ステップ番号5は、フルスクリーンクワッドとシェーダを使用して、オルト投影マトリクスを介して立体化テクスチャをレンダリングします。私がDX9で見たサンプルコードではこれは必要なく、単純にStretchRect(...)メソッドを呼び出してテクスチャをバックバッファにコピーします。だから多分この理由のために働いていないのでしょうか? DX10でこれを実現する同様の方法はありますか?バックバッファへのレンダリングは原理的にテクスチャをコピー(またはストレッチレーティング)するのと理論的には同じだと思っていましたが、おそらくそうではありませんか?ここで

は私のコード(slimdx)を、次のとおりです。 Stereoization手順

static Texture2D Make3D(Texture2D stereoTexture) 
{ 
// stereoTexture contains a stereo image with the left eye image on the left half 
// and the right eye image on the right half 
// this staging texture will have an extra row to contain the stereo signature 
Texture2DDescription stagingDesc = new Texture2DDescription() 
{ 
    ArraySize = 1, 
    Width = 3840, 
    Height = 1081, 
    BindFlags = BindFlags.None, 
    CpuAccessFlags = CpuAccessFlags.Write, 
    Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, 
    OptionFlags = ResourceOptionFlags.None, 
    Usage = ResourceUsage.Staging, 
    MipLevels = 1, 
    SampleDescription = new SampleDescription(1, 0) 
}; 
Texture2D staging = new Texture2D(device, stagingDesc); 

// Identify the source texture region to copy (all of it) 
ResourceRegion stereoSrcBox = new ResourceRegion { Front = 0, Back = 1, Top = 0, Bottom = 1080, Left = 0, Right = 3840 }; 
// Copy it to the staging texture 
device.CopySubresourceRegion(stereoTexture, 0, stereoSrcBox, staging, 0, 0, 0, 0); 

// Open the staging texture for reading 
DataRectangle box = staging.Map(0, MapMode.Write, SlimDX.Direct3D10.MapFlags.None); 
// Go to the last row 
box.Data.Seek(stereoTexture.Description.Width * stereoTexture.Description.Height * 4, System.IO.SeekOrigin.Begin); 
// Write the NVSTEREO header 
box.Data.Write(data, 0, data.Length); 
staging.Unmap(0); 

// Create the final stereoized texture 
Texture2DDescription finalDesc = new Texture2DDescription() 
{ 
    ArraySize = 1, 
    Width = 3840, 
    Height = 1081, 
    BindFlags = BindFlags.ShaderResource, 
    CpuAccessFlags = CpuAccessFlags.Write, 
    Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, 
    OptionFlags = ResourceOptionFlags.None, 
    Usage = ResourceUsage.Dynamic, 
    MipLevels = 1, 
    SampleDescription = new SampleDescription(1, 0) 
}; 

// Copy the staging texture on a new texture to be used as a shader resource 
Texture2D final = new Texture2D(device, finalDesc); 
device.CopyResource(staging, final); 
staging.Dispose(); 
return final; 
} 

NV_STEREO_IMAGE_SIGNATUREデータ

// The NVSTEREO header. 
    static byte[] data = new byte[] {0x4e, 0x56, 0x33, 0x44, //NVSTEREO_IMAGE_SIGNATURE   = 0x4433564e; 
     0x00, 0x0F, 0x00, 0x00, //Screen width * 2 = 1920*2 = 3840 = 0x00000F00; 
     0x38, 0x04, 0x00, 0x00, //Screen height = 1080    = 0x00000438; 
     0x20, 0x00, 0x00, 0x00, //dwBPP = 32      = 0x00000020; 
     0x02, 0x00, 0x00, 0x00}; //dwFlags = SIH_SCALE_TO_FIT  = 0x00000002 

メイン

private static Device device; 

[STAThread] 
static void Main() 
{ 
// Device creation 
var form = new RenderForm("Stereo test") {ClientSize = new Size(1920, 1080)}; 
var desc = new SwapChainDescription() 
       { 
        BufferCount = 1, 
        ModeDescription = new ModeDescription(1920, 1080, new Rational(120, 1), Format.R8G8B8A8_UNorm), 
        IsWindowed = true, 
        OutputHandle = form.Handle, 
        SampleDescription = new SampleDescription(1, 0), 
        SwapEffect = SwapEffect.Discard, 
        Usage = Usage.RenderTargetOutput 
       }; 

SwapChain swapChain; 
Device.CreateWithSwapChain(null, DriverType.Hardware, DeviceCreationFlags.Debug, desc, out device, out swapChain); 
//Stops Alt+enter from causing fullscreen skrewiness. 
Factory factory = swapChain.GetParent<Factory>(); 
factory.SetWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll); 

Texture2D backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0); 
RenderTargetView renderView = new RenderTargetView(device, backBuffer); 

ImageLoadInformation info = new ImageLoadInformation() 
           { 
            BindFlags = BindFlags.None, 
            CpuAccessFlags = CpuAccessFlags.Read, 
            FilterFlags = FilterFlags.None, 
            Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, 
            MipFilterFlags = FilterFlags.None, 
            OptionFlags = ResourceOptionFlags.None, 
            Usage = ResourceUsage.Staging, 
            MipLevels = 1 
           }; 

// Make texture 3D 
Texture2D sourceTexture = Texture2D.FromFile(device, "medusa.jpg", info); 
Texture2D stereoizedTexture = Make3D(sourceTexture); 
ShaderResourceView srv = new ShaderResourceView(device, stereoizedTexture); 

// Create a quad that fills the whole screen 
ushort[] idx; 
TexturedVertex[] quad = CreateTexturedQuad(Vector3.Zero, 1920, 1080, out idx); 

// fill vertex and index buffers 
DataStream stream = new DataStream(4*24, true, true); 
stream.WriteRange(quad); 
stream.Position = 0; 

Buffer vertices = new SlimDX.Direct3D10.Buffer(device, stream, new BufferDescription() 
                    { 
                     BindFlags = BindFlags.VertexBuffer, 
                     CpuAccessFlags = CpuAccessFlags.None, 
                     OptionFlags = ResourceOptionFlags.None, 
                     SizeInBytes = 4*24, 
                     Usage = ResourceUsage.Default 
                    }); 
stream.Close(); 

stream = new DataStream(6*sizeof (ushort), true, true); 
stream.WriteRange(idx); 
stream.Position = 0; 
Buffer indices = new SlimDX.Direct3D10.Buffer(device, stream, new BufferDescription() 
                    { 
                     BindFlags = BindFlags.IndexBuffer, 
                     CpuAccessFlags = CpuAccessFlags.None, 
                     OptionFlags = ResourceOptionFlags.None, 
                     SizeInBytes = 6*sizeof (ushort), 
                     Usage = ResourceUsage.Default 
                    }); 

// Create world view (ortho) projection matrices 
QuaternionCam qCam = new QuaternionCam(); 

// Load effect from file. It is a basic effect that renders a full screen quad through 
// an ortho projectio=n matrix 
Effect effect = Effect.FromFile(device, "Texture.fx", "fx_4_0", ShaderFlags.Debug, EffectFlags.None); 
EffectTechnique technique = effect.GetTechniqueByIndex(0); 
EffectPass pass = technique.GetPassByIndex(0); 
InputLayout layout = new InputLayout(device, pass.Description.Signature, new[] 
                      { 
                       new InputElement("POSITION", 0, 
                            Format. 
                             R32G32B32A32_Float, 
                            0, 0), 
                       new InputElement("TEXCOORD", 0, 
                            Format. 
                             R32G32_Float, 
                            16, 0) 
                      }); 
effect.GetVariableByName("mWorld").AsMatrix().SetMatrix(
    Matrix.Translation(Layout.OrthographicTransform(Vector2.Zero, 90, new Size(1920, 1080)))); 
effect.GetVariableByName("mView").AsMatrix().SetMatrix(qCam.View); 
effect.GetVariableByName("mProjection").AsMatrix().SetMatrix(qCam.OrthoProjection); 
effect.GetVariableByName("tDiffuse").AsResource().SetResource(srv); 

// Set RT and Viewports 
device.OutputMerger.SetTargets(renderView); 
device.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f)); 

// Create solid rasterizer state 
RasterizerStateDescription rDesc = new RasterizerStateDescription() 
             { 
              CullMode = CullMode.None, 
              IsDepthClipEnabled = true, 
              FillMode = FillMode.Solid, 
              IsAntialiasedLineEnabled = true, 
              IsFrontCounterclockwise = true, 
              IsMultisampleEnabled = true 
             }; 
RasterizerState rState = RasterizerState.FromDescription(device, rDesc); 
device.Rasterizer.State = rState; 

// Main Loop 
MessagePump.Run(form,() => 
    { 
     device.ClearRenderTargetView(renderView, Color.Cyan); 

     device.InputAssembler.SetInputLayout(layout); 
     device.InputAssembler.SetPrimitiveTopology(PrimitiveTopology.TriangleList); 
     device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, 24, 0)); 
     device.InputAssembler.SetIndexBuffer(indices, Format.R16_UInt, 0); 

     for (int i = 0; i < technique.Description.PassCount; ++i) 
     { 
      // Render the full screen quad 
      pass.Apply(); 
      device.DrawIndexed(6, 0, 0); 
     } 

     swapChain.Present(0, PresentFlags.None); 
    }); 

// Dispose resources 
vertices.Dispose(); 
layout.Dispose(); 
effect.Dispose(); 
renderView.Dispose(); 
backBuffer.Dispose(); 
device.Dispose(); 
swapChain.Dispose(); 

rState.Dispose(); 
stereoizedTexture.Dispose(); 
sourceTexture.Dispose(); 
indices.Dispose(); 
srv.Dispose(); 
}[/code] 

事前に感謝を!

+0

私は似たようなことをしようとしています。私はあなたの最初の投稿からどのように動作するのか良いアイデアを得たが、私はそれが正しいとは思わない。 最後のビットを共有してください。ありがとう –

答えて

4

私は最終的にそれを修正することができました。キーは、寸法を指定して(例えば、3840×1081の代わりに1920×1080)、立体化されたテクスチャのCopySubResourceRegionメソッドをバックバッファに戻すことにありました。

+1

後継のために、この方法を使用している自立型のSlimDXプログラムには[link](https://gist.github.com/AvengerDr/6062614)です。 – TheWanderer

関連する問題