NV_STEREO_IMAGE_SIGNATURE和DirectX 10/11(nVidia 3D Vision) [英] NV_STEREO_IMAGE_SIGNATURE and DirectX 10/11 (nVidia 3D Vision)

查看:87
本文介绍了NV_STEREO_IMAGE_SIGNATURE和DirectX 10/11(nVidia 3D Vision)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用SlimDX和DirectX10或11来控制nVidia 3D Vision Kit上的立体化过程.感谢这个问题我已经能够使其在DirectX 9中工作.但是,由于缺少一些方法,我无法使其在DirectX 10或11下工作.

I'm trying to use SlimDX and DirectX10 or 11 to control the stereoization process on the nVidia 3D Vision Kit. Thanks to this question I've been able to make it work in DirectX 9. However, due to some missing methods I've been unable to make it work under DirectX 10 or 11.

算法如下:

  1. 渲染左眼图像
  2. 渲染右眼图像
  3. 创建一个能够同时包含它们和一个额外行的纹理(因此纹理大小将为2 *宽度,高度+ 1)
  4. 写入此NV_STEREO_IMAGE_SIGNATURE值
  5. 在屏幕上渲染此纹理

我的测试代码跳过了前两个步骤,因为我已经有了立体纹理.它是以前的.JPS文件,特别是nvidia 3D套件随附的示例图片中包含的文件之一.步骤5使用全屏四边形和着色器,通过正交投影矩阵在其上渲染立体纹理.我在DX9上看到的示例代码不需要它,只需调用StretchRect(...)方法即可将纹理复制回Backbuffer.所以也许是因为这个原因不起作用?在DX10中有类似的方法可以完成此操作吗?我以为从理论上讲,渲染到后缓冲上与在其上复制(或拉伸拉伸)纹理是相同的,但是也许不是吗?

My test code skips the first two steps, as I already have a stereo texture. It was a former .JPS file, specifically one of those included in the sample pictures coming with the nvidia 3D kit. Step number 5 uses a full screen quad and a shader to render the stereoized texture onto it through an ortho-projection matrix. The sample code I've seen for DX9 doesn't need this and simply calls the StretchRect(...) method to copy the texture back onto the backbuffer. So maybe it is for this reason that is not working? Is there a similar method to accomplish this in DX10? I thought that rendering onto the backbuffer would theoretically be the same than copying (or StretchRecting) a texture onto it, but maybe it is not?

以下是我的代码(slimdx): 立体化步骤

Here follows my code (slimdx): Stereoization procedure

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数据

NV_STEREO_IMAGE_SIGNATURE data

// 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]

提前谢谢!

推荐答案

我最终设法修复了它.关键是在立体纹理上使用CopySubResourceRegion方法返回到后缓冲,并指定其尺寸(例如:1920 x 1080而不是3840 x 1081).

I eventually managed to fix it. The key was in using the CopySubResourceRegion method on the stereoized texture back to the backbuffer, specifying its dimension (e.g.: 1920 x 1080 instead of 3840 x 1081).

这篇关于NV_STEREO_IMAGE_SIGNATURE和DirectX 10/11(nVidia 3D Vision)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆