It seems that the same technique of predicated texturing is used on some Android phones as is used on XBox 360 which means that the texture buffer data for any given texture may not be available immediately after drawing because the Present method outputs the textures in sections according to how much graphics memory is available to the GPU.
The result of this is the frame buffer for a texture is not available for the SetData call and data converted over from the camera preview stream will corrupt the texture nastily if the update happens at the same time.
To overcome this I used two textures A and B and while displaying B I write into A and vice-versa. All a bit complicated but graphics is like that it seems.
I set up the textures
like so:
_cameraBGa = new
Texture2D(graphics.GraphicsDevice, _pvWidth,
_pvHeight, false, SurfaceFormat.Bgra5551);
_cameraBGb = new Texture2D(graphics.GraphicsDevice,
_pvWidth, _pvHeight, false, SurfaceFormat.Bgra5551);
_frameData = new short[bs.Width *
bs.Height];
Then I fill them like
so:
unsafe void _listener_PreviewFrame(object
sender, PreviewFrameEventArgs e)
{
lock
(this)
{
fixed
(short* fd = &_frameData[0])
{
fixed
(byte* yuv = &e.Data[0])
{
YUV2RGB.convertYUV420_NV21toRGB5551(yuv, fd,
_pvWidth, _pvHeight);
if (_textureSelect)
{
_cameraBGb.SetData(_frameData);
_bReady = true;
}
else
{
_cameraBGa.SetData(_frameData);
_aReady = true;
}
_textureSelect =
!_textureSelect;
}
}
_bgReady = true;
}
}
And finally display them
like so:
protected
override void
Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue); //Cleared
by the camera
if
(_aReady && _bReady)
{
spriteBatch.Begin();
spriteBatch.Draw(_textureSelect ?
_cameraBGa : _cameraBGb, new Rectangle(0, 0, _displayWidth, _displayHeight), Color.White);
etc, etc, etc.
Ahh I love graphics
problems. Why didn't I become a priest or something?
No comments:
Post a Comment