Как мне: преобразовать поверхность в текстуру или создать текстуру с определенными параметрами мультисэмплинга или визуализировать поверхность с альфа-слоем - PullRequest
1 голос
/ 24 марта 2011

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

Так что название этого вопроса в основном мои вопросы, как мне: - преобразоватьповерхность к текстуре или - создать текстуру с определенными параметрами мультисэмплинга или - правильно отобразить поверхность с помощью альфа-слоя

Ответы [ 2 ]

1 голос
/ 13 декабря 2013

Итак, новый ответ на старый вопрос, но я натолкнулся на это и подумал, что дам ответ на тот случай, если кто-нибудь еще столкнется с ним, столкнувшись с этой проблемой. Вот решение с урезанной версией моих оболочек и функциями для нее.

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

GeometryLayer :: Draw
* Активирует цель рендеринга, используемую этим слоем
* Устанавливает необходимые состояния рендеринга
* Очищает буфер
* Рисует геометрию
* Деактивирует цель рендеринга, используемую этим слоем

void GeometryLayer::Draw( const math::mat4& viewProjection )
{
    m_pRenderTarget->Activate();

    pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
    pDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
    pDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

    pDevice->Clear(0,0,D3DCLEAR_TARGET,m_clearColor,1.0,0);
    pDevice->BeginScene();
    pDevice->Clear(0,0,D3DCLEAR_ZBUFFER,0,1.0,0);

    for(auto it = m->visibleGeometry.begin(); it != m->visibleGeometry.end(); ++it)
        it->second->Draw(viewProjection);

    pDevice->EndScene();

    m_pRenderTarget->Deactivate();
}

Моя оболочка RenderTarget содержит IDirect3DTexture9 * (m_pTexture), который используется с D3DXCreateTexture для генерации текстуры, к которой нужно рисовать. Он также содержит IDirect3DSurface9 * (m_pSurface), который задается текстурой. Он также содержит другой IDirect3DSurface9 * (m_pMSAASurface).

В инициализации моего RenderTarget есть опция включения мультисэмплинга. Если эта опция отключена, m_pMSAASurface инициализируется как nullptr. Если эта опция включена, m_pMSAASurface создается для вас с помощью функции IDirect3DDevice9 :: CreateRenderTarget, в которой в качестве 4-го и 5-го аргументов указаны мои текущие настройки мультисэмплинга.

RenderTarget :: Init
* Создает текстуру
* Получает поверхность от текстуры (добавляет счетчик поверхности)
* Если MSAA, создает поверхность с поддержкой msaa

void    RenderTarget::Init(const int width,const int height,const bool enableMSAA)
{
    m_bEnableMSAA = enableMSAA;
    D3DXCreateTexture(pDevice,
        width,
        height,
        1,
        D3DUSAGE_RENDERTARGET,
        D3DFMT_A8R8G8B8,
        D3DPOOL_DEFAULT,
        &m_pTexture;
    );
    m_pTexture->GetSurfaceLevel(0,&m_pSurface);

    if(enableMSAA)
    {
        Renderer::GetInstance()->GetDevice()->CreateRenderTarget(
            width,
            height,
            D3DFMT_A8R8G8B8,
            d3dpp.MultiSampleType,
            d3dpp.MultiSampleQuality,
            false,
            &m_pMSAAsurface,
            NULL
        );
    }
}

Если этот параметр MSAA выключен, RenderTarget :: Activate устанавливает m_pSurface в качестве цели рендеринга. Если этот параметр MSAA включен, RenderTarget :: Activate устанавливает m_pMSAASurface в качестве цели рендеринга и включает состояние рендеринга мультисэмплинга.

RenderTarget :: Activate
* Сохраняет текущую цель рендеринга (добавляет к числу ссылок этой поверхности)
* Если не MSAA, устанавливает поверхность как новую цель рендеринга
* Если MSAA, устанавливает поверхность msaa как новую цель рендеринга, включает состояние рендеринга msaa

void    RenderTarget::Activate()
{
    pDevice->GetRenderTarget(0,&m_pOldSurface);

    if(!m_bEnableMSAA)
    {
        pDevice->SetRenderTarget(0,m_pSurface);
    }
    else
    {
        pDevice->SetRenderTarget(0,m_pMSAAsurface);
        pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,true);
    }
}

Если этот параметр MSAA выключен, RenderTarget :: Deactivate просто восстанавливает исходную цель рендеринга. Если этот параметр MSAA включен, RenderTarget :: Deactivate также восстанавливает исходную цель рендеринга, но также копирует m_pMSAASurface в m_pSurface.

RenderTarget :: Деактивировать
* Если MSAA, отключает состояние рендеринга MSAA
* Восстанавливает предыдущую цель рендеринга
* Отбрасывание ссылки рассчитывает на предыдущую цель рендеринга

void    RenderTarget::Deactivate()
{
    if(m_bEnableMSAA)
    {
        pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,false);
        pDevice->StretchRect(m_pMSAAsurface,NULL,m_pSurface,NULL,D3DTEXF_NONE);
    }
    pDevice->SetRenderTarget(0,m_pOldSurface);

    m_pOldSurface->Release();
    m->pOldSurface = nullptr;
}

Когда Renderer позже запрашивает геометрический слой для его текстуры RenderTarget, чтобы объединить его с другими слоями, эта текстура скопировала изображение из m_pMSAASurface. Предполагая, что вы используете формат, облегчающий альфа-канал, эту текстуру можно смешивать с другими, как я делаю с целями рендеринга нескольких слоев.

1 голос
/ 31 марта 2011

Документация для StretchRect конкретно объясняет, как это сделать:

Использование StretchRect для уменьшения выборки мультисэмпла Rendertarget

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

  • Создать мультисэмплированную цель рендеринга.
  • Создать вторую цель визуализации того же размера, которая не является мультисэмплированной.
  • Копировать (используя StretchRectмультисэмплерный рендеринг цели ко второму рендер-мишени.

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

...