Giochi 2D e OpenGL moderno


10

preconcetti

Ok, quindi quello che ho raccolto finora è questo:

  • non utilizzare la pipeline fissa (deprecato o destinato a essere deprecato)
  • vbos memorizza "modelli di oggetti" (n dati di vertici, principalmente)
  • i vaos descrivono come vengono disposti i dati in modo che le chiamate di disegno sappiano quale parte di ciascun vbo è per quale tipo di informazioni sui vertici (un vao può riferirsi a più vbo, il contrario è piuttosto difficile)
  • ogni chiamata di disegno invia anche dati vertici agli shader

Come vedo il 3D (opzionale)

Date queste informazioni, posso vedere come disegnare oggetti complicati in 3D sia molto bello con il moderno OpenGL. In pratica carichi un sacco di modelli di oggetti (probabilmente da Blender o altri software simili) in VBO con coordinate locali, e poi semplicemente fornisci a ciascuna istanza di un oggetto un diverso parametro shader (offset) per disegnare nello spazio mondiale.

Problema / domanda

In 2D, tuttavia, i problemi e le priorità sono completamente diversi. Non disegni oggetti molto complessi, non hai bisogno di matrici di proiezione complicate e quant'altro e shader sono molto più semplici.

Quale sarebbe il modo migliore per disegnare frequentemente (davvero frequentemente, praticamente ogni fotogramma) cambiando geometria con OpenGL moderno?

Nel paragrafo seguente puoi vedere alcune idee di problemi (il problema del cerchio e del rettangolo), che identificano meglio il tipo di cambiamenti che mi interessano.

I miei tentativi (facoltativo)

Quindi, ho iniziato a pensare come avrei gestito il disegno della geometria 2D di base sullo schermo:

  • un quadrato: carica un [(1, 0), (1, 1), (0, 1), (0, 0)]VBO per la geometria di un quadrato nello spazio locale, quindi fornisci allo shader la larghezza effettiva del quadrato e le coordinate del mondo e le informazioni sul colore

si raffredda, sembra facile. Passiamo a un cerchio:

  • un cerchio: triangolo fan con ... eh. quanta precisione (numero di vertici)? per i piccoli cerchi la precisione deve essere piccola e per i cerchi dei bug la precisione deve essere alta. Chiaramente il caricamento di 1 VBO non può essere adatto a tutti i casi. Cosa succede se devo aggiungere precisione perché un cerchio viene ridimensionato per essere più grande?

Meno fico. Passiamo a qualcosa di leggermente più semplice, un rettangolo:

  • un rettangolo: eh. non esiste una "geometria generale del rettangolo". Hai solo una proporzione larghezza / altezza e il gioco è fatto, ma ogni rettangolo è probabilmente diverso se le dimensioni cambiano.

Come puoi vedere, le cose vanno in discesa da lì. Soprattutto con poligoni complessi e quant'altro.

Nessuna politica di codice: P

Ho solo bisogno di una panoramica dell'idea, non è necessario alcun codice, in particolare il codice C o C ++. Dì cose come: "crea un VBO con questi dati di vertice e poi associali, ...".


Penso di capire cosa stai chiedendo, ma potresti voler dare a questa domanda un po 'più di direzione. Non è chiaro ciò che viene chiesto - che in realtà è una ragione stretta.
Lysol,

@AidanMueller Non sono sicuro di cosa intendi, ma sentiti libero di dare più direzione se ne senti il ​​bisogno.
Scarpa

La risposta principale inizia attualmente dicendo "La tua domanda principale sembra essere". Ciò indica che non è chiaro quello che stai chiedendo. Forse dovresti fornire un riepilogo di ciò che non devi sapere alla fine della tua domanda. Dopotutto, questo è un Q / A, non una discussione.
Lysol,

@AidanMueller Non in quel contesto, credo. Dice "La tua domanda principale sembra essere ..." e poi cita la domanda che ho pubblicato. Il che indica in realtà che è abbastanza chiaro per essere citato. Inoltre la frase indica non che la mia domanda non è chiara, piuttosto che c'è una domanda principale e un'altra domanda secondaria (che è: qual è la soluzione ai casi specifici che ho presentato). Davvero non vedo il problema con la mia domanda attuale, e apparentemente nemmeno i rispondenti hanno fatto poiché ho trovato entrambe le risposte molto utili e al punto.
Scarpa

Puoi disegnare un cerchio preciso con uno shader di frammenti.
user253751

Risposte:


5

La tua domanda principale sembra essere:

Quale sarebbe il modo migliore per disegnare frequentemente (davvero frequentemente, praticamente ogni fotogramma) cambiando geometria con OpenGL moderno?

Nella maggior parte dei modi, non c'è grande differenza tra OpenGL 2d e 3d. La pipeline grafica ha quella coordinata aggiuntiva, Z, che non verrà utilizzata tanto in 2d, ma è tutto.

Ci sono alcuni modi per cambiare la geometria su ogni disegno.

  • È possibile inviare nuovi vertici forniti dalla CPU in ogni frame. (Vedi /programming/14155615/opengl-updating-vertex-buffer-with-glbufferdata per alcune note sul riutilizzo dei buffer.)

  • È possibile disegnare diverse parti di un buffer esistente, con glDrawArrays(mode, first, count). Se l'animazione scorre, forse puoi mettere i fotogrammi precompilati con le diverse liste di vertici in un grande buffer e disegnare la porzione appropriata del buffer per ogni fotogramma.

  • È possibile influenzare l'elenco dei vertici con altri dati, come una matrice uniforme o una trama. Nel tuo vertice shader, leggi questi dati e applicali in modo appropriato. Questi sono solo altri modi di dire per presentare i dati alla GPU e probabilmente non avranno molte differenze nelle prestazioni.

  • Se hai molte istanze della stessa geometria (probabilmente influenzate dagli attributi), allora glDrawElementsInstanced()può essere utile

  • È possibile influenzare algoriticamente l'elenco dei vertici negli shader di vertice, geometria o tassellatura. Se l'animazione può essere descritta matematicamente, potresti essere in grado di mantenere lo stesso elenco di vertici e modificare solo alcune uniformi di shader per ogni fotogramma.

E forse la tua animazione potrebbe essere espressa come trame pure, con tutta l'animazione fatta pixel per pixel dalla CPU, o pre renderizzata dal disco.

Nel complesso, direi: "I computer sono veloci, fanno sì che funzioni nel modo più semplice possibile, il che è probabilmente impostando nuovi vertici realizzati dalla CPU su ogni frame. Quindi, vedi se è abbastanza buono. Profila l'utilizzo della batteria / CPU primo, footprint di memoria secondo. "

L'altra tua domanda , parafrasata, "Qual è un buon modo per disegnare cerchi e rettangoli?"

Circles.

  • Con gli shader di tassellatura (o shader della geometria) è possibile rendere dinamica la geometria.

  • Potresti disegnare dei quadrati e nel tuo frammento shader solo opaco (alfa = 1.0) all'interno di un raggio e trasparente (alfa = 0,0) al di fuori del raggio. Quindi è pixel perfetto ogni volta. (Rendi i tuoi vertici quadrati da -1 a +1 e nello shader di frammenti qualcosa del tipo outColor.a = dot(coord.xy, coord.xy) < 1.0 ? 1.0 : 0.0;. Potrebbe anche levigare un po 'il bordo, starebbe bene lì ...)

  • Potresti sempre usare, per esempio, un ventilatore a 120 triangoli. Probabilmente abbastanza buono.

Rettangoli.

  • Penso che tu abbia risposto alla tua stessa domanda, su quella. Quello che suggerirai funzionerà benissimo!

Il frammento-shader / raggio è piuttosto pulito, grazie. Per quanto riguarda il fatto che io risponda alla mia domanda, non credo di capire cosa intendi.
Scarpa

Oh, proprio come con un quadrato, dici di controllare la larghezza (con l'uniforme, suppongo) e hai scritto: "Hai solo una proporzione larghezza / altezza e basta, ma ogni rettangolo è probabilmente diverso se la dimensione cambia" . Quindi, per un rettangolo, fai lo stesso di un quadrato ma avrai bisogno di 4 valori (x, y, w, h) anziché 3 (x, y, w). Oppure passa (xlow, xhigh, ylow, yhigh) come quattro uniformi. Con il tuo input da (0,0) a (1,1), è sufficiente che Vertex Shader faccia ciò di cui ha bisogno.
David Van Brink,

Oh, capisco, ha senso.
Scarpa

Esiste un ventilatore automatico in GL moderno come GL_TRIANGLE_FAN dalla pipeline a funzione fissa?
John P

5

Non posso dire di essere esperto di questo argomento, e nei miei progetti di gioco mi sono concentrato di più sul lato 3D, quindi il mio lato 2D è piuttosto semplice generalmente usando cose fatte per lato 3D; e ovviamente, la mia prospettiva è dal lato dei giochi, quindi la mia grafica 2D è più incentrata sugli sprite che sulla geometria. Da quella prospettiva,

1) Quadrati e rettangoli sono abbastanza facili. Ho un solo box 1x1 in un VBO che uso per blitare tutto. Passo le matrici MVP allo shader con questa "scatola unitaria" e l'ho combinata con un ridimensionamento aggiuntivo per ridimensionare la scatola alle giuste dimensioni - come sai, puoi avere diverse scale xey.

Per i miei scopi, ho pensato di passare dall'uso della "unit box" a una sorta di motore di particelle per blandire gli sprite 2D, ma questa è un'altra storia.

2) Non lavoro molto con i cerchi, utilizzo solo VBO fissi con un numero specifico di vertici. Ma potrei immaginare di poter fare qualche passo in avanti per influenzare il numero di vertici disegnati per il cerchio.

Quando si collegano i dati VBO agli attributi dello shader, utilizzo glVertexAttribPointer. Ha un parametro falcata pensato per essere usato per i dati interlacciati (che io uso). Ma potrebbe essere possibile usarlo in questo modo:

glVertexAttribPointer(..., n * sizeof(VERTEX_DATA), ...);

... per selezionare ogni ennesimo vertice dal buffer, influenzando così il numero di vertici disegnati per il cerchio. Potrei creare diversi VAO con lo stesso VBO con passi diversi che influiscono sul numero di vertici disegnati per il cerchio. Non ci ho provato, ho pensato.

In generale, sì, lavorare con i VBO e questo rende un po 'più complicato il tweaking sul lato CPU, perché ho studiato cose diverse per rendere il tweaking sul lato GPU (shader). Tuttavia, secondo questo articolo, l'utilizzo dei VBO è più efficiente sull'hardware moderno anche se sono necessari molti "interventi" sul lato CPU:

http://www.quelsolaar.com/opengl_performance.txt

Spero che questo ti aiuti un po 'a progettare e decidere le tue indicazioni.


2
"passo a passo per influenzare il numero di vertici disegnati per il cerchio" Super cool!
David Van Brink,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.