Я бы делал не так. Многоуровнево, например:
Ресурсы Текстуры Шейдеры Буферы для батчей ... Стейты TextureStageStates для FFP, SamplerStates, в том числе фильтрация и "Mirroring". Параметры альфаналожения ... Методы Clear DrawTile DrawSprite DrawLines DrawBatch DrawParticles ...
Не старался бы делать полностью универсально, нельзя объять необъятное :)
Например, сомневаюсь в необходимости Z-буфера, 2D рендер подразумевает по большей части рисования спрайтов с альфаканалом, а их всё равно нужно упорядочивать.
Mikle
> Многоуровнево
Это как? На каждый уровень новые интерфейсы?
max255
> На каждый уровень новые интерфейсы?
На каждую "главу", если так можно выразиться. Разделение по принципу подобия методов, например у ресурсов могут быть однотипные менеджеры, у стейтов - проверки на то, что уже установлен и т. п.
Текстуры и их фильтрация - это совершенно разные вещи, а ты их объединил. В то же время BlendFaktor - это обычный стейт.
max255
> Помнится ты говорил что нужно подходить к архитектуре, в которой пользователь
> меньше всего будет взаимодействовать с директом напрямую
Хочется, чтобы уровень абстракции методов был примерно одинаков, речь об этом.
На время забудь про то, как устроены движки, и представь себе, что бы ты хотел от движка, если бы его заказывал.
Mikle
> На каждую "главу", если так можно выразиться.
Т.Е. один класс на все менеджеры ресурсов или отдельные классы на каждый менеджер?
Сейчас в движке только 2 типа ресурсов: текстуры и шейдеры(менеджеры пиксельных и вертексных шейдеров и буферы констант)
Mikle
>Разделение по принципу подобия методов
Я хотел совместить стейты и батч Т.К. при попытке сменить стейт - нужно нарисовать батч, а только потом ставить стейт...
Mikle
> На время забудь про то, как устроены движки
Хорошая мысль... попробую...
Смотрел в качестве примера hge... Там все достаточно просто, но чтобы сделать, к примеру, бамп нужно лезть в потроха директу...
Взвесил все за и против и решил не делать полностью автономный батч...
Т.Е. запускать и тормозить батч самому...
Все же разработчику известней когда он будет рисовать 1000 цветочков или же спрайт с уникальным блендом...
Все стейты оставить в Render-е + оставить проверку на повторную установку тут же...
А батч реализовать так:
Render2D.BeginBatch Render2D.Draw() Render2D.Draw() Render2D.EndBatch
Причем что бы не было постоянной переустановки стейтов в батче завести флаг и ставить только при первом рендере...
Mikle
> Батчинг линий - совершенно отдельный от спрайтов.
Почему отдельный? Что-бы параллельно выводить геометрию?
Или из-за типа вертекса? Лишние текстурные координаты особого выйгрыша не дают...
Из-за типа вертекса, из-за другого типа DIP, там всё разное.
Сделал батчинг спрайтов и линий, добавил интерфейс рендеринга в текстуру. Пересоздание текстур при ресете полностью автоматизировано...
Сейчас работа с интерфейсами выглядит так:
'начало сцены, очистка буфера
Render.BeginScene
Render.ClearScene D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, &HFF00FF00
'конфигурация 2D рендера
Render2D.SetDefaultView 'установка 2D камеры
Render2D.BeginDraw 'начало 2D рендеринга
Render2D.Set2DIdentity 'установка 2D трансформации
RT.BeginRenderTarget 'старт рендеринга в текстуру
Render.ClearScene D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, &HFF00FF00
Render.Textures.SetTexture 0, tex
Render2D.Draw 0, 0, Render.BackBufferSize.X, Render.BackBufferSize.Y, &HFFFFFFFF
Render2D.BatchLines 'старт батчинга линий
For i = 0 To 1000
Render2D.DrawLine 0, 0, Rand * 800, Rand * 600, &HFFFFFFFF
Next
Render2D.EndLines 'стоп батчинга линий
RT.EndRenderTarget 'конец рендеринга в текстуру
Render.ClearScene D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, &HFF00FF00
Render.Textures.SetTexture 0, RT.RenderTextureID 'рендерим RT
Render2D.Draw 0, 0, 100, 100, &HFFFFFFFF
Render2D.EndDrawПробовал измерять ускорение от батчинга?
Mikle
Рендеринг 10000 линий:
- с батчем: 392fps
- без батча: 192fps
PS: с текущим строением архитектуры ВСЕ интерфейсы надо ОБЯЗАТЕЛЬНО освобождать, в обратном порядке... Не знаю хорошо это или плохо...
То, что освобождать нужно - это не плохо, но что именно в обратном порядке - немного странно.
Mikle
> немного странно
В том смысле что перед освобождением интерфейса "родителя" - нужно освободить всех его "потомков"...
max255
А в RT обязательно юзать Depth Stencil для 2D? Или можно при создании RT ставить флаг юзать его или нет?
max255
Это в DX8 RT задавал сразу и ZB и CB. В DX9, как правило, пользуются общим ZB для всех таргетов, главное - чтобы был достаточный размер (он может быть больше, чем CB, не страшно).
Для 2D ZB не очень актуален из-за того, что, как правило, активно используется альфа, а спрайты с ней всё равно нужно упорядочивать. Для отключения ZB достаточно задать:
Dev.SetRenderState D3DRS_ZENABLE, D3DZB_FALSE
Mikle
> Для отключения ZB достаточно задать
Значит при старте 2D рендеринга его можно кэшировать(его предыдущее состояние), потом отключать...
Mikle
> пользуются общим ZB для всех таргетов, главное - чтобы был достаточный размер
> (он может быть больше, чем CB, не страшно)
Как я понял, Depth Stencil можно вообще отвязать от интерфейса RT... Просто проверять размер, и если он больше создавать временный... Стоп...
А если нужен рендеринг в текстуру глубины?
Тема в архиве.