Question

I am trying to make a simple application in WebGl and JavaScript, and while fallowing some tutorials I found on the internet, I came across a strange problem while creating some basic shaders. The function which creates the shader program looks like this :

 this.CreateShaderProgram = function(vertexShader, fragmentShader)
  {
    var tmp = this.gl.createProgram();

    var tempVert = this.gl.createShader(this.gl.VERTEX_SHADER);     
    this.gl.shaderSource(tempVert, vertexShader);
    this.gl.compileShader(tempVert);
    if(!this.gl.getShaderParameter(tempVert, this.gl.COMPILE_STATUS)) {
          this.Log("invalid shader : " + vertexShader);
          return null;
    };

    var tempFrag = this.gl.createShader(this.gl.FRAGMENT_SHADER); 
    this.gl.shaderSource(tempFrag, fragmentShader);
    this.gl.compileShader(tempFrag);    
    if(!this.gl.getShaderParameter(tempFrag, this.gl.COMPILE_STATUS)) {
          this.Log("invalid shader : " + fragmentShader);
          return null;
    };

    this.gl.attachShader(tmp, tempVert);
    this.gl.attachShader(tmp, tempFrag);

    return tmp;
  }

And the 2 shaders look like :

  attribute vec3 aVertexPosition;
  uniform mat4 uMVMatrix;
  uniform mat4 uPMatrix;
  void main(void) {
         gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
  }
  --------------------------------------------  

  #ifdef GL_ES  precision highp float;
  #endif
  void main(void) { 
  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);  };

The strange thing is that the first Vertex Shader compiles successfully, but for for the fragment shader it crashes on the "this.gl.compileShader(tempFrag);" line and I can't figure out why.

Was it helpful?

Solution

This snippet from your code:

#ifdef GL_ES  precision highp float;
#endif

Should be on separate lines:

#ifdef GL_ES
precision highp float;
#endif

This is because the shading language uses a preprocessor, much like the C Preprocessor. lines that start with # are preprocessor directives, that span the entire line. Whereas the precision statement is not; it is just a normal statement in GLSL. Putting them on the same line confuses the preprocessor, because it considers the precision statement as part of its directive.

Zecc's advice to use getShaderInfoLog is also invaluable for debugging these kinds of problems.

OTHER TIPS

If you don't know why it's not compiling, then change your code like this:

this.gl.compileShader(tempFrag);    
if(!this.gl.getShaderParameter(tempFrag, this.gl.COMPILE_STATUS)) {
      this.Log("invalid shader : " + this.gl.getShaderInfoLog(tempFrag));
      return null;
};

This should give you more information on what is wrong (possibly the use of #ifdef)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top