Bug in MOGRE 1.6.4?
when creating a Manual Texture like this:
TextureManager.Singleton.CreateManual(MaterialName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, TextureType.TEX_TYPE_2D, (uint)videoWidth, (uint)videoHeight, 0, PixelFormat.PF_BYTE_RGB)
The TexturePtr Format is PF_X8R8G8B8 not the one it was created with, so is this a bug or do i do something really wrong here?
i have never use dynamic texture but from the api, pixel format is described like this :
format The internal format you wish to request; the manager reserves the right to create a different format if the one you select is not available in this context.
and even if the format is not the one you requested at this point, desiredformat and srcformat seems correct.
Then i am out of luck here... I create my texture and my material the following way:
MaterialName = Guid.NewGuid().ToString();
outputFrame = TextureManager.Singleton.CreateManual(MaterialName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, TextureType.TEX_TYPE_2D, (uint)videoWidth, (uint)videoHeight, 0, PixelFormat.PF_BYTE_RGB);
outputFrame.Format = PixelFormat.PF_R8G8B8;
outputMaterial = (MaterialPtr)MaterialManager.Singleton.Create(MaterialName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
I fill a Video Texture into the Texture buffer like that:
HardwarePixelBufferSharedPtr buffer = outputFrame.GetBuffer();
PixelBox pbox = buffer.CurrentLock;
pbox.format = PixelFormat.PF_R8G8B8;
Marshal.Copy(videoFrameBytes, 0, pbox.data, videoFrameBytes.Length);
// Update current position read-out
But the Texture / Material that shows on the Object remains black. I am sure it is something obvious or stupid but i cant find it right now.
I recently fiddled around with video textures from DirectShow, maybe that's helpful to you:
... Capture.cs (that's mainly a modified version of DirectShowLib's capture sample)
'ISampleGrabberCB.BufferCB' gets called asynchronously when DirectShow has a new frame.
1) copies the buffer,
2) creates a temporary bitmap from the buffer,
3) resizes the bitmap to power-of-2 dimensions and
4) passes that bitmap to its owner.
... Control.cs (the owner)
'ConvertBitmap' usually gets called on Root.FrameStarted and
1) checks whether a new frame bitmap has been set,
2) creates the texture (if necessary),
3) locks the buffer of the texture,
4) creates a bitmap from the current lock,
5) gets the System.Drawing.Graphics from the texture bitmap,
6) draws the frame bitmap on the texture bitmap,
7) unlocks the buffer and
8) disposes all temporary objects.
The whole thing takes about 20ms per frame for a 640x480 video.
Yeah, if you do it on the same thread as Ogre is running, it takes a lot of time. What I do is actually, let the Video run in another thread, let BufferCB pre process everything and push it into a queue. On FrameEnded, I take the prepared data and just blit it to the texture. It is faster but takes time anyways. I want to try another solution, if we create 2 Textures, like Front and Back buffer, while the first one is shown, fill the other one and just change the material texture pass after frame ended. I dont know if this speeds up things but even a MS will give better frame rate results.
I don't push the processed bitmaps into a queue. The last video frame is dropped when it hasn't been rendered yet.
Only the final conversion from bitmap to texture is on the same thread as Ogre, to avoid running into thread-safety issues.
Right, but I do it like that and it speeds things up. For thread safety... yeah well... you just need to take care of it.