Um... Too much? Or too old?

Blitz3D Forums/Blitz3D Programming/Um... Too much? Or too old?

Adam Novagen(Posted 2009) [#1]
Okay, so I just did this thing which creates a 2D tile-based world in 3D. The grid array is 200x200, so 40,000 elements total. Regular "floor" tiles are sprites rendered in Alpha Blend mode, while "empty" spaces are invisible cubes to generate collisions. Thing is, when I fired it up, I got 3 frames per second.

My laptop, which is what I was using, is undoubtedly old; 750MHz PIII, and 8MB Gfx memory. However, the camera in this program is so close to the "ground" that there are only about 100 or so tiles/blocks visible onscreen at any given time, and I didn't think offscreen rendering slowed things down much. They're not moving or animated, either, just static.

SO, have I exceeded the practical limits of gaming by creating 40,000 B3D entities? Have I probably messed something up in my programming? Or is my laptop simply too slow to be useful in this case?


GfK(Posted 2009) [#2]
SO, have I exceeded the practical limits of gaming by creating 40,000 B3D entities?
Yes, pretty much.

You said invisible spaces are cubes - why? A cube is 12 tris. If you used quads, that'd be 2 tris - a saving of 10 tris per empty space.

Anyway ,depending on how you've done it, you potentially have 40,000 surfaces, and that's why its going so slow.


RifRaf(Posted 2009) [#3]
Thats alot of entities, and thats an old laptop :) You'll need to create a clever system that doesnt have so many enities loaded at one time. Blitz isnt happy when you try to make it muscle its way through things. Instead experiment with alternative methods.

For example, do your tiles have to be modified in real time? each one? If not you can use a grid system to check what tile the player is on istead of checking the entity itself. If you do this you can take every 10x10 or more and addmesh() them together to get your entity count down. Assuming you are reusing a texture set on tiles the surface count should stay tolerable with this method.

As mentioned you can still do grid checks with a simple bank or Dim.. such as DIM MapIndex(200,200) where the value is just an integer referring to the tile type, and knowing the tile size can do simple math on the character xy coordinates to get what grid location its on.


Ross C(Posted 2009) [#4]
I'd go with add mesh for the empty space for a start, to combine the cubes, and ditch sprites and go for a single surface method, with all the tile textures on the one texture.

That way, the collision cubes, become one whole mesh and are processed as such.


Adam Novagen(Posted 2009) [#5]
Hm, okay... So if I cut down the number of surfaces using AddMesh(), I can save some speed? In that case, I should be able to modify my old FloodFill routine to combine the cubes... Come to think of it, they only need to be going around the edges of the map... Mumble mumble...

Oh, yeah, I'm still typing. Heh, whoops. =^_^= Thanks for the info guys, I'll see what I can do & post back if I need more help. Ta!


PowerPC603(Posted 2009) [#6]
When you use AddMesh(), one of both meshes still exist, you will have to free it after you have done the adding, or you'll have 2 meshes on the same place.

Yes, when yoy should have 10.000 empty spaces, you would have 10.000 seperate cubes, which translates into 10.000 seperate surfaces.
If you would join all those into one mesh, you only have one mesh with one surface, which gives a great speedboost.

I've done a 3D maze where you can walk through, the size of the maze can be 62x62 tiles.
But each tile is added to one big mesh.
A maze of 62x62 almost reaches the maximum triangle limit for DX7, which is 65.535 triangles.
That maz can be rendered at 100fps minimum, as the graphics card only needs to render 1 object with 1 texture.


Adam Novagen(Posted 2009) [#7]
Right, I'll try it. Does AddMesh() work with sprites? 'Cuz if not, I'm gonna have to do some thinking.....


GfK(Posted 2009) [#8]
I don't think AddMesh works on sprites.

Anyway, use quads instead of sprites. It'll run far faster that way as you'll be able to reduce the number of surfaces to just a handful, instead of thousands of them.


Ross C(Posted 2009) [#9]
Yeah, use single surfaces method :) As mentioned before ;)


Adam Novagen(Posted 2009) [#10]
Yeah, I'm gonna do that today. I feel like SUCH a moron now, when I actually think about it.

The trouble (in my head) is that I'm porting this game from its lower-quality-but-well-established 2D version. The thing with 2D programming is that when it comes to the graphics, it's only what's on the screen that matters. I sometimes forget that 3D concepts differ in that anything that exists in the game must be updated with each call of UpdateWorld(). When I think about it, an individual cube in every empty space is LUDICROUS!!! I mean, come on; in the game levels, there will be PLENTY of open spaces several tiles across and down, and in places like those, you don't need cubes in the middle of nowhere, because the player'll never get past the ones on the outside!!! And since many of the levels won't be the full 200x200, that means even MORE wasted power with cubes that don't need to be there!

Anyway, thanks for the help guys (and gals? I never really thought about it, but there are probably a few female programmers here...) I'll update my code today, and hopefully bring the framerate up to a decent 30. Which is the most my laptop'll EVER get in a B3D game rendered in 1024x768x16. Believe me, I've tried. XD


Adam Novagen(Posted 2009) [#11]
Okay, I got it working. Had a little trouble with the textures, as usual, but I found a workaround that works fine in this scenario, so I'm not worried.

First off, I cut down the size of the game world. After going over the entire level in blank sample form, I realized that I really did NOT need a 200x200 map for any of the levels in this game. I cut it down to 100x100, so that means one quarter of the original tiles, and one quarter of the original power needed.

I made my own quad in Wings3D; two sides, four polygons & vertexes. I didn't technically need the second side, but Wings3D doesn't do one-sided models, and the other side won't get rendered by Blitz anyway as it's a backface, so I'm good. Each quad is 4x4 units, and gets textured with sixteen tiles. I spent ages grappling with CreateTexture(), because every time I used CreateTexture() with the Alpha flag it went totally black, but I ended up using the normal Color flag for the texture and setting the quads to blend mode Add. Due to the background in this particular game, this produces equally good, if not better, results.

Result: I actually got the game running at 60FPS, at a 1024x768x16 resolution, ON MY OLD LAPTOP. 8D I haven't coded in the walls yet, but that shouldn't be too hard. SO, a big thank you for all your help, and I'm getting back to work on Midnight Hacker, this time for REAL!!! I'll start a worklog in due time. Later!


cyberyoyo(Posted 2009) [#12]
That's not how you display a 2D tile-based world.
You have to create as many entities to cover only the area of the screen +1 tile in every direction, then do the math to display only the chunk of the grid that interests you, and have them scroll correctly and jump back when scroll passes to the next tile.
It is actually less complex than it sounds and then you have no limit on your number of tiles you can go to 2000x2000 if you want.


Adam Novagen(Posted 2009) [#13]
I know, cyberyoyo, that's... Pretty much what I was doing already, in the 2D version. I would direct your attention to my earlier statement:

The thing with 2D programming is that when it comes to the graphics, it's only what's on the screen that matters.

But that's immaterial now anyway, because I'm in the 3D realm, and there IS no onscreen-offscreen as far as UpdateWorld() is concerned.