Thread: Tile-map performance

  1. #16
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    @Bubba: Out of interest, what kind of performance are you getting out of this method?
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  2. #17
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ok then fractality....show me some code.

  3. #18
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    First thing that comes to my mind, is if the texture calls are what's causing your bottleneck and not necessarily the polygon pushing, why not slap all of your tiles in to a list and sort them by texture ID, then render them accordingly. You'd be pushing more vertices, yah, but as I said: if the texture binding is causing the largest problem, this should fix it (assuming you're not drawing millions of tiles).

  4. #19
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    I agree with Jverkoey and Fracticality. If the texture must be that big, then yes, kudos for finding a way to handle it. But I disagree that would be easier to manage or even faster than breaking it down into smaller textures and improving your algorithm to sort geometry by texture changes.

    If you break the big 4096x4096 texture into say 4 2048x2048 textures, then ordering by texture shouldn't be terribly difficult
    Code:
    int numTextures = 4;
    for(int i = 0; i < numTextures; ++i)
    {
        SetTexture(tileTextures[i]);
    
       for(int tile = i; tile < numTiles; tile+=numTextures)
       {  
          DrawTile(tileList[tile]);
       }
    }
    Breaking the texture down smaller will change numTextures. With this algorithm, you could actually have any number of breakdowns of the large texture, just calculate numTextures accordingly.

    Maybe we still don't fully understand your situation, Bubba?

  5. #20
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You are thinking incorrectly.

    Textures just wont work here. You must think old-school 2D. It's been done before and even in Direct3D you can do it. Think Command and Conquer, Zelda, etc, etc.

  6. #21
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    You're pushing polygons to the card, each with a specified texture and uv texture coordinate, correct? I don't see why sorting by texture ID can't work then, unless I'm still confused as to what you'd like to do.

  7. #22
    Registered User
    Join Date
    Apr 2006
    Posts
    43
    Bubba, I don't know if it's we who don't understand you or you who don't understand us, but I'm old-school enough to have done pure tile based games on the amiga and if I where to do it today I would do it the way I said since modern graphics cards are all about polygon pushing. I doubt you'll run into fill rate problems since you should have almost no overdraw with your 2d rendering style.

    About the code showing, it would take too much of my time to do it, sorry, fulltime work and girlfriend takes up enough of my time, I rather do my spare time coding on my own things.
    If you get your tile rendering to work then great, I was just trying to suggest an alternative way without so much work involved.

    You have to ask yourself if you're on the right track when your problem is that you need to render a fraction of the available texture memory on the graphics card onto the screen...I'm not trying to sound like a git, but I really think there are better ways to do this =)

    English is not my prefered choice of language, so misinterpret my words in the nicest way possible =P

  8. #23
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Quote Originally Posted by fractality
    Bubba, I don't know if it's we who don't understand you or you who don't understand us, but I'm old-school enough to have done pure tile based games on the amiga and if I where to do it today I would do it the way I said since modern graphics cards are all about polygon pushing. I doubt you'll run into fill rate problems since you should have almost no overdraw with your 2d rendering style.

    About the code showing, it would take too much of my time to do it, sorry, fulltime work and girlfriend takes up enough of my time, I rather do my spare time coding on my own things.
    If you get your tile rendering to work then great, I was just trying to suggest an alternative way without so much work involved.

    You have to ask yourself if you're on the right track when your problem is that you need to render a fraction of the available texture memory on the graphics card onto the screen...I'm not trying to sound like a git, but I really think there are better ways to do this =)

    English is not my prefered choice of language, so misinterpret my words in the nicest way possible =P
    I like the way you sneaked in "girlfriend" to prove you have one.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  9. #24
    Registered User
    Join Date
    Apr 2006
    Posts
    43
    Ha ha, nerds and girls, always a hot topic =P
    But I'm 30 years old and have been together with her for the last couple of years yes.

  10. #25
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Sweet.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  11. #26
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    You are thinking incorrectly.
    How so? *inquisitive, not snarky*

  12. #27
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ok this is the best I have so far. I scrapped the per-pixel algo and went with my old one, but I spiced it up a little bit.

    Instead of retrieving ID, draw quad, etc, etc. it now retrieves the ID. If the ID is not the same as the last ID then it sets the texture to the last id and renders primCount number of primitives. Then I increment a pointer in my software vertex buffer based on vertexCount.

    For scrolling, I have an ugly section of code but it's so much faster to increment a pointer than to use the array indexing.

    Here is the code. There are still some bugs but this thing renders rather fast.

    Code:
    void CScreenGrid::RenderSoftware(float fTimeDelta)
    {
      
      //m_pDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
      
      //Set FVF
      m_pDevice->SetFVF(TLVERTEX_FVF);
    
      //Texture ID
      DWORD dwTexID=0;
      //Previous texture ID
      DWORD dwLastID=0;
    
      
      //Variables for loop
      DWORD dwStartOffset=m_dwCurrentOffset;
      DWORD dwOffset=dwStartOffset;
      DWORD dwRow=0;
      DWORD dwCol=0;
    
      //Vertex buffer pointer
      TLVertex *pSVB=m_pSVB;
    
      //Vertex and primitive Counters
      int vertexCount=0;
      int primCount=0;
    
      //Draw flag
      bool bDraw=false;
    
      //Loop through all layers - bottom up
      for (DWORD map=1;map<m_pMapManager->GetSize();map++)
      {
        
        dwTexID=0xFFFFFFFF;
        dwOffset=dwStartOffset;
        dwStartOffset=m_dwCurrentOffset;
        dwRow=0;
        dwCol=0;
        primCount=0;
        bDraw=false;
    
        //Set to equal to start system
        dwLastID=dwTexID;
    
        //Loop through all vertices
        for (DWORD i=0;i<m_dwTotalVerts;i+=6)
        {
          //Get texture ID from map
          dwTexID=m_pMapManager->GetMapValue(map,dwOffset);
        
          //Increment vertex and primitive counters      
          primCount+=2;
          vertexCount+=6;
    
          //Is this ID the same as the last?
          if (dwTexID==dwLastID)
          {
            bDraw=false;
          } else bDraw=true;
          
          //If it is, draw the batch of primitives that share lastID's texture
          if (bDraw)
          {
            
            m_pDevice->SetTexture(0,m_pTexManager->GetTexture(dwLastID));
            m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,primCount,pSVB,sizeof(TLVertex));
            
            //Increment the vertex buffer pointer
            for (int v=0;v<vertexCount;v++)
            {
              *pSVB++;
            }
                    
            //Reset state
            primCount=0;
            vertexCount=0;
            bDraw=false;
            dwLastID=dwTexID;
            
          }
          
          //Map housekeeping
          dwOffset++;
          dwCol++;
    
          //Map counter
          if (dwCol>=m_iNumTilesHoriz)
          {
            dwCol=0;
            dwRow++;
            dwStartOffset+=m_pMapManager->GetWidth(map);
            dwOffset=dwStartOffset;
          }
        
          
        }
      }
    
    }
    And the ugly scroll code:
    Code:
    void CScreenGrid::ScrollSoftware(int irelScrollX,int irelScrollY)
    {
      //Scroll flag
      bool bScroll=true;
    
      //Map offset change for scroll
      int iOffsetChange=0;
        
      //Scroll vars
      m_iScrollX+=irelScrollX;
      m_iScrollY+=irelScrollY;
      
      //World scroll
      m_iWorldX+=-irelScrollX;
      m_iWorldY+=-irelScrollY;
    
      //Test for +X   
        if (m_iScrollX>=(m_iIncrementX-1))
        {
          irelScrollX=-m_iScrollX+irelScrollX;
          m_iScrollX=0.0f;
          iOffsetChange=-1;
         
        }
      
        //Test for -X
        if (m_iScrollX<=(-m_iIncrementX+1))
        {
          irelScrollX=-m_iScrollX+irelScrollX;
          m_iScrollX=0.0f;
          iOffsetChange=1;
        }
    
        //Text for +Y
        if (m_iScrollY>=m_iIncrementY)
        {
          irelScrollY=-m_iScrollY+irelScrollY;
          m_iScrollY=0.0f;
                
        }
      
        //Test for -Y
        if (m_iScrollY<=-m_iIncrementY)
        {
          irelScrollY=-m_iScrollY+irelScrollY;
          m_iScrollY=0.0f;
        
        }
      
        //Bounds check X
        if (m_iWorldX<0)
        {
          bScroll=false;
          m_iWorldX=0;
          iOffsetChange=0;
        }
        
        //Bounds check Y
        if (m_iWorldY<0)
        {
          bScroll=false;
          m_iWorldY=0;
          iOffsetChange=0;
        }
    
        if (bScroll)
        {
          //Change map offset
          m_dwCurrentOffset+=iOffsetChange;
    
          //Buffer pointer
          TLVertex *pSVB=m_pSVB;
    
          //Increment pointer and change values
          for (DWORD i=0;i<m_dwTotalVerts;i+=6)
          {
            pSVB->x+=irelScrollX;
            pSVB->y+=irelScrollY;
    
            *pSVB++;
    
            pSVB->x+=irelScrollX;
            pSVB->y+=irelScrollY;
            
            *pSVB++;
    
            pSVB->x+=irelScrollX;
            pSVB->y+=irelScrollY;
    
            *pSVB++;
            
            pSVB->x+=irelScrollX;
            pSVB->y+=irelScrollY;
    
            *pSVB++;
            
            pSVB->x+=irelScrollX;
            pSVB->y+=irelScrollY;
    
            *pSVB++;
            
            pSVB->x+=irelScrollX;
            pSVB->y+=irelScrollY;
          
            *pSVB++;
          }
      
        }
    
    }

  13. #28
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    I think it's pretty. Could do with a few more spaces between operators / operands but I guess my thumb gives up after a while too

    EDIT: Yes, I realise this has nothing to do with the topic at hand. Sue me. Unless you're a moderator who actually can do something about it...

    Meh.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  14. #29
    Registered User
    Join Date
    Apr 2006
    Posts
    43
    Hmm, do you have each tile in a separate texture?
    It looks like it but without knowing how the internals of the TexManager works it's hard to say...
    Do you update all the vertex positions when you do the scrolling?
    Those two things look a little fishy to me, perhaps that's why you have had problems with speed? What CPU/Gfx card/resolution and speed do you get from this routine?

    BTW, what are you doing here? Am I just tired or is this weird? No, time to watch movie, cu.
    Code:
      
            //Increment the vertex buffer pointer
            for (int v=0;v<vertexCount;v++)
            {
              *pSVB++;
            }

  15. #30
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by fractality
    BTW, what are you doing here? Am I just tired or is this weird?
    You are not just tired. That code is equivalent to "pSVB+= vertexCount;".
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Smooth walking on tile based map system
    By abraham2119 in forum C Programming
    Replies: 8
    Last Post: 07-10-2009, 10:33 AM
  2. Polynomials and ADT's
    By Emeighty in forum C++ Programming
    Replies: 20
    Last Post: 08-19-2008, 08:32 AM
  3. File map performance
    By George2 in forum C++ Programming
    Replies: 8
    Last Post: 01-04-2008, 04:18 AM
  4. Need testers for editor
    By VirtualAce in forum Game Programming
    Replies: 43
    Last Post: 07-10-2006, 08:00 AM
  5. Tile map loading/saving
    By sand_man in forum Game Programming
    Replies: 16
    Last Post: 04-23-2005, 09:38 PM