D
D
Dimka52018-01-10 00:02:55
JavaScript
Dimka5, 2018-01-10 00:02:55

Why does the vertexAttribPointer function work like this?

Why in WebGL Lesson 1 - Triangle and Square If you rearrange the gl.vertexAttribPointer function in the buffer initialization block, the triangle will not be displayed as it should as a result. What else does this function do that it should be in that place or some other one affects it? After all, it essentially sets the memory area where the buffer data is located (or I'm wrong), so why not use it immediately during initialization and not call it every time when rendering each frame.
Is it possible to do something to move this function, as in the code below, to the buffer initialization block, so that the triangle is displayed correctly?
Here is the complete working code. Unlike the original , it differs only in the position of the lines with the function
gl.vertexAttribPointer

My code
<html>

<head>
  <title>WebGL Урок 1 Демо</title>
  <meta charset="UTF-8">

  <script type="text/javascript" src="http://devburn.ru/wp-includes/js/glMatrix-0.9.5.min.js"></script>

  <script id="shader-fs" type="x-shader/x-fragment">
    precision mediump float;

    void main(void) {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
</script>

  <script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;

    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    }
</script>


  <script type="text/javascript">

    var gl;
    function initGL(canvas) {
      try {
        gl = canvas.getContext("experimental-webgl");
        gl.viewportWidth = canvas.width;
        gl.viewportHeight = canvas.height;
      } catch (e) {
      }
      if (!gl) {
        alert("Could not initialise WebGL, sorry :-(");
      }
    }


    function getShader(gl, id) {
      var shaderScript = document.getElementById(id);
      if (!shaderScript) {
        return null;
      }

      var str = "";
      var k = shaderScript.firstChild;
      while (k) {
        if (k.nodeType == 3) {
          str += k.textContent;
        }
        k = k.nextSibling;
      }

      var shader;
      if (shaderScript.type == "x-shader/x-fragment") {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
      } else if (shaderScript.type == "x-shader/x-vertex") {
        shader = gl.createShader(gl.VERTEX_SHADER);
      } else {
        return null;
      }

      gl.shaderSource(shader, str);
      gl.compileShader(shader);

      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
      }

      return shader;
    }


    var shaderProgram;

    function initShaders() {
      var fragmentShader = getShader(gl, "shader-fs");
      var vertexShader = getShader(gl, "shader-vs");

      shaderProgram = gl.createProgram();
      gl.attachShader(shaderProgram, vertexShader);
      gl.attachShader(shaderProgram, fragmentShader);
      gl.linkProgram(shaderProgram);

      if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
      }

      gl.useProgram(shaderProgram);

      shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
      gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

      shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
      shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
    }


    var mvMatrix = mat4.create();
    var pMatrix = mat4.create();

    function setMatrixUniforms() {
      gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
      gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
    }



    var triangleVertexPositionBuffer;
    var squareVertexPositionBuffer;

    function initBuffers() {
      triangleVertexPositionBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
      var vertices = [
        0.0,  1.0,  0.0,
        -1.0, -1.0,  0.0,
        1.0, -1.0,  0.0
      ];
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
      triangleVertexPositionBuffer.itemSize = 3;
      triangleVertexPositionBuffer.numItems = 3;
      gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
     // ПРОБЛЕМА в перестановке строчки выше из функции отрисовки, почему тут она работает некорректно?

      squareVertexPositionBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
      vertices = [
        1.0,  1.0,  0.0,
        -1.0,  1.0,  0.0,
        1.0, -1.0,  0.0,
        -1.0, -1.0,  0.0
      ];
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
      squareVertexPositionBuffer.itemSize = 3;
      squareVertexPositionBuffer.numItems = 4;
      gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
     // ПРОБЛЕМА в перестановке строчки выше из функции отрисовки, почему тут она работает некорректно?
    }


    function drawScene() {
      gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

      mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

      mat4.identity(mvMatrix);

      mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]);
      gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);

      setMatrixUniforms();
      gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);


      mat4.translate(mvMatrix, [3.0, 0.0, 0.0]);
      gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);

      setMatrixUniforms();
      gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
    }



    function webGLStart() {
      var canvas = document.getElementById("lesson01-canvas");
      initGL(canvas);
      initShaders();
      initBuffers();

      gl.clearColor(0.0, 0.0, 0.0, 1.0);
      gl.enable(gl.DEPTH_TEST);

      drawScene();
    }


  </script>


</head>


<body onload="webGLStart();">
<a href="/webgl-урок-1-треугольник-и-квадрат/">&lt;&lt; Обратно к первому уроку</a><br /><br />

<canvas id="lesson01-canvas" style="border: none;" width="500" height="500"></canvas>

<br/><br />
<a href="/webgl-урок-1-треугольник-и-квадрат/">&lt;&lt; Обратно к первому уроку</a><br />
</body>

</html>

The difference in pictures
5a552cabafef9470518245.png

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Kalibrov, 2018-01-10
@rework

Because the call to the vertexAttribPointer function must be done after the bindBuffer, in order to first bind the set of coordinates to the buffer.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question