1

So, I've been puttering around with a few books on DirectX (specifically 10) and am trying my hand at building a game that uses it, but I'm stumped by a problem that none of the books seem to mention: I'm building an isometric map with sprites and as the board gets larger, the program slows down dramatically. Each tile is 64x45 and by the time that I have constructed a 36x19 (684) tile map with sprites, it takes roughly 6 seconds for my application to load up and about 5 seconds between each frame. Since debugging with breakpoints hasn't yielded any good clues I've narrowed down the area in my current code where the problem is to this specific section:

Any help would be appreciated.

    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);
Bo T.
  • 43
  • 4
  • 1
    I would also recommend using tiles that are a squre power of two size; like 64x64. There are many optimizations available with power of two numbers. I would also recommend if it is not the case, that you use a [Texture Atlas](http://en.wikipedia.org/wiki/Texture_atlas) to contain your tile textures. – 3nixios May 30 '11 at 08:00

1 Answers1

3

The whole point of DrawSpritesImmediate is that you want to call it with an array of hundreds or thousands of sprites... not one sprite at a time.

Alternatively, try changing your "Immediate" call to using DrawSpritesBuffered, followed by a ID3DX10Sprite::Flush (outside the loops, just before the End()).

But even with that... 5s/frame sounds awfully slow... are you sure you're not using the software "reference rasterizer" instead of the HW ?

timday
  • 24,582
  • 12
  • 83
  • 135
  • 1
    I didn't really see any difference speedwise with doing immediate vs buffered/flush, but after a bit of investigation - Yes, my issue was coming from using D3D10_DRIVER_TYPE_REFERENCE instead of D3D10_DRIVER_TYPE_HARDWARE. You have my undying thanks. – Bo T. May 30 '11 at 08:55
  • 1
    @user775842 So why not accepting or at least upvoting his answer? – Christian Rau May 30 '11 at 12:35
  • It's still good practice to get into batching things up and getting as much drawing done per call as you can. Maybe less important for a few hundred tiles, but once you start adding say multiple layers for parallax effects, swarming units, and particle systems for explosions/smoking wreckage, the per-call overhead WILL become the bottleneck if you don't do more with each call. Modern GPUs are so mind bogglingly powerful that CPUs really can't keep them busy with a naive one-at-a-time approach to drawing. – timday May 30 '11 at 17:10
  • 1
    @Christian Rau - Because I lack the 15 reputation required unfortunately. – Bo T. Jun 01 '11 at 09:25
  • That makes a lot of sense and I will make sure to integrate buffer/flush into my standard practice. Thank you for the excellent examples. – Bo T. Jun 01 '11 at 09:25