En esta sección, aprenderemos a dibujar formas básicas utilizando OpenGL. Este es un paso fundamental para cualquier proyecto de gráficos, ya que todas las escenas complejas se construyen a partir de formas simples.

Conceptos Clave

  1. Contexto de OpenGL: El entorno en el que se ejecutan las operaciones de OpenGL.
  2. Vértices: Puntos en el espacio que definen las formas.
  3. Primitivas: Formas básicas como puntos, líneas y triángulos.
  4. Buffers: Áreas de memoria que almacenan datos como vértices y colores.

  1. Configuración Inicial

Antes de comenzar a dibujar, asegúrate de tener configurado tu entorno de desarrollo. Si no lo has hecho, revisa la sección "Configuración de tu Entorno de Desarrollo".

  1. Dibujando un Triángulo

Paso 1: Definir los Vértices

Primero, necesitamos definir los vértices del triángulo. Los vértices son los puntos en el espacio que forman las esquinas del triángulo.

// Definimos los vértices del triángulo
GLfloat vertices[] = {
    0.0f,  0.5f, 0.0f,  // Vértice superior
   -0.5f, -0.5f, 0.0f,  // Vértice inferior izquierdo
    0.5f, -0.5f, 0.0f   // Vértice inferior derecho
};

Paso 2: Crear un Buffer de Vértices

A continuación, necesitamos crear un buffer de vértices y cargar los datos de los vértices en él.

GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

Paso 3: Configurar los Atributos de los Vértices

Ahora, configuramos cómo OpenGL debe interpretar los datos de los vértices.

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);

Paso 4: Dibujar el Triángulo

Finalmente, utilizamos la función glDrawArrays para dibujar el triángulo.

glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

Código Completo

Aquí está el código completo para dibujar un triángulo:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

// Definimos los vértices del triángulo
GLfloat vertices[] = {
    0.0f,  0.5f, 0.0f,  // Vértice superior
   -0.5f, -0.5f, 0.0f,  // Vértice inferior izquierdo
    0.5f, -0.5f, 0.0f   // Vértice inferior derecho
};

int main() {
    // Inicializar GLFW
    if (!glfwInit()) {
        return -1;
    }

    // Crear una ventana
    GLFWwindow* window = glfwCreateWindow(800, 600, "Dibujando un Triángulo", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Inicializar GLEW
    if (glewInit() != GLEW_OK) {
        return -1;
    }

    // Crear un buffer de vértices
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // Configurar los atributos de los vértices
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    // Bucle de renderizado
    while (!glfwWindowShouldClose(window)) {
        // Limpiar la pantalla
        glClear(GL_COLOR_BUFFER_BIT);

        // Dibujar el triángulo
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Intercambiar buffers
        glfwSwapBuffers(window);

        // Procesar eventos
        glfwPollEvents();
    }

    // Limpiar recursos
    glDeleteBuffers(1, &VBO);
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

  1. Dibujando un Cuadrado

Para dibujar un cuadrado, necesitamos definir cuatro vértices y dos triángulos que formen el cuadrado.

Paso 1: Definir los Vértices

GLfloat vertices[] = {
    // Primer triángulo
    -0.5f,  0.5f, 0.0f,  // Vértice superior izquierdo
    -0.5f, -0.5f, 0.0f,  // Vértice inferior izquierdo
     0.5f, -0.5f, 0.0f,  // Vértice inferior derecho
    // Segundo triángulo
     0.5f, -0.5f, 0.0f,  // Vértice inferior derecho
     0.5f,  0.5f, 0.0f,  // Vértice superior derecho
    -0.5f,  0.5f, 0.0f   // Vértice superior izquierdo
};

Paso 2: Crear un Buffer de Vértices

GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

Paso 3: Configurar los Atributos de los Vértices

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);

Paso 4: Dibujar el Cuadrado

glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);

Código Completo

Aquí está el código completo para dibujar un cuadrado:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

// Definimos los vértices del cuadrado
GLfloat vertices[] = {
    // Primer triángulo
    -0.5f,  0.5f, 0.0f,  // Vértice superior izquierdo
    -0.5f, -0.5f, 0.0f,  // Vértice inferior izquierdo
     0.5f, -0.5f, 0.0f,  // Vértice inferior derecho
    // Segundo triángulo
     0.5f, -0.5f, 0.0f,  // Vértice inferior derecho
     0.5f,  0.5f, 0.0f,  // Vértice superior derecho
    -0.5f,  0.5f, 0.0f   // Vértice superior izquierdo
};

int main() {
    // Inicializar GLFW
    if (!glfwInit()) {
        return -1;
    }

    // Crear una ventana
    GLFWwindow* window = glfwCreateWindow(800, 600, "Dibujando un Cuadrado", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Inicializar GLEW
    if (glewInit() != GLEW_OK) {
        return -1;
    }

    // Crear un buffer de vértices
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // Configurar los atributos de los vértices
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    // Bucle de renderizado
    while (!glfwWindowShouldClose(window)) {
        // Limpiar la pantalla
        glClear(GL_COLOR_BUFFER_BIT);

        // Dibujar el cuadrado
        glDrawArrays(GL_TRIANGLES, 0, 6);

        // Intercambiar buffers
        glfwSwapBuffers(window);

        // Procesar eventos
        glfwPollEvents();
    }

    // Limpiar recursos
    glDeleteBuffers(1, &VBO);
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

Ejercicios Prácticos

  1. Dibujar un Pentágono: Define los vértices necesarios para dibujar un pentágono y renderízalo utilizando OpenGL.
  2. Colorear el Triángulo: Modifica el código del triángulo para que cada vértice tenga un color diferente.
  3. Animar el Cuadrado: Implementa una animación simple que haga que el cuadrado rote sobre su centro.

Soluciones

  1. Dibujar un Pentágono:
GLfloat vertices[] = {
    0.0f,  0.5f, 0.0f,  // Vértice superior
    -0.47f,  0.15f, 0.0f,  // Vértice superior izquierdo
    -0.29f, -0.4f, 0.0f,  // Vértice inferior izquierdo
    0.29f, -0.4f, 0.0f,  // Vértice inferior derecho
    0.47f,  0.15f, 0.0f   // Vértice superior derecho
};
  1. Colorear el Triángulo:
GLfloat vertices[] = {
    // Posiciones         // Colores
    0.0f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,  // Vértice superior (rojo)
   -0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,  // Vértice inferior izquierdo (verde)
    0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f   // Vértice inferior derecho (azul)
};
  1. Animar el Cuadrado:
float angle = 0.0f;
while (!glfwWindowShouldClose(window)) {
    // Limpiar la pantalla
    glClear(GL_COLOR_BUFFER_BIT);

    // Aplicar transformación de rotación
    angle += 0.01f;
    glm::mat4 transform;
    transform = glm::rotate(transform, angle, glm::vec3(0.0f, 0.0f, 1.0f));
    GLint transformLoc = glGetUniformLocation(shaderProgram, "transform");
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

    // Dibujar el cuadrado
    glDrawArrays(GL_TRIANGLES, 0, 6);

    // Intercambiar buffers
    glfwSwapBuffers(window);

    // Procesar eventos
    glfwPollEvents();
}

Conclusión

En esta sección, hemos aprendido a dibujar formas básicas como triángulos y cuadrados utilizando OpenGL. Estos conceptos son fundamentales y servirán como base para crear escenas más complejas en futuros módulos. Asegúrate de practicar los ejercicios para reforzar tu comprensión y estar preparado para los siguientes temas.

© Copyright 2024. Todos los derechos reservados