webgl - пытаюсь создать мой первый квадратный квадрат

1

Я очень новичок в webGL и пытался получить одно квадратное поле для отображения на моем холсте с помощью javascript. Я не знаю, как отлаживать. Было бы здорово, если бы кто-нибудь мог мне помочь. Спасибо!

    var gl,
        shaderProgram;
    initGL();
    createShaders();
    draw();
    
    function initGL() { 
      let canvas = document.getElementById("canvas");
      gl = canvas.getContext("webgl");
      gl.viewport(0.0, 0.0, canvas.width, canvas.height);
      gl.clearColor(0.0, 1.0, 1.0, 1.0);  // colors for r, g, b and alpha. these are all normalized values from 0 to 1.
    }
    
    function createShaders(){
      var vs="";
      vs+="void main(void) {";
      vs+="  gl_Position = vec4(0.0, 0.0, 0.0, 1.0)";
      vs+="  gl_PointSize = 10.0;";
      vs+="}";
      
      
      var vertexShader = gl.createShader(gl.VERTEX_SHADER);
      gl.shaderSource(vertexShader, vs);
      gl.compileShader(vertexShader);
      
      var fs="";
      fs+="void main(void) {";
      fs+="  gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0)"; // Fully opaque black
      fs+="}";
      
      var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(fragmentShader, fs);
      gl.compileShader(fragmentShader);
      
      shaderProgram = gl.createProgram();
      gl.attachShader(shaderProgram, vertexShader);
      gl.attachShader(shaderProgram, fragmentShader);
      gl.linkProgram(shaderProgram);
      gl.useProgram(shaderProgram);
      
    }
    
    function draw(){ 
      gl.clear(gl.COLOR_BUFFER_BIT);
      gl.drawArrays(gl.POINTS, 0, 1);
    }
<canvas id="canvas" width="600" height="600"> </canvas>
  • 0
    Почему вы не начинаете с three.js чтобы three.js понять концепцию.
  • 0
    спасибо @pirs, но, основываясь на обсуждениях с большим количеством инженеров, я думаю, что понимание мелочей библиотеки, понимание того, что именно входит в построение структур, лучше обучит меня, поэтому я буду менее невежественен с моими ошибками Three.js - я угадай эту начальную боль неизбежно :)
Показать ещё 4 комментария
Теги:
canvas
webgl

1 ответ

5
Лучший ответ

Пожалуйста, прочитайте несколько различных руководств по WebGL

Проблема в том, что вы получаете ошибку компилятора шейдера. Если вы откроете консоль JavaScript, вы, вероятно, увидите

Изображение 174551

Это первое сообщение означает, что ваша программа шейдеров плохая

Независимо от того, какую книгу/сайт вы читали, вы должны были сказать вам, чтобы проверить ошибки компиляции шейдеров, как это

      { 
        const success = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS);
        if (!success) {
           console.error(gl.getShaderInfoLog(vertexShader));
           return false;
        }
      }

А также для ошибок связи с программой, как это

      { 
        const success = gl.getProgramParameter(shaderProgram, gl.LINK_STATUS);
        if (!success) {
           console.error(gl.getProgramInfoLog(shaderProgram));
           return false;
        }
      }      

Это указывало бы на то, что с вашими шейдерами что-то не так. На этой линии вам не хватало точки с запятой

      gl_Position = vec4(0.0, 0.0, 0.0, 1.0)

Пожалуйста, прочитайте несколько лучших руководств. Также рассмотрите использование многострочных литералов JavaScript. Гораздо проще, чем конкатенировать строки.

Также вызов gl.useProgram внутри функции, которая компилирует и связывает шейдеры, является анти-шаблоном. Обычно приложения WebGL имеют более одной шейдерной программы.

var gl,
        shaderProgram;
    initGL();
    createShaders();
    draw();
    
    function initGL() { 
      let canvas = document.getElementById("canvas");
      gl = canvas.getContext("webgl");
      gl.viewport(0.0, 0.0, canvas.width, canvas.height);
      gl.clearColor(0.0, 1.0, 1.0, 1.0);  // colors for r, g, b and alpha. these are all normalized values from 0 to 1.
    }
    
    function createShaders(){
      var vs='
      void main(void) {
        gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
        gl_PointSize = 10.0;
      }';
      
      var vertexShader = gl.createShader(gl.VERTEX_SHADER);
      gl.shaderSource(vertexShader, vs);
      gl.compileShader(vertexShader);
      { 
        const success = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS);
        if (!success) {
           console.error(gl.getShaderInfoLog(vertexShader));
           return false;
        }
      }
      
      
      var fs='
      void main(void) {
        gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); // Fully opaque black
      }';
      
      var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(fragmentShader, fs);
      gl.compileShader(fragmentShader);
      { 
        const success = gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS);
        if (!success) {
           console.error(gl.getShaderInfoLog(fragmentShader));
           return false;
        }
      }
      
      shaderProgram = gl.createProgram();
      gl.attachShader(shaderProgram, vertexShader);
      gl.attachShader(shaderProgram, fragmentShader);
      gl.linkProgram(shaderProgram);
      { 
        const success = gl.getProgramParameter(shaderProgram, gl.LINK_STATUS);
        if (!success) {
           console.error(gl.getProgramInfoLog(shaderProgram));
           return false;
        }
      }      
      
      gl.useProgram(shaderProgram);
      return true;   // this is bad. You should be returning the program
    }
    
    function draw(){ 
      gl.clear(gl.COLOR_BUFFER_BIT);
      gl.drawArrays(gl.POINTS, 0, 1);
    }
<canvas id="canvas" width="600" height="600"> </canvas>
  • 0
    Мне любопытно, есть ли какие-либо спецификации, поддерживающие это поведение при рисовании без настройки, привязки и, в конечном итоге, использования каких-либо атрибутов вершин? Спецификация гласит: «Если атрибут вершины включен как массив через enableVertexAttribArray, но буфер не привязан к этому атрибуту через bindBuffer и vertexAttribPointer, то вызовы drawArrays или drawElements вызовут ошибку INVALID_OPERATION». и iirc attrib 0 включен по умолчанию, не так ли?
  • 0
    спасибо @gman за хорошее объяснение!
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню