Come creare un cubo in OpenGL (con immagini)

Sommario:

Come creare un cubo in OpenGL (con immagini)
Come creare un cubo in OpenGL (con immagini)

Video: Come creare un cubo in OpenGL (con immagini)

Video: Come creare un cubo in OpenGL (con immagini)
Video: Come installare Windows XP su Macchina Virtuale 2024, Aprile
Anonim

OpenGL è un potente strumento di programmazione 3D utilizzato per disegnare scene tridimensionali complesse da semplici primitive. Questo articolo ti insegnerà come disegnare un semplice cubo che puoi ruotare per visualizzare in tre dimensioni!

Per questo progetto avrai bisogno di un editor di codice e una certa conoscenza della programmazione C.

Passi

Parte 1 di 3: configurazione iniziale

1994315 1 1
1994315 1 1

Passaggio 1. Installa OpenGL Per iniziare, segui questi passaggi per installare OpenGL sul tuo sistema

Se hai già OpenGL, oltre a un compilatore C compatibile installato, puoi saltare questo passaggio e passare al successivo.

1994315 2 1
1994315 2 1

Passaggio 2. Creare il documento

Crea un nuovo file nel tuo editor di codice preferito e salvalo come mycube.c

1994315 3 1
1994315 3 1

Passaggio 3. Aggiungi #include

Queste sono le inclusioni di base di cui avrai bisogno per il tuo programma. È importante rendersi conto che in realtà sono necessarie diverse inclusioni per i diversi sistemi operativi. Assicurati di includere tutti questi elementi per assicurarti che il tuo programma sia versatile e possa essere eseguito per qualsiasi utente.

    // Include #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif

1994315 4 1
1994315 4 1

Passaggio 4. Aggiungi prototipi di funzioni e variabili globali

Il prossimo passo è dichiarare alcuni prototipi di funzioni.

    // Prototipi di funzioni void display(); void specialKeys(); // Variabili globali double rotate_y=0; doppia rotazione_x=0;

1994315 5 1
1994315 5 1

Passaggio 5. Imposta la funzione main()

    int main(int argc, char* argv){ // Inizializza GLUT ed elabora i parametri utente glutInit(&argc, argv); // Richiedi finestra True Color con doppio buffer con Z-buffer glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

  • Questa dichiarazione imposta il tuo ambiente. Una cosa importante da ricordare quando si scrivono programmi OpenGL è che devi chiedere tutto. Ciò richiede che tu abbia una maggiore comprensione di come funziona il tuo programma e cosa devi includere per ottenere la funzionalità che desideri. In questa riga, imposterai il display con doppio buffering, colore RGB e Z-buffer.
  • Doppio buffer è una tecnica utilizzata nei programmi di grafica per eliminare un problema che sorge a causa del modo in cui le immagini vengono disegnate sullo schermo. Ogni volta che si ridisegna la scena, il display deve prima essere cancellato, quindi verranno disegnate le nuove informazioni. Senza il doppio buffering osserverai un effetto di sfarfallio mentre lo schermo viene cancellato e ridisegnato ripetutamente.
  • Questo problema viene risolto aggiungendo un secondo buffer su cui disegnare. Con questo metodo, un'immagine viene disegnata nel primo buffer e quel buffer ti viene mostrato. Il fotogramma successivo verrà disegnato nel secondo buffer e, una volta fatto, i due buffer si scambieranno posizione. Vedrai immediatamente il secondo buffer, ma, nascosto a noi, il primo buffer viene cancellato e ridisegnato con il terzo frame che verrà scambiato al termine.
  • Vuoi anche abilitare il Colore RGB sistema nella tua finestra.
  • Z-buffering è come ottenere gli effetti 3D che desideri. OpenGL utilizza un sistema di coordinate tridimensionale con assi x, yez. Per dare l'effetto che un oggetto è più vicino a te, la sua posizione sull'asse z viene aumentata, tuttavia, per farlo apparire più lontano, la sua posizione sull'asse z viene diminuita.
1994315 6 1
1994315 6 1

Passaggio 6. Creare la finestra

Il prossimo passo è creare la finestra all'interno del quale disegnerai il cubo. In questo tutorial, la finestra si chiama "Awesome Cube".

    // Crea finestra glutCreateWindow("Awesome Cube");

1994315 7 1
1994315 7 1

Passaggio 7. Abilita il test di profondità

OpenGL è un linguaggio rigoroso in quanto non presuppone che siano abilitate funzionalità speciali. Affinché il tuo programma venga visualizzato correttamente in 3 dimensioni utilizzando lo Z-buffer che hai visto in precedenza, devi abilitare il test di profondità. Mentre continui a esplorare OpenGL, scoprirai molte funzionalità che dovrai abilitare tra cui illuminazione, trame, abbattimento e molto altro.

    // Abilita il test di profondità del buffer Z glEnable(GL_DEPTH_TEST);

1994315 8 1
1994315 8 1

Passaggio 8. Aggiungi funzioni di callback

Ecco le funzioni di callback per le quali hai scritto i prototipi in precedenza. Queste funzioni verranno chiamate ogni volta attraverso il ciclo principale. La funzione di visualizzazione ridisegna la scena in base a eventuali modifiche alle variabili apportate dalla chiamata precedente. La funzione specialKeys ci permette di interagire con il programma.

    // Funzioni di callback glutDisplayFunc(display); glutSpecialFunc(specialKeys);

1994315 9 1
1994315 9 1

Passaggio 9. Avviare MainLoop

Questo richiamerà la funzione principale fino alla chiusura del programma per consentire le animazioni e l'interazione dell'utente.

    // Passa il controllo a GLUT per gli eventi glutMainLoop(); // Ritorna al sistema operativo return 0; }

Parte 2 di 3: la funzione display()

1994315 10 1
1994315 10 1

Passaggio 1. Comprendere lo scopo di questa funzione

Tutto il lavoro per disegnare il tuo cubo sarà svolto in questa funzione. L'idea generale alla base del tuo cubo è disegnare tutti e sei i lati individualmente e posizionarli nella posizione appropriata.

Concettualmente, ogni lato verrà disegnato definendo i quattro angoli e lasciando che OpenGL colleghi le linee e le riempia con un colore che definisci. Di seguito sono riportati i passaggi per eseguire questa operazione

1994315 11 1
1994315 11 1

Passaggio 2. Aggiungi glClear()

Il primo passo che devi compiere in questa funzione è quello di cancella il colore e il buffer Z. Senza questi passaggi, i vecchi disegni potrebbero essere ancora visibili sotto i nuovi disegni e gli oggetti disegnati non sarebbero nella posizione corretta sullo schermo.

    void display(){ // Cancella schermo e Z-buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

1994315 12 1
1994315 12 1

Passaggio 3. Aggiungi glBegin() e glEnd()

OpenGL definisce gli oggetti come combinazioni di diversi poligoni. Usando il glInizio() comando, metti effettivamente giù una matita che disegnerà una forma. Per sollevare la matita e iniziare una nuova forma, devi usare il glEnd() comando. In questo tutorial utilizzerai GL_POLYGON per disegnare ciascun lato del cubo, ma è possibile utilizzare altre opzioni di parametri come GL_LINE, GL_QUAD o GL_TRIANGLE per creare altre forme.

  • Qui inizierai con la parte anteriore del tuo cubo. Successivamente aggiungerai colore a tutti e 6 i lati.
  • // Lato multicolore - FRONT glBegin(GL_POLYGON); // Vertici verranno aggiunti nel passaggio successivo glEnd();

1994315 13 1
1994315 13 1

Passaggio 4. Aggiungi glVertex3f()

Una volta che hai dichiarato che vuoi iniziare il tuo poligono, devi definire i vertici dell'oggetto. glVertex ha più forme a seconda di cosa vuoi fare con il tuo oggetto.

  • Il primo è in quante dimensioni stai lavorando. Il 3 sopra in glVertex3f dice che stai disegnando in 3 dimensioni. E' possibile lavorare anche in 2 o 4 dimensioni. La f sopra in glVertex3f dice che stai lavorando con numeri in virgola mobile. Puoi anche usare shorts, interi o doppi.
  • Si noti che questi punti sono definiti in a Antiorario maniera. Questo non è molto importante al momento, ma quando inizi a lavorare con l'illuminazione, le trame e il rivestimento, questo diventerà incredibilmente importante, quindi prendi l'abitudine di definire i tuoi punti in senso antiorario ora.
  • Aggiungi aggiungi i vertici tra le linee glBegin() e glEnd().
  • // Lato multicolore - FRONT glBegin(GL_POLYGON); glVertex3f(-0,5, -0,5, -0,5); // P1 glVertex3f(-0,5, 0,5, -0,5); // P2 glVertex3f(0,5, 0,5, -0,5); // P3 glVertex3f(0,5, -0,5, -0,5); // P4 glEnd();

1994315 14 1
1994315 14 1

Passaggio 5. Aggiungi glColor3f()

glColor funziona in modo simile a glVertex. È possibile definire punti come short, interi, doppi o float. Ogni colore ha un valore da 0 a 1. Tutti gli 0 rendono il punto nero e tutti gli 1 rendono il punto bianco. Il 3 in glColor3f() si riferisce al sistema di colori RGB senza canale alfa. L'alfa di un colore ne definisce la trasparenza. Per cambiare il livello alfa, usa glColor4f() con l'ultimo parametro che è un valore da 0 a 1 per da opaco a trasparente.

  • Quando chiami glColor3f() ogni vertice disegnato da quel punto in poi sarà di quel colore. Pertanto, se vuoi che tutti e quattro i vertici siano rossi, imposta il colore una volta in qualsiasi momento prima dei comandi glVertex3f() e tutti i vertici saranno rossi.
  • Il Front side definito di seguito mostra come definire un nuovo colore per ogni vertice. Quando lo fai, puoi vedere un'interessante proprietà dei colori OpenGL. Poiché ogni vertice del poligono ha il suo colore, OpenGL fonderà automaticamente i colori! Il passaggio successivo mostrerà come assegnare quattro vertici con lo stesso colore.
  • //Lato multicolore - FRONT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(0,5, -0,5, -0,5); // P1 è rosso glColor3f(0.0, 1.0, 0.0); glVertex3f(0,5, 0,5, -0,5); // P2 è verde glColor3f(0.0, 0.0, 1.0); glVertex3f(-0,5, 0,5, -0,5); // P3 è blu glColor3f(1.0, 0.0, 1.0); glVertex3f(-0,5, -0,5, -0,5); // P4 è viola glEnd();

1994315 15 1
1994315 15 1

Passaggio 6. Gestire gli altri lati

Calcola quale sarà la posizione di ciascun vertice per gli altri cinque lati del cubo ma, per semplicità, questi sono stati calcolati per te e sono inclusi nel funzione display() finale sotto.

    // Lato bianco - BACK glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); glVertex3f(0,5, -0,5, 0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); gEnd(); // Lato viola - RIGHT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 1.0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, -0,5, 0,5); gEnd(); // Lato verde - LEFT glBegin(GL_POLYGON); glColor3f(0.0, 1.0, 0.0); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, -0,5, -0,5); gEnd(); // Lato blu - TOP glBegin(GL_POLYGON); glColor3f(0.0, 0.0, 1.0); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, 0,5); gEnd(); // Lato rosso - BOTTOM glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, -0,5); gEnd(); glFlush(); glutSwapBuffers(); }

  • Vogliamo anche aggiungere due ultime righe di codice per questa funzione. Questi sono glFlush();

    e glutSwapBuffers();

    che ci danno l'effetto di doppio buffer di cui hai appreso in precedenza.

Parte 3 di 3: Interattività con l'utente

1994315 16 1
1994315 16 1

Passaggio 1. Aggiungi specialKeys()

Hai quasi finito, ma al momento puoi disegnare un cubo ma non hai modo di ruotarlo. Per fare questo, lo farai creare una chiave speciale() funzione per permetterci di premere i tasti freccia e ruotare il cubo!

  • Questa funzione è il motivo per cui hai dichiarato le variabili globali rotazioni_x e rotazioni_y. Quando si premono i tasti freccia destra e sinistra, rotate_y verrà incrementato o decrementato di 5 gradi. Allo stesso modo, quando si premono i tasti freccia su e giù, ruotare_x cambierà di conseguenza.
  • void specialKeys(int key, int x, int y) { // Freccia destra - aumenta la rotazione di 5 gradi if (key == GLUT_KEY_RIGHT) rotate_y += 5; // Freccia sinistra - riduce la rotazione di 5 gradi altrimenti if (key == GLUT_KEY_LEFT) rotate_y -= 5; else if (chiave == GLUT_KEY_UP) rotate_x += 5; else if (tasto == GLUT_KEY_DOWN) rotate_x -= 5; // Richiedi aggiornamento display glutPostRedisplay(); }

1994315 17 1
1994315 17 1

Passaggio 2. Aggiungi glRotate()

La tua ultima affermazione è aggiungere l'affermazione che ruoterà il tuo oggetto. Torna alla funzione display() e prima del lato FRONT, aggiungi queste righe:

    // Reimposta le trasformazioni glLoadIdentity(); // Ruota quando l'utente cambia rota_x e rota_y glRotatef(ruota_x, 1.0, 0.0, 0.0); glRotatef(ruotare_y, 0.0, 1.0, 0.0); // Lato multicolore - FRONTE ….

  • Notare innanzitutto che la sintassi di glRotatef() è simile a quello di glColor3f() e glVertex3f() ma richiede sempre 4 parametri. Il primo parametro è il grado di rotazione da applicare. I prossimi tre parametri definiscono su quale asse ruotare, il primo è l'asse x, il secondo è l'asse y e il terzo è l'asse z. In questo momento devi solo ruotare attorno agli assi x e y.
  • Tutte le trasformazioni che scrivi nel tuo programma richiedono linee simili a questa. Concettualmente, puoi pensare a questo come ruotare il tuo oggetto attorno all'asse x della quantità definita da rotate_x e quindi ruotare attorno all'asse y da rotate_y. Tuttavia, OpenGL combina tutte queste istruzioni in un'unica trasformazione di matrice. Ogni volta che si chiama la funzione di visualizzazione, si costruisce una matrice di trasformazione e glLoadIdentity() assicura che inizierai con una nuova matrice in ogni passaggio.
  • Le altre funzioni di trasformazione che potresti applicare sono glTranslatef() e glScalef(). Queste funzioni sono simili a glRotatef() con l'eccezione che accettano solo 3 parametri, gli importi x, yez per tradurre o ridimensionare l'oggetto.
  • Per ottenere l'effetto corretto quando si applicano tutte e tre le trasformazioni a un oggetto, è necessario applicarle nell'ordine corretto. Scriveteli sempre nell'ordine glTranslate, glRotate, quindi glScale. OpenGL applica essenzialmente le trasformazioni in modo dal basso verso l'alto. Per capirlo, prova a immaginare come sarebbe un semplice cubo 1x1x1 con le trasformazioni se OpenGL le applicasse dall'alto verso il basso e se OpenGL le applicasse dal basso verso l'alto.
1994315 18 1
1994315 18 1

Passaggio 3. Aggiungere i seguenti comandi per ridimensionare il cubo di 2 lungo l'asse x, 2 lungo l'asse y, ruotare il cubo di 180 gradi attorno all'asse y e traslare il cubo di 0,1 lungo l'asse x

Assicurati di disporre questi e i precedenti comandi glRotate() nell'ordine corretto come descritto sopra. (Se non sei sicuro, questo viene fatto nel codice finale alla fine del tutorial.)

    // Altre trasformazioni glTranslatef(0.1, 0.0, 0.0); glRotatef(180, 0.0, 1.0, 0.0); glScalef(2.0, 2.0, 0.0);

1994315 19 1
1994315 19 1

Passaggio 4. Compila ed esegui il tuo codice

Supponendo che tu stia usando gcc come compilatore, esegui questi comandi dal tuo terminale per compilare e testare il tuo programma.

    Su Linux: gcc cube.c -o cube -lglut -lGL./ mycube Su Mac: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Su Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube

1994315 20 1
1994315 20 1

Passaggio 5. Controlla il tuo codice completo

Dovrebbe essere così:

    // // File: mycube.c // Autore: Matt Daisley // Creato: 25/4/2012 // Progetto: Codice sorgente per Crea un cubo in OpenGL // Descrizione: Crea una finestra OpenGL e disegna un cubo 3D / / Che l'utente può ruotare utilizzando i tasti freccia // // Controlli: Freccia sinistra - Ruota a sinistra // Freccia a destra - Ruota a destra // Freccia su - Ruota su // Freccia giù - Ruota giù // ------ --------------------------------------------------- -- // Include // ----------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- ------------------------------- // Prototipi di funzioni / / ------------------------------------------------- --------- display vuoto(); void specialKeys(); // ------------------------------------------------ ---------- // Variabili globali // -------------------- ------------------------ doppia rotazione_y=0; doppia rotazione_x=0; // ------------------------------------------------ ---------- // display() Funzione di callback // ------------------------------- ------------- void display(){ // Cancella schermo e Z-buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Reimposta le trasformazioni glLoadIdentity(); // Altre trasformazioni // glTranslatef(0.1, 0.0, 0.0); // Non incluso // glRotatef(180, 0.0, 1.0, 0.0); // Non incluso // Ruota quando l'utente cambia rotante_x e rotante_y glRotatef(ruotare_x, 1.0, 0.0, 0.0); glRotatef(ruotare_y, 0.0, 1.0, 0.0); // Altre trasformazioni // glScalef(2.0, 2.0, 0.0); // Non incluso //Lato multicolore - FRONT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(0,5, -0,5, -0,5); // P1 è rosso glColor3f(0.0, 1.0, 0.0); glVertex3f(0,5, 0,5, -0,5); // P2 è verde glColor3f(0.0, 0.0, 1.0); glVertex3f(-0,5, 0,5, -0,5); // P3 è blu glColor3f(1.0, 0.0, 1.0); glVertex3f(-0,5, -0,5, -0,5); // P4 è viola glEnd(); // Lato bianco - BACK glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); glVertex3f(0,5, -0,5, 0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); gEnd(); // Lato viola - RIGHT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 1.0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, -0,5, 0,5); gEnd(); // Lato verde - LEFT glBegin(GL_POLYGON); glColor3f(0.0, 1.0, 0.0); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, 0,5, 0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, -0,5, -0,5); gEnd(); // Lato blu - TOP glBegin(GL_POLYGON); glColor3f(0.0, 0.0, 1.0); glVertex3f(0,5, 0,5, 0,5); glVertex3f(0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, -0,5); glVertex3f(-0,5, 0,5, 0,5); gEnd(); // Lato rosso - BOTTOM glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(0,5, -0,5, -0,5); glVertex3f(0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, 0,5); glVertex3f(-0,5, -0,5, -0,5); gEnd(); glFlush(); glutSwapBuffers(); } // --------------------------------- ----------- // Funzione di callback specialKeys() // ------------------------------ -------------- void specialKeys(int key, int x, int y) { // Freccia destra - aumenta la rotazione di 5 grado if (chiave == GLUT_KEY_RIGHT) ruotare_y += 5; // Freccia sinistra - riduce la rotazione di 5 gradi altrimenti if (key == GLUT_KEY_LEFT) rotate_y -= 5; else if (tasto == GLUT_KEY_UP) rotate_x += 5; else if (tasto == GLUT_KEY_DOWN) rotate_x -= 5; // Richiedi aggiornamento display glutPostRedisplay(); } // --------------------------------- ----------- // funzione principale // ------------------------------- ------------- int main(int argc, char* argv){ // Inizializza GLUT ed elabora i parametri utente glutInit(&argc, argv); // Richiedi finestra True Color con doppio buffer con Z-buffer glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Crea finestra glutCreateWindow("Awesome Cube"); // Abilita il test di profondità del buffer Z glEnable(GL_DEPTH_TEST); // Funzioni di callback glutDisplayFunc(display); glutSpecialFunc(specialKeys); // Passa il controllo a GLUT per gli eventi glutMainLoop(); // Ritorna al sistema operativo return 0; }

Consigliato: