Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.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 运行OpenGL着色器修改现有纹理/帧缓冲区_C_Opengl - Fatal编程技术网

C 运行OpenGL着色器修改现有纹理/帧缓冲区

C 运行OpenGL着色器修改现有纹理/帧缓冲区,c,opengl,C,Opengl,如何使用OpenGL着色器在不使用第二个纹理或帧缓冲区的情况下修改现有纹理/帧缓冲区?这可能吗?一开始: 从技术上讲,使用同一个通道读写是可能的,也是安全的——但是我不建议这样做,尤其是对于学习者,因为扩展受到严格限制,并且可能不是每个硬件都支持 也就是说: 所以不可能使用与采样器和帧缓冲区相同的纹理 您可以使用与帧缓冲区纹理附件相同的纹理并对其进行渲染,也可以使用纹理采样器在着色器中查找值,但不在同一过程中。这意味着,如果您有两个纹理,您可以从A读取并写入B,然后切换纹理并从B读取并写入A。但

如何使用OpenGL着色器在不使用第二个纹理或帧缓冲区的情况下修改现有纹理/帧缓冲区?这可能吗?

一开始: 从技术上讲,使用同一个通道读写是可能的,也是安全的——但是我不建议这样做,尤其是对于学习者,因为扩展受到严格限制,并且可能不是每个硬件都支持

也就是说:


所以不可能使用与采样器和帧缓冲区相同的纹理

您可以使用与帧缓冲区纹理附件相同的纹理并对其进行渲染,也可以使用纹理采样器在着色器中查找值,但不在同一过程中。这意味着,如果您有两个纹理,您可以从A读取并写入B,然后切换纹理并从B读取并写入A。但决不能是A->A或B->B(没有提到的扩展名)

作为技术细节,当前用作目标的纹理也可以同时绑定到采样器着色器变量,但不能使用它


假设我只想模糊纹理的一小部分。我必须通过着色器将其运行到第二个纹理,然后将该纹理复制回第一个纹理/帧缓冲区


第二,是的。但出于效率原因,请勿将纹理数据复制回原处。只需删除源纹理,并在将来使用已渲染到的目标纹理。如果必须经常执行此操作,请将源纹理保留为渲染目标,以便稍后使用以提高性能。如果你必须在每一帧都这样做,只需在每一帧交换纹理即可。开销很小。

使用以下代码很难实现

// in fragment shader
uniform sampler2D input;

out vec4 color;// bind sampler and framebuffer with same texture
void main(){
ivec2 pos = ivec2(gl_FragCoord.xy);
if(cond){
    color = vec4(0.0);
}else{
    color = texelFetch(input, pos, 0);
  }
}

不,你需要一个单独的缓冲区来保存旧的,而你正在编写新的,你只是无法绕过它。因此,它不可能使用相同的纹理作为采样器和帧缓冲区?想想它将如何在幕后工作,当片段着色器采样一个像素已经由以前的调用编写,OpenGL防止程序员犯这样的错误,所以假设我只想模糊纹理的一小部分。我必须通过着色器将其运行到第二个纹理,然后将该纹理复制回第一个纹理/帧缓冲区?您可以使用图像加载/存储或纹理屏障来执行此操作,但这非常复杂(您必须自己在所有并行着色器调用之间实现同步),几乎不可能。在大多数情况下,额外的工作不会给你带来任何有价值的东西。或者,如果你有多个过程需要做,那么只需在同一帧中来回渲染即可。