尝试从帧缓冲区传递纹理会导致 L_INVALID_OPERATION:glDrawArrays:绘制的源纹理和目标纹理相同

Posted

技术标签:

【中文标题】尝试从帧缓冲区传递纹理会导致 L_INVALID_OPERATION:glDrawArrays:绘制的源纹理和目标纹理相同【英文标题】:Trying to pass texture from framebuffer results in L_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same 【发布时间】:2019-10-25 21:55:44 【问题描述】:

我是 vanilla WebGL 的新手,正在尝试将帧缓冲区用于后期处理/高级着色器。当我运行我的代码时,我收到警告:

GL_INVALID_OPERATION : glDrawArrays: 绘制的源纹理和目标纹理相同。

到目前为止,这是我的代码。如果有人能指出我正确的方向,如何正确利用帧缓冲区将纹理传递到下一个通道。它被包裹在一个 vue.js 组件中,但这并不重要。

<template lang='pug'>

    canvas

</template>

<script>

import  mapGetters  from 'vuex'

export default 
    name: 'webGl',
    created ()
    
        this.static = 
            af: null,
            gl: null,
            fr: 0,
            shaders:
            
                vertex: `
                attribute vec2 a_position;

                void main() 
                    gl_Position = vec4(a_position, 0, 1);
                `,
                fragment: `
                #ifdef GL_ES
                precision mediump float;
                #endif

                uniform float u_time;
                uniform vec2 u_size;
                uniform int u_frame;
                uniform sampler2D u_texture;

                const int maxIter = 15;

                vec2 getPos() 
                    vec2 pos = ( gl_FragCoord.xy / u_size.xy ) - vec2(0.5);
                    pos.x *= u_size.x / u_size.y;
                    return pos;
                

                vec2 cmult(vec2 a, vec2 b)
                    return vec2(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
                

                float length2(vec2 v)
                    return v.x*v.x+v.y*v.y;
                

                vec2 map(vec2 pos)
                    return pos;
                    return vec2(pos.x * sqrt(1.-pos.y*pos.y*3.), pos.y * sqrt(1.-pos.x*pos.x*2.));
                

                vec2 iterate(vec2 p, vec2 c)
                    vec2 p2 = cmult(p,p);
                    return p2 + c;
                

                bool checkAbort(vec2 p, vec2 c)
                    return length2(p) > 400.;
                

                float l2 = log(2.);

                vec4 defaultColor ( void )
                
                    return vec4(0.35,0.35,0.35,1.0);
                

                vec4 color(int iterations, vec2 p)
                    float col = .20 + (float(iterations) - log(log(length2(p)))/l2) / float(maxIter);
                    return defaultColor() * vec4(col);
                

                void main( void )
                    if (u_frame < 300)
                    
                        vec2 c = map(getPos())*0.8 - vec2(0.5);
                        vec2 p = c + vec2(sin(-u_time), cos(u_time)) * 0.2;
                        float m;

                        for(int i = 0; i < maxIter ;i++) 
                            p = iterate(p,c);
                            if(checkAbort(p,c))
                                gl_FragColor = color(i,p);
                                return;
                            
                        
                        gl_FragColor = defaultColor();
                    
                    else
                    
                        gl_FragColor = texture2D(u_texture, gl_FragCoord.xy / u_size.xy);
                    
                `,
                program: null,
                attributes: ,
                uniforms: ,
                time: 0
            
        
    ,
    mounted ()
    
        this.setInitWebGlContext()
        this.setInitShaderProgram()
        this.setInitAttributes(['a_position'])
        this.setInitUniforms(['u_size', 'u_time', 'u_frame', 'u_texture'])
        this.setInitGeometryBuffer()

        this.setRenderLoop()
    ,
    beforeDestroy ()
    
        window.cancelAnimationFrame(this.static.af)
    ,
    computed:
    
        ...mapGetters([
            'getCalcs'
        ])
    ,
    methods:
    
        setInitWebGlContext ()
        
            this.static.gl = this.$el.getContext('webgl')

            if (this.static.gl === null)
            
                console.log('Unable to initialize WebGL. Your browser or machine may not support it.')
            
        ,
        setInitShaderProgram ()
        
            const gl = this.static.gl

            this.static.shaders.program = gl.createProgram()

            const vertexShader = gl.createShader(gl.VERTEX_SHADER)
            const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

            gl.shaderSource(vertexShader, this.static.shaders.vertex)
            gl.shaderSource(fragmentShader, this.static.shaders.fragment)

            gl.compileShader(vertexShader)
            gl.compileShader(fragmentShader)

            gl.attachShader(this.static.shaders.program, vertexShader)
            gl.attachShader(this.static.shaders.program, fragmentShader)
            gl.linkProgram(this.static.shaders.program)
            gl.useProgram(this.static.shaders.program)
        ,
        setInitAttributes (keys)
        
            const gl = this.static.gl
            const program = this.static.shaders.program

            for (let i = 0; i < keys.length; i++)
            
                this.static.shaders.attributes[keys[i]] = gl.getAttribLocation(program, keys[i])
            
        ,
        setInitUniforms (keys)
        
            const gl = this.static.gl
            const program = this.static.shaders.program

            for (let i = 0; i < keys.length; i++)
            
                this.static.shaders.uniforms[keys[i]] = gl.getUniformLocation(program, keys[i])
            
        ,
        setInitGeometryBuffer ()
        
            const gl = this.static.gl
            const buffer = gl.createBuffer()

            gl.bindBuffer(this.static.gl.ARRAY_BUFFER, buffer)
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0]), gl.STATIC_DRAW)
        ,
        setCreateTexture ()
        
            const gl = this.static.gl
            const width = this.getCalcs.vw
            const height = this.getCalcs.vh
            const texture = gl.createTexture()

            gl.bindTexture(gl.TEXTURE_2D, texture)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)

            return texture
        ,
        setCreateFramebuffer ()
        
            const gl = this.static.gl
            const buffer = gl.createFramebuffer()

            gl.bindFramebuffer(gl.FRAMEBUFFER, buffer)

            const texture = this.setCreateTexture()

            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)

            return 
                texture: texture,
                buffer: buffer
            
        ,
        setRenderLoop ()
        
            this.static.af = window.requestAnimationFrame(this.setRenderLoop)

            const gl = this.static.gl
            const fb = this.static.fb
            const width = this.getCalcs.vw
            const height = this.getCalcs.vh
            const attributes = this.static.shaders.attributes
            const uniforms = this.static.shaders.uniforms
            const mouse = this.static.shaders.mouse
            const fr = this.static.fr

            this.$el.width = width
            this.$el.height = height

            const bufferA = this.setCreateFramebuffer()

            gl.viewport(0, 0, width, height)
            gl.clearColor(0.0, 0.0, 0.0, 0.0)
            gl.clear(gl.COLOR_BUFFER_BIT)

            gl.enableVertexAttribArray(attributes.a_position)
            gl.vertexAttribPointer(attributes.a_position, 2, gl.FLOAT, false, 0, 0)
            gl.uniform2f(uniforms.u_size, width, height)
            gl.uniform1f(uniforms.u_time, window.performance.now() / 3000)
            gl.uniform1i(uniforms.u_frame, fr)
            gl.drawArrays(gl.TRIANGLES, 0, 6)

            gl.bindTexture(gl.TEXTURE_2D, bufferA.texture)
            gl.bindFramebuffer(gl.FRAMEBUFFER, null)

            gl.viewport(0, 0, width, height)
            gl.clearColor(0.0, 0.0, 0.0, 0.0)
            gl.clear(gl.COLOR_BUFFER_BIT)

            gl.enableVertexAttribArray(attributes.a_position)
            gl.vertexAttribPointer(attributes.a_position, 2, gl.FLOAT, false, 0, 0)
            gl.uniform2f(uniforms.u_size, width, height)
            gl.uniform1f(uniforms.u_time, window.performance.now() / 3000)
            gl.uniform1i(uniforms.u_frame, fr)
            gl.uniform1i(uniforms.u_texture, 0)
            gl.drawArrays(gl.TRIANGLES, 0, 6)

            this.static.fr++
        
    


</script>

我现在更进一步,下面的代码正在运行

<template lang='pug'>

    canvas

</template>

<script>

import  mapGetters  from 'vuex'

import forEach from 'lodash/forEach'

export default 
    name: 'webGl',
    created ()
    
        this.static = 
            af: null,
            gl: null,
            fr: 0,
            shaders:
            
                noise:
                
                    vertex: `
                    attribute vec2 a_position;

                    void main() 
                        gl_Position = vec4(a_position, 0, 1);
                    `,
                    fragment: `
                    #ifdef GL_ES
                    precision mediump float;
                    #endif

                    uniform vec2 u_size;

                    vec2 hash( vec2 p ) 
                        p = vec2( dot(p,vec2(127.1,311.7)),
                        dot(p,vec2(269.5,183.3)));

                        return -1.0 + 2.0 * fract(sin(p) * 43758.5453123);
                    

                    float noise( vec2 p ) 

                        const float K1 = 0.366025404;
                        const float K2 = 0.211324865;

                        vec2 i = floor(p + (p.x + p.y) * K1);
                        vec2 a = p - i + (i.x + i.y) * K2;
                        vec2 o = step(a.yx, a.xy);
                        vec2 b = a - o + K2;
                        vec2 c = a - 1.0 + 2.0 * K2;

                        vec3 h = max(0.5 - vec3(dot(a,a), dot(b,b), dot(c,c)), 0.0);

                        vec3 n = h * h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));

                        return dot(n, vec3(70.0));
                    

                    void main( void ) 
                        vec2 vUv = gl_FragCoord.xy / u_size.xy;
                        vec3 rnd = vec3(noise(16.0 * vUv + 1.1), noise(16.0 * vUv + 2.2), noise(16.0 * vUv + 3.3));
                        gl_FragColor = vec4(rnd, 1.0);
                    `,
                    program: null,
                    attributes:
                    
                        a_position: null
                    ,
                    uniforms:
                    
                        u_size: null
                    
                ,
                fluid:
                
                    vertex: `
                    attribute vec2 a_position;

                    void main() 
                        gl_Position = vec4(a_position, 0, 1);
                    `,
                    fragment: `
                    #ifdef GL_ES
                    precision mediump float;
                    #endif

                    uniform vec2 u_size;
                    uniform sampler2D u_image;

                    vec2 normz(vec2 x) 
                        return x == vec2(0.0, 0.0) ? vec2(0.0, 0.0) : normalize(x);
                    

                    vec3 advect(vec2 ab, vec2 vUv, vec2 step, float sc) 

                        vec2 aUv = vUv - ab * sc * step;

                        const float _G0 = 0.25; // center weight
                        const float _G1 = 0.125; // edge-neighbors
                        const float _G2 = 0.0625; // vertex-neighbors

                        // 3x3 neighborhood coordinates
                        float step_x = step.x;
                        float step_y = step.y;
                        vec2 n  = vec2(0.0, step_y);
                        vec2 ne = vec2(step_x, step_y);
                        vec2 e  = vec2(step_x, 0.0);
                        vec2 se = vec2(step_x, -step_y);
                        vec2 s  = vec2(0.0, -step_y);
                        vec2 sw = vec2(-step_x, -step_y);
                        vec2 w  = vec2(-step_x, 0.0);
                        vec2 nw = vec2(-step_x, step_y);

                        vec3 uv =    texture2D(u_image, fract(aUv)).xyz;
                        vec3 uv_n =  texture2D(u_image, fract(aUv+n)).xyz;
                        vec3 uv_e =  texture2D(u_image, fract(aUv+e)).xyz;
                        vec3 uv_s =  texture2D(u_image, fract(aUv+s)).xyz;
                        vec3 uv_w =  texture2D(u_image, fract(aUv+w)).xyz;
                        vec3 uv_nw = texture2D(u_image, fract(aUv+nw)).xyz;
                        vec3 uv_sw = texture2D(u_image, fract(aUv+sw)).xyz;
                        vec3 uv_ne = texture2D(u_image, fract(aUv+ne)).xyz;
                        vec3 uv_se = texture2D(u_image, fract(aUv+se)).xyz;

                        return _G0*uv + _G1*(uv_n + uv_e + uv_w + uv_s) + _G2*(uv_nw + uv_sw + uv_ne + uv_se);
                    

                    void main( void ) 

                        const float _K0 = -20.0/6.0; // center weight
                        const float _K1 = 4.0/6.0;   // edge-neighbors
                        const float _K2 = 1.0/6.0;   // vertex-neighbors
                        const float cs = -0.6;  // curl scale
                        const float ls = 0.05;  // laplacian scale
                        const float ps = -0.8;  // laplacian of divergence scale
                        const float ds = -0.05; // divergence scale
                        const float dp = -0.04; // divergence update scale
                        const float pl = 0.3;   // divergence smoothing
                        const float ad = 6.0;   // advection distance scale
                        const float pwr = 1.0;  // power when deriving rotation angle from curl
                        const float amp = 1.0;  // self-amplification
                        const float upd = 0.8;  // update smoothing
                        const float sq2 = 0.6;  // diagonal weight

                        vec2 vUv = gl_FragCoord.xy / u_size.xy;
                        vec2 texel = 1. / u_size.xy;

                        float step_x = texel.x;
                        float step_y = texel.y;
                        vec2 n  = vec2(0.0, step_y);
                        vec2 ne = vec2(step_x, step_y);
                        vec2 e  = vec2(step_x, 0.0);
                        vec2 se = vec2(step_x, -step_y);
                        vec2 s  = vec2(0.0, -step_y);
                        vec2 sw = vec2(-step_x, -step_y);
                        vec2 w  = vec2(-step_x, 0.0);
                        vec2 nw = vec2(-step_x, step_y);

                        vec3 uv =    texture2D(u_image, fract(vUv)).xyz;
                        vec3 uv_n =  texture2D(u_image, fract(vUv+n)).xyz;
                        vec3 uv_e =  texture2D(u_image, fract(vUv+e)).xyz;
                        vec3 uv_s =  texture2D(u_image, fract(vUv+s)).xyz;
                        vec3 uv_w =  texture2D(u_image, fract(vUv+w)).xyz;
                        vec3 uv_nw = texture2D(u_image, fract(vUv+nw)).xyz;
                        vec3 uv_sw = texture2D(u_image, fract(vUv+sw)).xyz;
                        vec3 uv_ne = texture2D(u_image, fract(vUv+ne)).xyz;
                        vec3 uv_se = texture2D(u_image, fract(vUv+se)).xyz;

                        vec3 lapl  = _K0*uv + _K1*(uv_n + uv_e + uv_w + uv_s) + _K2*(uv_nw + uv_sw + uv_ne + uv_se);
                        float sp = ps * lapl.z;

                        float curl = uv_n.x - uv_s.x - uv_e.y + uv_w.y + sq2 * (uv_nw.x + uv_nw.y + uv_ne.x - uv_ne.y + uv_sw.y - uv_sw.x - uv_se.y - uv_se.x);

                        float sc = cs * sign(curl) * pow(abs(curl), pwr);

                        float div  = uv_s.y - uv_n.y - uv_e.x + uv_w.x + sq2 * (uv_nw.x - uv_nw.y - uv_ne.x - uv_ne.y + uv_sw.x + uv_sw.y + uv_se.y - uv_se.x);
                        float sd = uv.z + dp * div + pl * lapl.z;

                        vec2 norm = normz(uv.xy);

                        vec3 ab = advect(vec2(uv.x, uv.y), vUv, texel, ad);

                        float ta = amp * ab.x + ls * lapl.x + norm.x * sp + uv.x * ds * sd;
                        float tb = amp * ab.y + ls * lapl.y + norm.y * sp + uv.y * ds * sd;

                        float a = ta * cos(sc) - tb * sin(sc);
                        float b = ta * sin(sc) + tb * cos(sc);

                        vec3 abd = upd * uv + (1.0 - upd) * vec3(a,b,sd);

                        abd.z = clamp(abd.z, -1.0, 1.0);
                        abd.xy = clamp(length(abd.xy) > 1.0 ? normz(abd.xy) : abd.xy, -1.0, 1.0);
                        gl_FragColor = vec4(abd, 0.0);
                    `,
                    program: null,
                    attributes:
                    
                        a_position: null
                    ,
                    uniforms:
                    
                        u_size: null
                    
                ,
                colorize:
                
                    vertex: `
                    attribute vec2 a_position;

                    void main() 
                        gl_Position = vec4(a_position, 0, 1);
                    `,
                    fragment: `
                    #ifdef GL_ES
                    precision mediump float;
                    #endif

                    uniform vec2 u_size;
                    uniform sampler2D u_image;

                    void main( void ) 
                        vec2 texel = 1. / u_size.xy;
                        vec2 uv = gl_FragCoord.xy / u_size.xy;
                        vec3 c = texture2D(u_image, uv).xyz;
                        vec3 norm = normalize(c);

                        vec3 div = vec3(0.1) * norm.z;
                        vec3 rbcol = 0.5 + 0.6 * cross(norm.xyz, vec3(0.5, -0.4, 0.5));

                        gl_FragColor = vec4(rbcol + div, 1.0);
                    `,
                    program: null,
                    attributes:
                    
                        a_position: null
                    ,
                    uniforms: 
                        u_size: null
                    
                
            ,
            textures:
            
                default: null
            
        
    ,
    mounted ()
    
        this.setInitWebGlContext()
        this.setInitGeometryBuffer()
        this.setInitShaderPrograms()
        this.setRenderLoop()
    ,
    beforeDestroy ()
    
        window.cancelAnimationFrame(this.static.af)
    ,
    computed:
    
        ...mapGetters([
            'getCalcs'
        ])
    ,
    methods:
    
        setInitWebGlContext ()
        
            this.static.gl = this.$el.getContext('webgl')

            if (this.static.gl === null)
            
                console.log('Unable to initialize WebGL. Your browser or machine may not support it.')
            
        ,
        setInitShaderPrograms ()
        
            const gl = this.static.gl

            forEach(this.static.shaders, shader =>
            
                shader.program = gl.createProgram()

                const vertexShader = gl.createShader(gl.VERTEX_SHADER)
                const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

                gl.shaderSource(vertexShader, shader.vertex)
                gl.shaderSource(fragmentShader, shader.fragment)

                gl.compileShader(vertexShader)
                gl.compileShader(fragmentShader)

                gl.attachShader(shader.program, vertexShader)
                gl.attachShader(shader.program, fragmentShader)

                gl.linkProgram(shader.program)
            )
        ,
        setInitGeometryBuffer ()
        
            const gl = this.static.gl
            const buffer = gl.createBuffer()

            gl.bindBuffer(this.static.gl.ARRAY_BUFFER, buffer)
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0]), gl.STATIC_DRAW)
        ,
        setDraw (width, height)
        
            const gl = this.static.gl

            gl.clearColor(0.0, 0.0, 0.0, 0.0)
            gl.clear(gl.COLOR_BUFFER_BIT)
            gl.viewport(0, 0, width, height)
            gl.drawArrays(gl.TRIANGLES, 0, 6)
        ,
        setProgram (shader)
        
            const gl = this.static.gl
            const program = this.static.shaders[shader].program
            const attributes = this.static.shaders[shader].attributes
            const uniforms = this.static.shaders[shader].uniforms

            gl.useProgram(program)

            forEach(attributes, (attribute, key) =>
            
                attributes[key] = gl.getAttribLocation(program, key)
            )

            forEach(uniforms, (uniform, key) =>
            
                uniforms[key] = gl.getUniformLocation(program, key)
            )
        ,
        setFrameBuffer (width, height)
        
            const gl = this.static.gl
            const texture = gl.createTexture()

            gl.bindTexture(gl.TEXTURE_2D, texture)
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

            const framebuffer = gl.createFramebuffer()

            gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)

            return 
                frameBuffer: framebuffer,
                texture: texture
            
        ,
        setNoise (width, height)
        
            const gl = this.static.gl
            const attributes = this.static.shaders.noise.attributes
            const uniforms = this.static.shaders.noise.uniforms

            gl.enableVertexAttribArray(attributes.a_position)
            gl.vertexAttribPointer(attributes.a_position, 2, gl.FLOAT, false, 0, 0)
            gl.uniform2f(uniforms.u_size, width, height)
        ,
        setFluid (width, height)
        
            const gl = this.static.gl
            const attributes = this.static.shaders.fluid.attributes
            const uniforms = this.static.shaders.fluid.uniforms

            gl.enableVertexAttribArray(attributes.a_position)
            gl.vertexAttribPointer(attributes.a_position, 2, gl.FLOAT, false, 0, 0)
            gl.uniform2f(uniforms.u_size, width, height)
        ,
        setColorize (width, height)
        
            const gl = this.static.gl
            const attributes = this.static.shaders.colorize.attributes
            const uniforms = this.static.shaders.colorize.uniforms

            gl.enableVertexAttribArray(attributes.a_position)
            gl.vertexAttribPointer(attributes.a_position, 2, gl.FLOAT, false, 0, 0)
            gl.uniform2f(uniforms.u_size, width, height)
        ,
        setRenderLoop ()
        
            this.static.af = window.requestAnimationFrame(this.setRenderLoop)

            const gl = this.static.gl
            const width = this.getCalcs.vw
            const height = this.getCalcs.vh

            this.$el.width = width
            this.$el.height = height

            if (!this.static.fr)
            
                const noiseBuffer = this.setFrameBuffer(width, height)

                this.setProgram('noise')
                this.setNoise(width, height)
                this.setDraw(width, height)

                this.static.textures.default = noiseBuffer.texture
            

            const fluidBuffer = this.setFrameBuffer(width, height)

            gl.bindTexture(gl.TEXTURE_2D, this.static.textures.default)

            this.setProgram('fluid')
            this.setFluid(width, height)
            this.setDraw(width, height)

            this.static.textures.default = fluidBuffer.texture

            gl.bindFramebuffer(gl.FRAMEBUFFER, null)

            this.setProgram('colorize')
            this.setColorize(width, height)
            this.setDraw(width, height)

            this.static.fr++
        
    


</script>

但是我正在尝试采用来自 shadertoy https://www.shadertoy.com/view/XddSRX 的着色器,如果我朗读我的代码,它的行为会非常不同。

【问题讨论】:

【参考方案1】:

问题与错误中所述完全相同。

绘制的源纹理和目标纹理相同。

查看您的代码,有一个着色器,它引用一个纹理,有一个纹理,它附加到帧缓冲区,并且默认绑定到纹理单元 0。因此,当您绘制它时,它同时用作输入 (u_texture) 和输出(当前帧缓冲区)。这是不允许的。

简单的解决方案是您需要另一个纹理。绘制到帧缓冲区时绑定该纹理。

更好的解决方案是您需要 2 个不同的着色器程序。一个用于绘制到不使用纹理作为输入的帧缓冲区,另一个用于绘制到画布。因为你有一个在u_frame 上分支的着色器。删除该分支并将事物分成 2 个着色器程序。一个计算颜色然后 u_frame

一些可能有用也可能没用的链接:drawing multiple things、render targets、image processing。

【讨论】:

以上是关于尝试从帧缓冲区传递纹理会导致 L_INVALID_OPERATION:glDrawArrays:绘制的源纹理和目标纹理相同的主要内容,如果未能解决你的问题,请参考以下文章

将视口渲染到纹理会产生重叠视口吗?

在 iOS 上的 OpenGL ES 着色器中混合多个纹理会导致反向行为

OpenGL:加载纹理会改变当前颜色

为啥从 FBO 解除绑定纹理会清除纹理?

OpenGL:如果我将新的纹理绑定到另一个目标,纹理会发生啥?

渲染 CCSprite 纹理会给出旧图像