Russian Qt Forum
Ноябрь 26, 2024, 03:12 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Использование QOpenGLBuffer  (Прочитано 28979 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Ноябрь 12, 2016, 14:29 »

Добрый день

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

- Есть исходные данные стандартные для OpenGL - вертексы и индексы, число индексов на фейс (могут быть не только тр-ки) + всякая опциональная всячина (нормали, цвет, UV(s)  др). Хранятся они в массивах/векторах, в общем у любого пользующего OpenGL практически то же самое. Данные могут шариться разными объектами, напр N объектов может использовать одни и те же вертексы и индексы, или только индексы. Ну и конечно все данные буферированы с использованием QOpenGLBuffer чтобы не гонять их CPU -> GPU при каждом рисовании

- И вот возникает "еще одно" представление/рисование объекта. Юзер включает бубочки и ожидает увидеть объект с высокой деталировкой (вместо исходного с низкой). Что однако, не означает "объект изменился" - нет, он хочет только "видеть", а все действия по-прежнему выполнять с исходным простым объектом, (а не таскать тонны геометрии)

Ясно что решение одно - хранить высоко деталированный объект на карте, но как это сделать ?

Спасибо
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #1 : Ноябрь 12, 2016, 15:35 »

В функциях gl имеется параметр stride. Может его задействование как-то поможет...
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #2 : Ноябрь 12, 2016, 21:16 »

А разве при изменении "простого" объекта не должен будет меняться "сложный"?
Скорее всего, тут "хранить" надо некую изменяемую модель данных. А оба OpenGl-представления генерировать при изменении модели.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Ноябрь 13, 2016, 09:58 »

В функциях gl имеется параметр stride. Может его задействование как-то поможет...
stride - это просто размер единицы вертексных данных, который может быть больше требуемого. Напр если данные хранятся как QVector<QVector4D> то указав stride = 16 мы можем их скормить напрямую, без перевода в QVector<QVector3D>

А разве при изменении "простого" объекта не должен будет меняться "сложный"?
Конечно должен. Изменения бывают 2 типов

а) изменилась вся модель полностью
б) изменились вертексы и нормали к ним (только значения, их число осталось тем же)

Скорее всего, тут "хранить" надо некую изменяемую модель данных. А оба OpenGl-представления генерировать при изменении модели.
Так вот и хотелось бы поговорить/конкретизировать как генерировать разные OpenGL-представления.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Ноябрь 13, 2016, 10:53 »

Как должна быть создана картинка в стартовом посте

- есть исходный объект (слева). Он копируется 3 раза. Пока все 4 объекта используют одни и же QOpenGLBuffer для вертексов, индексов, нормалей и.т.д. Все шарится

- Теперь юзер открывает UI каждой из копий и назначает уровни деталировки 1, 2, 3 соответственно. Должны быть созданы/посчитаны новые данные, которые записываются в буфера. Теперь у каждого объекта все буфера свои. Ничего не шарится

Возиожно (хотя и не показано на картинке) юзер скопирует любой из объектов - копия шарит оригинал. Если же  копия или оригинал изменены (напр как-то деформированы), то 2 буфера (вертексы и нормали) у каждого свои, остальные буфера по-прежнему шарятся
 
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #5 : Ноябрь 14, 2016, 11:03 »

Я смотрю описание glVertexAttribPointer
Цитировать
stride
Specifies the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.
Вроде как им можно сказать конвейеру брать каждую вторую/третью вершину.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #6 : Ноябрь 14, 2016, 11:50 »

Так вот и хотелось бы поговорить/конкретизировать как генерировать разные OpenGL-представления.

Щас подумал - видно, я ранее чушь сказал... Хранить-модифицировать надо высокополигональную модель.
Потому что из хай-поли лоу-поли сделать можно, а наоборот - это неоднозначно.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Ноябрь 14, 2016, 14:05 »

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

Щас подумал - видно, я ранее чушь сказал... Хранить-модифицировать надо высокополигональную модель.
Потому что из хай-поли лоу-поли сделать можно, а наоборот - это неоднозначно.
Самокритика - это прекрасно, но в данном случае все наоборот: исходные данные LOW-resolution меш, часто его называют "cage". Заметим что частенько результат заметно лучше если исходные полигоны 4-угольники (а не тр-ки).   
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #8 : Ноябрь 14, 2016, 14:58 »

Я имел в виду, что поскольку 1-й объект (исходный) - это некий треугольник в 3д, то как мы можем быть уверенными, что в хай-поли оно превращается в 4-й (сильно сглажены углы), а не должно оставаться таки треугольным?
Судя по картинкам - это не просто хай-поли, а объект плюс деформация.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Ноябрь 14, 2016, 15:32 »

Судя по картинкам - это не просто хай-поли, а объект плюс деформация.
Да, точнее "не просто триангуляция". Это называется SDS (surface sub-division) и известно уже не один десяток лет. Вертекс заменяется взвешенной суммой соседей. Если не вдаваться в тонкости с sharpness - можно самому написать за день. Конечно это не "magic", хороший рез-т получается для достаточно грамотных, аккуратных исходных cage(s).

Однако и это не имеет отношения к теме  Улыбающийся 
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #10 : Ноябрь 15, 2016, 10:55 »

Разную детализацию на основе одних и тех же вертексных данных можно получить путем формирования различных массивов индексов. Например, загрубив полигональный объект путем пропуска вершин по какому-либо критерию, можно выполнить тесселяцию столько раз, сколько нужно. Тогда для одного набора вершин получим несколько наборов индексов для разной степени детальности.

Для облегчения перетаскивания объектов несколько раз видел прием, когда все примитивы в момент перемещения отображаются в режиме отображения точек. Получается просто, легко и может даже эффектно.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #11 : Ноябрь 15, 2016, 11:06 »

Насчёт упрощения представления, кстати, есть несколько способов: feature lines, bounding box, node cloud, element centroid
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Ноябрь 15, 2016, 13:55 »

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

Для облегчения перетаскивания объектов несколько раз видел прием, когда все примитивы в момент перемещения отображаются в режиме отображения точек. Получается просто, легко и может даже эффектно.
Тут у меня очередные "чудеса на виражах" Улыбающийся Если рисовать точки и wireframe с помощью gl(Multi)DrawElements (установив glPolygonMode) то скорость почти в 3 раза НИЖЕ чем для "залитых" полигонов даже с текстурами и материалом! Если же соскочить на glDrawArrays для точек, то конечно шустрее, но я попадаю в др беду - не работает Cull(Back)Fаce

Ну и вообще-то вопрос был как хранить разные представления
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Ноябрь 15, 2016, 14:08 »

Ладно, попробуем набросать структуры данных, может обсуждение станет более конкретным.
Вот "принципиальная схема"

Код
C++ (Qt)
typedef QVector<QVector3D> TVerArray;  
typedef QVector<int> TIndArray;
 
struct CRenderObject {
...
// данные рисования, могут шариться любым кол-вом CRenderObject
QSharedPointer<CGeometry> m_geometry;
 
// уровень деталировки, 0 = исходная геометрия
int m_detailLevel;      
 
// Если к объекту применены нелинейные преобразования
// то его "личные" вертексы и нормали должны использоваться
// (вместо тех же данных в m_geomretry)
TVerArray m_vertex, m_normal;
};
 
// класс данных рисования
struct CGeometry {
...
 TVerArray m_vertex, m_normal, m_color, m_uv0, m_uv1;
 TIndArray m_indices, m_ver_per_face;
};
Вот собсно и все - теперь надо куда-то поселить буфера (QOpenGLBuffer). Вот как и куда?
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #14 : Ноябрь 15, 2016, 14:46 »



Полигональная модель всегда может быть преобразована (в конечном счете) к набору треугольников. Если по какому-то принципу исключить из рассмотрения некоторые вершины, то можно "загрубить" исходный объект. При этом изменится и его геометрическая форма, хотя исходные данные будут прежними, кроме массива индексов.

Если исходные данные представляют собой уже массивы треугольников или других примитивов, то для проведения такого анализа потребуется формировать и анализировать связи вершин между собой.

Или можно хранить копии одного объекта с разной детализацией? Тогда достаточно в момент рендеринга выбирать нужный вид.
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.185 секунд. Запросов: 23.