我有一个 C# 小游戏,主要使用固定的精灵(从磁盘加载的位图)和一些视频。
现在我们目前的方法是
加载:
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);
绘画
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);
和更新:
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);
所有纹理都保留到使用前,所以加载只在启动时完成一次(通常)所以首先:对该方法有什么评论吗?现在我想正确使用 PBO 来更新纹理(主要用于视频) A)使用 PBO 添加纹理(来自 bmp)是个好主意吗?我会创建一个 pbo,将数据从 bmp 复制到 pbo,然后使用 TexSubImage2D。是否有任何性能点或者开销是否很高?B)更新相同:当前代码:
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);
这真的有效还是没有任何好处?
我阅读了http://www.opengl.org/wiki/Pixel_Buffer_Object和http://www.songho.ca/opengl/gl_pbo.html以及关于下载和使用的第一篇文章,如果我上传数据和立即绘制该纹理(甚至使用 TexSubImage2D?)然后我将无法通过 PBO 获得更多速度。这是正确的吗?因此,如果我使用 PBO,我是否必须使用第二个 PBO 并延迟一帧绘制帧?
我的主循环是这样的:
{
DoSomeInputHandling();
CopyDecodedVideoFrameToTexture();
DrawTexture();
}
在另一个线程中进行视频解码。
是一种非常幼稚的方法,但有效。这样做的正确/更好的方法是什么?