Как эффективно изменить размер окна DirectX? - PullRequest
4 голосов
/ 07 января 2012

Я посмотрел на этот пример сайта: http://www.codesampler.com/dx9src/dx9src_6.htm

Но код довольно странный: он освобождает каждую текстуру, буфер вершин, все!и затем создает их снова: загружает модель с диска ... я не думаю, что это очень эффективно!OpenGL может изменять размер окна на лету без таких ограничений.Как я могу сделать то же самое, что и OpenGL: эффективное изменение размера окна без необходимости освобождать каждый ресурс в моей программе?

Я пробовал код в приведенном выше примере ссылки, без этих вызовов invalidateDeviceObjects / restoreDeviceObjects, но этоне работает .. так что я думаю, это должно быть сделано?Надеюсь, что нет, иначе изменение размера окна будет проблемой для больших приложений, в которых сотни мегабайт данных размещены в текстурах, моделях и т. Д.

Ответы [ 3 ]

7 голосов
/ 07 января 2012

Это следствие того, как был разработан d3d9. Изменение размера окна d3d9 требует вызова IDirect3DDevice9 :: Reset и из документов:

Вызов IDirect3DDevice9 :: Reset приводит к потере всех поверхностей памяти текстур, удалению управляемых текстур из видеопамяти и потере всей информации о состоянии.

Так оно и есть. На самом деле вы обычно не изменяете разрешение экрана вообще, от начала игры до конца игры. Обычно вы устанавливаете разрешение при запуске игры, позволяете сбросить настройки на экране некоторых специальных настроек.

Теперь я должен добавить, что если вы используете D3D9, есть специальный флаг выделения ресурсов, который вы можете использовать ( D3DPOOL_MANAGED ), который фактически позаботится о повторной загрузке ресурсов для вас . Таким образом, локальная (системная память) копия всех текстур, буферов вершин и т. Д. автоматически сохраняется в системной памяти, и когда графический процессор сбрасывается, эти текстуры и т. Д. Автоматически копируются обратно в графический процессор.

Имейте в виду, D3DPOOL_MANAGED не допускается, если вы используете более новую IDirect3DDevice9Ex.

3 голосов
/ 07 января 2012

В неигровом бизнес-приложении, где частое изменение размеров окон было важной частью пользовательского интерфейса, я обошел эту проблему, создав устройство D3D в качестве устройства памяти с обнаруженным полноэкранным разрешением, затем использовал StretchBlt в CWnd :: OnDraw (...), чтобы изменить размер растрового изображения памяти во время его записи из буфера на экран. Это не очень хорошее решение для анимации с высокой частотой кадров, но в относительно статической ситуации просмотра, когда действия пользователя управляют движением объекта / представления, он работает лучше, чем подход с разрывом и воссозданием.

0 голосов
/ 03 марта 2019

Создайте задний буфер в качестве максимального разрешения монитора и используйте SWAPEFFECT_COPY.

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

При вызове Presentукажите размер окна для исходного и конечного прямоугольников.

Затем у вас будет окно с изменяемым размером, которому не нужно повторно создавать устройство D3D при изменении размера окна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...