使用OpenGL快速调色屏幕blit

时间:2012-09-21 05:36:42

标签: opengl 2d

游戏使用软件渲染在内存中绘制全屏调色板(8位)图像。

使用OpenGL将图像放在屏幕上的最快方法是什么?

我尝试过的事情:

  • glDrawPixelsglPixelMap指定调色板,让OpenGL执行调色板映射。表演很糟糕(约5 FPS)。
  • 在软件中进行调色板映射(索引 - > BGRX),然后使用glDrawPixels绘制它。性能更好,但CPU使用率仍远高于使用32位DirectDraw和相同的软件调色板映射。

我应该使用某种纹理吗?

1 个答案:

答案 0 :(得分:5)

  
      
  • glDrawPixels与glPixelMap指定调色板,让OpenGL进行调色板映射。表演很糟糕(约5 FPS)。
  •   

这并不奇怪。 glDrawPixels的开始并不是很快,glPixelMap将在CPU上进行索引/调色板→RGB转换,但肯定不是非常优化的代码路径。

  
      
  • 在软件中进行调色板映射(索引 - > BGRX),然后使用glDrawPixels绘制它。
  •   

glDrawPixels是OpenGL中最慢的函数之一。这有两个主要原因:首先它是一个没有太多优化的代码补丁,其次它直接写入目标帧缓冲区,因此每次调用时都强制管道进入同步。此外,在大多数GPU上,它都没有任何缓存支持。

我建议您将索引图像放入单通道纹理,例如GL_R8(对于OpenGL-3或更高版本)或GL_LUMINANCE8,并将您的调色板转换为1D RGB纹理,以便用作纹理坐标的索引确实查找颜色。使用纹理作为LUT是完全正常的。使用此组合,您可以使用片段着色器进行颜色转换的原位调色板索引。

片段着色器看起来像这样

#version 330

uniform sampler2D image;
uniform sampler1D palette;

in vec2 texcoord;

void main()
{
    float index = tex2D(image, texcoord).r * 255.f; // 255 for a 8 bit palette
    gl_FragColor = texelFetch(palette, index, 0);
}