如何用C#分别控制立体声帧? (NVIDIA 3D快门眼镜)

我正在尝试制作一个非常简单的应用程序,它会在每只眼睛上显示不同的图像。 我有华硕VG236H显示器和NVIDIA 3D Vision套件,立体3D快门眼镜。 我正在使用C#,.NET Framework 2.0,DirectX 9(Managed Direct X)和Visual Studio 2008.我一直在搜索高低版本的示例和教程,实际上找到了一对并基于我创建的程序但是由于某种原因,我不能让它工作。

在寻找如何为每只眼睛显示不同图像的示例时,许多人不断参考GDC 09(着名的GDC09-3DVision-The_In_and_Out.pdf文档)和第37-40页的NVIDIA演示文稿。 我的代码主要是基于这个例子构建的:

  1. 我在表面上加载了两个纹理(Red.png和Blue.png)(_imageLeft和_imageRight),在函数LoadSurfaces()中
  2. Set3D()函数将这两个图像并排放置到一个较大的图像中,该图像的大小为2x屏幕宽度和屏幕高度+ 1(_imageBuf)。
  3. 通过在最后一行附加立体声签名继续Set3D()函数。
  4. OnPaint() – 函数获取后台缓冲区(_backBuf)并将组合图像(_imageBuf)的内容复制到它。

当我运行程序时,快门眼镜开始工作,但我只能在屏幕上并排看到这两个图像。 有人可以帮忙告诉我我做错了什么吗? 我相信解决这个问题也可能有助于其他人,因为似乎还没有一个简单的例子如何用C#做到这一点。

以下是我的代码的战术部分。 完整的项目可以在这里下载: http : //koti.mbnet.fi/jjantti2/NVStereoTest.rar

public void InitializeDevice() { PresentParameters presentParams = new PresentParameters(); presentParams.Windowed = false; presentParams.BackBufferFormat = Format.A8R8G8B8; presentParams.BackBufferWidth = _size.Width; presentParams.BackBufferHeight = _size.Height; presentParams.BackBufferCount = 1; presentParams.SwapEffect = SwapEffect.Discard; presentParams.PresentationInterval = PresentInterval.One; _device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); } public void LoadSurfaces() { _imageBuf = _device.CreateOffscreenPlainSurface(_size.Width * 2, _size.Height + 1, Format.A8R8G8B8, Pool.Default); _imageLeft = Surface.FromBitmap(_device, (Bitmap)Bitmap.FromFile("Blue.png"), Pool.Default); _imageRight = Surface.FromBitmap(_device, (Bitmap)Bitmap.FromFile("Red.png"), Pool.Default); } private void Set3D() { Rectangle destRect = new Rectangle(0, 0, _size.Width, _size.Height); _device.StretchRectangle(_imageLeft, _size, _imageBuf, destRect, TextureFilter.None); destRect.X = _size.Width; _device.StretchRectangle(_imageRight, _size, _imageBuf, destRect, TextureFilter.None); GraphicsStream gStream = _imageBuf.LockRectangle(LockFlags.None); byte[] data = new byte[] {0x44, 0x33, 0x56, 0x4e, //NVSTEREO_IMAGE_SIGNATURE = 0x4433564e 0x00, 0x00, 0x0F, 0x00, //Screen width * 2 = 1920*2 = 3840 = 0x00000F00; 0x00, 0x00, 0x04, 0x38, //Screen height = 1080 = 0x00000438; 0x00, 0x00, 0x00, 0x20, //dwBPP = 32 = 0x00000020; 0x00, 0x00, 0x00, 0x02}; //dwFlags = SIH_SCALE_TO_FIT = 0x00000002; gStream.Seek(_size.Width * 2 * _size.Height * 4, System.IO.SeekOrigin.Begin); //last row gStream.Write(data, 0, data.Length); gStream.Close(); _imageBuf.UnlockRectangle(); } protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { _device.BeginScene(); // Get the Backbuffer then Stretch the Surface on it. _backBuf = _device.GetBackBuffer(0, 0, BackBufferType.Mono); _device.StretchRectangle(_imageBuf, new Rectangle(0, 0, _size.Width * 2, _size.Height + 1), _backBuf, new Rectangle(0, 0, _size.Width, _size.Height), TextureFilter.None); _backBuf.ReleaseGraphics(); _device.EndScene(); _device.Present(); this.Invalidate(); } 

我的一个朋友发现了这个问题。 立体声签名中的字节顺序相反。 这是正确的顺序:

 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; 

此更改后代码完美运行。 这段代码甚至可以作为其他人尝试同样事情的好教程。 🙂