0
votes

I'm trying to draw to a texture, so that the rendering keeps getting compounded on top of each other. I'm using two textures and two framebuffers. texture[0] is attached to framebuffer[0], and texture[1] is attached to framebuffer[1].

    var gl = webgl.context;

    gl.useProgram(this.program);

    gl.bindTexture(gl.TEXTURE_2D, this.texture[this.pingpong]);
    this.pingpong = (this.pingpong==0?1:0);
    var pp = this.pingpong;

    gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer[pp]);

    gl.drawArrays(gl.TRIANGLES, 0, 6);              //primitiveType, offset, count

    gl.bindTexture(gl.TEXTURE_2D, this.texture[pp]);        //bind to the texture we just drew to
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);               //render the above texture to the canvas

    gl.drawArrays(gl.TRIANGLES, 0, 6);

The issue, is that I'm not seeing the previous renders get saved into the textures. I thought that bindframebuffer() would make it render to the texture. my fragment shader:

precision mediump float;                                    // fragment shaders don't have a default precision so we need to pick one. mediump is a good default

    varying vec2 v_texCoord;                                    // the texCoords passed in from the vertex shader.

    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;

    uniform sampler2D u_image;                              // this isn't set, so it will default to 0 (the current active texture)
void main() {       

        vec4 texColor = texture2D(u_image, v_texCoord);         // Look up a color from the texture.

        vec2 coord = vec2(gl_FragCoord.x,u_resolution.y-gl_FragCoord.y);

        vec4 color = step(distance(coord,u_mouse),100.0)*vec4(1,0,0,1) + step(100.0,distance(coord,u_mouse))*texColor;


        gl_FragColor = color;                   // gl_FragColor is a special variable a fragment shader is responsible for setting
    }

u_image is set to default 0, the active texture.

Is there something I'm overlooking? Why won't the previous renders get compounded on top of each other? It is just showing the latest render as if the textures haven't been altered.

here is the vertex shader:

precision mediump float;

    attribute vec2 a_position;                                  // an attribute will receive data from a buffer
    attribute vec2 a_texCoord;
    varying vec2 v_texCoord;                                    // a varying 
    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;
    uniform float u_flip;

    // all shaders have a main function
    void main() {
        v_texCoord = a_texCoord;                                // pass the texCoord to the fragment shader.The GPU will interpolate this value between points

        vec2 zeroToOne = a_position / u_resolution;     // convert the position from pixels to 0.0 to 1.0
        vec2 zeroToTwo = zeroToOne * 2.0;               // convert from 0->1 to 0->2
        vec2 clipSpace = zeroToTwo - 1.0;                   // convert from 0->2 to -1->+1 (clipspace)

        // gl_Position is a special variable a vertex shader is responsible for setting
        gl_Position = vec4(clipSpace * vec2(1, u_flip), 0, 1);
    }
2
Can you explain on what you expect the shader to do? Draw a red (+ color from another texture) circle around the mouse cursor? - WacławJasper
yes, it draws a red circle around the mouse cursor when I move the mouse. I want it to keep the previous draws, but it isn't doing it for some reason, so I only get a red circle and not a series of circles where the mouse has moved from. I am using two textures and two framebuffers that I thought could be used to draw the circle to, and then alternate between them so that it keeps the previous drawings, but it's not working. I don't understand why. - user3591153
what concerns me is that it appears as if the textures aren't preserving their data. If I am drawing to them when I bind the framebuffer, then afterwards when I bind the texture to get the color, it should have the previous rendered image, right? yet when I read their color, it doesn't appear to have what was rendered previously- it's just blank. - user3591153
if I try that, it looks the same- just a red circle around the mouse. - user3591153
I updated post with vertex shader code, in the case someone might see error in it? - user3591153

2 Answers

0
votes

I tried to emulate what you are doing:

loop.flexStep = function(){
    gl.clear(gl.COLOR_BUFFER_BIT);

    pingPong.pingPong().applyPass( //pingPong() just swaps the FBOs and return the current FBO being draw to
        "outColor += src0 * 0.98;",
        pingPong.otherTexture() // the src0 texture
    );
    points.drawPoint([mouse.x, mouse.y, 0 ]);
    points.renderAll(camera); 

    screenBuffer.applyPass(
        "outColor = src0;",
        pingPong.resultFBO  // src0
    );
};

Here is what it looks like (gl.POINTS instead of circle): enter image description here

Here are the gl commands: enter image description here

You should check if your framebuffers are setup correctly first. Since that part isnt shown its hard to say.

Also consider to separate your shader. You should have one shader in the pingpong stage to copy/alter the result of previous texture to the current pingPong FBO texture. And another shader to draw the new stuff to the current pingPong FBO texture.

0
votes

Issue seemed to be with getting the wrong texture coordinate and also flipping the texture. It's working as expected now.

here's the updated vertex/fragment shaders:

this.vertex = `
    precision mediump float;

    attribute vec2 a_position;                                  // an attribute will receive data from a buffer
    attribute vec2 a_texCoord;
    varying vec2 v_texCoord;                                    // a varying 
    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;
    uniform float u_flip;

    // all shaders have a main function
    void main() {
        v_texCoord = a_texCoord / u_resolution;                             // pass the texCoord to the fragment shader.The GPU will interpolate this value between points

        vec2 zeroToOne = a_position / u_resolution;     // convert the position from pixels to 0.0 to 1.0
        vec2 zeroToTwo = zeroToOne * 2.0;               // convert from 0->1 to 0->2
        vec2 clipSpace = zeroToTwo - 1.0;                   // convert from 0->2 to -1->+1 (clipspace)

        // gl_Position is a special variable a vertex shader is responsible for setting
        gl_Position = vec4(clipSpace * vec2(1, u_flip), 0, 1);
    }

`;

this.fragment = ` 

    precision mediump float;                                    // fragment shaders don't have a default precision so we need to pick one. mediump is a good default

    varying vec2 v_texCoord;                                    // the texCoords passed in from the vertex shader.

    uniform vec2 u_resolution;                                  // a uniform
    uniform vec2 u_mouse;
    uniform float u_flip;

    uniform sampler2D u_image;                              // this isn't set, so it will default to 0 (the current active texture)
    uniform sampler2D u_texture0;
    uniform sampler2D u_texture1;

    void main() {       

        vec4 texColor = texture2D(u_image, v_texCoord);         // Look up a color from the texture.

        vec2 coord = vec2(gl_FragCoord.x, step(0.0,u_flip)*gl_FragCoord.y + step(u_flip,0.0)*(u_resolution.y-gl_FragCoord.y) );

        vec4 color = step(distance(coord,u_mouse),100.0)*vec4(1,0,0,1) + step(100.0,distance(coord,u_mouse))*texColor;


        gl_FragColor = color;                   // gl_FragColor is a special variable a fragment shader is responsible for setting
    }

`;