I have a little game in C# which uses mainly fixed sprites (bitmaps loaded from disk) and some videos.
Now our current approach is
Loading:
texture.ID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texture.ID);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, w, h, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, data);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, 0);
Drawing
GL.BindTexture(TextureTarget.Texture2D, texture.ID);
GL.MatrixMode(MatrixMode.Texture);
GL.PushMatrix();
GL.Begin(BeginMode.Quads);
GL.TexCoord2(x1, y1);
GL.Vertex3(rx1, ry1, rect.Z);
GL.TexCoord2(x1, y2);
GL.Vertex3(rx1, ry2, rect.Z);
GL.TexCoord2(x2, y2);
GL.Vertex3(rx2, ry2, rect.Z);
GL.TexCoord2(x2, y1);
GL.Vertex3(rx2, ry1, rect.Z);
GL.End();
GL.PopMatrix();
GL.BindTexture(TextureTarget.Texture2D, 0);
And Updating:
GL.BindTexture(TextureTarget.Texture2D, texture.ID);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, data);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, 0);
All the textures are kept till they are used, so loading is only done once at startup (in general) So first: Any comments on that method? Now I'd want to use PBO properly to update the textures (mainly for video) A) Is it a good idea to use a PBO to add the texture (from bmp)? I'd create a pbo, copy data from bmp to pbo and then use TexSubImage2D. Are there any performance points for that or is the overhead to high? B) Same for updating: Current Code:
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, texture.PBO);
IntPtr buffer = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
Marshal.Copy(data, 0, buffer, data.Length);
GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer);
GL.BindTexture(TextureTarget.Texture2D, texture.ID);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
Does this actually work or is there no benefit with that?
I read http://www.opengl.org/wiki/Pixel_Buffer_Object and http://www.songho.ca/opengl/gl_pbo.html and the first article about the download-and-use suggest, that if I upload data and immediately draw that texture (or even use TexSubImage2D?) then I won't get any more speed by the PBO. Is this right? So if I use the PBO would I have to use a 2nd PBO and draw the frames a frame delayed?
My main-loop is like:
{
DoSomeInputHandling();
CopyDecodedVideoFrameToTexture();
DrawTexture();
}
With video decoding in another thread.
Is a pretty naive approach but working. What's the correct/better way of doing this?