English 中文(简体)
Merging multiple line segments
原标题:

My program uses PyOpenGL (so it s Python) with psyco.

I have around 21,000 line segments which I need to render in each frame of my render (unless the user zooms in, in which case line segments are culled and not sent to the card at all). This is currently taking around 1.5 seconds each frame to complete. That s just not good enough, so I m looking at ways to reduce the number of distinct line segments.

I imagine there would be cases where multiple line segments can be merged into one big line, but I honestly do not even know where to begin with this. I do have the start point and end point of each line stored, so that might help things. Note that I am able to take as long as I need to at startup, and memory usage isn t too much of a concern.

Any ideas would be much appreciated.

最佳回答

It s almost certainly the overhead of all the immediate mode function calls that s killing your performance. I would do the following.

Don t use GL_LINE_STRIPS, use a single list of GL_LINES instead so they can be rendered in one go.

Use glDrawArrays instead of immediate mode rendering:

float* coordinates = {....}; //x and y coordinate pairs for all line segments
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 2 * sizeof(float), coordinates);
glDrawArrays(GL_LINES, 0, 2 * linecount);
glDisableClientState(GL_VERTEX_ARRAY);

(For even better performance you can store the vertex buffer in something called a vertex buffer object, but this should be fine to begin with)

One final thing, if you re do culling on a per line basis it s probably faster to just skip it and send all the lines to the GPU.

问题回答

20K segments isn t that much. Also, you ll be lucky when you can merge 10-100 lines per frame, so the speedup by this optimization will be neglectable. The rendering process is probably slow because you create the model again and again. Use glNewList() to save all the rendering commands in an GL render list on the card and then just issue glCallList() to render it with a single command.

You can define an error metric for merging two line segments into one and then testing all pairs of segments and then merging them if the error is below a certain threshold.

One example is this algorithm:

  1. Construct a new line segment X from the two points farthest away from each other in the two line segments A and B.
  2. Find the minimum distance to X for all points in A and B.
  3. Assign the error as the maximum of those minimum distances.
  4. Replace A and B with X if the error is below your threshold.

This isn t the best algorithm, but it is easy to implement.

Edit 1

Definitely try doing display lists or vertex buffer object rendering before implementing this.





相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签