Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
1

WebGL перемещение объекта, изменение вершин в VAO

26.03.2019, 23:12. Показов 1877. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем добрый вечер. Можете подсказать, постараюсь как можно яснее описать свой вопрос.
Я рисую кубик, перемещаю его, например по оси z верх. Тут у меня сложностей нет, использую матрицу модели, передаю ее в шейдер как иниформу. Весь кубик перемещается вверх.

Я захотел сделать перемещение не всего кубика, а поднять только одно его ребро, или изменить только 1 вершину. И не понимаю как это сделать.

Javascript
1
2
3
4
5
6
this.attribs = {
  vertexs: [-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, .....],
  colors: [1.0,0.0,0.0 , 1.0,0.0,0.0 , 1.0,0.0,0.0 , .....],
  texcoord: [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, .....],
  indices: [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, .....],
};
Перед началом отрисовки, я прохажусь по всему этому, создаю vbo и все записываю в vao.
Вот как мне сделать, что при клике на кнопку менялась только одна верщина.

Javascript
1
2
this.attribs.vertexs[0] = -2 //первый клик
this.attribs.vertexs[0] = -3 //второй клик
// и т.д.
Я пробовал при отрисовке кажого кадра заново создавать vao и vbo, работает, но производительность в таком случае падает просто ниже плинтуса. Можно ли как-то изменить vao?

Пробовал смотреть через консоль, но все что получаю.

Javascript
1
2
console.dir(obj.vao);
VM553:1 WebGLVertexArrayObject
Решил записать видео, там 2 минуты, наглядно показываю что я имею ввиду https://yadi.sk/i/PcG5WKdk8bBpVg

Заранее всем спасибо за помощь.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.03.2019, 23:12
Ответы с готовыми решениями:

WebGl 2.0 Vertex Array Object (VAO)
Всем привет. Помогите пожалуйста разобраться с Vertex Array Object (VAO). После поиска в...

Отрисовать 2й объект с другими индексами(2 объекта в одном VAO)
Всем привет! Первый объект отрисовывается нормально. Хочу добавить 2й объект со своими...

Несколько vao в один vao
В общем, как объединить несколько уже существующих вао в один ? У них одинаковые атрибуты.

Перемещение вершин на плоскости
У меня есть задача, где у меня есть некоторый динамический (геометрический) граф в котором вершины...

15
652 / 233 / 46
Регистрация: 24.01.2013
Сообщений: 719
27.03.2019, 01:54 2
С bufferSubData() можно изменить только часть буфера, VAO при этом менять не надо.
0
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
27.03.2019, 07:47  [ТС] 3
Спасибо, на днях почитаю что такое bufferSubData.

Добавлено через 5 часов 3 минуты
Почитал про bufferSubData, вообще не понял как он работает.

Пример кода:

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Аттрибуты
this.attribs = {
    vertexs: [-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, ...],
    colors: [1.0,0.0,0.0 , 1.0,0.0,0.0 , 1.0,0.0,0.0 , 1.0,0.0,0.0, ...],
    texcoord: [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, ...],
    indices: [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, ...],
};
 
// Создание буферов и запись в VAO
this.vao = gl.createVertexArray();
gl.bindVertexArray(this.vao);
for (var attrib in this.attribs) {
    this.createBuffer(attrib);
}
gl.bindVertexArray(null);
gl.bindBuffer(gl.ARRAY_BUFFER,null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,null);
 
// Создание буферов
createBuffer (attrib) {
    var buffer = gl.createBuffer();
    if (attrib == 'indices') {
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.attribs[attrib]), gl.STATIC_DRAW);
    } else {
        var itemSize = attrib == 'texcoord' ? 2 : 3 ;
        var loc = Object.keys(this.attribs).indexOf(attrib);            
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.attribs[attrib]), gl.STATIC_DRAW);
        gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.attribs[attrib]));
        gl.vertexAttribPointer(loc, itemSize, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(loc);
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
    }
}
Во всех примерах что я находил показывают как его создать. Сразу после gl.bufferData. Я так и сделал, что сделал вообще не понял, как этим пользоваться тоже. Может кто объяснить логику работы bufferSubData или дать ссылку на хороший пример.
0
с++
1282 / 523 / 225
Регистрация: 15.07.2015
Сообщений: 2,562
27.03.2019, 08:30 4
https://stackoverflow.com/ques... fersubdata
0
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
27.03.2019, 08:54  [ТС] 5
Верно ли я понимаю логику?
Чтобы во время отрисовки изменить аттрибуты (вершины), мне нужно:

Javascript
1
2
3
4
5
6
7
8
// 1. Забиндить нужный буфер 
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
 
// 2. Изменить нужное мне значение в массиве вершин
this.attribs[attrib][0] = -5;
 
// 3. Перезаписать этот буфер через buffersubdata
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.attribs[attrib]));
0
652 / 233 / 46
Регистрация: 24.01.2013
Сообщений: 719
27.03.2019, 10:50 6
Цитата Сообщение от SkyWeb Посмотреть сообщение
3. Перезаписать этот буфер через buffersubdata
Не весь буфер, а только то значение, что поменялось (или диапазон значений).
0
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
27.03.2019, 14:17  [ТС] 7
А как перезаписать только первое значение?, или например с 5 по 10 значение?
0
3409 / 1596 / 236
Регистрация: 26.02.2009
Сообщений: 7,850
Записей в блоге: 5
27.03.2019, 15:51 8
SkyWeb,
https://www.khronos.org/regist... ubData.xml
Там всего 4 параметра, два из них offset и size как раз задают смещение и размер в байтах.
Как это правильно сделать на javaScript не знаю
0
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
27.03.2019, 16:02 9
WebGLRenderingContext.bufferSubData()
https://developer.mozilla.org/... ferSubData

Javascript
1
2
3
4
5
6
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
gl.bufferSubData(gl.ARRAY_BUFFER, 512, data);
WebGL2:
Javascript
1
void gl.bufferSubData(target, dstByteOffset, ArrayBufferView srcData, srcOffset, length);
0
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
27.03.2019, 18:45  [ТС] 10
8Observer8, А Вас не затруднит пояснить что такое dstByteOffset, srcOffset, length.
И если возможно пару примеров этой строк, для замены только 1ого значения и например значений с 5 по 10.
Сейчас я просто делаю
Javascript
1
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.attribs[attrib]));
Как я понимаю я перезаписываю весь массив. Хотя в нем я меняю только одну вершину. Перезаписывать весь массив - это трудоемкий процесс сильно влияющий на производительность?
0
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
27.03.2019, 20:22 11
My Original Message in English

I do not understand what do you use: WebGL 1 or WebGL 2?

Цитата Сообщение от SkyWeb Посмотреть сообщение
А Вас не затруднит пояснить что такое dstByteOffset, srcOffset, length.
It is WebGL 2. Did you read the documentation? https://developer.mozilla.org/... ferSubData

WebGL 2 is analog of OpenGL 3 ES. You can read here in addition: http://docs.gl/es3/glBufferSubData

Цитата Сообщение от SkyWeb Посмотреть сообщение
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.attribs[attrib]));
It is WebGL 1.



Translate Google Result:

Я не понимаю, что вы используете: WebGL 1 или WebGL 2?

Цитата Сообщение от SkyWeb Посмотреть сообщение
А Вас не затруднит пояснить что такое dstByteOffset, srcOffset, length.
Это WebGL 2. Вы читали документацию? https://developer.mozilla.org/... ferSubData

WebGL 2 является аналогом OpenGL 3 ES. Вы можете прочитать здесь дополнительно: http://docs.gl/es3/glBufferSubData

Цитата Сообщение от SkyWeb Посмотреть сообщение
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(this.attribs[attrib]));
Это WebGL 1.
0
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
27.03.2019, 20:27  [ТС] 12
WEBGL2 у меня. Я переводил страницу через ХРОМ, ни особо понятно что передавать, что за параметры.

offset
Задает смещение в хранилище данных объекта буфера, где начнется замена данных, измеренное в байтах.

size
Определяет размер в байтах области хранилища данных, подлежащей замене.

Мне нужно делать как-то так?
Javascript
1
2
3
var offset = ???
var size = ???
gl.bufferSubData(gl.ARRAY_BUFFER, offset, size, new Float32Array(this.attribs[attrib]));
В байтах нужно указывать, как мне это сделать, как-то посчитать нужно? offset - это начало замещения, size - конец замещения?
0
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
27.03.2019, 21:01 13
Цитата Сообщение от SkyWeb Посмотреть сообщение
где начнется замена данных, измеренное в байтах.
TypedArray.BYTES_PER_ELEMENT
https://developer.mozilla.org/... ER_ELEMENT

Javascript
1
2
console.log(Float32Array.BYTES_PER_ELEMENT);
// expected output: 4
0
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
27.03.2019, 21:49  [ТС] 14
8Observer8, Верно ли я понимаю.
Float32Array.BYTES_PER_ELEMENT - это размер байтов 1 ого элемента.
И как мне это указать? Если нужно заменять с первого байта я так и указываю Float32Array.BYTES_PER_ELEMENT, если с 2 умножаю на 2, если с 3 умножаю на 3 и т.д.

Javascript
1
2
3
4
5
6
7
8
9
// Если заменить только 1ый(первый) элемент
var offset = Float32Array.BYTES_PER_ELEMENT;
var size = Float32Array.BYTES_PER_ELEMENT;
gl.bufferSubData(gl.ARRAY_BUFFER, offset, size, new Float32Array(this.attribs[attrib]));
 
Если заменить с 5 по 7?
var offset = Float32Array.BYTES_PER_ELEMENT * 5;
var size = Float32Array.BYTES_PER_ELEMENT * 7 ;
gl.bufferSubData(gl.ARRAY_BUFFER, offset, size, new Float32Array(this.attribs[attrib]));
Или я вообще ничего не понял?!
0
3409 / 1596 / 236
Регистрация: 26.02.2009
Сообщений: 7,850
Записей в блоге: 5
28.03.2019, 11:07 15
Цитата Сообщение от SkyWeb Посмотреть сообщение
Если заменить с 5 по 7?
Javascript
1
2
var offset = Float32Array.BYTES_PER_ELEMENT * 5;
var size = Float32Array.BYTES_PER_ELEMENT * (7-5+1); // не конец блока, а - размер изменяемого блока
Добавлено через 5 минут
Только я не уверен что
Javascript
1
new Float32Array(this.attribs[attrib])
правильно.
Как я понял это создаст новый массив из всех элементов, а нужно только 3 элемента 5,6 и 7
0
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 119
28.03.2019, 11:09  [ТС] 16
snake32, спасибо. Теперь вроде все понятно. Проверю на практике.
0
28.03.2019, 11:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.03.2019, 11:09
Помогаю со студенческими работами здесь

Перемещение прямоугольника с изменением положения его вершин
Добрый день! Не могу решить данную задачу. Необходимо обеспечить метаморфозу многоугольника из...

Перемещение объекта
Есть код осуществляющий поворот объектов из 3дмакса по имени:...

Перемещение объекта
В лист добавляю префабы. Создаю их на сцене с помощью Instantiate. так: ...

Перемещение объекта
Придумал вот такое перемещение облаков, чтоб летали туда сюда (да наверно не очень правильно, но я...

Перемещение объекта
Всем привет. Немного запутался с перемещением.. Игра 2d. Нажимаем в любую точку на экране, и...

Перемещение 2 d объекта
Помогите пожалуйста. Могу нарисовать несколько треугольников в различных точках. А как реализовать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru