Animazione 2D in OpenGL [chiuso]

-1

Sto cercando di animare una texture in OpenGL. Mi sembra che dovrebbe essere facile, perché so come animare in SDL e in altre librerie, ma ho problemi. Ho una x, y, w, h che contiene le coordinate della trama per il frame che voglio. I miei dati del vertice hanno una x, y per il vertice e una x, y per le coordinate della trama. So come cambiarle, ma il problema è la larghezza e l'altezza. Come posso cambiarli in uno sprite? Tutto quello che vedo sono i vettori 2d senza larghezza o altezza. Sto trascurando qualcosa? Dovrei farlo nel VBO o nel vertex shader? Ho esaminato diverse altre domande correlate, ma stavano tutti cercando la migliore strategia, o la più ottimizzata o non correlata a questa domanda di animazione.

Modifica Mi sono reso conto che stavo guardando questo nel modo sbagliato. Posso mostrare una porzione della trama, quindi decidere quale porzione guardare, nel vertex shader molto facilmente.

    
posta Mithreindeir 26.01.2016 - 02:17
fonte

1 risposta

0

Sei davvero nel giusto percorso mentale.

Quando disegni la geometria, il vertex shader viene eseguito separatamente su ciascun vertice della geometria e trasforma le posizioni nello spazio clip, oltre a consentire la manipolazione di qualsiasi attributo associato.

Lo shader del frammento viene invocato su ciascun pixel considerato come coperto dalla geometria e gli attributi dei tre vertici sono interpolati sul triangolo.

Se si desidera modificare la posizione del proprio sprite nella vista, si altera l'attributo position, modificando il buffer dei vertici o modificando i parametri sullo shader con cui è possibile sfalsare la geometria nello spazio. Allo stesso modo, puoi modificare le coordinate della trama per decidere da quale regione della trama sei interessato al campionamento.

Se disegni solo uno o alcuni sprite, ciò che fai non ha un peso eccessivo sulle prestazioni.

Se sei interessato a disegnarli alla rinfusa, ti imbatterai in diversi colli di bottiglia:

  • il ricalcolo e la memorizzazione dei vertici di tutti i tuoi sprite ha un costo di CPU e memoria;
  • caricare la geometria ha una larghezza di banda e un colpo di latenza;
  • ogni chiamata di estrazione ha un sacco di spese generali nel driver.

Una soluzione comune a questo è istanziamento . Invece di legare un singolo set di buffer di vertici che contengono gli attributi di vertice per una mesh, puoi associare due set.

Uno degli insiemi sarà un insieme di vertici, che descrive un singolo pezzo di geometria. L'altro set rappresenta istanze distinte di quella geometria master, contenente gli attributi per istanza.

Se in precedenza avevi attributi vertice pos e tc in una configurazione come questa:

vertices = 
// position                        texcoord
{ {corner                        , tc_corner}
, {corner + float2(width, 0)     , tc_corner + float2(sprite_width, 0)            }
, {corner + float2(width, height), tc_corner + float2(sprite_width, sprite_height)}
, {corner + float2(0, height)    , tc_corner + float2(0, sprite_height)           } }

con le istanze potresti separare le cose che variano per istanza, lasciandoti un buffer di vertici che può essere riutilizzato su più sprite:

pervertex =
// position      texcoord
{ {float2(0, 0), float2(0, 0)}
, {float2(1, 0), float2(1, 0)}
, {float2(1, 1), float2(1, 1)}
, {float2(0, 1), float2(0, 1)} }

perinstance =
// world_pos  world_size             texture_pos  texture_size
{ {corner,    float2(width, height), tc_corner,   float2(sprite_width, sprite_height)}
, another_instance
, more_instances... }

Dal punto di vista del vertex shader, assomiglierà a un gruppo di attributi, la distribuzione degli attributi per-vertice e per-instance viene eseguita in anticipo dall'assembly input.

Il vertex shader farebbe semplicemente i conti sulla falsariga di:

out_tc = texture_pos + tc * texture_size;
gl_Position = float4(world_pos + pos * world_size, 0.0, 1.0);

Nota che l'instancing non è necessario per fare questo genere di cose, puoi emularlo ragionevolmente bene con più draw call e passare i parametri per istanza in variabili uniformi al tuo programma shader.

    
risposta data 26.01.2016 - 08:23
fonte

Leggi altre domande sui tag