Как нарисовать большое (500+) количество спрайтов для построения изометрической мозаичной карты в DirectX 10?

Итак, я возился с несколькими книгами по DirectX (в частности, с 10) и пытаюсь создать игру, в которой он используется, но меня ставит в тупик проблема, которая, похоже, не упоминается ни в одной из книг: Я строю изометрическую карту со спрайтами, и по мере увеличения доски программа резко замедляется. Каждый тайл имеет размер 64x45, и к тому времени, когда я создал тайловую карту 36x19 (684) со спрайтами, моему приложению требуется примерно 6 секунд для загрузки и около 5 секунд между каждым кадром. Поскольку отладка с помощью точек останова не дала никаких хороших подсказок, я сузил область в моем текущем коде, где проблема заключается в этом конкретном разделе:

Любая помощь будет оценена по достоинству.

    const FLOAT clearcolor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; 
    pD3DDevice->ClearRenderTargetView(pRenderTargetView, clearcolor);
    if(spriteObject != NULL){
        spriteObject->Begin(D3DX10_SPRITE_SORT_TEXTURE);        
        pD3DDevice->OMGetBlendState(&pOriginalBlendState10, OriginalBlendFactor, &OriginalSampleMask);
        if(pBlendState10)
        {
            FLOAT NewBlendFactor[4] = {0,0,0,0};
            pD3DDevice->OMSetBlendState(pBlendState10, NewBlendFactor,0xffffffff);
        }
        D3DXMatrixScaling(&matScale, 64, 45, 1.0f);

        for(int y = 0;y < 36;y++){
            px=0;
            if(y % 2 == 1)
                px-=32;
            for(int x = 0;x < 19;x++){  
                D3DXMatrixTranslation(&matTrans, px, viewport.Height - py, 0.1f);
                testTile.matWorld = (matScale * matTrans);
                spriteObject->DrawSpritesImmediate(&testTile, 1, 0, 0);
                px+=64;
            }
            py+=23;
        }
        spriteObject->End();
        pD3DDevice->OMSetBlendState(pOriginalBlendState10, OriginalBlendFactor, OriginalSampleMask);

person Bo T.    schedule 30.05.2011    source источник
comment
Я бы также рекомендовал использовать плитки, которые являются квадратной степенью двойки; вроде 64х64. Существует множество оптимизаций со степенью двойки. Я бы также рекомендовал, если это не так, использовать атлас текстур для хранения вашего текстуры плитки.   -  person 3nixios    schedule 30.05.2011


Ответы (1)


Весь смысл DrawSpritesImmediate в том, что вы хотите вызывать его с массивом из сотен или тысяч спрайтов... не по одному спрайту за раз.

В качестве альтернативы попробуйте изменить вызов «Немедленно» на использование DrawSpritesBuffered, за которым следует ID3DX10Sprite::Flush (вне циклов, непосредственно перед End()).

Но даже с этим ... 5 с / кадр звучит ужасно медленно ... вы уверены, что не используете программный «эталонный растеризатор» вместо HW?

person timday    schedule 30.05.2011
comment
Я действительно не видел никакой разницы в скорости при выполнении немедленного или буферизованного/сброса, но после небольшого расследования - да, моя проблема возникла из-за использования D3D10_DRIVER_TYPE_REFERENCE вместо D3D10_DRIVER_TYPE_HARDWARE. Примите мою вечную благодарность. - person Bo T.; 30.05.2011
comment
@user775842 user775842 Так почему бы не принять или хотя бы не проголосовать за его ответ? - person Christian Rau; 30.05.2011
comment
По-прежнему хорошей практикой является группирование вещей и выполнение как можно большего количества рисунков за вызов. Может быть, это менее важно для нескольких сотен плиток, но как только вы начнете добавлять, скажем, несколько слоев для эффектов параллакса, роящихся юнитов и систем частиц для взрывов/дымящихся обломков, накладные расходы на вызов станут узким местом, если вы не сделаете больше с каждый звонок. Современные графические процессоры настолько ошеломляюще мощны, что процессоры действительно не могут занять их наивным подходом к рисованию по одному за раз. - person timday; 30.05.2011
comment
@Christian Rau - Потому что, к сожалению, мне не хватает 15 репутации. - person Bo T.; 01.06.2011
comment
Это имеет большой смысл, и я обязательно интегрирую буфер/сброс в свою стандартную практику. Спасибо за отличные примеры. - person Bo T.; 01.06.2011