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
- Colors RGB: Els colors en OpenGL es defineixen utilitzant el model de color RGB (Red, Green, Blue).
- Shaders de Fragment: Programes que s'executen per cada fragment (potencial píxel) i determinen el seu color final.
- 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.
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
- Crea un shader de fragment que permeti canviar el color d'un triangle utilitzant una variable uniform.
- 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
- Modifica el shader de fragment per crear un gradient de color en un quadrat.
- 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ó.
Curs de Programació OpenGL
Mòdul 1: Introducció a OpenGL
- Què és OpenGL?
- Configurar el Teu Entorn de Desenvolupament
- Crear el Teu Primer Programa OpenGL
- Entendre el Pipeline d'OpenGL
Mòdul 2: Renderització Bàsica
- Dibuixar Formes Bàsiques
- Entendre les Coordenades i les Transformacions
- Coloració i Ombrejat
- Ús de Buffers
Mòdul 3: Tècniques de Renderització Intermèdies
- Textures i Mapeig de Textures
- Il·luminació i Materials
- Barreja i Transparència
- Prova de Profunditat i Prova de Plantilla
Mòdul 4: Tècniques de Renderització Avançades
Mòdul 5: Optimització del Rendiment
- Optimitzar el Codi OpenGL
- Ús d'Objectes de Matriu de Vèrtexs (VAOs)
- Gestió Eficient de la Memòria
- Perfilat i Depuració