Skip to main content

Command Palette

Search for a command to run...

Introducción a OpenGL: Tutorial para Principiantes

Guía básica y configuración inicial para comenzar con OpenGL

Updated
7 min read
Introducción a OpenGL: Tutorial para Principiantes

En los inicios de la programación gráfica, los desarrolladores debían adaptar su código a cada tipo de hardware o sistema operativo, lo que dificultaba la portabilidad y el mantenimiento. Para resolver este problema surgieron bibliotecas como OpenGL (Open Graphics Library), una de las más influyentes y duraderas, que proporciona una interfaz multiplataforma estandarizada para crear gráficos 2D y 3D. Su función principal es actuar como una capa intermedia entre las aplicaciones y la GPU, ocultando las particularidades del hardware y permitiendo que el mismo código funcione en distintos entornos.

English version of this article

Este enfoque facilita aprovechar el paralelismo de las GPU modernas: operaciones como transformar vértices, aplicar texturas o calcular colores de píxeles pueden ejecutarse de forma masiva y simultánea, lo que permite alcanzar un rendimiento elevado en aplicaciones interactivas y en tiempo real.

Sin embargo, el avance del hardware y la necesidad de un control más preciso han impulsado el desarrollo de APIs de bajo nivel como Vulkan, que ofrecen acceso directo a la GPU y una personalización detallada de cada etapa del proceso gráfico. Aunque OpenGL sigue siendo ampliamente utilizado —especialmente por su simplicidad y su curva de aprendizaje más amigable—, en contextos donde se busca la máxima eficiencia y control, Vulkan se está convirtiendo en la opción preferida.

Ahora que entendemos el papel de OpenGL en la programación gráfica y por qué sigue siendo una herramienta fundamental para iniciarse en este campo, es momento de preparar el entorno necesario para comenzar a escribir nuestros primeros programas. Esto implica integrar correctamente las bibliotecas complementarias, gestionar dependencias y establecer una estructura de proyecto robusta que facilite el desarrollo a medida que avanzamos.

Configuración y Estructura del Entorno

Antes de comenzar a escribir código, es necesario contar con un entorno de desarrollo que nos permita compilar y ejecutar nuestras aplicaciones.

Para trabajar con OpenGL de forma cómoda necesitamos integrar otras bibliotecas —como GLFW para el manejo de ventanas y contextos, GLAD para la carga de funciones—GLM para el manejo del algebra lineal entre otras que estaremos usando a lo largo de esta serie, para lograr la inclusion correcta utilizaremos CMake, que nos permiten coordinar todos estos componentes de forma ordenada.

En esta sección te explico cómo está estructurado el entorno de desarrollo, Si bien configurar todo esto puede requerir algo de experiencia, ya tienes el proyecto preparado en el repositorio principal de esta serie, así que puedes empezar directamente. si ya dominas estas herramientas, también tienes la libertad de montar tu propia configuración desde cero.

Estructura del Proyecto

El proyecto está organizado en carpetas específicas que separan claramente el código fuente, las librerías, los binarios y los shaders (la distribución del proyecto cambiara a lo largo de la serie).

A continuación, se muestra una visión general de la estructura:

graphics/
├── src/                # Archivos fuente .cpp, uno por cada programa
│   └── shaders/        # Shaders GLSL utilizados por los programas
├── libs/               # Librerías locales como GLAD
├── build/              # Carpeta generada por CMake para la compilación
├── CMakeLists.txt      # Script principal de configuración del proyecto
├── conanfile.py        # Script de Conan para gestión de dependencias
├── buildLinux.py       # Script Python para compilar en Linux
├── buildWindows.py     # Script Python para compilar en Windows
└── README.md           # Instrucciones y documentación del proyecto

Construcción del proyecto

CMake es una herramienta multiplataforma ampliamente utilizada en proyectos C++ para generar scripts de compilación adaptados a distintos entornos. En esta serie, nos enfocaremos principalmente en los sistemas operativos Windows y Linux, que son los más comunes entre los desarrolladores. Si bien CMake es sumamente poderosa y flexible, también puede resultar compleja para quienes no están familiarizados con ella. Por eso, aunque haremos uso de esta herramienta y puede que aparezcan algunas referencias a su funcionamiento, el enfoque de esta serie será mantener las cosas lo más simples posible, ya que el objetivo no es aprender CMake, sino centrarnos en la programación gráfica con OpenGL.

  • Se requiere CMake versión 3.25 o superior.

  • Se configura el proyecto para usar C++23.

  • Se incluyen manualmente subdirectorios como libs/glad.

  • Se integran las dependencias externas glfw, glm y OpenGL mediante find_package, que son gestionadas por Conan.

  • Se detectan automáticamente todos los archivos .cpp en la carpeta src/ y se compilan como ejecutables individuales.

  • Los ejecutables se colocan en build/programs/.

  • Los shaders (.glsl) se copian automáticamente a build/programs/shaders/, garantizando que estén disponibles junto al ejecutable al momento de la ejecución.

  •     file(GLOB SOURCE_FILES ${SOURCE_MAIN_DIR}/*.cpp)
    
        foreach(SOURCE_FILE ${SOURCE_FILES})
            get_filename_component(SOURCE_FILE_NAME ${SOURCE_FILE} NAME_WE)
    
            add_executable(${SOURCE_FILE_NAME} ${SOURCE_FILE})
            target_link_libraries(${SOURCE_FILE_NAME} PRIVATE glad glfw glm::glm ${OPENGL_LIBRARIES})
    
            set_target_properties(${SOURCE_FILE_NAME} PROPERTIES
                RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/programs
            )
        endforeach()
    

    Esto permite agregar nuevos programas simplemente añadiendo un nuevo archivo .cpp en src/, sin necesidad de modificar el archivo CMake.

Gestión de Dependencias

En este caso, utilizamos Conan, un moderno gestor de paquetes para C/C++, para descargar e instalar las dependencias externas como GLFW y GLM. Esto elimina la necesidad de configurar rutas manualmente o instalar librerías a mano.

El archivo conanfile.py especifica las librerías requeridas y sus versiones. Para preparar el entorno, basta con ejecutar

conan install . --build=missing

Esto descargará y configurará automáticamente todas las dependencias necesarias para que CMake pueda encontrarlas.

Scripts de Construcción

Para facilitar el proceso de compilación en distintos sistemas operativos, el proyecto incluye scripts auxiliares:

  • buildLinux.py: Genera y compila el proyecto en sistemas Linux.

  • buildWindows.py: Hace lo mismo en Windows, utilizando rutas y generadores adecuados para ese entorno.

Primer Programa con OpenGL

En este primer ejemplo, creamos una ventana a pantalla completa utilizando GLFW y limpiamos la pantalla con un color rojo utilizando OpenGL. Es una excelente forma de comprobar que nuestra configuración del entorno gráfico funciona correctamente.

A continuación se presenta el código fuente del programa y su análisis detallado:

hello window

#include <glad/glad.h>  // Carga de funciones OpenGL
#include <GLFW/glfw3.h> // Manejo de ventanas y entrada
#include <iostream>     // Salida de texto a consola

Estas tres cabeceras son fundamentales: glad.h para inicializar funciones OpenGL modernas, glfw3.h para crear y gestionar la ventana, y <iostream> para imprimir información del monitor.

Inicialización y función de dibujo

void init(GLFWwindow* window){
}

void display(GLFWwindow* window){
    glClear(GL_COLOR_BUFFER_BIT);       
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
}
  • La función init está preparada para futuras inicializaciones, como la carga de shaders o configuración de buffers.

  • La función display establece el color de fondo (rojo) y limpia el color buffer, lo cual borra la pantalla cada vez que se dibuja un nuevo frame.

Función principal

int main() {

    // Initialize GLFW, terminate program if failed
    if (!glfwInit()) {exit(EXIT_FAILURE);}

    // Set window properties
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);                  
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);                  
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

Se inicia GLFW. Si falla, el programa termina.

Estas instrucciones configuran una ventana con OpenGL versión 4.3 en modo core, lo cual exige el uso de funciones modernas (sin funciones obsoletas).

Creación de ventana

    const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, " 01_hello_window ", nullptr, nullptr);

Aquí se crea una ventana a pantalla completa con la resolución nativa del monitor principal. También se imprime información útil del modo de video:

    glfwMakeContextCurrent(window);

    if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
        std::cout << "failed to initialize GLAD " << std::endl;
        return -1;
    }

Se establece el contexto OpenGL actual y se inicializa GLAD, que permite usar todas las funciones de OpenGL que necesitemos (por ejemplo, glClearColor, glGenBuffers, etc.).

Ciclo principal

    while (!glfwWindowShouldClose(window)) {
        display(window);          
        glfwPollEvents();        
        glfwSwapBuffers(window); 
    }
  • display() limpia la pantalla con color rojo.

  • glfwPollEvents() procesa eventos del sistema como teclado o mouse.

  • glfwSwapBuffers() intercambia los framebuffers para mostrar la imagen renderizada.

Resultado

Al ejecutar este programa, deberías ver una ventana a pantalla completa (o modo ventana si modificas el código) con un fondo completamente rojo. Si ves esto, ¡felicitaciones! Tu pipeline básico de OpenGL está funcionando correctamente.

A computer window titled "01_hello_window" displays a solid red background.


Este primer acercamiento a OpenGL marca el inicio de un recorrido fascinante por el desarrollo gráfico en tiempo real. Hemos creado una ventana, establecido el contexto de OpenGL y generado un color de fondo simple, sentando así las bases sobre las que construiremos conceptos más avanzados como shaders, buffers y geometría 3D. A medida que avancemos, profundizaremos en el funcionamiento interno de la GPU y exploraremos técnicas modernas que nos permitirán aprovechar al máximo su poder de cómputo. Te invito a continuar con los siguientes tutoriales, donde desglosaremos el pipeline gráfico y daremos vida a nuestras primeras escenas interactivas.

More from this blog