javascriptglslrenderingwebglwebgl2

WebGL not displaying my triangle despite no errors or warnings


WebGL not even rendering my triangle that I want its not giving me any errors or anything..

I've tried changing the order of how I do the inputs and rewriting the shader code multiple times. I'm just trying to draw a triangle.

Here are some snippets of the code I am using

My Vertex Shader

    attribute vec4 a_position;
    attribute vec4 a_color;
    varying vec4 v_color;

    void main()
    {
        v_color = a_color;
        gl_Position = a_position;
    }

My Fragment Shader

    attribute vec4 a_position;
    attribute vec4 a_color;
    varying vec4 v_color;

    void main()
    {
        v_color = a_color;
        gl_Position = a_position;
    }

the Draw function

function drawTri(x1,y1,x2,y2,x3,y3){
    const a_position = new Float32Array([x1,y1,0,1,x2,y2,0,1,x3,y3,0,1]);

    const a_color = new Float32Array([
      testColor[0],testColor[1],testColor[2],testColor[3],
      testColor[0],testColor[1],testColor[2],testColor[3],
      testColor[0],testColor[1],testColor[2],testColor[3]
    ]);

    gl.useProgram(myShaders.untextured.ProgramInf.program);
    gl.viewport(0, 0, 630, 360);

    //? Bind Positional Data
    gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);

    gl.bufferData(gl.ARRAY_BUFFER, a_position, gl.STATIC_DRAW);

    gl.enableVertexAttribArray(a_position_Location);

    gl.vertexAttribPointer(a_position_Location, 4, gl.FLOAT, false, 0, 0);

    //? Bind Color Data
    gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer);

    gl.bufferData(gl.ARRAY_BUFFER, a_color, gl.STATIC_DRAW);

    gl.enableVertexAttribArray(a_color_Location);

    gl.vertexAttribPointer(a_color_Location, 4, gl.FLOAT, false, 0, 0);

    gl.drawArrays(gl.TRIANGLES, 0, 3);
}

testColor is defined as

const testColor = [0,0,1,1];

Stack Snippet

const canvas = document.createElement("canvas"); //! getting so mad at this stuff rn that I'm just going to make a fake canvas that renders the real canvas ontop of it.
const gl =
  canvas.getContext("webgl2") ||
  canvas.getContext("experimental-webgl") ||
  canvas.getContext("webgl");
canvas.width = 480;
canvas.height = 360;

gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

//Get Shaders
const myShaders = {
  untextured: {
    Shaders: {
      vert: `
                precision highp float;
                attribute vec4 a_position;
                attribute vec4 a_color;
                varying vec4 v_color;

                void main()
                {
                  v_color = a_color;
                  gl_Position = a_position;
                }
            `,
      frag: `
                precision highp float;
                varying vec4 v_color;

                void main()
                {
                  gl_FragColor = vec4(0,0,1,1);
                }
            `,
    },
    ProgramInf: null,
  },
  /*textured: {
    Shaders: {},
    ProgramInf: null,
  },*/ //todo Later
  createAndCompileShaders: (vert, frag) => {
    //? compile vertex Shader
    const vertShader = gl.createShader(gl.VERTEX_SHADER);
    try {
      gl.shaderSource(vertShader, vert.trim());
      gl.compileShader(vertShader);
      if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
        throw gl.getShaderInfoLog(vertShader);
      }
    } catch (error) {
      console.error(error);
    }

    //? compile fragment Shader
    const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    try {
      gl.shaderSource(fragShader, frag.trim());
      gl.compileShader(fragShader);
      if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
        throw gl.getShaderInfoLog(fragShader);
      }
    } catch (error) {
      console.error(error);
    }

    //? compile program
    const program = gl.createProgram();
    try {
      gl.attachShader(program, vertShader);
      gl.attachShader(program, fragShader);
      gl.linkProgram(program);
      if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        throw gl.getProgramInfoLog(program);
      }

      gl.validateProgram(program);
      if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) {
        throw gl.getProgramInfoLog(program);
      }
    } catch (error) {
      console.error(error);
    }

    return {
      program: program,
      vert: vertShader,
      frag: fragShader,
    };
  },
};

myShaders.untextured.ProgramInf = myShaders.createAndCompileShaders(
  myShaders.untextured.Shaders.vert,
  myShaders.untextured.Shaders.frag
);

const a_position_Location = gl.getAttribLocation(
  myShaders.untextured.ProgramInf.program,
  "a_position"
);
const a_color_Location = gl.getAttribLocation(
  myShaders.untextured.ProgramInf.program,
  "a_color"
);

console.log(a_position_Location, a_color_Location);

document.body.appendChild(canvas);

const positionBuffer = gl.createBuffer();

//predefine penColor's postion so we don't have to call it as much.
const penColor = [0, 0, 1, 1];

const drawTri = (x1, y1, x2, y2, x3, y3) => {
  const a_position = new Float32Array([
    x1,
    y1,
    1,
    1,
    penColor[0],
    penColor[1],
    penColor[2],
    penColor[3],
    x2,
    y2,
    1,
    1,
    penColor[0],
    penColor[1],
    penColor[2],
    penColor[3],
    x3,
    y3,
    1,
    1,
    penColor[0],
    penColor[1],
    penColor[2],
    penColor[3],
  ]);

  gl.useProgram(myShaders.untextured.ProgramInf.program);
  gl.viewport(0, 0, 480, 360);

  //? Bind Positional Data

  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  gl.bufferData(
    gl.ARRAY_BUFFER,
    a_position,
    gl.STATIC_DRAW
  );

  gl.vertexAttribPointer(
    a_position_Location,
    4,
    gl.FLOAT,
    false,
    4 * Float32Array.BYTES_PER_ELEMENT,
    0
  );
  gl.vertexAttribPointer(
    a_color_Location,
    4,
    gl.FLOAT,
    false,
    4 * Float32Array.BYTES_PER_ELEMENT,
    4 * Float32Array.BYTES_PER_ELEMENT
  );

  gl.enableVertexAttribArray(a_position_Location);
  gl.enableVertexAttribArray(a_color_Location);

  gl.useProgram(myShaders.untextured.ProgramInf.program);
  console.log(
    gl.getProgramInfoLog(myShaders.untextured.ProgramInf.program)
  );
  gl.drawArrays(gl.TRIANGLES, 0, 3);
};

drawTri(0, 0, 0.5, 0.5, 0, 0.5);


Solution

  • The problem in your code is that you specified the stride for the vertexAttribPointer(doc) incorrectly. In your original code (not the one in the snippet) it'd need to be the size of the attribute in bytes so NUM_COMPONENTS * BYTES_PER_COMPONENT, where NUM_COMPONENTS is 4 (x,y,z,w) and BYTES_PER_COMPONENT is 4 as you're using 32 bit floats. In your newly added snippet code you use an interleaved buffer so it needs to be the size of a whole vertex in bytes.

    In addition to setting the proper stride I renamed your buffer variables to reflect that it's a single interleaved buffer.

    const canvas = document.createElement("canvas"); //! getting so mad at this stuff rn that I'm just going to make a fake canvas that renders the real canvas ontop of it.
    const gl =
      canvas.getContext("webgl2") ||
      canvas.getContext("experimental-webgl") ||
      canvas.getContext("webgl");
    canvas.width = 480;
    canvas.height = 360;
    
    gl.clearColor(0, 0, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    
    //Get Shaders
    const myShaders = {
      untextured: {
        Shaders: {
          vert: `
                    precision highp float;
                    attribute vec4 a_position;
                    attribute vec4 a_color;
                    varying vec4 v_color;
    
                    void main()
                    {
                      v_color = a_color;
                      gl_Position = a_position;
                    }
                `,
          frag: `
                    precision highp float;
                    varying vec4 v_color;
    
                    void main()
                    {
                      gl_FragColor = v_color;
                    }
                `,
        },
        ProgramInf: null,
      },
      /*textured: {
        Shaders: {},
        ProgramInf: null,
      },*/ //todo Later
      createAndCompileShaders: (vert, frag) => {
        //? compile vertex Shader
        const vertShader = gl.createShader(gl.VERTEX_SHADER);
        try {
          gl.shaderSource(vertShader, vert.trim());
          gl.compileShader(vertShader);
          if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {
            throw gl.getShaderInfoLog(vertShader);
          }
        } catch (error) {
          console.error(error);
        }
    
        //? compile fragment Shader
        const fragShader = gl.createShader(gl.FRAGMENT_SHADER);
        try {
          gl.shaderSource(fragShader, frag.trim());
          gl.compileShader(fragShader);
          if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {
            throw gl.getShaderInfoLog(fragShader);
          }
        } catch (error) {
          console.error(error);
        }
    
        //? compile program
        const program = gl.createProgram();
        try {
          gl.attachShader(program, vertShader);
          gl.attachShader(program, fragShader);
          gl.linkProgram(program);
          if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            throw gl.getProgramInfoLog(program);
          }
    
          gl.validateProgram(program);
          if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) {
            throw gl.getProgramInfoLog(program);
          }
        } catch (error) {
          console.error(error);
        }
    
        return {
          program: program,
          vert: vertShader,
          frag: fragShader,
        };
      },
    };
    
    myShaders.untextured.ProgramInf = myShaders.createAndCompileShaders(
      myShaders.untextured.Shaders.vert,
      myShaders.untextured.Shaders.frag
    );
    
    const a_position_Location = gl.getAttribLocation(
      myShaders.untextured.ProgramInf.program,
      "a_position"
    );
    const a_color_Location = gl.getAttribLocation(
      myShaders.untextured.ProgramInf.program,
      "a_color"
    );
    
    console.log(a_position_Location, a_color_Location);
    
    document.body.appendChild(canvas);
    
    const vertexBuffer = gl.createBuffer();
    
    //predefine penColor's postion so we don't have to call it as much.
    const penColor = [0, 0, 1, 1];
    
    const drawTri = (x1, y1, x2, y2, x3, y3) => {
      const vertexBufferData = new Float32Array([
        x1,
        y1,
        1,
        1,
        penColor[0],
        penColor[1],
        penColor[2],
        penColor[3],
        x2,
        y2,
        1,
        1,
        penColor[0],
        penColor[1],
        penColor[2],
        penColor[3],
        x3,
        y3,
        1,
        1,
        penColor[0],
        penColor[1],
        penColor[2],
        penColor[3],
      ]);
    
      gl.useProgram(myShaders.untextured.ProgramInf.program);
      gl.viewport(0, 0, 480, 360);
    
      //? Bind Positional Data
    
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
      gl.bufferData(
        gl.ARRAY_BUFFER,
        vertexBufferData,
        gl.STATIC_DRAW
      );
    
      gl.vertexAttribPointer(
        a_position_Location,
        4,
        gl.FLOAT,
        false,
        8 * Float32Array.BYTES_PER_ELEMENT,
        0
      );
      gl.vertexAttribPointer(
        a_color_Location,
        4,
        gl.FLOAT,
        false,
        8 * Float32Array.BYTES_PER_ELEMENT,
        4 * Float32Array.BYTES_PER_ELEMENT
      );
      gl.enableVertexAttribArray(a_position_Location);
      gl.enableVertexAttribArray(a_color_Location);
    
      gl.useProgram(myShaders.untextured.ProgramInf.program);
      gl.drawArrays(gl.TRIANGLES, 0, 3);
    };
    
    drawTri(0, 0, 0.5, 0.5, 0, 0.5);