C# NV_立体声_图像_签名和DirectX 10/11(nVidia 3D Vision) 我尝试使用SLIMDX和DIXTX10或11来控制英伟达3D视觉工具包的立体化过程。多亏了这一点,我才能够在DirectX 9中工作。然而,由于缺少一些方法,我无法使它在DirectX 10或11下工作
算法如下所示:C# NV_立体声_图像_签名和DirectX 10/11(nVidia 3D Vision) 我尝试使用SLIMDX和DIXTX10或11来控制英伟达3D视觉工具包的立体化过程。多亏了这一点,我才能够在DirectX 9中工作。然而,由于缺少一些方法,我无法使它在DirectX 10或11下工作,c#,directx,nvidia,slimdx,stereoscopy,C#,Directx,Nvidia,Slimdx,Stereoscopy,算法如下所示: 渲染左眼图像 渲染右眼图像 创建一个能够同时包含它们和一行的纹理(因此纹理大小为2*宽度,高度+1) 写下此NV\u立体声\u图像\u签名值 在屏幕上渲染此纹理 我的测试代码跳过了前两步,因为我已经有了立体纹理。这是一个前一个JPS文件,特别是其中包含英伟达3D工具包的样本图片中的一个。步骤5使用全屏四元体和着色器通过正交投影矩阵渲染立体化纹理。我看到的DX9示例代码不需要这个,只需调用StretchRect(…)方法将纹理复制回backbuffer。所以,也许正是因为这个原因,
静态纹理2D Make3D(纹理2D立体纹理)
{
//立体纹理包含一个立体图像,左眼图像位于左半部
//右眼图像在右半部分
//此分段纹理将有一个额外的行来包含立体签名
Texture2DDescription stagingDesc=新的Texture2DDescription()
{
ArraySize=1,
宽度=3840,
高度=1081,
BindFlags=BindFlags.None,
CpuAccessFlags=CpuAccessFlags.Write,
Format=SlimDX.DXGI.Format.R8G8B8A8_UNorm,
OptionFlags=ResourceOptionFlags.None,
用法=ResourceUsage.Staging,
MIP级别=1,
SampleDescription=新的SampleDescription(1,0)
};
Texture2D staging=新的Texture2D(设备,stagingDesc);
//标识要复制的源纹理区域(全部)
ResourceRegion立体rcbox=new ResourceRegion{Front=0,Back=1,Top=0,Bottom=1080,Left=0,Right=3840};
//将其复制到暂存纹理
CopySubresourceRegion(立体文本,0,立体框,暂存,0,0,0,0);
//打开暂存纹理进行读取
DataRectangle box=staging.Map(0,MapMode.Write,SlimDX.Direct3D10.MapFlags.None);
//到最后一排
box.Data.Seek(steroidexture.Description.Width*steroidexture.Description.Height*4,System.IO.SeekOrigin.Begin);
//写入NV立体声标题
box.Data.Write(数据,0,数据长度);
staging.Unmap(0);
//创建最终的立体化纹理
Texture2DDescription finalDesc=新的Texture2DDescription()
{
ArraySize=1,
宽度=3840,
高度=1081,
BindFlags=BindFlags.ShaderResource,
CpuAccessFlags=CpuAccessFlags.Write,
Format=SlimDX.DXGI.Format.R8G8B8A8_UNorm,
OptionFlags=ResourceOptionFlags.None,
用法=ResourceUsage.Dynamic,
MIP级别=1,
SampleDescription=新的SampleDescription(1,0)
};
//将暂存纹理复制到要用作着色器资源的新纹理上
Texture2D final=新的Texture2D(设备,finalDesc);
设备.复制资源(暂存,最终);
staging.Dispose();
返回最终结果;
}
NV_立体声_图像_签名数据
// 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
主要
专用静态设备;
[状态线程]
静态void Main()
{
//设备创建
var form=newrenderform(“立体测试”){ClientSize=new Size(19201080)};
var desc=新SwapChainDescription()
{
BufferCount=1,
ModeDescription=新的ModeDescription(19201080,新的Rational(120,1),格式为.R8G8B8A8_UNorm),
IsWindowed=true,
outputhHandle=form.Handle,
SampleDescription=新的SampleDescription(1,0),
SwapEffect=SwapEffect.丢弃,
用法=用法.RenderTargetOutput
};
SwapChain SwapChain;
CreateWithSwapChain(null,DriverType.Hardware,DeviceCreationFlags.Debug,desc,out Device,out swapChain);
//停止Alt+enter导致全屏显示。
Factory Factory=swapChain.GetParent();
SetWindowAssociation(form.Handle,WindowAssociationFlags.IgnoreAll);
Texture2D backBuffer=Resource.FromSwapChain(swapChain,0);
RenderTargetView renderView=新的RenderTargetView(设备,backBuffer);
ImageLoadInformation=新ImageLoadInformation()
{
BindFlags=BindFlags.None,
CpuAccessFlags=CpuAccessFlags.Read,
FilterFlags=FilterFlags.None,
Format=SlimDX.DXGI.Format.R8G8B8A8_UNorm,
MipFilterFlags=FilterFlags.None,
OptionFlags=ResourceOptionFlags.None,
用法=ResourceUsage.Staging,
MIP级别=1
};
//使纹理为3D
Texture2D sourceTexture=Texture2D.FromFile(设备“medusa.jpg”,信息);
Texture2D stereoizedTexture=Make3D(sourceTexture);
ShaderResourceView srv=新的ShaderResourceView(设备,立体化纹理);
//创建一个填充整个屏幕的四边形
ushort[]idx;
TexturedVertex[]quad=CreateTexturedQuad(Vector3.Zero、1920、1080,输出idx);
//填充顶点和索引缓冲区
数据流=新数据流(4*24,真,真);
stream.WriteRange(四元组);
流位置=0;
缓冲区顶点=new SlimDX.Direct3D10.Buffer(设备、流、新缓冲区描述()
{
BindFlags=Bi
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]