Com fer un cub a OpenGL (amb imatges)

Taula de continguts:

Com fer un cub a OpenGL (amb imatges)
Com fer un cub a OpenGL (amb imatges)

Vídeo: Com fer un cub a OpenGL (amb imatges)

Vídeo: Com fer un cub a OpenGL (amb imatges)
Vídeo: Lightweight Distro Winner & Runner Up 2024, Abril
Anonim

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

1994315 1 1
1994315 1 1

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.

1994315 2 1
1994315 2 1

Pas 2. Creeu el document

Creeu un fitxer nou al vostre editor de codi favorit i deseu-lo com a mycube.c

1994315 3 1
1994315 3 1

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

1994315 4 1
1994315 4 1

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;

1994315 5 1
1994315 5 1

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);

  • Aquesta afirmació configura el vostre entorn. Una cosa important que cal recordar quan s’escriuen programes OpenGL és que cal demanar-ho tot. Això requereix que tingueu una millor comprensió de com funciona el vostre programa i què heu d’incloure per obtenir la funcionalitat que desitgeu. En aquesta línia, configurareu la pantalla amb doble memòria intermèdia, color RGB i una memòria intermèdia Z.
  • Doble memòria intermèdia és una tècnica utilitzada en programes gràfics per eliminar un problema que sorgeix a causa de com es dibuixen les imatges a la pantalla. Cada vegada que torneu a dibuixar l’escena, primer s’ha d’esborrar la pantalla i després es dibuixarà la nova informació. Sense una memòria intermèdia doble observareu un efecte de parpelleig a mesura que la pantalla s’esborra i es torna a dibuixar repetidament.
  • Aquest problema es soluciona afegint un segon buffer al qual dibuixar. Amb aquest mètode, es dibuixa una imatge al primer buffer i se us mostra aquest buffer. El següent fotograma es dibuixarà al segon buffer i, quan això estigui acabat, els dos buffers canviaran de lloc. Veuràs immediatament el segon buffer, però, ocult per a nosaltres, el primer buffer s’esborra i es torna a dibuixar amb el tercer marc que s’intercanviarà quan acabi.
  • També voleu habilitar el fitxer Color RGB a la finestra.
  • Z-buffering és com obteniu els efectes 3D que desitgeu. OpenGL utilitza un sistema de coordenades tridimensionals amb eixos x, y i z. Per donar l'efecte que un objecte és més a prop vostre, augmenta la seva posició sobre l'eix z, però, per fer-lo aparèixer més lluny, es redueix la seva posició sobre l'eix z.
1994315 6 1
1994315 6 1

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");

1994315 7 1
1994315 7 1

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);

1994315 8 1
1994315 8 1

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);

1994315 9 1
1994315 9 1

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 ()

1994315 10 1
1994315 10 1

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

1994315 11 1
1994315 11 1

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);

1994315 12 1
1994315 12 1

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 ();

1994315 13 1
1994315 13 1

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 ();

1994315 14 1
1994315 14 1

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 ();

1994315 15 1
1994315 15 1

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

1994315 16 1
1994315 16 1

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 (); }

1994315 17 1
1994315 17 1

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….

  • Primerament observeu que la sintaxi de glRotatef () és similar al de glColor3f () i glVertex3f () però sempre requereix 4 paràmetres. El primer paràmetre és el grau de rotació que s’ha d’aplicar. Els tres paràmetres següents defineixen quin eix girar, sent el primer l’eix x, el segon l’eix y i el tercer l’eix z. Ara mateix només cal girar sobre els eixos x i y.
  • Totes les transformacions que escriviu al vostre programa necessiten línies similars a aquesta. Conceptualment, es pot pensar en això com girar l’objecte sobre l’eix x en la quantitat definida per rotate_x i després girar al voltant de l’eix y per rotate_y. No obstant això, OpenGL combina totes aquestes afirmacions en una transformació de matriu. Cada vegada que crideu a la funció de visualització, creeu una matriu de transformació i glLoadIdentity () assegura que començareu amb una nova matriu a cada passada.
  • Les altres funcions de transformació que podeu aplicar són glTranslatef () i glScalef (). Aquestes funcions són similars a glRotatef () amb l'excepció que només prenen 3 paràmetres, les quantitats x, y i z per traduir o escalar l'objecte.
  • Per obtenir l’efecte correcte en aplicar les tres transformacions a un objecte, cal aplicar-les en l’ordre correcte. Escriviu-los sempre en l’ordre glTranslate, glRotate i, a continuació, glScale. OpenGL aplica bàsicament les transformacions de manera ascendent. Per entendre-ho, intenteu imaginar com seria un simple cub 1x1x1 amb les transformacions si OpenGL les apliqués de dalt a baix i si OpenGL les apliqués de baix a dalt.
1994315 18 1
1994315 18 1

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);

1994315 19 1
1994315 19 1

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

1994315 20 1
1994315 20 1

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; }

Recomanat: