2012-06-30 41 views
13

में डायरेक्टएक्स 11 और स्लिम डीएक्स का उपयोग करते हुए एनवीडिया 3 डी वीडियो अच्छा दिन, मैं एनवीडिया 3 डी विजन और दो आईपी कैमरों का उपयोग करके एक वास्तविक समय स्टीरियो वीडियो प्रदर्शित करने की कोशिश कर रहा हूं। मैं डायरेक्टएक्स के लिए बिल्कुल नया हूं, लेकिन इस और अन्य साइटों पर कुछ ट्यूटोरियल और अन्य प्रश्नों के माध्यम से काम करने की कोशिश की है। अभी के लिए, मैं बाएं और दाएं आंखों के लिए दो स्थैतिक बिटमैप प्रदर्शित कर रहा हूं। एक बार मुझे अपने प्रोग्राम के काम का हिस्सा मिलने के बाद इन्हें मेरे कैमरों से बिटमैप्स द्वारा प्रतिस्थापित किया जाएगा। यह प्रश्न NV_STEREO_IMAGE_SIGNATURE and DirectX 10/11 (nVidia 3D Vision) ने मुझे काफी मदद की है, लेकिन मैं अभी भी अपने कार्यक्रम को काम करने के लिए संघर्ष कर रहा हूं। मुझे जो मिल रहा है वह यह है कि मेरे शटर ग्लास काम करना शुरू कर देते हैं, लेकिन केवल सही आंख के लिए छवि प्रदर्शित होती है, जबकि बायां आंख खाली रहता है (माउस कर्सर को छोड़कर)।सी #

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.IO; 

using SlimDX; 
using SlimDX.Direct3D11; 
using SlimDX.Windows; 
using SlimDX.DXGI; 

using Device = SlimDX.Direct3D11.Device;   // Make sure we use DX11 
using Resource = SlimDX.Direct3D11.Resource; 

namespace SlimDxTest2 
{ 
static class Program 
{ 
    private static Device device;    // DirectX11 Device 
    private static int Count;     // Just to make sure things are being updated 

    // The NVSTEREO header. 
    static byte[] stereo_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 

    [STAThread] 
    static void Main() 
    { 

     Bitmap left_im = new Bitmap("Blue.png");  // Read in Bitmaps 
     Bitmap right_im = new Bitmap("Red.png"); 

     // 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 = false, //true, 
      OutputHandle = form.Handle, 
      SampleDescription = new SampleDescription(1, 0), 
      SwapEffect = SwapEffect.Discard, 
      Usage = Usage.RenderTargetOutput 
     }; 

     SwapChain swapChain; 
     Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, desc, out device, out swapChain); 

     RenderTargetView renderTarget;   // create a view of our render target, which is the backbuffer of the swap chain we just created 
     using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0)) 
      renderTarget = new RenderTargetView(device, resource); 

     var context = device.ImmediateContext;     // set up a viewport 
     var viewport = new Viewport(0.0f, 0.0f, form.ClientSize.Width, form.ClientSize.Height); 
     context.OutputMerger.SetTargets(renderTarget); 
     context.Rasterizer.SetViewports(viewport); 

     // prevent DXGI handling of alt+enter, which doesn't work properly with Winforms 
     using (var factory = swapChain.GetParent<Factory>()) 
      factory.SetWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll); 

     form.KeyDown += (o, e) =>     // handle alt+enter ourselves 
     { 
      if (e.Alt && e.KeyCode == Keys.Enter) 
       swapChain.IsFullScreen = !swapChain.IsFullScreen; 
     }; 

     form.KeyDown += (o, e) =>     // Alt + X -> Exit Program 
     { 
      if (e.Alt && e.KeyCode == Keys.X) 
      { 
       form.Close(); 
      } 
     }; 

     context.ClearRenderTargetView(renderTarget, Color.Green);  // Fill Screen with specified colour 

     Texture2DDescription stereoDesc = 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) 
     }; 

     // Main Loop 
     MessagePump.Run(form,() => 
     { 
      Texture2D texture_stereo = Make3D(left_im, right_im);  // Create Texture from two bitmaps in memory 
      ResourceRegion stereoSrcBox = new ResourceRegion { Front = 0, Back = 1, Top = 0, Bottom = 1080, Left = 0, Right = 1920 }; 
      context.CopySubresourceRegion(texture_stereo, 0, stereoSrcBox, renderTarget.Resource, 0, 0, 0, 0); 
      texture_stereo.Dispose(); 

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

     // Dispose resources 

     swapChain.IsFullScreen = false;  // Required before swapchain dispose 
     device.Dispose(); 
     swapChain.Dispose(); 
     renderTarget.Dispose(); 

    } 



    static Texture2D Make3D(Bitmap leftBmp, Bitmap rightBmp) 
    { 
     var context = device.ImmediateContext; 
     Bitmap left2 = leftBmp.Clone(new RectangleF(0, 0, leftBmp.Width, leftBmp.Height), PixelFormat.Format32bppArgb);  // Change bmp to 32bit ARGB 
     Bitmap right2 = rightBmp.Clone(new RectangleF(0, 0, rightBmp.Width, rightBmp.Height), PixelFormat.Format32bppArgb); 

     // Show FrameCount on screen: (To test) 
     Graphics left_graph = Graphics.FromImage(left2); 
     left_graph.DrawString("Frame: " + Count.ToString(), new System.Drawing.Font("Arial", 16), Brushes.Black, new PointF(100, 100)); 
     left_graph.Dispose(); 

     Graphics right_graph = Graphics.FromImage(right2); 
     right_graph.DrawString("Frame: " + Count.ToString(), new System.Drawing.Font("Arial", 16), Brushes.Black, new PointF(200, 200)); 
     right_graph.Dispose(); 
     Count++; 

     Texture2DDescription desc2d = new Texture2DDescription() 
     { 
      ArraySize = 1, 
      Width = 1920, 
      Height = 1080, 
      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 leftText2 = new Texture2D(device, desc2d);  // Texture2D for each bmp 
     Texture2D rightText2 = new Texture2D(device, desc2d); 

     Rectangle rect = new Rectangle(0, 0, left2.Width, left2.Height); 
     BitmapData leftData = left2.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
     IntPtr left_ptr = leftData.Scan0; 
     int left_num_bytes = Math.Abs(leftData.Stride) * leftData.Height; 
     byte[] left_bytes = new byte[left_num_bytes]; 
     byte[] left_bytes2 = new byte[left_num_bytes]; 

     System.Runtime.InteropServices.Marshal.Copy(left_ptr, left_bytes, 0, left_num_bytes);  // Get Byte array from bitmap 
     left2.UnlockBits(leftData); 
     DataBox box1 = context.MapSubresource(leftText2, 0, MapMode.Write, SlimDX.Direct3D11.MapFlags.None); 
     box1.Data.Write(left_bytes, 0, left_bytes.Length); 
     context.UnmapSubresource(leftText2, 0); 

     BitmapData rightData = right2.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
     IntPtr right_ptr = rightData.Scan0; 
     int right_num_bytes = Math.Abs(rightData.Stride) * rightData.Height; 
     byte[] right_bytes = new byte[right_num_bytes]; 

     System.Runtime.InteropServices.Marshal.Copy(right_ptr, right_bytes, 0, right_num_bytes);  // Get Byte array from bitmap 
     right2.UnlockBits(rightData); 
     DataBox box2 = context.MapSubresource(rightText2, 0, MapMode.Write, SlimDX.Direct3D11.MapFlags.None); 
     box2.Data.Write(right_bytes, 0, right_bytes.Length); 
     context.UnmapSubresource(rightText2, 0); 

     Texture2DDescription stereoDesc = 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 stereoTexture = new Texture2D(device, stereoDesc); // Texture2D to contain stereo images and Nvidia 3DVision Signature 

     // 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 = 1920 }; 

     // Copy it to the stereo texture 
     context.CopySubresourceRegion(leftText2, 0, stereoSrcBox, stereoTexture, 0, 0, 0, 0); 
     context.CopySubresourceRegion(rightText2, 0, stereoSrcBox, stereoTexture, 0, 1920, 0, 0); // Offset by 1920 pixels 

     // Open the staging texture for reading and go to last row 
     DataBox box = context.MapSubresource(stereoTexture, 0, MapMode.Write, SlimDX.Direct3D11.MapFlags.None); 
     box.Data.Seek(stereoTexture.Description.Width * (stereoTexture.Description.Height - 1) * 4, System.IO.SeekOrigin.Begin); 
     box.Data.Write(stereo_data, 0, stereo_data.Length);   // Write the NVSTEREO header 
     context.UnmapSubresource(stereoTexture, 0); 

     left2.Dispose(); 
     leftText2.Dispose(); 
     right2.Dispose(); 
     rightText2.Dispose(); 
     return stereoTexture; 
    } 

} 

}

मैं सहित स्टीरियो छवि हस्ताक्षर (3840x1081) backbuffer के Texture2D कॉपी करने के विभिन्न तरीके की कोशिश की है, लेकिन कोई भी:

यहाँ स्टीरियो छवियों पैदा करने के लिए मेरे कोड है तरीकों में से मैं प्रदर्शन दोनों छवियों की कोशिश की है ... कोई मदद या टिप्पणी बहुत सराहना की जाएगी, रयान

+0

मैंने डायरेक्ट 3 डी 9 पर वापस जाने का प्रयास किया है (ताकि मैं खिंचाव का उपयोग कर सकूं), लेकिन अब मुझे प्रोग्राम को पूर्ण स्क्रीन मोड में चलाने में परेशानी हो रही है। जैसे ही मैं presentparams सेट करता हूं। Windowed = false, जब मैं अपना स्वैपचैन बनाता हूं तो प्रोग्राम क्रैश हो जाता है। मुझे निम्न त्रुटि मिलती है: D3DERR_INVALIDCALL (-2005530516)। अगर यह बिल्कुल मदद करता है, तो मैं 3 डी ट्रांसमीटर में निर्मित डेल एक्सपीएस 17 लैपटॉप का उपयोग कर रहा हूं ... –

+0

ठीक है, इसलिए मैंने स्लिम डीएक्स और डायरेक्ट 3 डी 9 का उपयोग करके इसे काम करने में कामयाब रहा है। मैं केवल अपने प्रस्तुतियों का उपयोग करके एक डिवाइस बना रहा हूं, और एक स्वैपचैन नहीं बना रहा (जो पूर्णस्क्रीन मोड में शुरू करने की कोशिश करते समय मेरा प्रोग्राम क्रैश हो रहा था)। मैंने सोचा कि डिवाइस बनाने के दौरान एक स्वैपचैन की आवश्यकता थी, लेकिन ऐसा नहीं लगता है। अभी के लिए, मैं डायरेक्ट 3 डी 9 तक रहूंगा और अपना बाकी प्रोग्राम काम कर रहा हूं (दो कैमरों को जोड़ रहा हूं और सबकुछ सिंक्रनाइज़ कर रहा हूं)। यह अभी भी Direct3D11 में काम करने के लिए अच्छा होगा, लेकिन उसे प्रतीक्षा करनी होगी। –

+0

मुख्य पाश में आपके पास संसाधन क्षेत्र नीचे = 1080 है और दाएं = 1920 सही नहीं होना चाहिए = 1920 * 2? –

उत्तर

0

चौड़ाई के साथ backbufer बनाने = 1920 और नहीं 3840.प्रयास करेंप्रत्येक छवि को आधा आकार चौड़ाई में खींचें और उन्हें एक तरफ रखें।

+0

सलाह के लिए धन्यवाद। जैसा कि मैंने उपरोक्त टिप्पणियों में उल्लेख किया है, मुझे यह डी 3 डी 9 के साथ काम कर रहा है। मेरा बैकबफर चौड़ाई = 1920 के साथ सेट है, लेकिन मेरी समस्या यह है कि D3D 10 और 11. में StretchRectangle() के लिए कोई समकक्ष फ़ंक्शन नहीं है। आप StretchRectangle() के बिना 3840 पिक्सेल चौड़ी छवि को 1920 पिक्सेल चौड़े बैकबफर तक फैलाते हैं? मैंने CopySubResourceRegion() का उपयोग करने का प्रयास किया, लेकिन केवल स्रोत आकार निर्दिष्ट किया जा सकता है और मुझे यह काम नहीं मिल रहा है ... –

0

मुझे कुछ दिनों पहले एनवीडिया डेवलपर मंचों पर खोज करते समय यह वही प्रश्न देखना याद है। दुर्भाग्यवश हाल ही में हैकर हमले के कारण मंच नीचे आ गए हैं। मुझे याद है कि उस धागे पर ओपी हस्ताक्षर हैक का उपयोग कर डीएक्स 11 और स्लिमडैक्स के साथ काम करने में सक्षम था। आप stretchRectangle विधि का उपयोग नहीं करते हैं, यह कुछ बनाने जैसा था ResuroseRegion() या नहीं, लेकिन वास्तव में मुझे याद नहीं है। यह इन तरीकों से हो सकता है CopyResource() या CopySubresourceRegion() इस समान थ्रेड में प्रवाह पर ढेर पर पाया जाता है। Copy Texture to Texture

0

क्या आप छवि को निरंतर या कम से कम कुछ बार प्रस्तुत कर रहे हैं? मैं डीएक्स 9 में एक ही काम कर रहा था और ड्राइवर को इसे 3 डी दृष्टि के रूप में पहचाने जाने से पहले 3 फ्रेम प्रस्तुत करने के लिए डीएक्स को बताना था। क्या आपके चश्मा किक पर थे? अपने backbuffer = है (चौड़ाई * 2), (ऊंचाई + 1) और तुम इतनी तरह backbuffer लिख रहे हैं:

_________________________ 
|   |   |  
| img1  |  img2 | 
|   |   | 
-------------------------- 
|_______signature________| where this last row = 1 pix tall 
+0

हाय। हां मैं लगातार प्रतिपादन कर रहा हूं। जैसा कि मैंने उपरोक्त मेरी टिप्पणियों में उल्लेख किया है, मैंने इसे डीएक्स 9 के साथ काम किया है। अब मुझे दो कैमरे चल रहे हैं और यह अच्छी तरह से काम करता है। जैसा कि आप ऊपर वर्णित करते हैं, मैं इंटरमीडिएट बफर जैसा दिखता हूं, लेकिन बैकबफर जिसे मैं स्ट्रेटच्रैक्टंगल() का उपयोग करके लिखता हूं, केवल 1920x1080 है, और चौड़ाई और ऊंचाई को दोगुना नहीं करता है। 1. मुझे लगता है कि एनवीडिया ड्राइवर इसे तुरंत पहचानता है, लेकिन यह लेता है कुछ समय के लिए आईआर ट्रांसमीटर स्विच करने के लिए और चश्मा काम शुरू करने के लिए। मैं इस चरण में आगे बढ़ने के लिए डीएक्स 11 में काम करने की कोशिश नहीं कर रहा हूं। –

1

तो DirectX11.1 का उपयोग कर एक विकल्प है, वहाँ त्रिविम सुविधाओं को सक्षम करने के लिए एक बहुत ही आसान तरीका है , एनवीडिया के बाइट जादूगर पर भरोसा किए बिना। असल में, आप नियमित SwapChain के बजाय SwapChan1 बनाते हैं, तो यह सही है कि Stereo को सही पर सेट करना उतना आसान है।

मैंने यह देखा है कि यह post मैंने देखा है, यह आपको स्टीरियो स्वैप चेन बनाने का तरीका दिखाता है। कोड एमएस के अपने स्टीरियो नमूने के सी # के लिए एक पोर्टिंग है। फिर आपके पास दो रेंडर लक्ष्य होंगे और यह बहुत आसान है।

void RenderEye(bool rightEye, ITarget target) 
{ 
    RenderTargetView currentTarget = rightEye ? target.RenderTargetViewRight : target.RenderTargetView; 
    context.OutputMerger.SetTargets(target.DepthStencilView, currentTarget); 
    [clean color/depth] 
    [render scene] 
    [repeat for each eye] 
} 

जहां ITarget backbuffer, rendertargets, आदि यह है कि एक वर्ग उपलब्ध कराने के लिए उपयोग के लिए एक इंटरफेस है, DirectX सब कुछ का ख्याल रखना होगा: प्रतिपादन इससे पहले कि आप के लिए है। उम्मीद है की यह मदद करेगा।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^