Cómo hacer un cubo en OpenGL (con imágenes)

Tabla de contenido:

Cómo hacer un cubo en OpenGL (con imágenes)
Cómo hacer un cubo en OpenGL (con imágenes)

Video: Cómo hacer un cubo en OpenGL (con imágenes)

Video: Cómo hacer un cubo en OpenGL (con imágenes)
Video: ✅ ¿Cómo INSTALAR Windows XP en una Maquina Virtual? | VirtualBox 2024, Abril
Anonim

OpenGL es una poderosa herramienta de programación 3D que se utiliza para dibujar escenas tridimensionales complejas a partir de primitivas simples. ¡Este artículo te enseñará cómo dibujar un cubo simple que puedes girar para verlo en tres dimensiones!

Para este proyecto, necesitará un editor de código y algunos conocimientos de programación en C.

Pasos

Parte 1 de 3: Configuración inicial

1994315 1 1
1994315 1 1

Paso 1. Instale OpenGL Para comenzar, siga estos pasos para instalar OpenGL en su sistema

Si ya tiene OpenGL, así como un compilador C compatible instalado, puede omitir este paso y pasar al siguiente.

1994315 2 1
1994315 2 1

Paso 2. Cree el documento

Cree un nuevo archivo en su editor de código favorito y guárdelo como mycube.c

1994315 3 1
1994315 3 1

Paso 3. Agregue #includes

Estas son las inclusiones básicas que necesitará para su programa. Es importante darse cuenta de que en realidad se requieren diferentes inclusiones para los diferentes sistemas operativos. Asegúrese de incluir todos estos para asegurarse de que su programa sea versátil y pueda ejecutarse para cualquier usuario.

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

1994315 4 1
1994315 4 1

Paso 4. Agregue prototipos de funciones y variables globales

El siguiente paso es declarar algunos prototipos de funciones.

    // Prototipos de funciones void display (); void specialKeys (); // Variables globales double rotate_y = 0; doble rotate_x = 0;

1994315 5 1
1994315 5 1

Paso 5. Configure la función principal ()

    int main (int argc, char * argv ) {// Inicializa GLUT y procesa los parámetros de usuario glutInit (& argc, argv); // Solicitar una ventana de color verdadero con doble búfer con Z-buffer glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

  • Esta declaración configura su entorno. Algo importante para recordar al escribir programas OpenGL es que debes pedirlo todo. Esto requiere que comprenda mejor cómo funciona su programa y qué debe incluir para obtener la funcionalidad que desea. En esta línea, configurará la pantalla con búfer doble, color RGB y búfer Z.
  • Doble búfer es una técnica utilizada en programas de gráficos para eliminar un problema que surge debido a cómo se dibujan las imágenes en la pantalla. Cada vez que vuelva a dibujar la escena, primero se debe borrar la pantalla y luego se dibujará la nueva información. Sin el doble almacenamiento en búfer, observará un efecto de parpadeo a medida que la pantalla se borra y se vuelve a dibujar repetidamente.
  • Este problema se soluciona agregando un segundo búfer al que dibujar. Con este método, se dibuja una imagen en el primer búfer y se le muestra ese búfer. El siguiente fotograma se dibujará en el segundo búfer y cuando esté hecho, los dos búferes cambiarán de lugar. Inmediatamente verá el segundo búfer, pero, oculto para nosotros, el primer búfer se borrará y se volverá a dibujar con el tercer cuadro que se intercambiará cuando termine.
  • También desea habilitar el Color RGB sistema en su ventana.
  • Almacenamiento en búfer Z así es como obtienes los efectos 3D que deseas. OpenGL utiliza un sistema de coordenadas tridimensional con ejes x, y y z. Para dar el efecto de que un objeto está más cerca de usted, su posición en el eje z aumenta, sin embargo, para que parezca más alejado, su posición en el eje z se reduce.
1994315 6 1
1994315 6 1

Paso 6. Cree la ventana

El siguiente paso es crea la ventana dentro del cual dibujarás el cubo. En este tutorial, la ventana se llama "Awesome Cube".

    // Crear ventana glutCreateWindow ("Awesome Cube");

1994315 7 1
1994315 7 1

Paso 7. Habilite la prueba de profundidad

OpenGL es un lenguaje estricto en el sentido de que no asume que se habiliten funciones especiales. Para que su programa se muestre correctamente en 3 dimensiones usando el búfer Z que miró anteriormente, necesita habilitar prueba de profundidad. A medida que continúe explorando OpenGL, descubrirá muchas funciones que deberá habilitar, incluidas iluminación, texturas, eliminación selectiva y mucho más.

    // Habilita la prueba de profundidad del búfer Z glEnable (GL_DEPTH_TEST);

1994315 8 1
1994315 8 1

Paso 8. Agregue funciones de devolución de llamada

Estas son las funciones de devolución de llamada para las que escribió los prototipos anteriormente. Cada vez que pase por el bucle principal, se llamarán estas funciones. La función de visualización vuelve a dibujar la escena en función de los cambios realizados en las variables desde la llamada anterior. La función specialKeys nos permite interactuar con el programa.

    // Funciones de devolución de llamada glutDisplayFunc (display); glutSpecialFunc (teclas especiales);

1994315 9 1
1994315 9 1

Paso 9. Inicie MainLoop

Esto recordará la función principal hasta que cierre el programa para permitir las animaciones y la interacción del usuario.

    // Pasar el control a GLUT para eventos glutMainLoop (); // Regresar al SO return 0; }

Parte 2 de 3: La función display ()

1994315 10 1
1994315 10 1

Paso 1. Comprenda el propósito de esta función

Todo el trabajo de dibujar tu cubo se realizará en esta función. La idea general detrás de su cubo es dibujar los seis lados individualmente y colocarlos en la posición adecuada.

Conceptualmente, cada lado se dibujará definiendo las cuatro esquinas y dejando que OpenGL conecte las líneas y lo rellene con un color que usted defina. A continuación se muestran los pasos para hacer esto

1994315 11 1
1994315 11 1

Paso 2. Agregue glClear ()

El primer paso que debe realizar en esta función es borrar el color y el búfer Z. Sin estos pasos, los dibujos antiguos pueden seguir siendo visibles debajo de los nuevos dibujos y los objetos dibujados no estarían en la ubicación correcta en la pantalla.

    void display () {// Limpiar pantalla y Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

1994315 12 1
1994315 12 1

Paso 3. Agregue glBegin () y glEnd ()

OpenGL define los objetos como combinaciones de diferentes polígonos. Utilizando el glBegin () comando, efectivamente dejas un lápiz que dibujará una forma. Para levantar el lápiz y comenzar una nueva forma, debe usar el glEnd () mando. En este tutorial, usará GL_POLYGON para dibujar cada lado del cubo, pero es posible usar otras opciones de parámetros como GL_LINE, GL_QUAD o GL_TRIANGLE para crear otras formas.

  • Aquí comenzará con el frente de su cubo. Luego agregará color a los 6 lados.
  • // Lado multicolor - FRONT glBegin (GL_POLYGON); // Los vértices se agregarán en el siguiente paso glEnd ();

1994315 13 1
1994315 13 1

Paso 4. Agregue glVertex3f ()

Una vez que haya indicado que desea comenzar su polígono, debe definir los vértices del objeto. glVertex tiene múltiples formas dependiendo de lo que quieras hacer con tu objeto.

  • La primera es en cuántas dimensiones estás trabajando. Las 3 de arriba en glVertex3f dice que estás dibujando en 3 dimensiones. También es posible trabajar en 2 o 4 dimensiones. La f de arriba en glVertex3f dice que está trabajando con números de coma flotante. También puedes usar cortos, enteros o dobles.
  • Observe que estos puntos se definen en un en sentido anti-horario conducta. Esto no es muy importante en este momento, pero cuando empiece a trabajar con la iluminación, las texturas y el refrentado, esto se volverá increíblemente importante, así que acostúmbrese a definir sus puntos ahora en sentido contrario a las agujas del reloj.
  • Agregue agregue los vértices entre las líneas glBegin () y glEnd ().
  • // Lado 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

Paso 5. Agregue glColor3f ()

glColor funciona de manera similar a glVertex. Puede definir puntos como cortos, enteros, dobles o flotantes. Cada color tiene un valor de 0 a 1. Todos los 0 hacen que el punto sea negro y todos los 1 hacen que el punto sea blanco. El 3 en glColor3f () se refiere al sistema de color RGB sin canal alfa. El alfa de un color define su transparencia. Para cambiar el nivel alfa, use glColor4f () con el último parámetro siendo un valor de 0 a 1 para opaco a transparente.

  • Cuando llame a glColor3f (), todos los vértices dibujados a partir de ese punto serán de ese color. Por lo tanto, si desea que los cuatro vértices sean rojos, simplemente establezca el color una vez en cualquier momento antes de los comandos glVertex3f () y todos los vértices serán rojos.
  • El lado frontal definido a continuación muestra cómo definir un nuevo color para cada vértice. Al hacer esto, puede ver una propiedad interesante de los colores OpenGL. Dado que cada vértice del polígono tiene su propio color, ¡OpenGL combinará automáticamente los colores! El siguiente paso mostrará cómo asignar cuatro vértices con el mismo color.
  • // Lado multicolor - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 es rojo glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 es verde glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 es azul glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 es púrpura glEnd ();

1994315 15 1
1994315 15 1

Paso 6. Manipule los otros lados

Calcule cuál será la ubicación de cada vértice para los otros cinco lados del cubo, pero para simplificar, estos se han calculado para usted y están incluidos en el función de visualización final () debajo.

    // Lado blanco - ATRÁS 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 (); // Lado morado - DERECHA 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 (); // Lado verde - IZQUIERDA 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 (); // Lado azul - 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 (); // Lado rojo - INFERIOR 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 (); }

  • También queremos agregar dos últimas líneas de código para esta función. Estos son glFlush ();

    y glutSwapBuffers ();

    lo que nos da el efecto de doble búfer del que aprendiste antes.

Parte 3 de 3: Interactividad del usuario

1994315 16 1
1994315 16 1

Paso 1. Agregue specialKeys ()

Ya casi has terminado, pero en este momento puedes dibujar un cubo pero no tienes forma de rotarlo. Para hacer esto, lo harás crear un specialKeys () función para permitirnos presionar las teclas de flecha y rotar el cubo!

  • Esta función es la razón por la que declaró las variables globales rotate_x y rotate_y. Cuando presione las teclas de flecha derecha e izquierda, rotate_y aumentará o disminuirá en 5 grados. Del mismo modo, cuando presione las teclas de flecha hacia arriba y hacia abajo, rotate_x cambiará en consecuencia.
  • void specialKeys (int key, int x, int y) {// Flecha derecha - aumentar la rotación en 5 grados if (key == GLUT_KEY_RIGHT) rotate_y + = 5; // Flecha izquierda - disminuir la rotación en 5 grados si no (clave == GLUT_KEY_LEFT) rotate_y - = 5; de lo contrario si (clave == GLUT_KEY_UP) rotate_x + = 5; si no (clave == GLUT_KEY_DOWN) rotate_x - = 5; // Solicitar actualización de visualización glutPostRedisplay (); }

1994315 17 1
1994315 17 1

Paso 2. Agregue glRotate ()

Su última declaración es agregar la declaración que rotará su objeto. Regrese a la función display () y antes del lado FRONT, agregue estas líneas:

    // Restablecer transformaciones glLoadIdentity (); // Rotar cuando el usuario cambia rotate_x y rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0.0, 1.0, 0.0); // Lado multicolor - FRENTE….

  • Primero observe que la sintaxis de glRotatef () es similar al de glColor3f () y glVertex3f () pero siempre requiere 4 parámetros. El primer parámetro es el grado de rotación a aplicar. Los siguientes tres parámetros definen sobre qué eje girar, siendo el primero el eje x, el segundo el eje y y el tercero el eje z. En este momento, solo necesita girar sobre los ejes xey.
  • Todas las transformaciones que escriba en su programa necesitan líneas similares a esta. Conceptualmente, puede pensar en esto como rotar su objeto sobre el eje x por la cantidad definida por rotate_x y luego rotar alrededor del eje y por rotate_y. Sin embargo, OpenGL combina todas estas declaraciones en una transformación matricial. Cada vez que llama a la función de visualización, crea una matriz de transformación y glLoadIdentity () asegura que comenzará con una nueva matriz en cada pasada.
  • Las otras funciones de transformación que podría aplicar son glTranslatef () y glScalef (). Estas funciones son similares a glRotatef () con la excepción de que solo toman 3 parámetros, las cantidades x, y, z para traducir o escalar el objeto.
  • Para obtener el efecto correcto al aplicar las tres transformaciones a un objeto, debe aplicarlas en el orden correcto. Escríbalos siempre en el orden glTranslate, glRotate, luego glScale. OpenGL esencialmente aplica las transformaciones de abajo hacia arriba. Para entender esto, intente imaginar cómo se vería un simple cubo de 1x1x1 con las transformaciones si OpenGL las aplicara de arriba a abajo y si OpenGL las aplicara de abajo hacia arriba.
1994315 18 1
1994315 18 1

Paso 3. Agregue los siguientes comandos para escalar el cubo en 2 a lo largo del eje x, 2 a lo largo del eje y, rotar el cubo 180 grados alrededor del eje y y trasladar el cubo en 0,1 a lo largo del eje x

Asegúrese de organizarlos, así como los comandos glRotate () anteriores, en el orden correcto, como se describe anteriormente. (Si no está seguro, esto se hace en el código final al final del tutorial).

    // Otras transformaciones 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

Paso 4. Compile y ejecute su código

Suponiendo que está usando gcc como su compilador, ejecute estos comandos desde su terminal para compilar y probar su programa.

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

1994315 20 1
1994315 20 1

Paso 5. Verifique su código completo

Debería ser así:

    // // Archivo: mycube.c // Autor: Matt Daisley // Creado: 25/4/2012 // Proyecto: Código fuente para Make a Cube en OpenGL // Descripción: Crea una ventana OpenGL y dibuja un cubo 3D / / Que el usuario puede rotar usando las teclas de flecha // // Controles: Flecha izquierda - Girar a la izquierda // Flecha derecha - Girar a la derecha // Flecha arriba - Girar hacia arriba // Flecha abajo - Girar hacia abajo // ------ -------------------------------------------------- - // Incluye // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- --------------------------------------------- // Prototipos de funciones / / ------------------------------------------------- --------- visualización vacía (); void specialKeys (); // ------------------------------------------------ ---------- // Variables globales // ---------------------------------- ------------------------ doble rotate_y = 0; doble rotate_x = 0; // ------------------------------------------------ ---------- // display () Función de devolución de llamada // ------------------------------- --------------------------- void display () {// Limpiar la pantalla y el búfer Z glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Restablecer transformaciones glLoadIdentity (); // Otras transformaciones // glTranslatef (0.1, 0.0, 0.0); // No incluido // glRotatef (180, 0.0, 1.0, 0.0); // No incluido // Rotar cuando el usuario cambia rotate_x y rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0.0, 1.0, 0.0); // Otras transformaciones // glScalef (2.0, 2.0, 0.0); // No incluido // Lado multicolor - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 es rojo glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 es verde glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 es azul glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 es púrpura glEnd (); // Lado blanco - ATRÁS 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 (); // Lado morado - DERECHA 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 (); // Lado verde - IZQUIERDA 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 (); // Lado azul - 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 (); // Lado rojo - INFERIOR 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 (); } // ----------------------------------------------- ----------- // función de devolución de llamada specialKeys () // ------------------------------ ---------------------------- void specialKeys (int key, int x, int y) {// Flecha derecha - aumentar la rotación en 5 grado if (clave == GLUT_KEY_RIGHT) rotate_y + = 5; // Flecha izquierda - disminuir la rotación en 5 grados si no (clave == GLUT_KEY_LEFT) rotate_y - = 5; de lo contrario si (clave == GLUT_KEY_UP) rotate_x + = 5; si no (clave == GLUT_KEY_DOWN) rotate_x - = 5; // Solicitar actualización de visualización glutPostRedisplay (); } // ----------------------------------------------- ----------- // función principal // ------------------------------- --------------------------- int main (int argc, char * argv ) {// Inicializa GLUT y procesa los parámetros de usuario glutInit (& argc, argv); // Solicitar una ventana de color verdadero con doble búfer con Z-buffer glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Crear ventana glutCreateWindow ("Awesome Cube"); // Habilita la prueba de profundidad del búfer Z glEnable (GL_DEPTH_TEST); // Funciones de devolución de llamada glutDisplayFunc (display); glutSpecialFunc (teclas especiales); // Pasar el control a GLUT para eventos glutMainLoop (); // Regresar al SO return 0; }

Recomendado: