javascriptframebufferregl

How to write to a framebuffer in regl?


I am trying to update the texture inside a framebuffer in REGL. But for some reason, it does not update the framebuffer.

here is the full code:

const regl = createREGL({
  extensions: 'OES_texture_float'
})

const initialTexture = regl.texture([
  [
    [0, 255, 0, 255]
  ]
])

const fbo = regl.framebuffer({
  color: initialTexture,
  depth: false,
  stencil: false,
})

const updateColor = regl({
  framebuffer: () => fbo,
  vert: `
    precision mediump float;
		
    attribute vec2 position;

    void main() {
      gl_Position = vec4(position, 0.0, 1.0);
    }
	`,
  frag: `
    precision mediump float;

    void main() {
      gl_FragColor = vec4(255.0, 0.0, 0.0, 255.0);
    }
	`,
  attributes: {
    // a triangle big enough to fill the screen
    position: [
     -4, 0,
      4, 4,
      4, -4
    ],
  },

  count: 3,
})

regl.clear({
  // background color (black)
  color: [0, 0, 0, 1],
  depth: 1,
});

updateColor(() => {
  console.log(regl.read())
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/regl/1.3.11/regl.min.js"></script>

What am I doing wrong?


Solution

  • Apparently if you provide a function to a regl command then you have to manually draw

    updateColor(() => {
      regl.draw();   // manually draw
      console.log(regl.read())
    });
    

    I guess the point is if you provided a function then you're asking to customize stuff?

    const regl = createREGL({
      extensions: 'OES_texture_float'
    })
    
    const initialTexture = regl.texture([
      [
        [0, 255, 0, 255]
      ]
    ])
    
    const fbo = regl.framebuffer({
      color: initialTexture,
      depth: false,
      stencil: false,
    })
    
    const updateColor = regl({
      framebuffer: () => fbo,
      vert: `
        precision mediump float;
    		
        attribute vec2 position;
    
        void main() {
          gl_Position = vec4(position, 0.0, 1.0);
        }
    	`,
      frag: `
        precision mediump float;
    
        void main() {
          gl_FragColor = vec4(255.0, 0.0, 0.0, 255.0);
        }
    	`,
      // Here we define the vertex attributes for the above shader
      attributes: {
        // regl.buffer creates a new array buffer object
        position: regl.buffer([
          [-2, -2],   // no need to flatten nested arrays, regl automatically
          [4, -2],    // unrolls them into a typedarray (default Float32)
          [4,  4]
        ])
        // regl automatically infers sane defaults for the vertex attribute pointers
      },
      count: 3,
    })
    
    regl.clear({
      // background color (black)
      color: [0, 0, 0, 1],
      depth: 1,
    });
    
    updateColor(() => {
      regl.draw();
      console.log(regl.read())
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/regl/1.3.11/regl.js"></script>

    As for how I found the answer I first checked that drawArrays and/or drawElements was being called by adding

    WebGLRenderingContext.prototype.drawArrays = function() {
      console.log('drawArrays');
    }
    

    and similar for drawElements and I saw that it was never being called.

    I tried the sample in the regl readme and it did.

    Then I stepped though the code in the debugger, it wasn't that deep to see it never called drawXXX but if removed the function from updateColor it did call drawXXX. As for how to know that regl.draw() would fix it that was a guess. It is mentioned in the docs but it's not clear that's what's right to do