Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / WebGl 2.0 Vertex Array Object (VAO)

WebGl 2.0 Vertex Array Object (VAO)

Страницы: 1 2 Следующая »
SkyWebПользовательwww9 фев. 201813:32#0
Всем привет.
Помогите пожалуйста разобраться с Vertex Array Object (VAO). После поиска в интернете и прочтения многих статей возникло еще больше вопросов. Например "Vertex Array Object (или VAO) - специальный тип объектов, который инкапсулирует все данные". Тут возникает еще больше вопросов, что такое "инкапсулирует". Но находил и статьи где более простым языком все описывалось и из всего чего я начитался в голове сложилось вот такая картина:

VAO - это объект в котором хранятся буфферы, а в буфере массив. (не знаю как это правильно сформулировать, ниже станет ясно что я имею ввиду)
То есть, если у нас есть:

1-буфер в нем хранятся вершин объекта,например куба.

var vertexBuffer = gl.createBuffer();
var vertices = [
    ...
];
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

2-буфер в нем хранятся цвета граней этого куба.

var colorBuffer = gl.createBuffer();
var colors = [
   ...
];
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

Мы эти 2а буфера можем объединить в VAO ??? И например для другого объекта, сферы например создать свой VAO.

В одном из примеров на сайте webgl2fundamentals.org используется VAO, но что это дает, зачем не как не могу понять. Вот ссылка https://jsfiddle.net/37b4v3fx/
  97 строка - Создаем VAO
100 строка - Активируем VAO и начинаем с ним работать
127 строка - ??? тоже самое что и в 100 строке, для чего, что тут происходит?

Очень, очень, очень хочу разобраться, помогите пожалуйста. Если кто-то сможет объяснить на примере в jsfiddle.net буду очень признателен.
Заранее всем спасибо.

Правка: 9 фев. 2018 15:18

MrShoorУчастникwww9 фев. 201815:34#1
VAO - это сугубо оптимизация. Сейчас тебе чтобы установить буфер надо:
1. Забиндить его
2. Потом для каждого параметра (координата, нормаль, цвет и т.п.) вызвать gl.enableVertexAttribArray
3. Так же ля каждого параметра вызвать gl.vertexAttribPointer
4. А если есть инстансинг, то для каждого буфера еще вызвать gl.vertexAttribDivisor
5. Если есть инстансинг повторить все вышеописанное для инстанс буфера
6. Забиндить буфер индексов
В случае же с VAO ты все вышеописанные действия можешь записать в VAO и потом устанавливать все за один вызов.
dayllengerПользовательwww9 фев. 201815:47#2
VAO инкапсулирует не сами данные, а только информацию о том, как буферы связаны с шейдерными атрибутами и какой там индексный буфер (если есть).
VAO обычно создаётся один раз при инициализации и потом при перерисовке просто байндится, поэтому ваш пример неудачный - в нём всё происходит в main(), которая запускается один раз.
Соответственно, если у вас есть N объектов и у каждого по пачке буферов, то да, на каждый объект нужно создать VAO.
SkyWebПользовательwww9 фев. 201817:08#3
MrShoor, dayllenger спасибо большое за ответ. Но все-таки как-то не понятно. Я создал в песочнице https://jsfiddle.net/r36cw20t/233/ программку, вращение куба с разноцветными гранями. Вы могли бы в свободное время показать на моем примере как использовать VAO. Буду очень благодарен.
SkyWebПользовательwww13 фев. 201812:53#5
MrShoor, Спасибо большое! 
Вроде стало понятно как это работает. Решил поэкспериментировать.
Я вынес проверку из отрисовки. https://jsfiddle.net/9cLdxf1u/1/ Все работает.
Решил сделать 2 vao - геометрия и цвет. У меня так не работает, что не правильно я делаю в таком случае? https://jsfiddle.net/9cLdxf1u/4/
vao_geo = gl.createVertexArray();
gl.bindVertexArray(vao_geo);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);

vao_col = gl.createVertexArray();
gl.bindVertexArray(vao_col);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.enableVertexAttribArray(aColor);
gl.vertexAttribPointer(aColor, 3, gl.FLOAT, false, 0, 0);

....
//render
gl.bindVertexArray(vao_geo);
gl.bindVertexArray(vao_col);

youtubeПостоялецwww13 фев. 201813:55#6
SkyWeb, ты не понял зачем нужен VAO.
Вот https://jsfiddle.net/9cLdxf1u/6/ поправил.
Правка: исправил кривой урл.

Правка: 13 фев. 2018 13:57

SkyWebПользовательwww13 фев. 201814:05#7
youtube, ну так это тот же самый код что делал я https://jsfiddle.net/9cLdxf1u/1/ тут у меня вопросов нет.
А если я хочу создать 2 VAO? В одном геометрия в другом цвет. ???
youtubeПостоялецwww13 фев. 201814:33#8
SkyWeb
Допустим есть два объекта. 1 кубик. 2 шарик. У каждого из них есть вершины, индексы, нормали, цвета, еще какая-нибудь хрень.
Делаем так:
1. Создать вао для кубика.
  1.1 Связать вао кубика с буфером вершин кубика.
  1.2 Связать вао кубика с буфером индексов кубика.
  1.3 Связать вао кубика с буфером цветов кубика.
  ...
2. Создать вао для шарика.
  1.1 Связать вао шарика с буфером вершин шарика.
  1.2 Связать вао шарика с буфером индексов шарика.
  1.3 Связать вао шарика с буфером цветов шарика.
  ...
3.
  3.1 glBindVertexArray(вао_кубика);
  3.2 glDraw...
4.
  4.1 glBindVertexArray(вао_шарика);
  4.1 glDraw...

Когда ты не используешь вао, тебе в в пунктах 3 и 4 надо повторять пункты 1 и 2 соответственно. Чтобы вот так не дергать по сто раз эти все glBindBuffer glArrtib и т. п. придумали VAO.
Один раз описал, потом биндишь нужный вао и его рисуешь.

SkyWebПользовательwww13 фев. 201814:51#9
youtube, спасибо. Попробую сделать 2 объекта.
MrShoorУчастникwww13 фев. 201821:35#10
SkyWeb
> А если я хочу создать 2 VAO? В одном геометрия в другом цвет. ???
Нельзя. Одновременно можно использовать только один VAO. Твой второй бинд:
gl.bindVertexArray(vao_geo);
gl.bindVertexArray(vao_col);
Можно сказать затирает первый.
DampireПостоялецwww14 фев. 201811:28#11
MrShoor
> VAO - это сугубо оптимизация
wrong. VAO сейчас необходим для рендера. Хотя бы один. (если у тебя конечно не compatibility profile, там за тебя создается 0 VAO как объект).

Также важно не забывать, что он хранит условно сырые указатели на данные. Если ты изменил буфер без привязки к vao, (через DSA например) то твой vao будет сломан.

MrShoorУчастникwww14 фев. 201812:56#12
Dampire
> wrong
А что же такое VAO, если не оптимизация?

> VAO сейчас необходим для рендера.
Рисую без VAO. Все работает. ЧЯДНТ?. В первом WebGL1 VAO вообще как экстеншн идет, и в том же IE и EDGE в принципе отсутствует.

> (если у тебя конечно не compatibility profile, там за тебя создается 0 VAO как объект).
Там это вилами по воде писано, и все зависит от драйвера.

DampireПостоялецwww14 фев. 201813:17#13
MrShoor
Это оптимизация, но не сугубо. Это уже часть пайплайна since 3.3 по-моему.
SkyWebПользовательwww14 фев. 201813:55#14
Сколько новых непонятных слов я уже забил в википедию ))
Страницы: 1 2 Следующая »

/ Форум / Программирование игр / Веб

2001—2018 © GameDev.ru — Разработка игр