Войти
ПрограммированиеФорумГрафика

Render Target в DX 9, 10, 11, GL...

#0
13:17, 15 фев 2010

Добрый день!

Пытаюсь придумать как лучше организовать инфраструктуру Render Target-ов для обобщённого Графического АПИ (ГАПИ). И ничего не получается. Кое какие идеи есть - но все они получаются с ориентацией в сторону того или иного ГАПИ, либо очень корявые. А вот золотой середины никак не могу отыскать. Мне очень хотелось бы узнать о каком-то решении которое было бы эффективным для всех ГАПИ- если конечно такое решение вообще в природе существует.

Использование Render Target-ов предполагается для реализации Теней и рендеринга сцены в текстуру (собственно других способов использования наверное нет :) ).

Вообще - изначально думаю сделать так:

Есть некоторый общий интерфейс рендера - RenderDriver - реализация которого зависит от конкретного ГАПИ. RenderDriver умеет создавать такие ресурсы (примитивы):
1. Texture;
2. CubeTexture;

Каждые из этих примитивов создаются с резными Usage флагами один их которых - RenderTarget. При этом - настраивается их внутренняя логика, создаются дополнительные объекты - тоесть они настраиваются для работы под конкретным ГАПИ.

У каждого из вышеперечисленных ресурсов есть методы:
1. Surface* Texture::GetRTSurface(uint mip_id = 0)
2. Surface* CubeTexture::GetRTSurface(uint subresource_id  = 0, uint mip_id  = 0)

У рендера в свою очередь есть метод:
void RenderDriver::SetSurface(Surface*psurf, uint surf_id  = 0)
surf_id - используется для подключения большого количества RednerTarget и видимо актуально только для DX10.

ну и потом - для рендеринга вызывается просто
RenderDriver::BeginScene()
RenderDriver::EndScene()

Логика которых полностью зависит от конкретного ГАПИ.

Например для DX9 это будет что-то вроде такого:

void RenderDriver::BeginScene()
{
if(pRenderTarget)
{
IDirect3DSurface9* psurface  = pRenderTarget->GetImplementation()->GetSurface();
ID3DDevice->SetRenderTarget(psurface);
}
ID3DDevice->BeginScene();
//..


Проблема этого решения в том - что оно больше подходит для ДХ9, и на сколько оно впишется в ГАПИ типа ДХ10 и OpenGL - мне очень сложно представить.

Кроме этого - это решение частично учитвывает наявность в ДХ11 отдельных контекстов рендеринга - потому что привязка конкретного таргета к девайсу  - осуществляется в недрах самого RenderDriver-а. Но в этом случае - не понятно - на сколько эффективно данное решение будет для OpenGL.

Буду благодарен за любую помощь в столь щепетильном для меня вопросе.

Спасибо.

#1
14:07, 15 фев 2010

Ну я всегда думал что сперва сама игра имеет структуру. Где есть данные вроде координат вершин, текстуры из файлов - точнее даже имена пути, расчеты физики и прочей лабуды не касающейся ГАПИ. Далее юзер выбирает ГАПИ - скажем ДХ9.
В цикле будет вызыватся функция РЕНДЕРДХ9() , и так и далее... Ну т.е. выносить все функции различные для ГАПИ в отдельные, и вызывать их в зависимости от использования...

Вообще то темка довольно интересная (напоминает "подгонку под ключ"). Ну другого способа я не вижу... Т.к. еще зеленый в архитектуре GAPI...))

#2
15:08, 15 фев 2010

Liberty Prime
Можешь например глянуть как это у меня сделано: SVN URL: https://phengine.svn.sourceforge.net/svnroot/phengine
В частности по твоему вопросу тебе надо там глянуть библиотеку RenderSystemInterface.lib где описаны интерфейсы
к объектам GAPI. Оно проектировалось для d3d9-d3d10, и на этих GAPI будет легко реализовать эти интерфейсы,
в часности реализацию для d3d9 можно глянуть в либе D3D9Render.lib, на огле я до этого пару лет писал и когда
проектировал так же прикидывал как эти интерфейсы будут релизованы в огле, так что должно нормально лечь и под огл.

#3
16:27, 15 фев 2010

fzr125
:)

Phoenics
Спасибо за такой ёмкий ответ! Если Вы не против - я возьму Вашу реализацю Render Target-ов за основу !? Тоже сделаю класс RenderTarget, а на уровне RenderDriver - сделаю стек RenderTarget-ов с push\pop методами.

#4
16:58, 15 фев 2010

Как сделано у меня (нас).
Имеется основной рендер который имеет в своем наборе что-то вроде
render->AddRenderTarget
render->AddRenderDepthStencil
render->AddRenderCubeTarget

переключение
render->SetRenderTarget

возврат
render->ResetRenderTargets

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

В глубине сиих функций содержиться вызов более низких функций..
например
graphics_device->AddRenderTarget
в свою очередь graphics_device имеет в себе вызовы гапи на прямую.

graphics_device инициализируется в момент создания контекста графического устройства под нужный гапи.

Вот как то так.

#5
17:25, 15 фев 2010

Liberty Prime
> Спасибо за такой ёмкий ответ! Если Вы не против - я возьму Вашу реализацю
> Render Target-ов за основу !? Тоже сделаю класс RenderTarget, а на уровне
> RenderDriver - сделаю стек RenderTarget-ов с push\pop методами.

Мой код полностью свободный опенсорс, мы можете взять оттуа всё что хотите. Мне будет приятно если мой труд будет полезен кому-то ещё. Если тчо-то по коду будет непонятно - пишите в личку, постараюсь разъяснить, либо добавить коменты к нужному для вас коду

#6
17:38, 15 фев 2010

Мух
Конечно - очень хорошо что у Вас всё уже на таком уровне! Я пока пытаюсь сделать что-то немного по-проще и CubeTarget у меня видимо не будет. Хотя реализовать их тоже хочется - и на первое время думаю его раздробить на таргеты, каждый их которых будет ассоциироваться с гранью. Ну а рендер - будет только таргеты добавлять.
Phoenics
Большое спасибо! В исходниках - всё очень понятно сделано, и пока нет надобности что-либо разъяснять :) Но в случае чего - я обязательно с Вами свяжусь ! :)

#7
17:42, 15 фев 2010

Liberty Prime
> В исходниках - всё очень понятно сделано

Блин, как приятно такое слышать :) Чуть не прослезился :)))

ПрограммированиеФорумГрафика

Тема в архиве.