I have a program which draws some terrain and simulates water flowing over it (in a cheap and easy way).
Updating the water was easy to parallelize using OpenMP, so I can do ~50 updates per second. The problem is that even with a small amounts of water, my draws per second are very very low (starts at 5 and drops to around 2 once there’s a significant amount of water).
It’s not a problem with the video card because the terrain is more complicated and gets drawn so quickly that boost::timer tells me that I get infinity draws per second if I turn the water off. It may be related to memory bandwidth though (since I assume the model stays on the card and doesn’t have to be transfered every time).
What I’m concerned about is that on every draw, I’m calling glVertex3f() about a million times (max size is 450*600, 4 vertices each), and it’s done entirely sequentially because Glut won’t let me call anything in parallel.
So.. is if there’s some way of building the list in parallel and then passing it to OpenGL all at once? Or some other way of making it draw this faster? Am I using the wrong method (besides the obvious “use less vertices”)?
Your approach to drawing in parallel is exactly the opposite of what you should be doing.
Graphics hardware is inherently parallel and there isn’t much use in trying to make as many calls to it as possible in a very short time. It is important to make single huge calls that send data to the hardware where the parallel processing can take place. All your
glVertex()calls are exactly the opposite.As Georg pointed out:
glVertexPointer()accompanied withglDrawElements()orglDrawArrays()are a good fit for your situation, if those aren’t enough you should take the step up to Vertex Buffer Objects. Another would be to take calculations directly into the GPU with shaders. In all those methods you get parallism in the GPU nearly for free.