WebGL - Modalità di Disegno

Ciao, futuri maghi di WebGL! ? Oggi, ci immergeremo nel mondo emozionante delle modalità di disegno in WebGL. Come il tuo amico insegnante di informatica del quartiere, sono qui per guidarti in questo viaggio, anche se non hai mai scritto una riga di codice prima. Allora, prendi il tuo pennello virtuale e creiamo alcune opere d'arte digitali!

WebGL - Modes of Drawing

Il Parametro mode

Prima di iniziare a disegnare, parliamo della stella del nostro spettacolo: il parametro mode. Pensa a esso come una bacchetta magica che dice a WebGL come collegare i punti (o, nel nostro caso, vertici) per creare diverse forme e modelli.

In WebGL, quando chiamiamo la funzione gl.drawArrays() o gl.drawElements(), dobbiamo specificare un parametro mode. Questo parametro è come dare istruzioni a un puzzle di collegamento dei punti - dice a WebGL come unire i punti che abbiamo definito.

Ecco una tabella delle diverse modalità di disegno disponibili in WebGL:

Modalità Descrizione
gl.POINTS Disegna un singolo punto per ogni vertice
gl.LINES Disegna una linea tra ogni coppia di vertici
gl.LINE_STRIP Disegna una linea continua che connette i vertici
gl.LINE_LOOP Simile a LINE_STRIP, ma chiude la forma
gl.TRIANGLES Disegna un triangolo per ogni tre vertici
gl.TRIANGLE_STRIP Disegna un gruppo connettuto di triangoli
gl.TRIANGLE_FAN Disegna una forma a ventaglio di triangoli connessi

Non preoccuparti se queste sembrano confuse ora. Esploreremo ognuna di esse con esempi man mano che procediamo!

Esempio - Disegnare Tre Linee Parallele

Iniziamo con un esempio semplice: disegnare tre linee parallele. Questo ci aiuterà a comprendere come funziona il parametro mode nella pratica.

// Prima, impostiamo il nostro contesto WebGL
const canvas = document.getElementById('myCanvas');
const gl = canvas.getContext('webgl');

// Ora, definiamo il nostro vertex shader
const vertexShaderSource = `
attribute vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
}
`;

// E il nostro fragment shader
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Colore rosso
}
`;

// Creiamo e compileremo gli shader (non preoccuparti, spiegheremo questo in dettaglio nelle lezioni future)
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);

// Creiamo un programma e colleghiamo gli shader
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);

// Definiamo le posizioni delle nostre linee
const positions = new Float32Array([
-0.8, -0.8,  // Inizio della Linea 1
-0.8,  0.8,  // Fine della Linea 1
-0.3, -0.8,  // Inizio della Linea 2
-0.3,  0.8,  // Fine della Linea 2
0.2, -0.8,  // Inizio della Linea 3
0.2,  0.8   // Fine della Linea 3
]);

// Creiamo un buffer e mettiamo le posizioni in esso
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

// Diciamo a WebGL come leggere il buffer e attribuirlo a `a_position`
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

// Puliamo il canvas
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

// Disegniamo le linee
gl.drawArrays(gl.LINES, 0, 6);

Ora, analizziamo questo:

  1. Abbiamo impostato il nostro contesto WebGL e definito i nostri shader. Non preoccuparti troppo di questi ora; copriremo gli shader in profondità nelle lezioni future.

  2. Abbiamo creato un programma e collegato i nostri shader a esso. Questo è come preparare il nostro pennello digitale.

  3. Abbiamo definito le posizioni delle nostre linee. Ogni linea è definita da due punti (il suo inizio e la sua fine), e ogni punto è definito da due coordinate (x e y). Quindi, abbiamo 6 punti in totale per le nostre 3 linee.

  4. Abbiamo creato un buffer e messo le nostre posizioni in esso. Pensa a questo come caricare la vernice sul pennello.

  5. Abbiamo detto a WebGL come leggere questo buffer e associarlo all'attributo a_position nel nostro vertex shader.

  6. Infine, abbiamo chiamato gl.drawArrays(gl.LINES, 0, 6). Questo è dove avviene la magia!

  • gl.LINES è la nostra modalità. Dice a WebGL di disegnare linee tra le coppie di vertici.
  • 0 è l'indice di partenza nel nostro array di posizioni.
  • 6 è il numero di vertici da considerare (ricorda, abbiamo 6 punti per le nostre 3 linee).

Esegui questo codice, e voilà! Dovresti vedere tre linee rosse parallele su uno sfondo nero. Congratulazioni, hai appena creato il tuo primo disegno WebGL! ?

Modalità di Disegno

Ora che abbiamo visto gl.LINES in azione, esploriamo alcune altre modalità di disegno. Useremo lo stesso setup di prima, ma cambieremo le posizioni e la modalità di disegno.

gl.POINTS

Iniziamo con la modalità più semplice: gl.POINTS. Questa modalità disegna un singolo punto per ogni vertice.

// ... (codice di setup precedente)

const positions = new Float32Array([
-0.5, 0.5,
0.0, 0.0,
0.5, -0.5
]);

// ... (codice di setup del buffer)

gl.drawArrays(gl.POINTS, 0, 3);

Questo disegnerà tre punti rossi sul tuo canvas. Semplice, vero?

gl.LINE_STRIP

Ora, proviamo gl.LINE_STRIP. Questa modalità disegna una linea continua che connette i vertici.

// ... (codice di setup precedente)

const positions = new Float32Array([
-0.5, 0.5,
0.0, -0.5,
0.5, 0.5
]);

// ... (codice di setup del buffer)

gl.drawArrays(gl.LINE_STRIP, 0, 3);

Dovresti vedere una linea a V che connette i tre punti.

gl.LINE_LOOP

gl.LINE_LOOP è simile a LINE_STRIP, ma chiude la forma connettendo l'ultimo vertice al primo.

// ... (codice di setup precedente)

const positions = new Float32Array([
-0.5, 0.5,
0.0, -0.5,
0.5, 0.5
]);

// ... (codice di setup del buffer)

gl.drawArrays(gl.LINE_LOOP, 0, 3);

Questo disegnerà un contorno di triangolo.

gl.TRIANGLES

Ora, passiamo a riempire le forme con gl.TRIANGLES. Questa modalità disegna un triangolo per ogni tre vertici.

// ... (codice di setup precedente)

const positions = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5
]);

// ... (codice di setup del buffer)

gl.drawArrays(gl.TRIANGLES, 0, 3);

Dovresti vedere un triangolo rosso solido.

gl.TRIANGLE_STRIP

gl.TRIANGLE_STRIP è un po' più complesso. Disegna un gruppo connettuto di triangoli, dove ogni triangolo condivide due vertici con il precedente.

// ... (codice di setup precedente)

const positions = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
-0.5, 0.5,
0.5, 0.5
]);

// ... (codice di setup del buffer)

gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

Questo disegnerà due triangoli connessi a formare un rettangolo.

gl.TRIANGLE_FAN

Infine, esploriamo gl.TRIANGLE_FAN. Questa modalità disegna una forma a ventaglio di triangoli connessi, dove tutti i triangoli condividono il primo vertice come punto comune.

// ... (codice di setup precedente)

const positions = new Float32Array([
0.0, 0.0,    // Punto centrale
0.5, 0.0,    // Punto 1
0.35, 0.35,  // Punto 2
0.0, 0.5,    // Punto 3
-0.35, 0.35  // Punto 4
]);

// ... (codice di setup del buffer)

gl.drawArrays(gl.TRIANGLE_FAN, 0, 5);

Questo disegnerà una forma che assomiglia a un quarto di cerchio.

Ecco fatto! Abbiamo esplorato tutte le modalità di disegno in WebGL. Ricorda, la chiave per padroneggiare queste è la pratica. Prova a combinare diverse modalità, cambiare i colori e giocare con le posizioni dei vertici. Prima di sapere, sarai in grado di creare scene WebGL complesse con facilità!

Nella nostra prossima lezione, approfondiremo gli shader e impariamo come aggiungere un tocco di classe ai nostri disegni con colori e testure. Fino allora, felice programmazione, futuri artisti di WebGL! ??‍??‍?

Credits: Image by storyset