This project is read-only.

customize video display

Apr 2, 2009 at 3:32 PM
Hi! I would like to display the video image in only part of the window (like the top right corner). How can I do it ?
What about multiple windows ?
Thanks =)

Coordinator
Apr 2, 2009 at 9:51 PM
Edited Apr 2, 2009 at 10:11 PM
If you want to show the video image in only part of the window, then what you need to do is to set the Scene.ShowCameraImage to false, so it won't be displayed on the entire background. Next, you should get the video image from the ImagePtr property of whatever IVideoCapture class (e.g., DirectShowCapture) you're using, and apply the pixel information (you can retrieve the pixel information from IntPtr using unsafe code) to a texture of your preferred size. Then render this texture on the 2D screen using UI2DRenderer.FillRectangle(...) method.

We do not explicitly support multiple windows yet, but you can achieve this by doing the following in your Draw method:

<code>
// Render the main window with the full width and height
graphics.GraphicsDevice.Viewport = defaultViewport; 
base.Draw(gameTime);

// Now change the viewport to a smaller view port at (400, 0) with dimension 400x300
Viewport viewport = new Viewport();
viewport.Width = 400;
viewport.Height = 300;
viewport.X = 400;
viewport.Y = 0;
graphics.GraphicsDevice.Viewport = viewport;
            
// Render a 2nd window inside of the main window
scene.Draw(gameTime)
</code>

The defaultViewport can be: <code>defaultViewport = graphics.GraphicsDevice.Viewport;</code> defined in your initialization code.

I haven't rigorously tested multiple window setting yet, so there might be many bugs. I will include explicit support for multiple window rendering from v3.3. (v3.2 will be released soon, but it won't include explicit support for multiple window). 

Ohan
Apr 3, 2009 at 5:06 PM
Tkx for the quick answer =)

I've tried what you said, but all i see is a dark rectangle.

DirectShowCapture captureDevice = new DirectShowCapture();
captureDevice.InitVideoCapture(0, 0, FrameRate._30Hz, Resolution._320x240, false);
image=captureDevice.ImagePtr;

I set the length to 320*240*3 = 230400 //i dont know another way to find the length
in the Draw() funtion:

byte[] bgrData = new byte[length];
Marshal.Copy(tex, bgrData, 0, length);
Color[] colorData = new Color[length / 3];
for (int i = 0; i < colorData.Length; i++)
{
       colorData[i] = new Microsoft.Xna.Framework.Graphics.Color(bgrData[3 * i + 2], bgrData[3 * i + 1], bgrData[3 * i]);
}
txt = new Texture2D(graphics.GraphicsDevice, 320, 240, 1, TextureUsage.None, SurfaceFormat.Color);// Version 2.0
txt.SetData<Microsoft.Xna.Framework.Graphics.Color>(colorData);
UI2DRenderer.FillRectangle(new Rectangle(0, 0, 320, 240), txt, Color.White);          

I am a newbie, so probably I'm doing some stupid thing and dont even realize it.. :|
Coordinator
Apr 6, 2009 at 9:44 PM
The length of the ImagePtr is camera_width * camera_height * bpp. In v3.1, bpp is always 3 (R8G8B8_24). It'll be clearer from v3.2 since I included one more parameter that specifies the format of ImagePtr. 

In your code, I don't see that you're copying your "image" data to your texture. You need to do something similar to the following:

unsafe{
   byte* pixels = (byte*) captureDevice.ImagePtr;
   int[] texture = new int[camera_width * camera_height];
   for(int i = 0; i < camera_width * camera_height * 3; i++)
       texture[i/3] = (appropriately shifted pixel information based on your texture format);

   (your texture).SetData<int>(texture);
}

Ohan