I've been adding a minimap to my Isometric game, I first did this by drawing each cell as a simple square using al_draw_filled_rectangle. I then switched to using two al_draw_filled_rectangle calls to draw a diamond shape instead..
The problem I am having is there is a huge FPS difference between the two.. drawing squares results in a sold 60-70 FPS.. drawing two rectangles drops this down to just under 30!
Is this purely because I am making twice as many draw calls? How can I improve this code to be faster?
For those interested in how the map is looking here is a WIP shot:
{"name":"mapwip.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/9\/99eea73c7016c301ba7731a646e0b2a6.png","w":768,"h":576,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/9\/99eea73c7016c301ba7731a646e0b2a6"}
I'm just guessing, but I'd say you aren't getting hardware acceleration. Drawing lines is pretty easy even for software, but filling areas takes thousands of memory accesses. Show the code that sets the screen mode please.
Hmm I tried using the non-fill method (al_draw_triangle) and it was even worse performance wise ~8FPS!
{"name":"mapviewwipnonfilled.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/9\/d9e4a4492860f78f469f01ae2beeb73f.png","w":768,"h":576,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/9\/d9e4a4492860f78f469f01ae2beeb73f"}
This is the screen setting code, I'm afraid it's part of my engine so there is plenty of extra logic in there, but I've tried to cut it down to the essentials for clarity...
I've been adding a minimap to my Isometric game, I first did this by drawing each cell as a simple square using al_draw_filled_rectangle. I then switched to using two al_draw_filled_rectangle calls to draw a diamond shape instead..
Did you mean al_draw_triangle where I did put bold text? Seems so looking at the code but ain't sure (no native English speaker here).
Is the diamond shape a rotated square? or is it a more generalized quadrilateral?
Either way, there SHOULD be single-call drawing functions (in the 5.1 branch?) of Allegro that could do the trick to get back to the 60-70FPS (just like al_draw_rotated_rectangle maybe?)
Then again, we should find the cause of such a difference...skimming through your code I see nothing obvious but, you know, I am no expert there.
Are you in any position to properly profile the code?
Also, a more efficient solution could be caching the vertexes for each cell in a buffer and the use a single al_draw_prim call?
Sorry, just throwing around ideas for the moment....
Hey pkrcel, no I was using two calls to al_draw_filled_triangle. I switched to al_draw_triangle this morning to try something based on what Arthur Kalliokoski said but it made things worse..
The diamond shape is two triangles drawn one after the other (top then bottom), but you're right, I could try using a rotated square but I don't see any references to al_draw_rotated_rectangle in the 5.0.x library I'm using. I'd sooner not switch to an unstable branch unless there is no other choice...
I really don't understand why there would be such a difference in performance between these calls, hence the reason for this thread for reference I'm using Allegro 5.0.10. I can profile my code, but not the allegro library properly.
I think I'm just going to load a suitably sized sprite and tint it to the correct colour as a work around for now, but it seems crazy to go through so much 'heavy' lifting to draw a primitive
The diamond shape is two triangles drawn one after the other (top then bottom), but you're right, I could try using a rotated square but I don't see any references to al_draw_rotated_rectangle in the 5.0.x library I'm using. I'd sooner not switch to an unstable branch unless there is no other choice...
Just a quick post...I confused rectangles with bitmaps!!!! shame on me.
EDIT:
in the 5.1 branch there is al_draw_filled_polygon which should do the trick.
Anyway as I see it is a convenient wrapper around al_draw_prim, which could be tougher to use but is available in 5.0 (I guess? there is no "since" in the docs for this).
Thanks for the prod in the right direction! I dug around and figured out how to make al_draw_prim do what I wanted. Getting about 50 FPS now which is almost twice what two triangle calls was for the same result.. going to fiddle a bit more but quite pleased with this.
EDIT: Here is the optimised code:
You will also find that drawing bitmaps will be substantially faster than drawing (filled or not) primitives. You would get a speed boost if you made square bitmaps and drew those instead.
Thanks for the prod in the right direction! I dug around and figured out how to make al_draw_prim do what I wanted. Getting about 50 FPS now which is almost twice what two triangle calls was for the same result.. going to fiddle a bit more but quite pleased with this.
There are countless discussions about primitives having overhead, not really sure if unfounded or not, anyway it makes sense that you group all calls to al_draw_prim building a list of vertexes and making a single draw call....call it an exercise, and if you succeed pls share results with me as I have no Idea of what I'm talking about
You will also find that drawing bitmaps will be substantially faster than drawing (filled or not) primitives. You would get a speed boost if you made square bitmaps and drew those instead.
Wouldn't this be true only if holding bitmap draws (al_hold_bitmap_drawing)?
Wouldn't this be true only if holding bitmap draws (al_hold_bitmap_drawing)?
I've never actually run any tests with al_hold_bitmap_drawing, but I can tell you that you will get a faster render with bitmaps whether or not you defer your bitmap drawing.
Recent discussions seem to indicate that there is some controversy about that...
Batching a single al_draw_prim (with either textures or not) seems still the most efficient way to draw a (somewhat big) bunch of (maybe non overlapping) things...
Defer drawing seems to have similar effects as batching draw calls in al_draw_prim.
I found it extremely interesting but I am unable to test that right-no, actually I am unable to devote any serious time to Allegro or programming (aside participating in the forums not to rot my already abysmal knowledge )
EDIT:
Hey ionising thaks for posting the draw code...interesting...
I've never actually run any tests with al_hold_bitmap_drawing, but I can tell you that you will get a faster render with bitmaps whether or not you defer your bitmap drawing.
Does using the al_draw_(primitive) functions create a vertex buffer, fill it, pass it on and the destroy it, and that is the reason why bitmap drawing is faster even without deferred drawing?
If so then I think using al_draw_prim won't help (since you are passing vertex data from your memory), but using al_draw_vertex_buffer should speed things up considerably, though I see no simple way to control where the buffer will be drawn other then setting the appropriate transformation before drawing and then restoring it.