我制作了一个着色器来显示YUYV表面(数据排列为: Y0 U0 Y1 V0)。这是可行的,但我不知道任何关于着色器,或openGL,或任何图形相关的事情,事实上。我觉得我更像是一个疯狂的科学家,把随机的代码拼凑在一起,而不是程序员。因此,如果有人能查一查,告诉我我能改进什么,性能上,逻辑上还是语法上,我会很感激。我也有一些问题:
我将YUYV纹理作为width/2
的RGBA纹理通过height
加载。其余的应该是不言自明的:
#version 330 core
uniform sampler2D tex;
uniform mat4 convMat; /* Color conversion matrix */
uniform vec2 dim; /* Width and height of image */
in vec2 UV;
out vec3 color;
void main(){
vec4 yuv;
ivec2 iUV = ivec2(UV*dim*vec2(0.5, 1)); /* Absolute coordinate of desired pixel in texture */
yuv = texelFetch(texy, iUV, 0);
if (int(UV.x*dim.x) % 2 == 1){
/* There are 2 Y in a texture RGBA pixel, choose the right one based on absolute pixel coordinate */
yuv.x = yuv.z;
};
yuv.z = yuv.w;
yuv.w = 1;
color = (convMat*yuv).rgb;
};
发布于 2015-04-27 20:36:08
好吧,据我所知,试着回答你的几个问题:
这将在哪些桌面硬件上工作?是否有任何限制,或它会在任何10年前的桌面上工作?
可能不是在10溜溜的电脑里。您的代码目前的目标是GLSL版本3.3,该版本大约在2010年发布。您可以检查版本历史记录这里。但是,如果需要向后兼容,则可以对此代码进行更改,以针对较早的OpenGL版本。我会在结尾提到这些。
这在android平板电脑上能用吗?
不是的。安卓设备使用OpenGL-ES,这是桌面OpenGL 2.0版本的一个变体。您将不会有texelFetch()
函数,也不会在当前的OpenGL中使用iOS和Android设备中的整数类型。
如果我的渲染表面和纹理大小相同,会进行像素插值吗?是否有可能有插补(有一些标志,而不是通过实现)?
你所说的插值到底是什么意思?你说的是纹理滤波吗?通过使用texelFetch()
,您已经选择了退出纹理过滤。不过,我不清楚你为什么这么做。如果您要将纹理采样切换到像texture()
(或者texture2D
,如果针对旧版本)这样的函数,您将能够进行过滤查找并避免不可移植的texelFetch()
。texture()/texture2D()
还将UV作为归一化的0-1范围纹理坐标,因此它将消除整数转换,从而使您的着色器更快。
向后兼容性:正如我前面提到的,您可以通过用OpenGL替换texelFetch()
来使此代码向后兼容旧的texture()/texture2D()
版本。这对于当前的OpenGL-ES公司也是必要的。您还必须删除任何整数转换。较老的OpenGL和OpenGL-ES硬件只能在浮点类型上操作!(无int
或ivec
)。
对性能的评论:在许多图形硬件上,分支仍然是一项昂贵的操作。因此,这里最明显的改进是消除条件if
测试。你也许可以用几个聪明的技巧来完成它。也许mod
函数会有所帮助。
https://codereview.stackexchange.com/questions/88174
复制