私は、それぞれの目に異なる画像を表示する非常に単純なアプリケーションを作成しようとしています。Asus VG236H モニターと NVIDIA 3D Vision キット、ステレオ 3D シャッター グラスを持っています。私は C#、.NET Framework 2.0、DirectX 9 (Managed Direct X)、および Visual Studio 2008 を使用しています。私は例とチュートリアルを高低で検索してきましたが、実際にいくつかを見つけて、それらに基づいてプログラムを作成しましたが、何らかの理由で私はそれを機能させることができません。
目ごとに異なる画像を表示する方法の例を探すとき、多くの人が GDC 09 での NVIDIA プレゼンテーション (有名な GDC09-3DVision-The_In_and_Out.pdf ドキュメント) と 37 ~ 40 ページを参照し続けます。私のコードは主にその例に基づいて構築されています:
- 関数 LoadSurfaces() で、サーフェス (_imageLeft と _imageRight) に 2 つのテクスチャ (Red.png と Blue.png) をロードしています。
- Set3D() 関数は、これらの 2 つの画像を横に並べて、画面幅の 2 倍、画面高さ + 1 (_imageBuf) のサイズの 1 つの大きな画像にします。
- Set3D() 関数は、最後の行にステレオ シグネチャを追加して続行します。
- OnPaint() 関数は、バック バッファー (_backBuf) を取得し、結合されたイメージ (_imageBuf) の内容をそこにコピーします。
プログラムを実行すると、シャッター メガネが機能し始めますが、画面に 2 つの画像が並んでいるだけです。誰かが助けて、私が間違っていることを教えてもらえますか? 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();
}