En aquest tema, aprendrem com aplicar colors i ombrejats als objectes que dibuixem amb OpenGL. La coloració i l'ombrejat són elements essencials per donar vida i realisme a les escenes gràfiques. Explorarem conceptes bàsics com els colors RGB, els shaders de fragment i com utilitzar-los per crear efectes visuals.

Conceptes Clau

  1. Colors RGB: Els colors en OpenGL es defineixen utilitzant el model de color RGB (Red, Green, Blue).
  2. Shaders de Fragment: Programes que s'executen per cada fragment (potencial píxel) i determinen el seu color final.
  3. Uniforms: Variables que es poden utilitzar per passar dades constants als shaders.

Colors RGB

Els colors en OpenGL es defineixen utilitzant tres components: vermell (Red), verd (Green) i blau (Blue). Cada component té un valor entre 0.0 i 1.0.

// Exemple de color vermell pur
glColor3f(1.0f, 0.0f, 0.0f);

Shaders de Fragment

Els shaders de fragment són programes que s'executen per cada fragment generat durant la rasterització. Aquests shaders determinen el color final del fragment.

Exemple de Shader de Fragment

#version 330 core
out vec4 FragColor;

void main()
{
    // Assignar un color vermell pur al fragment
    FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Explicació del Codi

  • #version 330 core: Especifica la versió de GLSL (OpenGL Shading Language) que estem utilitzant.
  • out vec4 FragColor: Declara una variable de sortida que contindrà el color del fragment.
  • void main(): Funció principal del shader de fragment.
  • FragColor = vec4(1.0, 0.0, 0.0, 1.0): Assigna un color vermell pur al fragment.

Aplicar Colors als Objectes

Per aplicar colors als objectes, necessitem passar els colors als shaders. Això es pot fer utilitzant variables uniform.

Exemple de Shader de Fragment amb Uniform

#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;

void main()
{
    FragColor = vec4(objectColor, 1.0);
}

Codi en C++ per Passar el Color

// Obtenir la ubicació de la variable uniform
int objectColorLoc = glGetUniformLocation(shaderProgram, "objectColor");

// Passar el color al shader
glUniform3f(objectColorLoc, 0.0f, 1.0f, 0.0f); // Color verd

Exercicis Pràctics

Exercici 1: Canviar el Color d'un Triangle

  1. Crea un shader de fragment que permeti canviar el color d'un triangle utilitzant una variable uniform.
  2. Escriu el codi en C++ per passar diferents colors al shader i dibuixa el triangle.

Solució

Shader de Fragment:

#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;

void main()
{
    FragColor = vec4(objectColor, 1.0);
}

Codi en C++:

// Configurar el shader
int shaderProgram = glCreateProgram();
// ... (codi per compilar i enllaçar els shaders)

// Obtenir la ubicació de la variable uniform
int objectColorLoc = glGetUniformLocation(shaderProgram, "objectColor");

// Passar el color al shader
glUniform3f(objectColorLoc, 0.0f, 1.0f, 0.0f); // Color verd

// Dibuixar el triangle
glDrawArrays(GL_TRIANGLES, 0, 3);

Exercici 2: Crear un Gradient de Color

  1. Modifica el shader de fragment per crear un gradient de color en un quadrat.
  2. Escriu el codi en C++ per passar els colors als vèrtexs del quadrat.

Solució

Shader de Fragment:

#version 330 core
in vec3 ourColor;
out vec4 FragColor;

void main()
{
    FragColor = vec4(ourColor, 1.0);
}

Shader de Vèrtex:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

out vec3 ourColor;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
}

Codi en C++:

// Dades dels vèrtexs amb colors
float vertices[] = {
    // posicions        // colors
     0.5f,  0.5f, 0.0f,  1.0f, 0.0f, 0.0f,  // superior dret
     0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,  // inferior dret
    -0.5f, -0.5f, 0.0f,  0.0f, 0.0f, 1.0f,  // inferior esquerre
    -0.5f,  0.5f, 0.0f,  1.0f, 1.0f, 0.0f   // superior esquerre
};

// Índexs dels vèrtexs
unsigned int indices[] = {
    0, 1, 3,
    1, 2, 3
};

// Configurar VAO, VBO i EBO
unsigned int VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

// Posicions
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

// Colors
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);

// Dibuixar el quadrat
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

Conclusió

En aquesta secció, hem après com aplicar colors i ombrejats als objectes utilitzant OpenGL. Hem explorat els conceptes bàsics dels colors RGB, els shaders de fragment i com utilitzar variables uniform per passar dades als shaders. A més, hem practicat amb exercicis per reforçar els conceptes apresos. En el següent tema, aprofundirem en l'ús de buffers per optimitzar la renderització.

© Copyright 2024. Tots els drets reservats