When I create about 70 objects on my screen wich are made of rendering and coliding , my "game" starts lagging a bit , but if I push further and create around 128 objects, my game freezes , or only screen does , because in console everything I chechk is working perfectly fine. Is it possible that its lagging because of allegro , or I am just making too much objects on screen and doing too much stuff with them?
]]>What version of allegro?
What are your specs?
OS?
DirectX or OpenGL?
Are you printing a lot to the console?
IN addition to what taron asked, without seeing your code, it's very difficult to tell you what's causing the lag.
]]>allegro version 5.0.9
My specs: Intel Core i3 -540 3.07GHz
4,99GB RAM
ATI Radeon HD 4800 ( 2GB graphics memory)
64bit Windows 7 ultimate
directX or OpenGL , huh none? I only use allegro XD I dont understand :S
I print velY and state changing to my console , just to see if player is working and he is , but nothing is happeninig on the sreen , so screen is forzen but game still working ( maybe since I cant test properly , or better then console)
Since I didint even understand directX and openGL question , maybe thats the problem :S since I dont even know how to make my project use one ?
]]>Are you calling al_flip_display()?
]]>Yes ofc I am calling flip display :S , maybe code from main could help you guys out?
]]>Yes, please show your display code. And the DirectX / OpenGL question applies to what Allegro is using behind the scenes. Default on Windows is DirectX. Don't worry about it.
]]>So this is the render code ( I am using list as you can see)
if(render && al_is_event_queue_empty(event_queue))
{
render = false;
//BEGIN PROJECT RENDER================
for(iter = objects.begin(); iter != objects.end(); ++iter)
(*iter)->Render();
//FLIP BUFFERS========================
al_flip_display();
al_clear_to_color(al_map_rgb(255, 255, 255));
}
Render in player class:
int fx = curFrame * frameWidth;
int fy = animationColumns * frameHeight;
al_convert_mask_to_alpha(image, al_map_rgb(255,255, 255));
al_draw_scaled_bitmap(image, fx, fy, frameWidth, frameHeight, x, y, 16, 19, 0);
Render of a Cube ( 128 objects I create):
al_draw_scaled_bitmap(image, 0, 0, 24, 24, x, y, 24, 24, 0);
As far as I understand its probably not problem in rendering, but in soo much objects created , maybe 128 objects is too much for PC even thought I dont uunderstand how can I run 3D games then wich seem khm , far more complex.
128 objects is not that much when using hardware acceleration, trust me, your objects aren't even that complex. It's far more likely a bug in your code somewhere.
Dereferencing a list iterator and an object pointer will take some time, but should not be noticeable yet. If all else fails use a vector instead, especially if the number of objects doesn't change often or you have a fixed limit to the number of them.
One thing is that you should only be calling al_convert_mask_to_alpha once when you load your objects. After that, all the color you specify (white, in your case) will be cleared to zero alpha.
So, you have checked your x and y values? And they are on screen? Everything else you showed looks okay I believe.
]]>I know my objects are not complex I mean its only drawing them , thats why this is soo weird to me.
Dereferecing iterators Il try that till tomorow since I have no clue what that does, or how to do that , Il look up on internet about that or something.
I am calling mask to alpha only once now ( when I create images tnx for the tip )
and by chechking x and y values if you mean about player ones , yes they are working fine , its like screen gets forzen at moment I make over 180 objects , and in console whatever I set to cout seems to work , but with delay , and delay of couting gets bigger and bigger , like I move play or tell him to jimp his Y updates like 7 seconds after I clicked , and further I let my program to work delay is longer , even for exiting I must wait over 10 sec.
So it seems like screen is completly forezn , nothing keeps rendering ,but code is still working , with lagg /delay.
]]>Okay, I'm gonna guess it's in your event loop. Delays like that usually have something to do with not processing events in a timely manner. Post main, or whatever holds your game / event loop.
]]>Here is my hole main.
]]>
Well, the problem may be in your collision detection routine. Your event loop looks okay as far as I can see. If you have n blocks, you are calling CheckCollisions (n*(n-1))/2 times, which is (n^2 - n)/2 which is O(n^2) time. So at 180 objects, that is 16110 calls per frame and 96,660 calls per second. And that's not to mention each time you dereference an iterator and then dereference a pointer. The second bit can't be helped, but the first part can.
If I was you, I would go ahead and switch to using a std::vector (See the SGI STL guide). There is also a problem with your algorithm. iter2 should start at iter + 1, not iter. Second, extract the pointers first.
int sz = (int)objects.size(); for (unsigned int i = 0 ; i < sz ; ++i) { Object* o1 = objects[i]; if (!o1->Collidable()) {continue;} for (unsigned int i2 = i + 1 ; i2 < sz ; ++i2) { Object* o2 = objects[i2]; if (!o2->Collidable()) {continue;} if (o1->CheckCollisions(o2)) { o1->CollidedWith(o2); o2->CollidedWith(o1); } } }
That should get you a modest speed increase. I'm not sure how using vector's iterator compares with indexing in terms of speed. It might be negligible in which case you could simply change your declaration of object to be of type std::vector. I would still extract the Object*'s from the iterator though, instead of dereferencing them multiple times (dereferencing is when you access the object pointed to by a pointer or in this case, iterator).
After that you should look into quad trees and space partitioning to reduce the number of collision checks necessary.
]]>
And sadly I cant write iter2 = iter+1
I get bunch of errors saying I cant add int to list ...
But ignore what I wrote up , because I dont need to do iter2=iter+1 ,since its loop inside of loop and first loop wich is iter is like equal 1 for example , second loop wich is iter2 is at beginig same as iter , but after 1st chechk its not , because iter wont add +1 untill second loop is done ( Sry for bad english )
EXPLANATION =============================
If you run this , result will be:
i: 1 j; 1
i: 1 j; 2
i: 1 j; 3
i: 2 j; 2
i: 2 j; 3
i: 3 j; 3
Wich clearly shows that iters will be same at one point , but will be ignore and it will continue , so j (iter 2 ) will only be equal to i(iter) in 1 out of 3 cases untill i changes.
As far as I can understand this should work just fine?( but maybe creates unneccesery chechks ....)
]]>And sadly I cant write iter2 = iter+1
Oh, sorry bout that. It would be nice if list supported pointer addition, but you can do it a different way.
Or you can use vector (which in this case you should). It supports std::vector<Type>::iterator operator+(std::vector<Type>::iterator , int);
]]>Thank you alot for showing me all this , you are amazingly good at this O.o.
Il try to replace list with vectors and see what is gonna happen. Il let you know the results
===================================== SOLUTION =================================
Just like edgar suggested I switched to vectors , and now I can create 256 cubes before getting small lagg , and it stops rendering at 300 , wich I think will be fine for now , since my agme project is very small and I probbaly wont have more then 50 objects on screen , but I still wanted to learn something more and solve this problem , Thank you everyone for the help
(edit : typos)
Btw if anyone wants to tell me why is this way working soo much better, fell free to pm me because I am trying to figure it out myself now , but its not working
]]>IIRC direct access to random access containers (like a vector) is constant complexity (O(1)) while for non-random access (like a list) it's linear (O(n) n being the number of items in the container), and that's a big difference for large numbers.
Thou I think the most of the improvement comes since you decreased the times you call the Collision routine itself.
And that's also what Edgar suggested to do further, in case of many more objects, you should partition your space so that you only check for meaningful collisions.
Usually this is called the "broad" phase of collision detection, followed by a "narrow" one that is usually exactly like yours, checking for only objects that are "close enough" to actually collide.
]]>The difference comes from all the pointer dereferencing that a list does, which a vector does not. A list's items are linked together by pointers to the next and the previous node, and to get from one to the other you have to return *next. Jumping from address to address slows the computer down significantly in cases like this. A vector works so much faster because all it takes to access the vector is to do some pointer addition.
]]>Thank you for explanation , but why is there list library then? , why would anyone use it if its soo much slower.
I also looked up what a list and vector libraries can do , and its about 80% same.
Anyhow thank you for explanation , even thought I still wonder how big games avoid this kind of problems ...
]]>Well, first of all there are MARKED differences between the two containers:
- Vectors support fast random-access ( constant time ) but are quite slow at inserting and removing objects in the middle
- conversely, lists support only a slower sequential access ( linear time ) but are extremely efficient in removing and inserting objects anywhere in the list (which is constantly sorted by comparison) in constant time.
So based on the type of operations (and algorythms) you will end up doing more frequently on the container you can choose the one that best fits your needs: handy link
Secondly, AAA games implement all of those tricks here you just had a tip to, like spatial division of objects for a very efficient broad collision phase, custom memory management for quick allocation/deallocation, deadly optimized routines for the most frequent tasks, hard-core custom containers, shader tricks...etc..etc..etc...basically thou, you'll be digging this hard only when really pushing the resources available to their limit.
]]>