Domanda

Il mio programma utilizza Pyopengl (quindi è Python) con Psyco.

Ho circa 21.000 segmenti di linea che ho bisogno di rendere in ogni frame del mio rendering (a meno che l'utente si ingrandisca, nel qual caso i segmenti di linea vengono abbattuti e non inviati alla scheda). Questo è attualmente richiesto circa 1,5 secondi per il completamento. Non è abbastanza buono, quindi sto cercando modi per ridurre il numero di segmenti di linea distinti.

Immagino che ci sarebbero casi in cui i segmenti di più linee possono essere uniti in una grande linea, ma onestamente non so nemmeno da dove cominciare. Ho il punto di partenza e il punto finale di ogni riga memorizzata, quindi ciò potrebbe aiutare le cose. Nota che sono in grado di impiegare tutto il tempo che ho bisogno all'avvio e l'utilizzo della memoria non è troppo preoccupante.

Qualsiasi idea sarebbe molto apprezzata.

È stato utile?

Soluzione

È quasi certamente il sovraccarico di tutte le chiamate della funzione in modalità immediata che sta uccidendo la tua performance. Farei quanto segue.

Non usare GL_LINE_STRIPS, usa un unico elenco di GL_LINES Invece così possono essere resi in una volta.

Uso glDrawArrays Invece di rendering in modalità immediata:

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

(Per prestazioni ancora migliori puoi archiviare il buffer vertice in qualcosa chiamato oggetto buffer vertice, ma questo dovrebbe andare bene per cominciare)

Un'ultima cosa, se stai abbattendo su base per riga, è probabilmente più veloce saltarlo e mandare tutte le linee alla GPU.

Altri suggerimenti

20k segmenti non è molto. Inoltre, sarai fortunato quando potrai unire 10-100 righe per fotogramma, quindi lo SpeedUp da questa ottimizzazione sarà trascurabile. Il processo di rendering è probabilmente lento perché crei il modello ancora e ancora. Uso glNewList() Per salvare tutti i comandi di rendering in un elenco di rendering GL sulla scheda e quindi emettere glCallList() per renderlo con un unico comando.

È possibile definire una metrica di errore per la fusione di due segmenti di riga in uno e quindi testare tutte le coppie di segmenti e quindi unendole se l'errore è inferiore a una determinata soglia.

Un esempio è questo algoritmo:

  1. Costruire un nuovo segmento di linea X dai due punti più lontani l'uno dall'altro nei segmenti di due righe A e B.
  2. Trova la distanza minima a X per tutti i punti in A e B.
  3. Assegnare l'errore come massimo di tali distanze minime.
  4. Sostituisci A e B con X se l'errore è al di sotto della soglia.

Questo non è il miglior algoritmo, ma è facile da implementare.

EDIT 1

Sicuramente prova a fare elenchi di visualizzazioni o rendering degli oggetti buffer vertice prima di implementare questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top