hello guys,
I'm trying to create a game that has tons of cubes ( around millions or even more ), so i have read about instancing and i have done what the tutorial said.
but when i add 100,000 cubes to the scene i have insane lags ( can't move the mouse or exit ).

Try starting with smaller amounts, like 1,000, and keep ramping it up, until you find the lag starts. You are probably doing everything correctly, because, again yeah, 100,000 cubes should cause lag.

Jeff
(here is a link to my youtube channel on opengl programming tutorials, by the way...)
https://www.youtube.com/channel/UCzx8alrxVELz5h1dfCdkdfg?view_as=subscriber

mhagain

12-10-2017, 11:53 PM

What you've done wrong is make the classic OO mistake of having each object maintain it's own GL state and GL objects, and be responsible for drawing itself. This approach just doesn't scale, leads to 100,000 draw calls, and will bring most hardware to it's knees.

Instead of this you need to start hatching objects, so that you can handle multiple objects per draw call and start getting performance back. Modern hardware can easily handle the object counts you have; this is a design problem.

One approach is that instead of drawing each object as it passes (i.e. In an object::draw call) you instead add it to a list of drawables. At some later time you take that list, construct a big batch out of it, then draw it in as few draw calls as possible.

OceanJeff40

12-11-2017, 09:00 AM

I see what mhagain is saying, yeah, I had that problem early on in learning opengl as well when I started to put classes into the picture. The CPU would be the bottleneck, or more to the point the CPU to GPU communication is your bottleneck.

Jeff

mhagain

12-11-2017, 09:59 AM

At this stage I also have to mention the dreaded unbinding.

Simplified, what goes on inside a GL driver when you issue a draw call looks something like this:
if (StateHasChanged)
{
// this part is really really expensive
ValidateState();
}
Draw();
If you have a draw loop with no unbinding, something like:
for (LotsOfObjects)
{
glBind(obj);
glDraw();
}
Then your driver may be able to intelligently optimize for cases where state doesn't actually change, and you can get lots of draw calls done fairly quickly.

On the other hand, look at it with unbinding:
for (LotsOfObjects)
{
glBind(obj);
glDraw();
glBind(0);
}
Now you're going to hit the validation check every single iteration through the loop. You've taken what could have been a quick and simple driver optimization and completely destroyed it.

If you have a problem that unbinding solves, then don't unbind - go back and fix the real source of the problem. If you don't have a problem that unbinding solves, then why the f%#*!; are you unbinding? Either way - don't unbind.

Silence

12-12-2017, 01:37 AM

And to make it simple and more clear to the OP:

* Keep a single VAO (so a single VBO)
* Read (again ?) this tutorial about instancing (https://learnopengl.com/#!Advanced-OpenGL/Instancing).