WebGL - Modos de Dibujado
¡Hola, futuros magos de WebGL! ? Hoy vamos a sumergirnos en el emocionante mundo de los modos de dibujado en WebGL. Como tu amable profesor de informática del vecindario, estoy aquí para guiarte en este viaje, incluso si nunca has escrito una línea de código antes. Así que, toma tu pincel virtual, y ¡vamos a crear algunas obras maestras digitales!
El Parámetro mode
Antes de comenzar a dibujar, hablemos de la estrella de nuestro espectáculo: el parámetro mode
. Piensa en él como la varita mágica que le dice a WebGL cómo conectar los puntos (o, en nuestro caso, vértices) para crear diferentes formas y patrones.
En WebGL, cuando llamamos a la función gl.drawArrays()
o gl.drawElements()
, necesitamos especificar un parámetro mode
. Este parámetro es como dar instrucciones a un rompecabezas de conectar puntos: le dice a WebGL cómo unir los puntos que hemos definido.
Aquí tienes una tabla de los diferentes modos de dibujado disponibles en WebGL:
Modo | Descripción |
---|---|
gl.POINTS | Dibuja un punto para cada vértice |
gl.LINES | Dibuja una línea entre cada par de vértices |
gl.LINE_STRIP | Dibuja una línea continua conectando los vértices |
gl.LINE_LOOP | Similar a LINE_STRIP, pero cierra la forma |
gl.TRIANGLES | Dibuja un triángulo por cada tres vértices |
gl.TRIANGLE_STRIP | Dibuja un grupo conectado de triángulos |
gl.TRIANGLE_FAN | Dibuja una forma en abanico de triángulos conectados |
No te preocupes si estos parecen confundirte ahora. Exploraremos cada uno de ellos con ejemplos a medida que avanzamos!
Ejemplo - Dibujar Tres Líneas Paralelas
Vamos a empezar con un ejemplo simple: dibujar tres líneas paralelas. Esto nos ayudará a entender cómo funciona el parámetro mode
en la práctica.
// Primero, configuremos nuestro contexto WebGL
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl');
// Ahora, definamos nuestro vertex shader
const vertexShaderSource = `
attribute vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
}
`;
// Y nuestro fragment shader
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Color rojo
}
`;
// Crear y compilar los shaders (no te preocupes, explicaremos esto en detalle en lecciones futuras)
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
// Crear un programa y enlazar los shaders
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
// Definir las posiciones de nuestras líneas
const positions = new Float32Array([
-0.8, -0.8, // Inicio de la línea 1
-0.8, 0.8, // Fin de la línea 1
-0.3, -0.8, // Inicio de la línea 2
-0.3, 0.8, // Fin de la línea 2
0.2, -0.8, // Inicio de la línea 3
0.2, 0.8 // Fin de la línea 3
]);
// Crear un buffer y poner las posiciones en él
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
// Decirle a WebGL cómo leer el buffer y atribuirlo a `a_position`
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
// Limpiar el lienzo
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Dibujar las líneas
gl.drawArrays(gl.LINES, 0, 6);
Ahora, desglosemos esto:
-
Configuramos nuestro contexto WebGL y definimos nuestros shaders. No te preocupes demasiado por estos ahora; cubriremos los shaders en profundidad en lecciones futuras.
-
Creamos un programa y enlazamos nuestros shaders a él. Esto es como preparar nuestro pincel digital.
-
Definimos las posiciones de nuestras líneas. Cada línea se define por dos puntos (su inicio y fin), y cada punto se define por dos coordenadas (x e y). Así que tenemos 6 puntos en total para nuestras 3 líneas.
-
Creamos un buffer y ponemos nuestras posiciones en él. Piensa en esto como cargar nuestra pintura en el pincel.
-
Le decimos a WebGL cómo leer este buffer y asociarlo con el atributo
a_position
en nuestro vertex shader. -
Finalmente, llamamos a
gl.drawArrays(gl.LINES, 0, 6)
. ¡Aquí ocurre la magia!
-
gl.LINES
es nuestro modo. Le dice a WebGL que dibuje líneas entre pares de vértices. -
0
es el índice de inicio en nuestro array de posiciones. -
6
es el número de vértices a considerar (recuerda, tenemos 6 puntos para nuestras 3 líneas).
Ejecuta este código, y ¡voilà! Deberías ver tres líneas rojas paralelas en un fondo negro. ¡Felicidades, acabas de crear tu primer dibujo en WebGL! ?
Modos de Dibujado
Ahora que hemos visto gl.LINES
en acción, exploremos algunos otros modos de dibujado. Usaremos el mismo conjunto de configuración que antes, pero cambiaremos nuestras posiciones y el modo de dibujado.
gl.POINTS
Comencemos con el modo más simple: gl.POINTS
. Este modo dibuja un punto para cada vértice.
// ... (código de configuración anterior)
const positions = new Float32Array([
-0.5, 0.5,
0.0, 0.0,
0.5, -0.5
]);
// ... (código de configuración del buffer)
gl.drawArrays(gl.POINTS, 0, 3);
Esto dibujará tres puntos rojos en tu lienzo. Simple, ¿verdad?
gl.LINE_STRIP
Ahora, probemos gl.LINE_STRIP
. Este modo dibuja una línea continua conectando cada vértice con el siguiente.
// ... (código de configuración anterior)
const positions = new Float32Array([
-0.5, 0.5,
0.0, -0.5,
0.5, 0.5
]);
// ... (código de configuración del buffer)
gl.drawArrays(gl.LINE_STRIP, 0, 3);
Deberías ver una línea en forma de V conectando los tres puntos.
gl.LINE_LOOP
gl.LINE_LOOP
es similar a LINE_STRIP
, pero cierra la forma conectando el último vértice con el primero.
// ... (código de configuración anterior)
const positions = new Float32Array([
-0.5, 0.5,
0.0, -0.5,
0.5, 0.5
]);
// ... (código de configuración del buffer)
gl.drawArrays(gl.LINE_LOOP, 0, 3);
Esto dibujará un contorno de triángulo.
gl.TRIANGLES
Ahora, pasemos a rellenar formas con gl.TRIANGLES
. Este modo dibuja un triángulo por cada tres vértices.
// ... (código de configuración anterior)
const positions = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5
]);
// ... (código de configuración del buffer)
gl.drawArrays(gl.TRIANGLES, 0, 3);
Deberías ver un triángulo rojo sólido.
gl.TRIANGLE_STRIP
gl.TRIANGLE_STRIP
es un poco más complejo. Dibuja un grupo conectado de triángulos, donde cada triángulo comparte dos vértices con el anterior.
// ... (código de configuración anterior)
const positions = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
-0.5, 0.5,
0.5, 0.5
]);
// ... (código de configuración del buffer)
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
Esto dibujará dos triángulos conectados formando un rectángulo.
gl.TRIANGLE_FAN
Finalmente, veamos gl.TRIANGLE_FAN
. Este modo dibuja una forma en abanico, donde todos los triángulos comparten el primer vértice como un punto común.
// ... (código de configuración anterior)
const positions = new Float32Array([
0.0, 0.0, // Punto central
0.5, 0.0, // Punto 1
0.35, 0.35, // Punto 2
0.0, 0.5, // Punto 3
-0.35, 0.35 // Punto 4
]);
// ... (código de configuración del buffer)
gl.drawArrays(gl.TRIANGLE_FAN, 0, 5);
Esto dibujará una forma que se parece a un cuarto de círculo.
Y ahí lo tienes! Hemos explorado todos los modos de dibujado en WebGL. Recuerda, la clave para dominar estos es la práctica. Intenta combinar diferentes modos, cambiar colores y jugar con las posiciones de los vértices. Antes de que te des cuenta, estarás creando escenas WebGL complejas con facilidad!
En nuestra próxima lección, profundizaremos en los shaders y aprenderemos a agregar un poco de brillo a nuestros dibujos con colores y texturas. ¡Hasta entonces, feliz codificación, futuros artistas de WebGL! ?????
Credits: Image by storyset