Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用着色器和rtt复制纹理子矩形_C++_Opengl - Fatal编程技术网

C++ 使用着色器和rtt复制纹理子矩形

C++ 使用着色器和rtt复制纹理子矩形,c++,opengl,C++,Opengl,我需要编写一个函数,该函数将从2D纹理non-power-of-2中获取一个子矩形,并使用着色器no-glSubImage或类似工具将其复制到输出2D纹理的目标子矩形。 此外,源和目标可能没有相同的大小,因此我需要使用线性过滤甚至mipmap void CopyToTex(GLuint dest_tex,GLuint src_tex, GLuint src_width,GLuint src_height, GLuint dest_wid

我需要编写一个函数,该函数将从2D纹理non-power-of-2中获取一个子矩形,并使用着色器no-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_线性过滤

我希望此函数以一致的方式运行,即使用多个子矩形多次调用它,将产生与子矩形并集的一次调用相同的结果;也就是说,线性采样器应该采样输入像素的精确中心

此外,如果输入矩形正好适合目标矩形,则应生成精确的副本。 这似乎特别困难

我现在得到的是这样的东西:

//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矩形的精确复制

我可能在偏移和缩放方面遇到了一些问题,这些小问题不起作用。

解决方案:

texcoords定义中的0.5/tex_宽度部分是错误的。 一个简单的解决方法是完全移除该部件

float texcoords[4] = {
      (srcRect[0] * (src_width - 1) + 0.5) / src_width,
      (srcRect[1] * (src_height - 1) + 0.5) / src_height,
      (srcRect[2] * (src_width - 1) + 0.5) / src_width,
      (srcRect[3] * (src_height - 1) + 0.5) / src_height
};
相反,我们绘制一个较小的四边形,通过以下方式偏移顶点:

float dx = 1.0 / (dest_rect[2] - dest_rect[0]) - epsilon;
float dy = 1.0 / (dest_rect[3] - dest_rect[1]) - epsilon;

// assume glTexCoord for every vertex 
glVertex2f(vertices[0] + dx, vertices[1] + dy);
glVertex2f(vertices[2] - dx, vertices[1] + dy);
glVertex2f(vertices[2] - dx, vertices[3] - dy);
glVertex2f(vertices[0] + dx, vertices[3] - dy);
通过这种方式,我们绘制了一个从每个边界像素的精确中心经过的四边形。 由于OpenGL在这种情况下可能绘制边界像素,也可能不绘制边界像素,因此我们需要ε


我相信我的原始解决方案“不偏移顶点坐标”仍然可以工作,但需要一些额外的数学来计算texcoords的正确偏移。

我最难的测试用例是在输入和输出纹理都大于2xN时执行2xN矩形的精确复制。在这种情况下会发生什么?@NicolBolas输入像素被合并。我的输入是棋盘纹理,输出是褪色的棋盘。你是说棋盘模糊吗?这可能与下采样和过滤有关。您应该显示顶点[4]的整个初始化过程,特别是glVertex2fvertices[2],顶点[1]似乎是错误的。glVertex2fvertices[2],vertices[3]我认为GL_NEAREST可能会让你得到更清晰、更准确的结果。听起来他试图使用双线性过滤来完成平滑缩放图像的肮脏工作:但他没有意识到,OpenGL中的双线性过滤在样本权重方面是不标准的。所以这可能不会产生一致的结果。。。