Pregunta

Mi programa usa Pyopengl (por lo que es Python) con PSYCO.

Tengo alrededor de 21,000 segmentos de línea que necesito renderizar en cada cuadro de mi renderizado (a menos que el usuario se acerca, en cuyo caso los segmentos de línea se seleccionan y no se envían a la tarjeta). Actualmente, esto está tardando alrededor de 1.5 segundos en cada cuadro para completar. Eso no es lo suficientemente bueno, así que estoy buscando formas de reducir la cantidad de segmentos de línea distintos.

Me imagino que habría casos en los que se pueden fusionar múltiples segmentos de línea en una gran línea, pero honestamente ni siquiera sé por dónde empezar con esto. Tengo el punto de inicio y el punto final de cada línea almacenada, por lo que eso podría ayudar a las cosas. Tenga en cuenta que puedo tomar todo el tiempo que necesite en el inicio, y el uso de la memoria no es una gran preocupación.

Cualquier idea sería muy apreciada.

¿Fue útil?

Solución

Es casi seguro que es la sobrecarga de todas las llamadas de función de modo inmediato que está matando su rendimiento. Yo haría lo siguiente.

No lo usas GL_LINE_STRIPS, use una sola lista de GL_LINES En cambio, para que se puedan renderizar de una vez.

Usar glDrawArrays En lugar de representación de modo inmediato:

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);

(Para un rendimiento aún mejor, puede almacenar el búfer de vértice en algo llamado objeto de búfer de vértice, pero esto debería estar bien para empezar)

Una última cosa, si estás sacrificando por línea, probablemente sea más rápido omitirlo y enviar todas las líneas a la GPU.

Otros consejos

Los segmentos de 20k no son tanto. Además, tendrá suerte cuando pueda fusionar 10-100 líneas por cuadro, por lo que la aceleración por esta optimización será negligente. El proceso de representación probablemente sea lento porque crea el modelo una y otra vez. Usar glNewList() Para guardar todos los comandos de renderizado en una lista de renderizado de GL en la tarjeta y luego solo emitir glCallList() para renderizarlo con un solo comando.

Puede definir una métrica de error para fusionar dos segmentos de línea en uno y luego probar todos los pares de segmentos y luego fusionarlos si el error está por debajo de cierto umbral.

Un ejemplo es este algoritmo:

  1. Construya un nuevo segmento de línea X a partir de los dos puntos más lejos uno del otro en los dos segmentos de línea A y B.
  2. Encuentre la distancia mínima a X para todos los puntos en A y B.
  3. Asigne el error como el máximo de esas distancias mínimas.
  4. Reemplace A y B con X si el error está por debajo de su umbral.

Este no es el mejor algoritmo, pero es fácil de implementar.

Edición 1

Definitivamente intente hacer listas de visualización o representación de objetos de búfer de vértice antes de implementar esto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top