LINUX.ORG.RU

Скрываемые поля структуры


0

2

Предположим есть некий класс Vertex, который хранит информацию о вершине: позицию, нормаль, текстурные координаты.
Массив таких Vertex'ов находится в классе Mesh. Далее этот массив копируется в память видеокарты, где рендерится.
Однако есть проблема, т.к. текстурные координаты не всегда нужны, т.е. поле нужно убрать, чтобы в видеокарте оно не занимало лишнее пространство.
Быстро написал на шаблонах: http://ideone.com/0ZOGOH .
Правильно ли такое решение?

Лучше бы сделал наследованием. А я бы вообще вручную объявил два разных класа, вовсе.

anonymous
()

ИМХО, любое решение с использованием особенностей C++ — убого

ttnl ★★★★★
()

Блин… Здорово вышло, но это хак. Если хочешь использовать шаблоны, то лучше напиши две разных специализации.

KblCb ★★★★★
()
Ответ на: комментарий от Boy_from_Jungle

можно и без методов, но если ты наследуешся то деструктор и родителя должен быть тогда виртаульным

С чего вдруг деструктор родителя должен быть виртуальным? Вопрос риторический. В данном случае оверхеда с наследованием нет.

Dendy ★★★★★
()
Ответ на: комментарий от Dendy

С чего вдруг деструктор родителя должен быть виртуальным?

Чтобы не поймать UB, когда попытаешься удалить экземпляр класса наследника по указателю на класс родитель, видимо. Или речь о том, что в данном случае никому не впился полиморфизм и данное развитие событий крайне маловероятно?

KblCb ★★★★★
()

Далее этот массив копируется в память видеокарты, где рендерится.

и как ты это собираешься делать, совать произвольные структуры в видеопамять? Этим же вроде OpenGL/DirectX/видеодрайверы рулят, а если что-то юзером и передаётся в видеопамять, то в заранее заданном формате?

Harald ★★★★★
()
Ответ на: комментарий от Harald

В OpenGL есть Vertex Buffer Object, в который можно скопировать атрибуты вершин. Далее указывается шаг(stride) - расстояние между началами двух соседних атрибут.
На самом деле OpenGL 4.0 предоставляет большую гибкость и сам мало что делает.

sol_linux ★★
() автор топика
Ответ на: комментарий от KblCb

Или речь о том, что в данном случае никому не впился полиморфизм и данное развитие событий крайне маловероятно?

Именно. Экземпляры аллоцируются, используются и удаляются по значению. Хотя я бы предпочёл в этом случае избежать наследования и сделать обычную композицию.

Dendy ★★★★★
()

1. Прикрутите FVF.
2. Сделайте нужное количество структур вертексов.

andreyu ★★★★★
()
Ответ на: комментарий от sol_linux

Главное не забывайте про #pragma pack, чтобы выравнивание в C-структурах соответствовало ожидаемому представлению в памяти VBO. А так любой вариант подходит. Шаблоны стоит использовать в случае, если у вас есть generic-код, который работает с Mesh<T>, в остальных случаях более простой вариант предпочтительней.

Dendy ★★★★★
()
Ответ на: комментарий от vertexua

Честно говоря, а даже не понимаю как здесь наследованием... Очень важно, чтобы в памяти атрибуты вершин шли цельным куском и чередовались:
pos|normal|texCoord|pos|normal и т.д

sol_linux ★★
() автор топика
Ответ на: комментарий от Dendy

есть простое правило, если класс наследуется, то его деструктор должен быть виртуальным, в общем пересказывать не буду, Саттер писал уже об этом не раз.

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от sol_linux

Да не сложно в общем-то. Просто это трюк на понимание которого у читающего уйдёт время (правда не большое, если шаблон и enum далеко не разъедутся) в том числе и у тебя через пару лет. Кроме того почти уверен что любая IDE скажет тебе что у Vertex<UNTEXTURED> есть поле texCoord. Это уже может привести к ошибкам.

KblCb ★★★★★
()
Ответ на: комментарий от Dendy

Главное не забывайте про #pragma pack, чтобы выравнивание в C-структурах соответствовало ожидаемому представлению в памяти VBO

может проще писать мемберы в правильном порядке,
хотя я не в курсе, #pragma pack уже все компиляторы поддерживают?

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от sol_linux

Есть возможность располагать опциональные элементы в конце? Если да, то можно или отнаследоваться и тогда поля потомков будут дальше. Или применить композицию, расположив обязательные поля в объекте внутри объекта с опциальнальными полями. Может повезет и они будут подряд, я не знают точно что говорит стандарт.

vertexua ★★★★★
()

Предположим есть некий класс Vertex, который хранит информацию о вершине: позицию, нормаль, текстурные координаты. Массив таких Vertex'ов находится в классе Mesh. Далее этот массив копируется в память видеокарты, где рендерится. Однако есть проблема, т.к. текстурные координаты не всегда нужны, т.е. поле нужно убрать, чтобы в видеокарте оно не занимало лишнее пространство.

В данном случае ИМХО наследование более грамотное решение. А вот делать или не делать деструктор виртуальным - решать вам. Будете вы когда-нибудь удалять вершину через базовый класс? Вам хочется, что-бы сами удалялись текстурные координаты? (если они есть) Если да, то придётся потратить 4/8 байт на каждый объект. Если нет, то можно сделать деструктор невиртуальным, и эти байты сэкономить. ИМХО последний вариант более правильный, ибо тут базовый класс - это некое представление в памяти, а вовсе не базовый класс с т.з. полиморфизма. Т.е. строго говоря это НЕ ООП. Возможно следует сделать базовый класс структурой, что-бы это подчеркнуть...

И да, шаблоны имхо здесь не в тему.

drBatty ★★
()
Ответ на: комментарий от anonymous

Или можно просто динамический массив и перегрузить оператор ->.

maggotroot
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.