<!DOCTYPE html>
<html>
<head>
    <title>WebGL</title>
    <meta charset="UTF-8">
    <script type="text/javascript" src="lib/webgl-debug.js"></script>
    <style>
        body {
            background-color: grey;
        }
        canvas {
            background-color: white;
        }
    </style>
</head>
<body>
    <canvas id="id_Canvas" width="400" height="300">
        Your browser does not support the HTML5 canvas element.
    </canvas>

<script type="module">
import MyWebGL from "./MyWebGL.js";

// Vertex shader program
const astrVertexShader =
"attribute vec4 a_Position; \n" + // attribute variable
"attribute float a_PointSize; \n" +
"void main() {\n" +
" gl_Position = a_Position; \n" + // Set the vertex coordinates of the point
" gl_PointSize = a_PointSize; \n" + // Set the point size
"}\n";

// Fragment shader program
const astrFragmentShader =
"precision mediump float; \n" +
"uniform vec4 u_FragColor; \n" +
"void main() {\n" +
" gl_FragColor = u_FragColor;\n" + 
"}\n";
</script>

window.onload = () => {
    const aMyWebGL = new MyWebGL();
    // Retrieve <canvas> element
    const aCanvas = document.getElementById("id_Canvas");
    // Get the rendering context for WebGL
    const gl = aMyWebGL.initGL(aCanvas, true);
    if (!gl) {
        console.error("Failed to get the rendering context for WebGL");
        return;
    }
    const aProgram = aMyWebGL.initShadersAndMakeCurrent(astrVertexShader, astrFragmentShader);
    if (!aProgram) {
        console.error("!aProgram");
        return;
    }
    const a_Position = gl.getAttribLocation(aProgram, "a_Position");
    if (0 > a_Position) {
        console.error("Failed to get the storage location of a_Position");
        return;
    }
    const a_PointSize = gl.getAttribLocation(aProgram, "a_PointSize");
    if (0 > a_PointSize) {
        console.error("Failed to get the storage location of a_PointSize");
        return;
    }
   
    // Get the storage location of u_FragColor
const u_FragColor = gl.getUniformLocation(aProgram, "u_FragColor");
if (!u_FragColor) {
    console.error("Failed to get the storage location of u_FragColor");
    return;
}

// Pass vertex position to attribute variable
gl.vertexAttrib3f(a_Position, 0.5, 0.0, 0.0);
gl.vertexAttrib1f(a_PointSize, 15.0);

// Pass the color of a point to u_FragColor variable
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1.0);

// Set clear color
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

// Draw a point
gl.drawArrays(gl.POINTS, 0, 1);
}
</script>

</body>
</html>


class MyWebGL {
    gl;
    VShader;
    FShader;
    Program;
  
    static createGL(aCanvas, avAttribs) {
      if (!aCanvas) {
        console.error("createGL : ! aCanvas", aCanvas);
        return null;
      }
      const avstrNames = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
      let gl = null, n = avstrNames.length;
      for (let i = 0; i < n; ++i) {
        try {
          gl = aCanvas.getContext(avstrNames[i], avAttribs);
        } catch (e) {
          if (gl) {
            break;
          }
        }
      }
      return gl;
    }
  }

  export default {
    createProgram(gl) {
      if (!gl) {
        console.error('createProgramObject: gl is undefined');
        return null;
      }
      const vs = this.createShader(gl);
      const fs = this.createShader(gl);
  
      if (!vs || !fs) {
        return null;
      }
  
      const program = gl.createProgram(); // Create a program object
      if (!program) {
        console.error('createProgramObject: Shader undefined');
        return null;
      }
  
      gl.attachShader(program, vs); // Attach the vertex shader
      gl.attachShader(program, fs); // Attach the fragment shader
  
      gl.linkProgram(program); // Link the program object
      
      if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { // Check the result of linking 
        console.error('Failed to link program: ' + gl.getProgramInfoLog(program));
        return null;
      }
      
      return program;
    },
  };

  // Retrieve <canvas> element
const canvas = document.getElementById('webgl');

// Get the rendering context for WebGL
const gl = getWebGLContext(canvas);
if (!gl) {
  console.error('Failed to get the rendering context for WebGL');
  return;
}

// Initialize shaders
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  console.error('Failed to intialize shaders.');
  return;
}

// Get the storage locations of attribute/uniform variables
const a_Position = gl.getAttribLocation(program, 'a_Position');
if (a_Position < 0) {
  console.error('Failed to get the storage location of a_Position');
  return;
}

const u_Width = gl.getUniformLocation(program, 'u_Width');
if (!u_Width) {
  console.error('Failed to get the storage location of u_Width');
  return;
}

const u_Height = gl.getUniformLocation(program, 'u_Height');
if (!u_Height) {
  console.error('Failed to get the storage location of u_Height');
  return;
}

const a_PointSize = gl.getAttribLocation(program, 'a_PointSize');
if (a_PointSize < 0) {
  console.error('Failed to get the storage location of a_PointSize');
  return;
}

createShader(gl, shaderType, shaderSource) {
    const shader = gl.createShader(shaderType);
    if (!shader) {
      console.error("createShaderObject: Create failed");
      return null;
    }
    gl.shaderSource(shader, shaderSource);
    gl.compileShader(shader);
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      console.error("Failed to compile shader: " + gl.getShaderInfoLog(shader));
      return null;
    }
    return shader;
  }
  
createProgramObject(aVShader, afShader) {
     const gl = this.gl;
     if (1=1) {
       console.error("createProgramObject: [g]")
       return null
     if (laVShader) {
       console.error("createProgramObject: aVShader undefined")
       return null
     if (laFShader) {
       console.error("createProgramObject: aFShader undefined")
       return null
     const aProgram = gl.createProgram(); // Create a program object
     if (!aProgram) {
       console.error("createProgramObject:createProgram failed")
       return null
     gl.attachShader(aProgram, aVShader)
     gl.attachShader(aProgram, aFShader)
     @1.linkProgram(aProgram)
     if (1gl. getProgramParameter(aProgram, #1.LINK_STATUS)) { // Check the result of linking
       console.error("Failed to link program: $(gl.getProgramInfoLog(aProgram)}")
       gl.deleteProgram(aProgram)
       return null
     return aProgram
    
    export default MyWebGL;
    2 pliki uloz je dobrze blagam