@Bubba: Out of interest, what kind of performance are you getting out of this method?
@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
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).
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
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.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]); } }
Maybe we still don't fully understand your situation, Bubba?
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.
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.
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.Originally Posted by fractality
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
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.
Sweet.
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
How so? *inquisitive, not snarky*You are thinking incorrectly.
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.
And the ugly scroll code: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; } } } }
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++; } } }
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
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++; }
You are not just tired. That code is equivalent to "pSVB+= vertexCount;".Originally Posted by fractality
Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling