Most Quake engines are CPU-bound.
By intentionally constraining themselves to the same set of GL calls that GLQuake used, they're not able to take advantage of more recent GPU features that can work to accelerate exactly the problem that you (the OP) are encountering. And when I say "more recent" I'm actually speaking about hardware that's up to 10 years old here.
Common issues that lead to exactly this problem include:
- A preference for brute-forcing simple calculations on the CPU that a GPU is able to do much faster.
- Hundreds of draw calls per-object.
- Constantly having to stream vertex data to the GPU each frame, even if that data does not change.
- Massive subdivision of surfaces to get acceptable results per-vertex for effects that really need to run per-pixel.
The end result is that the CPU is saturated, the PCI-E bus is saturated, and the GPU is mostly idle. This only gets worse as the object count increases; the most powerful processor in your machine, the one that scales really well for handling this kind of workload, ends up hardly being used at all, while the weaker CPU takes the brunt of the load, and the single-threaded nature of the Quake engine prevents today's multicore CPUs from working best.
This is all by way of saying that moving to a software engine is
not going to help you here. It's just going to load even more on the CPU and leave the GPU even more idle.
The problem with the Quake engine is not that BSP or MDL formats can't handle high object counts or complex scenes. They're not the best formats for them for sure, but they
can handle them and they
can give acceptable performance while doing so (provided you don't get too silly).
The problem with the Quake engine is that the GL calls it uses are woefully inadequate and sub-optimal for this kind of drawing. Even by restricting yourself to GL 1.1 but moving from glBegin/glEnd to vertex arrays with proper batching you can remove a lot of CPU-side overhead and start getting the GPU really working for you, and framerates will soar as scenes become more complex. Move to VBOs and transfer some CPU-side work to shaders (which allows certain classes of vertex data - like MDLs - to remain static) and things only get better.
Of the currently maintained engines I'd recommend QuakeSpasm as a solution to this problem. It's (at least last time I looked) still missing the final piece of the puzzle, which is to get some instancing in and which can really help with high MDL counts (provided they're all the same MDL, of course), but despite that recent versions are still a huge stride forward from what GLQuake did.
DarkPlaces, by the way, does also solve much of this, but it also comes with some new overhead of it's own.