Domanda

Di default sembra che gli oggetti siano disegnati da davanti a dietro. Sto disegnando un oggetto UI 2-D e vorrei crearlo di nuovo in primo piano. Ad esempio, potrei creare prima un quadrato bianco, quindi creare un quadrato nero leggermente più piccolo sopra di esso creando così un riquadro nero con un bordo bianco. Questo post ha avuto qualche discussione al riguardo e ha descritto questo ordine come " Algoritmo del pittore " ma alla fine l'esempio che hanno fornito ha semplicemente reso gli oggetti in ordine inverso per ottenere l'effetto desiderato. Immagino di fronte (i primi oggetti tornano indietro, gli oggetti successivi vengono disegnati in alto) il rendering può essere ottenuto tramite una trasformazione (gOrtho?)?

Menzionerò anche che non sono interessato a una soluzione usando una libreria wrapper come GLUT.

Ho anche scoperto che il comportamento predefinito sul Mac che utilizza Cocoa NSOpenGLView sembra tornare indietro, dove come in Windows non riesco a ottenere questo comportamento. Il codice di installazione in Windows che sto usando è questo:

glViewport (0, 0, wd, ht);
glMatrixMode(GL_PROJECTION);           
glLoadIdentity();                      
glOrtho (0.0f, wd, ht, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);             
glLoadIdentity();                       
È stato utile?

Soluzione

La seguente chiamata disattiverà il test di profondità causando il disegno di oggetti nell'ordine creato. Questo in effetti farà tornare indietro gli oggetti.

glDepthFunc(GL_NEVER);      // Ignore depth values (Z) to cause drawing bottom to top

Assicurati di non chiamare questo:

glEnable (GL_DEPTH_TEST);   // Enables Depth Testing

Altri suggerimenti

Per la tua domanda specifica, non esiste un modo standardizzato per specificare l'ordine di profondità in OpenGL. Alcune implementazioni possono effettuare ordinamenti di profondità dalla parte anteriore a quella predefinita perché di solito è più veloce, ma ciò non è garantito (come hai scoperto).

Ma non vedo davvero come ti aiuterà nel tuo scenario. Se si disegna un quadrato nero davanti a un quadrato bianco, il quadrato nero deve essere disegnato davanti al quadrato bianco indipendentemente dall'ordine in cui sono disegnati, purché sia ??abilitato il buffering di profondità. Se sono effettivamente complanari, nessuno dei due è realmente di fronte all'altro e qualsiasi algoritmo di ordinamento della profondità sarebbe imprevedibile.

Il tutorial a cui hai pubblicato un link ne parlava solo perché l'ordinamento di profondità È rilevante quando usi la trasparenza. Ma non mi sembra che sia quello che stai cercando.

Ma se davvero devi farlo in quel modo, allora devi farlo da solo. Prima invia il tuo quadrato bianco alla pipeline di rendering, forza il rendering e quindi invia il tuo quadrato nero. Se lo fai in questo modo e disabiliti il ??buffering di profondità, i quadrati possono essere complanari e avrai comunque la garanzia che il quadrato nero sia disegnato sopra il quadrato bianco.

L'ordine di disegno è difficile. Non esiste una soluzione facile. L'alogoritmo del pittore (ordina gli oggetti in base alla loro distanza in relazione alla vista della tua macchina fotografica) è il più semplice, ma come hai scoperto, non risolve tutti i casi.

Suggerirei una combinazione di algroitmo e strati del pittore. Costruisci livelli per elementi specifici sul tuo programma. Quindi hai un livello di sfondo, livelli di oggetti, livelli di effetti speciali e livello GUI.

Usa l'algoritmo del pittore sugli oggetti di ogni livello. In alcuni livelli speciali (come il livello GUI), non ordinare con l'algoritmo del pittore, ma in base al tuo ordine di chiamata. Chiamate prima quel quadrato bianco in modo che venga disegnato per primo.

Disegna gli oggetti che vuoi dietro leggermente dietro gli oggetti che vuoi mettere in primo piano. Cioè, in realtà cambia il valore z (supponendo che z sia perpendicolare al piano dello schermo). Non devi cambiarlo molto per ottenere gli oggetti da disegnare uno di fronte all'altro. E se modifichi solo leggermente il valore z, non dovresti notare gran parte di un offset dalla posizione desiderata. Potresti persino diventare davvero fantasioso e calcolare la posizione x, y corretta in base alla posizione z modificata, in modo che l'elemento appaia dove dovrebbe essere.

I tuoi oggetti verranno disegnati nell'ordine esatto in cui chiami le funzioni glBegin / glEnd. Puoi ottenere il buffering di profondità usando il buffer z, e se i tuoi oggetti 2d hanno valori z diversi, puoi ottenere l'effetto che desideri quel modo. L'unico modo in cui vedi il comportamento che descrivi sul Mac è se il programma sta disegnando cose in ordine manuale o usando il buffer z per farlo. Altrimenti OpenGL non ha alcuna funzionalità automaticamente come descritto.

Come ha sottolineato AlanKley, il modo per farlo è disabilitare il buffer di profondità. L'algoritmo del pittore è in realtà una tecnica di conversione della scansione 2D utilizzata per eseguire il rendering dei poligoni nell'ordine corretto quando non si ha qualcosa come un buffer z. Ma non lo applicheresti ai poligoni 3D. In genere li trasformi e li proietti (gestendo le intersezioni con altri poligoni) e quindi ordinando l'elenco risultante dei poligoni proiettati in 2D in base alla loro coordinata z proiettata, quindi disegnandoli nell'ordine z inverso.

Ho sempre pensato all'algoritmo del pittore come una tecnica alternativa per la rimozione di superfici nascoste quando non puoi (o non vuoi) usare un buffer z.

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