Как управлять текстурами - PullRequest
       7

Как управлять текстурами

3 голосов
/ 16 сентября 2010

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

Когда я смотрю на пример кода в интернете, то никогда не говорят о том, как управлять текстурами. Они просто загружают некоторые текстуры при запуске приложения, показывают свои демонстрационные материалы и затем программа закрывается. Но что, если я изменю вещи на сцене довольно часто? Что если я хочу отобразить сцену с 10 текстурами, а затем удалить узел на сцене, чтобы 2 текстуры больше не нужны, а затем добавить новый узел с 4 новыми текстурами. Таким образом, 2 старые текстуры должны быть удалены из видеопамяти, и мне нужно добавить 4 новые текстуры. Затем я полностью заменяю всю сцену, поэтому снова необходимо удалить все неиспользуемые текстуры и загрузить новые текстуры, в то время как текстуры, которые использовались ранее и также используются в новой сцене, должны быть повторно использованы. Это звучит довольно сложно.

Как управлять текстурами в профессиональных 3D движках? Это глобальный одноэлементный менеджер текстур, который отслеживает использование текстур с помощью счетчиков ссылок и время от времени очищает видеопамять? Или есть более гениальный способ сделать это?

Ответы [ 2 ]

4 голосов
/ 19 сентября 2010

Я думаю, вам нужно понять, что проблема, которую вы пытаетесь решить, связана не только с текстурами, но и со всеми игровыми ресурсами.Я думаю, что лучшим решением является автоматизированный метод отслеживания зависимостей в сочетании с подсчетом ссылок.Для каждой «вещи», которую вы хотите в своей игре, у вас должен быть какой-то корневой файл, который ссылается на все остальные ресурсы (звуки, текстуры, модели, эффекты частиц), которые эта «вещь» использует.У вас должен быть какой-то инструмент или скрипт сборки, который будет упаковывать все ресурсы для каждого элемента.Прежде чем создавать какие-либо свои «вещи», вы загружаете соответствующий пакет.Каждая вещь, которую вы загружаете, добавляет пакет, и, в свою очередь, пакет добавляет все ресурсы, которые загружены.Вы знаете, что безопасно удалять ресурсы или целые пакеты, как только счетчик ссылок становится равным 0.

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

3 голосов
/ 18 сентября 2010

Если вы реализуете это в C ++, самый простой способ - это просто иметь класс Texture, который может загружать и выгружать себя сам. Всякий раз, когда объект загружается, он также загружает необходимые ему текстуры. Когда этот объект исчезает, он уничтожает загруженные им текстуры, тем самым выгружая их.

Решение в C будет аналогичным; у вас есть структура, которая содержит достаточно данных, чтобы «выгрузить» эту текстуру, когда пришло время извлечь ее из vram и освободить ее ресурсы.

Это в основном то, что мы делаем в «профессиональных играх», хотя в серии, в которой я сейчас работаю, для каждой области мира используются все необходимые текстуры, поэтому каждый объект в этой области, имеющий одинаковые текстуры, имеет общие одни и те же данные текстуры. Прилегающие области могут иметь объекты с одинаковыми исходными текстурами, но в этом случае мы просто оставим в памяти две копии, так как управление намного проще.

С подсчетом ссылок и глобальным менеджером можно справиться, но тогда вам также потребуется придумать схему дефрагментации памяти и т. Д. И т. П., Это забавное академическое упражнение, но в конечном итоге оно вызывает слишком много беда, когда проект близок к завершению.

...