2

Learning my first WebGL, attempting to draw an image (from url) on a canvas WebGL context.

My goal is to have a background image on the canvas with a transparent image on top, showing the background, to ultimately use captureStream.

While my shaders are compiling successfully (per gl.COMPILE_STATUS) it appears I'm missing a step to a valid program:

  const vs = gl.createShader(gl.VERTEX_SHADER)
  gl.shaderSource(vs, document.getElementById('draw-image-vertex-shader').innerText)
  gl.compileShader(vs)

  const fs = gl.createShader(gl.FRAGMENT_SHADER)
  gl.shaderSource(fs, document.getElementById('draw-image-fragment-shader').innerText)
  gl.compileShader(fs)

  var vs_success = gl.getShaderParameter(vs, gl.COMPILE_STATUS);
  console.log( vs_success )

  var fs_success = gl.getShaderParameter(fs, gl.COMPILE_STATUS);
  console.log( fs_success )

  const program = gl.createProgram()

  gl.useProgram(program)

I'm getting:

WebGL: INVALID_OPERATION: useProgram: program not valid

Here are the shaders:

<script id="draw-image-vertex-shader" type="glsl">
  attribute vec4 a_position;
  attribute vec2 a_texcoord;
  uniform mat4 u_matrix;
  varying vec2 v_texcoord;
  void main() {
     gl_Position = u_matrix * a_position;
     v_texcoord = a_texcoord;
  }
</script>
<script id="draw-image-fragment-shader" type="glsl">
  precision mediump float;
  varying vec2 v_texcoord;
  uniform sampler2D u_texture;
  void main() {
     gl_FragColor = texture2D(u_texture, v_texcoord);
  }
</script>

Any insight would be amazing, big thanks :)

2
  • Most likely there was an error compiling or linking the shader. You need to show us the shader code. Commented Apr 9, 2021 at 17:04
  • Done! All I'm really trying to do is put an image as the background in cover:fit style fashion, but getting held up on just getting an image on the canvas. The tutorials out there are old and missing a lot of assets. Thanks for any insight :) Commented Apr 9, 2021 at 17:25

1 Answer 1

2

You have to attach the shders to the program object and you must link the program object:

const vs = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vs, document.getElementById('draw-image-vertex-shader').innerText)
gl.compileShader(vs)
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) 
    console.log(gl.getShaderInfoLog(vs));

const fs = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fs, document.getElementById('draw-image-fragment-shader').innerText)
gl.compileShader(fs)
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) 
    console.log(gl.getShaderInfoLog(fs));

const program = gl.createProgram()
gl.attachShader(program, vs)
gl.attachShader(program, fs)

gl.linkProgram(program)
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) 
    console.log(gl.getProgramInfoLog(program))

gl.useProgram(program)
Sign up to request clarification or add additional context in comments.

1 Comment

Nice - we can ` console.log(gl.getProgramInfoLog(program))` collect logs !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.