beyond-all-reason / Beyond-All-Reason

Main game repository for Beyond All Reason.
https://www.beyondallreason.info/
Other
1.8k stars 302 forks source link

Large grid of building placements lags #2589

Open Brian-Catcow-B opened 9 months ago

Brian-Catcow-B commented 9 months ago

Description

When issuing commands to a constructor, sometimes it is handy to utilize shift+alt+[left click + drag] to create a grid of the currently selected building. However, when holding shift, scrolling out is magnified a lot so that you can very quickly view the whole map. This combination of things sometimes causes an absurdly large grid to draw on the map, which can lag the game upwards of 2 full seconds on larger maps (with a structure like wind turbines, that are somewhat small).

Expected Behaviour

The game shouldn't lag

Actual Behaviour

The game lags pretty badly

Reproduction steps

No response

Other

I suggest that to fix this, either scrolling is normal when both shift and alt are being held, or after a certain size of grid, draw culling should take place so that only the outer border of the building's dimensions be drawn. The second option wouldn't look bad because with a sufficiently large grid being placed, the player must be scrolled out an amount where it would hardly be noticable (and might actually look better because the specific buildings could be more distinguishable).

jacobguenther commented 7 months ago

I suspect whatever gadget/widget that handles this is using old opengl(glPushMatrix, glRotate, etc) to render each building. I haven't confirmed this yet though. Still trying to find which gadget/widget is responsible or if its in the engine. But that is a tomorrow project.

jacobguenther commented 7 months ago

I believe the culprit is in the engine. spring/rts/Game/UI/GUIHandler.cpp Its either in CGuiHandler::GetBuildPositions or CGuiHandler::DrawMapStuff(starting at line 3760) for each unit we use

    glPushMatrix();
    glLoadIdentity();
    glTranslatef3(buildPos);
    glRotatef(bi.buildFacing * 90.0f, 0.0f, 1.0f, 0.0f);

    unitDrawer->DrawIndividualDefAlpha(bi.def, gu->myTeam, false);

    glPopMatrix();
    glBlendFunc((GLenum)cmdColors.SelectedBlendSrc(), (GLenum)cmdColors.SelectedBlendDst());

That could cause hundreds or thousands of draw calls.

The game can render thousands of units just fine when its done right.

jacobguenther commented 7 months ago

The scroll behavior when building a grid is a separate issue but also very annoying.