2012-12-12 18 views
6

Questo è un codice che uso per disegnare rettangolo nel mio programma:bordo intorno tessitura, OpenGL

glBegin(GL_QUADS); 
    glTexCoord2f(0.0f, maxTexCoordHeight);    glVertex2i(pos.x, pos.y + height); 
    glTexCoord2f(0.0f, 0.0f);       glVertex2i(pos.x, pos.y); 
    glTexCoord2f(maxTexCoordWidth, 0.0f);    glVertex2i(pos.x + width, pos.y); 
    glTexCoord2f(maxTexCoordWidth, maxTexCoordHeight); glVertex2i(pos.x + width, pos.y + height); 
glEnd(); 

Essa trae solo un semplice rettangolo con trama specificato, per esempio in questo modo: enter image description here

vorrei chiedere se è possibile in OpenGL per ottenere effetto frontiera in questo modo:

Come si vede all'interno di questa tessera c'è solo un semplice sfondo blu che potrebbe essere gestito separatamente - trama ridimensionata automaticamente. Questo può essere ottenuto facilmente con uno snippet di codice che ho dato, ma il problema è con il bordo.

Se il bordo doveva essere un colore, potrei provare a disegnare un rettangolo vuoto non riempito usando GL_LINES attorno alla mia trama, ma non lo è.

Anche se le tessere erano sempre con una dimensione fissa, potevo preparare una texura che le corrispondesse, ma DEVONO essere facilmente ridimensionabili senza cambiare un file bitmap che utilizzo come texture.

Quindi, se non è possibile con le funzioni di base OpenGL, quali sono gli approcci per ottenere questo effetto che sarebbe più efficiente e/o facile?

MODIFICA: Deve essere 2D.

+0

A meno che non sia necessario 2d, perché non creare effettivamente l'effetto smussato creando quella forma trapezoidale in 3D e utilizzare l'illuminazione per ottenere gli effetti ombreggiati di cui hai bisogno? – Quetzalcoatl

+0

@Quetzalcoatl Grazie per la risposta, ma sì, deve essere 2D. Modificherò la mia domanda per aggiungere queste informazioni. –

+1

È possibile scrivere uno shader di frammenti per aggiungere il bordo. Tuttavia, se stai ancora utilizzando la modalità immediata (funzioni obsolete come 'glVertex'), probabilmente ti ci vorrà un po 'per raggiungere il meraviglioso mondo di OpenGL 2.0 e oltre. –

risposta

4

Questo è un problema classico di GUI con OpenGL e viene spesso risolto utilizzando il modello a 9 celle. In questo, aggiungi l'effetto all'immagine originale (o definiscilo con altri parametri opengl) e dividi il quadrante renderizzato in nove quad: tre righe e tre colonne.

Quindi si fissa l'altezza della riga superiore e inferiore, mentre si fissa la larghezza della colonna sinistra e quella destra. Il quad centrale è ridimensionato in modo tale che il tuo oggetto si adatti al rettangolo che vuoi adattare. Quindi si mappano solo le parti di confine della trama ai quad che formano le celle esterne, mentre si mappa il centro della trama sul quad centrale.


In relazione a quanto detto nei commenti, è possibile utilizzare anche effetti 3D effettivi realizzando il quad 3D. Nessuno ti obbliga a utilizzare la proiezione prospettica in quel caso, puoi stare con la proiezione ortogonale (modalità 2D). OpenGL eseguirà comunque sempre calcoli 3D.

+0

Penso che la risposta consista in tutto ciò che dovevo sapere. Grazie mille, Jonas! –

0

A parte la risposta di Jonas, che è eccellente, voglio aggiungere altre due opzioni.
Il primo è quello di rendere la texture simile al quadrato desiderato. Non è necessario alcun codice di fantasia se è possibile farlo in Photoshop;).
Il secondo è complicare un po 'il codice di disegno. Se guardi la tua immagine puoi vedere che ogni "pendenza laterale" del tuo quadrato può essere disegnata con due triangoli. È possibile rendere il codice disegnare 10 triangoli invece di un quadrato e utilizzare un colore diverso per ogni gruppo di due triangoli:

draw() { 
    GLFloat i = <your_inset_here>; 

    //top border part, top left triangle 
    glColor3f(<color_0>); 
    glVertex2f(pos.x, pos.y); 
    glVertex2f(pos.x + w, pos.y); 
    glVertex2f(pos.x + i, pos.y + i); 
    //top border part, bottom right triangle 
    glVertex2f(pos.x + w, pos.y); 
    glVertex2f(pos.x + w - i, pos.y + i); 
    glVertex2f(pos.x + i, pos.y + i); 

    //repeat this process with the other coordinates for the other three borders 

    // draw the middle square using {(pos.x+i,pos.y+i),(pos.x+w-i,pos.y+i),(pos.x+w-i,pos.y+h-i),(pos.x+i,pos.y+h-i)} as coordinates 
} 

è possibile migliorare ulteriormente questo con la creazione di una funzione per disegnare un quad di forma irregolare con le coordinate dare e un colore e chiama quella funzione 5 volte.

Problemi correlati