我需要编写一个函数,该函数应从 2D 纹理(非 2 次幂)中获取子矩形,并使用着色器(无 glSubImage 或类似)将其复制到输出 2D 纹理的目标子矩形。此外,源和目标的大小可能不同,所以我需要使用线性过滤(甚至是 mipmap)。
void CopyToTex(GLuint dest_tex,GLuint src_tex,
GLuint src_width,GLuint src_height,
GLuint dest_width,GLuint dest_height,
float srcRect[4],
GLuint destRect[4]);
这里 srcRect 是标准化的 0-1 坐标,即矩形 [0,1]x[0,1] 触摸输入纹理的每个边框像素的中心。
为了在输入和源尺寸不匹配时获得良好的结果,我想使用GL_LINEAR
过滤。
我希望这个函数以一种连贯的方式运行,即多次使用多个子区域调用它会产生与使用子区域联合的一次调用相同的结果;也就是说,线性采样器应该对输入像素的确切中心进行采样。
此外,如果输入矩形恰好适合目标矩形,则应该出现精确的副本。这似乎特别难。
我现在得到的是这样的:
//Setup RTT, filtering and program
float vertices[4] = {
float(destRect[0]) / dest_width * 2.0 - 1.0,
float(destRect[1]) / dest_height * 2.0 - 1.0,
//etc..
};
float texcoords[4] = {
(srcRect[0] * (src_width - 1) + 0.5) / src_width - 0.5 / dest_width,
(srcRect[1] * (src_height - 1) + 0.5) / src_height - 0.5 / dest_height,
(srcRect[2] * (src_width - 1) + 0.5) / src_width + 0.5 / dest_width,
(srcRect[3] * (src_height - 1) + 0.5) / src_height + 0.5 / dest_height,
};
glBegin(GL_QUADS);
glTexCoord2f(texcoords[0], texcoords[1]);
glVertex2f(vertices[0], vertices[1]);
glTexCoord2f(texcoords[2], texcoords[1]);
glVertex2f(vertices[2], vertices[1]);
//etc...
glEnd();
为了编写此代码,我遵循了此页面中的信息。
这似乎在某些极端情况下按预期工作(精确复制,复制一个像素的行或列)。
我最难的测试案例是在输入和输出纹理都大于 2xN 时执行 2xN 矩形的精确复制。
我可能对偏移和缩放有一些问题(琐碎的不起作用)。