Хобрук: Ваш путь к мастерству в программировании

Webgl vertexAttribPointer: индекс вне допустимого диапазона

Я пытаюсь передать ультрафиолетовый буфер, а также обычный буфер в webgl. Но по какой-то причине я получаю это предупреждение vertexAttribPointer: index out of range при передаче значений. Я не понимаю, что я делаю неправильно, так как массив uv кажется хорошим, то же самое касается нормалей.

Похоже, что ошибки возникали только с нормальным и ультрафиолетовым, а не с позицией.

enableVertexAttribArray: index out of range

vertexAttribPointer: index out of range

let canvas = document.querySelector("canvas");
let gl = canvas.getContext("webgl");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

const vsSource = `
    attribute vec4 position;
    attribute vec2 uv;
    attribute vec3 normal;
    uniform mat4 modelViewMatrix;
    varying vec4 vColor;
    void main(void) {
      gl_Position = position;
    }
  `;

const fsSource = `  
    precision mediump float;
    varying vec4 vColor;
    void main(void) {
      gl_FragColor = vec4(1.0,0.0,1.0,1.0);
    }
  `;

// Shader setup

let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);

if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
    var log = gl.getShaderInfoLog(vertexShader);
    throw "Shader compilation failed\n\n" + log + "\n\n";
}

var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);

if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
    var log = gl.getShaderInfoLog(fragmentShader);
    throw "Shader compilation failed\n\n" + log + "\n\n";
}

let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);

gl.linkProgram(program);
gl.validateProgram(program);

if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    var log = gl.getProgramInfoLog(program);
    throw "Program link failed\n\n" + log;
}

gl.useProgram(program);

let modelViewMatrix = gl.getUniformLocation(program, "modelViewMatrix");

let model = mat4.create();

gl.uniformMatrix4fv(modelViewMatrix, false, model);

var vertices = new Float32Array([
    0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5
]);

var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

let position = gl.getAttribLocation(program, "position");

gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(position);

var uvBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
gl.bufferData(
    gl.ARRAY_BUFFER,
    new Float32Array([
        0,
        1,
        1,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        1,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        1,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        1,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        1,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        1,
        1,
        0,
        0,
        1,
        0
    ]),
    gl.STATIC_DRAW
);

let uv = gl.getAttribLocation(program, "uv");

gl.vertexAttribPointer(uv, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(uv);

var normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(
    gl.ARRAY_BUFFER,
    new Float32Array([
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1
    ]),
    gl.STATIC_DRAW
);

let normal = gl.getAttribLocation(program, "normal");

gl.vertexAttribPointer(normal, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normal);

var indices = new Uint16Array([
    0,
    2,
    1,
    2,
    3,
    1,
    4,
    6,
    5,
    6,
    7,
    5,
    8,
    10,
    9,
    10,
    11,
    9,
    12,
    14,
    13,
    14,
    15,
    13,
    16,
    18,
    17,
    18,
    19,
    17,
    20,
    22,
    21,
    22,
    23,
    21
]);

var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
<canvas></canvas>

26.02.2019

Ответы:


1

Ваши шейдеры не используют uv или normal, поэтому ваш драйвер оптимизирует эти атрибуты. В этом случае gl.getAttribLocation возвращает -1 для местоположения (-1 = атрибут с таким именем не существует). -1 вне диапазона. Допустимые значения: от 0 до gl.getParameter(gl.MAX_VERTEX_ATTRIBS) - 1.

Другими словами, вам нужно проверить расположение ваших атрибутов, и если они не существуют, не устанавливайте их.

Это одна из причин, почему полезно написать вспомогательные функции для WebGL. чтобы решить эти проблемы за вас, чтобы при изменении шейдеров ваш код не ломался.

26.02.2019
Новые материалы

Управление DOM для чайников вроде меня
Одной из первых вещей, которую мы рассмотрели, когда начали изучать Javascript во Flatiron, была модель DOM. Кто он? Чем он занимается? Он больше машина, чем человек? Ну да довольно много. ДОМ..

Что такое структура данных?
Структура данных хранит и извлекает данные. Все, что обеспечивает эти две функции, является структурой данных . Период. Вы можете пропустить оставшуюся часть статьи, если ответ..

мои январские чтения по программированию
Эрик Эллиот Программирование приложения JavaScript Эл Свейгарт «Автоматизируйте скучные вещи с помощью Python» Прогрессивное веб-приложение Google..

Создание ассоциаций секвелизации с помощью инструмента командной строки Sequelize
Sequelize - популярный, простой в использовании инструмент объектно-реляционного сопоставления (ORM) JavaScript, который работает с базами данных SQL. Довольно просто начать новый проект с..

Искусственный интеллект в юридической отрасли - пример прогнозирования судебных решений с помощью глубокого обучения
На протяжении всей истории люди полагались на суды, присяжных, королей и королев в отправлении правосудия. Сегодня способность судов обеспечивать справедливое и быстрое правосудие для своих..

Введение в машинное обучение для обнаружения аномалий (часть 1)
Тщательно созданный, тщательно спроектированный ресурс для специалистов по данным. Часть 1 Главы 03 из Руководства по машинному обучению для обнаружения аномалий Внимание! Прежде чем вы..

Начало работы с Pulumi в Digital Ocean
Цифровой океан (ДО) — отличная альтернатива многим другим поставщикам облачных услуг. DO предоставляет простой и понятный пользовательский интерфейс, упрощающий управление инфраструктурой и..