OpenGL és una potent eina de programació 3D que s’utilitza per dibuixar escenes tridimensionals complexes a partir de primitives simples. Aquest article us ensenyarà a dibuixar un cub senzill que podeu girar per veure en tres dimensions.
Per a aquest projecte necessitareu un editor de codi i alguns coneixements de programació C.
Passos
Part 1 de 3: Configuració inicial
Pas 1. Instal·leu OpenGL Per començar, seguiu aquests passos per instal·lar OpenGL al vostre sistema
Si ja teniu OpenGL, així com un compilador C compatible instal·lat, podeu ometre aquest pas i anar al següent.
Pas 2. Creeu el document
Creeu un fitxer nou al vostre editor de codi favorit i deseu-lo com a mycube.c
Pas 3. Afegiu #includes
Aquests són els elements bàsics que necessiteu per al vostre programa. És important adonar-se que realment hi ha diferents inclusions necessàries per als diferents sistemes operatius. Assegureu-vos d’incloure-ho tot per garantir que el vostre programa sigui versàtil i que pugui funcionar per a qualsevol usuari.
// Inclou #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif
Pas 4. Afegiu prototips de funció i variables globals
El següent pas és declarar alguns prototips de funció.
// Funció Prototips void display (); void specialKeys (); // Variables globals double rotate_y = 0; doble rotació_x = 0;
Pas 5. Configureu la funció main ()
int main (int argc, char * argv ) {// Inicialitza GLUT i processa els paràmetres de l'usuari glutInit (& argc, argv); // Sol·liciteu una finestra de color veritable amb doble memòria intermèdia amb el buffer Z glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Pas 6. Creeu la finestra
El següent pas és fer-ho crear la finestra dins del qual dibuixareu el cub. En aquest tutorial, la finestra s'anomena "Cub impressionant".
// Crea una finestra glutCreateWindow ("Cub impressionant");
Pas 7. Activa la prova de profunditat
OpenGL és un llenguatge estricte perquè no suposa que hi hagi cap funció especial habilitada. Perquè el vostre programa es mostri correctament en 3 dimensions mitjançant el buffer Z que heu vist anteriorment, cal que ho feu habilitar la prova de profunditat. A mesura que continueu explorant OpenGL, descobrireu moltes funcions que haureu d’habilitar, incloses la il·luminació, les textures, la reducció i molt més.
// Activa la prova de profunditat del buffer Z glEnable (GL_DEPTH_TEST);
Pas 8. Afegiu funcions de devolució de trucada
Aquí teniu les funcions de devolució de trucada per a les quals heu escrit els prototips anteriorment. Cada vegada que travesseu el bucle principal, s'anomenaran aquestes funcions. La funció de visualització torna a dibuixar l’escena en funció de qualsevol canvi a les variables que es van fer des de la trucada anterior. La funció specialKeys ens permet interactuar amb el programa.
// Funcions de devolució de trucada glutDisplayFunc (display); glutSpecialFunc (specialKeys);
Pas 9. Inicieu MainLoop
Això recordarà la funció principal fins que tanqueu el programa per permetre animacions i la interacció de l'usuari.
// Passa el control a GLUT per als esdeveniments glutMainLoop (); // Torna a SO retorn 0; }
Part 2 de 3: la funció display ()
Pas 1. Comprendre l'objectiu d'aquesta funció
Tot el treball de dibuix del cub es realitzarà en aquesta funció. La idea general darrere del cub és dibuixar els sis costats individualment i situar-los a la posició adequada.
Conceptualment, cada costat es dibuixarà definint les quatre cantonades i deixant que OpenGL connecti les línies i l’ompli amb un color que definiu. A continuació es mostren els passos per fer-ho
Pas 2. Afegiu glClear ()
El primer pas que heu de fer en aquesta funció és esborreu el color i la memòria intermèdia Z. Sense aquests passos, els dibuixos antics encara podrien ser visibles sota els nous dibuixos i els objectes dibuixats no es trobarien a la ubicació correcta a la pantalla.
void display () {// Esborra la pantalla i el buffer Z glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Pas 3. Afegiu glBegin () i glEnd ()
OpenGL defineix els objectes com a combinacions de diferents polígons. Utilitzant el glBegin () per ordre, posareu efectivament un llapis que dibuixarà una forma. Per aixecar el llapis i començar una nova forma, heu d'utilitzar el glEnd () comandament. En aquest tutorial faràs servir GL_POLYGON per dibuixar cada costat del cub, però és possible utilitzar altres opcions de paràmetres com GL_LINE, GL_QUAD o GL_TRIANGLE per crear altres formes.
- Aquí començareu per la part frontal del cub. Més endavant afegiràs color als 6 costats.
// Costat multicolor: FRONT glBegin (GL_POLYGON); // Els vèrtexs s’afegiran al següent pas glEnd ();
Pas 4. Afegiu glVertex3f ()
Un cop hàgiu declarat que voleu començar el vostre polígon, cal que ho feu definiu els vèrtexs de l’objecte. glVertex té diverses formes en funció del que vulgueu fer amb el vostre objecte.
- El primer és el nombre de dimensions que esteu treballant. El 3 anterior a glVertex3f diu que dibuixeu 3 dimensions. També és possible treballar en 2 o 4 dimensions. La f que apareix a glVertex3f indica que esteu treballant amb números de coma flotant. També podeu utilitzar curtmetratges, enters o dobles.
- Fixeu-vos que aquests punts es defineixen a en sentit antihorari manera. Això no és molt important en aquest moment, però quan comenceu a treballar amb la il·luminació, les textures i l’objecte, això esdevindrà increïblement important, així que acostumeu a definir els vostres punts en sentit antihorari ara.
- Afegir afegir els vèrtexs entre les línies glBegin () i glEnd ().
// Costat multicolor: 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 ();
Pas 5. Afegiu glColor3f ()
glColor funciona de manera similar a glVertex. Podeu definir punts com a curts, enters, dobles o flotants. Cada color té un valor de 0 a 1. Tots els 0 fan que el punt sigui negre i tots els 1 faran que el punt sigui blanc. El 3 de glColor3f () fa referència al sistema de color RGB sense canal alfa. L’alfa d’un color defineix la seva transparència. Per canviar el nivell alfa, utilitzeu glColor4f () amb l'últim paràmetre en un valor de 0 a 1 per opac a transparent.
- Quan truqueu a glColor3f (), tots els vèrtexs dibuixats a partir d’aquest punt seran d’aquest color. Per tant, si voleu que els quatre vèrtexs siguin vermells, només heu d’establir el color una vegada en qualsevol moment abans de les ordres glVertex3f () i tots els vèrtexs quedaran vermells.
- La cara frontal definida a continuació mostra com es defineix un color nou per a cada vèrtex. Quan feu això, podeu veure una interessant propietat dels colors OpenGL. Com que cada vèrtex del polígon té el seu propi color, OpenGL barrejarà automàticament els colors. El següent pas mostrarà com assignar quatre vèrtexs amb el mateix color.
// Costat multicolor: FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 és vermell glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 és de color verd glColor3f (0,0, 0,0, 1,0); glVertex3f (-0,5, 0,5, -0,5); // P3 és blau glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 és morat glEnd ();
Pas 6. Manegeu els altres costats
Esbrineu quina serà la ubicació de cada vèrtex per als altres cinc costats del cub, però per simplicitat, s'han calculat per a vosaltres i s'inclouen a la funció display final () baix.
// Cara blanca - 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); glEnd (); // Costat porpra - Dret 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); glEnd (); // Costat verd - ESQUERRA 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); glEnd (); // Cara blava: 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); glEnd (); // Cara vermella - 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); glEnd (); glFlush (); glutSwapBuffers (); }
També volem afegir dues darreres línies de codi per a aquesta funció. Aquests són glFlush ();
i glutSwapBuffers ();
que ens proporcionen l’efecte de doble amortiment que heu conegut anteriorment.
Part 3 de 3: Interactivitat de l'usuari
Pas 1. Afegiu specialKeys ()
Gairebé heu acabat, però de moment podeu dibuixar un cub però no teniu cap manera de girar-lo. Per fer-ho, ho faràs crea un specialKeys () funció que ens permet prémer les tecles de fletxa i girar el cub.
- Per aquesta funció, heu declarat les variables globals rotate_x i rotate_y. Quan premeu les tecles de fletxa dreta i esquerra, rotate_y s'incrementarà o disminuirà en 5 graus. De la mateixa manera, quan premeu les tecles de fletxa amunt i avall, rotate_x canviarà en conseqüència.
void specialKeys (tecla int, int x, int y) {// Fletxa dreta: augmenta la rotació 5 graus si (tecla == GLUT_KEY_RIGHT) rotate_y + = 5; // Fletxa esquerra: redueix la rotació 5 graus més si (tecla == GLUT_KEY_LEFT) rotate_y - = 5; altrament si (clau == GLUT_KEY_UP) rotate_x + = 5; else if (clau == GLUT_KEY_DOWN) rotate_x - = 5; // Sol·licita l’actualització de la pantalla glutPostRedisplay (); }
Pas 2. Afegiu glRotate ()
La vostra última sentència és afegir la sentència que farà girar l'objecte. Torneu a la funció display () i abans de la part FRONT, afegiu aquestes línies:
// Restableix les transformacions glLoadIdentity (); // Gira quan l'usuari canvia rotate_x i rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0,0, 1,0, 0,0); // Costat multicolor - FRONT….
Pas 3. Afegiu les ordres següents per escalar el cub en 2 al llarg de l'eix X, 2 al llarg de l'eix Y, gireu el cub 180 graus al voltant de l'eix Y i traduïu el cub en 0,1 al llarg de l'eix X
Assegureu-vos d’organitzar-los, així com les ordres anteriors glRotate (), en l’ordre correcte, tal com es descriu anteriorment. (Si no esteu segur, ho feu al codi final al final del tutorial.)
// Altres transformacions glTranslatef (0,1, 0,0, 0,0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2.0, 2.0, 0.0);
Pas 4. Compileu i executeu el vostre codi
Suposant que utilitzeu gcc com a compilador, executeu aquestes ordres des del terminal per compilar i provar el vostre programa.
A Linux: gcc cube.c -o cube -lglut -lGL./ mycube A Mac: gcc -o foo foo.c -frame GLUT -framework OpenGL./ mycube Al Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Pas 5. Comproveu el codi complet
Hauria de ser així:
// // Fitxer: mycube.c // Autor: Matt Daisley // Creació: 2012-04-25 // Projecte: codi font per fer un cub a OpenGL // Descripció: crea una finestra OpenGL i dibuixa un cub 3D / / Que l'usuari pugui girar amb les tecles de fletxa // // Controls: Fletxa esquerra - Gira a l'esquerra // Fletxa dreta - Gira a la dreta // Fletxa cap amunt - Gira cap amunt // Fletxa cap avall - Gira cap avall // ------ -------------------------------------------------- - // Inclou // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- --------------------------------------------- // Prototips de funcions / / ------------------------------------------------- --------- pantalla nula (); void specialKeys (); // ------------------------------------------------ ---------- // Variables globals // ---------------------------------- ------------------------ doble rotació_y = 0; doble rotació_x = 0; // ------------------------------------------------ ---------- // display () Funció de devolució de trucada // ------------------------------- --------------------------- pantalla neta () {// Pantalla neta i memòria intermèdia Z glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Restableix les transformacions glLoadIdentity (); // Altres transformacions // glTranslatef (0,1, 0,0, 0,0); // No inclòs // glRotatef (180, 0,0, 1,0, 0,0); // No inclòs // Gira quan l'usuari canvia rotate_x i rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0,0, 1,0, 0,0); // Altres transformacions // glScalef (2.0, 2.0, 0.0); // No inclòs // Costat multicolor: FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 és vermell glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 és de color verd glColor3f (0,0, 0,0, 1,0); glVertex3f (-0,5, 0,5, -0,5); // P3 és blau glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 és morat glEnd (); // Cara blanca - TORNAR 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); glEnd (); // Costat porpra - Dret 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); glEnd (); // Costat verd - ESQUERRA 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); glEnd (); // Cara blava: 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); glEnd (); // Cara vermella - 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); glEnd (); glFlush (); glutSwapBuffers (); } // ----------------------------------------------- ----------- // specialKeys () Funció de devolució de trucada // ------------------------------ ---------------------------- void specialKeys (int key, int x, int y) {// Fletxa dreta: augmenta la rotació en 5 grau si (clau == GLUT_KEY_RIGHT) rotate_y + = 5; // Fletxa esquerra: redueix la rotació 5 graus més si (tecla == GLUT_KEY_LEFT) rotate_y - = 5; altrament si (clau == GLUT_KEY_UP) rotate_x + = 5; else if (clau == GLUT_KEY_DOWN) rotate_x - = 5; // Sol·licita l’actualització de la pantalla glutPostRedisplay (); } // ----------------------------------------------- ----------- // funció main () // ------------------------------- --------------------------- int main (int argc, char * argv ) {// Inicialitza GLUT i processa els paràmetres de l'usuari glutInit (& argc, argv); // Sol·liciteu una finestra de color veritable amb doble memòria intermèdia amb el buffer Z glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Crea una finestra glutCreateWindow ("Awesome Cube"); // Activa la prova de profunditat del buffer Z glEnable (GL_DEPTH_TEST); // Funcions de devolució de trucada glutDisplayFunc (display); glutSpecialFunc (specialKeys); // Passa el control a GLUT per als esdeveniments glutMainLoop (); // Torna a SO retorn 0; }