• Non ci sono risultati.

HELLO WORLD, I’M A TRIANGLE!

N/A
N/A
Protected

Academic year: 2021

Condividi "HELLO WORLD, I’M A TRIANGLE!"

Copied!
11
0
0

Testo completo

(1)

Computer Graphics

Marco Tarini

Università dell’Insubria Corso di Laurea in Informatica Anno Accademico 2014/15

Il primo Hello World

HELLO WORLD, I’M A TRIANGLE!

Reminder: API

Scheda Grafica Driver Scheda grafica

API Applicazioni

Monitor Algoritmi

SDK

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

• Open Graphic Language

• Libreria “C-like”

– Cross platform – Qualche centinaio

di routines

• www.opengl.org

– specifiche

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Specifiche API

ver 4.5

(da Ago 2014)

Storia

• inizialmente sviluppato da Silicon Graphics

• dal 2002 al 2006:

OpenGL A rchitecture R eview B oard – mantiene e aggiorna le specifiche – industria 90%, accademia 10%

– ogni compagnia / gruppo, un voto

• dal 2006: Khronos Gruop

– come sopra

• ci sono anche le estensioni private – Soprattutto e

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

etc...

(2)

: derivazioni

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

– per web

– basato su (la ver 2.0 di) – HTML5

– un language binding in JavaScript

– soluz emergente per il 3D sul Web (no plug-in!) – per embedded devices

– sottoinsieme di OpenGL (in pratica)

adottiamo questo

alternative

• Direct3D

– Microsoft

• (proprietario, e non cross platform) – Parte di DirectX

– Stessi scopi di OpenGL

• una API per usare le stesse GPU

• struttura non dissimile

– di solito, meno elegante, più macchinoso

• C (e C++)

– E’ l'alternativa più comune a OpenGL

• Grossomodo:

– Direct3D = industry standard (e ) – OpenGL = industry + academy standard

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

futuro?

– by Khronos (again)

– versione rivista e corretta delle API OpenGL

• basso livello

• “bytecode” for the shaders

• better debugging

• unified mobile / embedded / desktop – Simile alla vers 12 di Direct3D?

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

OpenGL: State Machine!

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 2 / 1 3 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

gemoetria qui

screen buffer tutto il pipeline

stato di OpenGL

manipolazioni di stato

(es. settare depth test, etc)

(3)

è basato sullo stato

• Una state machine – che include, ad esempio

• il clear color (colore di cancellamento)

• depth test (abilitato o no, quale funzione usare)

• il blending (abilitato o no, quale funzione usare)

• Molti comandi OpenGL non fanno nulla di immediato – cambiano lo stato,

dunque il comportamento dei comandi successivi

• (queries sullo stato: glGet[tipo]( COSTANTE, valori_da_riempire ); )

• es (in C):

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 2 / 1 3 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

double v[4];

gl.GetDoublev( gl.COLOR_CLEAR_VALUE , v );

WebGL pipeline

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Primitive:

primitive assembler (& setup) Transformed

Vertex:

XYZW

(clip space)

transformed +

attributes vertex

shader Input

Vertex:

(object space)

XYZ input + attributes

GPU-RAM

Mesh:

vertex puller vertex buffer index

buffer rasterizer

rasterizer point

(1xV) (2xV)

line triangle

(3xV)

WebGL pipeline

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a GPU-RAM

screento

Pixels:

RGBa + Depth + Stencil

RGBa buffer Depth buffer Stencil

buffer

output combiner

Fragments:

buffer pos (fixed, XY) + interpolated attributes

fragment shader Primitive:

rasterizer lines rasterizer triangles rasterizer punti

WebGL pipeline

• Vertex Puller (VP)

– prende i vertici da buffers in memoria Video

• Vertex Shader (VS)

– include la transform. geometrica

• Primitive Assembler (PA)

– ogni 1,2 ,3 vertici produce una primitiva

• Rasterizer (RS)

– fabbrica tutti i frammenti:

edge test + inteprolaz attributi

• Fragment Shader (FS)

– produce i pixel values, include tipicamente il lighting

• Output Combiner (OC)

– depth test, alpha blend, stencil ops, etc

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

programmable!

in GLSL

(OpenGL Shading Language)

(4)

First Rendering (hello world): piano

• Geometria minimale:

un triangolo, no indexing

• Vertex shader minimale:

“simply pass down the vertices”

• Fragment shader minimale:

“give the same color to all fragments”

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Plan of attack

1. Costruiamo una paginetta per il nostro programma 2. Initializzaziamo WebGL 3. Definiamo cosa disegnare 4. Definiamo come disegnare 5. Disegnamo (on load)

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

HTML

JavaScript (+ WebGL)

HTML Page

<html>

<head>

<script type="text/javascript">

</script>

</head>

<body>

<canvas

id = "OUTPUT-CANVAS"

width = "500px"

height = "500px"

style = "border: 1px solid black"

></canvas>

</body>

</html>

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

he ad bo dy

Scheletro degli script

<script type="text/javascript">

</script>

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

function setupWebGL() { … } function setupWhatToDraw() { … } function setupHowToDraw() { … } function draw() { … }

function helloDraw() { setupWebGL();

setupWhatToDraw();

setupHowToDraw();

draw();

}

window.onload = helloDraw;

(5)

Passo 2: inizializziamo WebGL

• OpenGL (tutte le versioni) = state machine

– comandi per cambiare lo stato interno (non fanno nulla di visibile) – comandi per “far cose” – il risultato dipende dallo stato

• in OpenGL base:

– lo stato è implicito (aka “rendering context”)

• in WebGL:

– stato = JavaScript object: WebGLRenderingContext – legato ad un Canvas HTML (l’output del rendering) – funzioni WebGL = metodi di questo object

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var

gl = null; /* contesto (var globale) */

functionsetupWebGL() {

var

canvas = document.getElementById("OUTPUT-CANVAS");

gl = canvas.getContext(

"experimental-webgl" // oppure, “webgl”

);

}

Passo 2: inizializziamo WebGL (notes)

• Associamo la var JavasScipt canvas al canvas HTML

– definito nel sorgente HTML della pagina

• I Canvas sono oggetti con i buffer richiesti (RGBA framebuffer, depth buffer…)

– L’alpha può essere usato per la trasparenza nei confronti degli altri elementi HTML

• Il metodo getContext restutisce il suo contesto WebGL – “webgl” is the string denoting it in most browsers

– in some cases you need to use “experimental-webgl”

• Le funzioni / variabili / constanti di WebGL sono membri di questo context “gl.”

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Codice per disegnare: preliminare cancellare lo schermo

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

function draw() {

gl.clearColor( 0.0, 0.0, 0.0, 1.0 );

gl.clear( gl.COLOR_BUFFER_BIT );

/* ... */

}

Red Green Blue Alpha

quale dei buffer?

(maschera di bit)

qui: solo l’RGB buffer (oppure: anche il depth, etc.)

Codice per disegnare: preliminare cancellare lo schermo

• Il comando clearColor modifica sullo stato

– (specifica con che colore cancellare lo schermo)

• Il comando clear “fa”

– resetta uno o più buffer – (specificando quali)

• maschera di bit

– è una «framebuffer operation»

• agisce direttamente sui buffer in output, senza passare dal pipeline

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

(6)

Reminder: Clip Space

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

VIEWPORT (il nostro canvas)

− 1 0 + 1

− 1 + 1

Definiamo cosa disegnare

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

• Una indexed Mesh?

• Facciamocela facile:

– di un solo trianglolo – in 2D

– già in clip coordinates (no transform!) – non indexed

• (reminder: «ogni tre vertici, un triangolo»)

• In JavaScript: var single_triangle_mesh = { vertexPositions : [

[0.0 , 0.0], // 1st vertex [1.0 , 0.0], // 2nd vertex [0.0 , 1.0], // 3rd vertex ]

};

Definiamo cosa disegnare

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

var myMesh = {

vertexPositions : [

[0.0 , 0.0], // 1st vertex [1.0 , 0.0], // 2nd vertex [0.0 , 1.0], // 3rd vertex ]

};

una buona struttura intuiviva, ma non va bene per WebGL.

Ci vuole più semplice / a basso livello!

Definiamo cosa disegnare

Here’s why not:

JavaScript does not represent arrays as contiguous areas (reason: they can be non-homogenous)

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

struttura piatta (singolo livello):

meglio,

ma non va ancora bene per WebGL

var

myMesh = [

0.0, 0.0, // 1st vertex

1.0, 0.0, // 2nd vertex

0.0, 1.0 // 3rd vertex

];

(7)

Definiamo cosa disegnare

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var

positions = [

0.0, 0.0, // 1st vertex 1.0, 0.0, // 2nd vertex 0.0, 1.0 // 3rd vertex ];

Usiamo invece una struttra dati apposita

(array di record omogenei e contigui):

il Float32Array

System RAM 0.0

1.0

0.0

1.0 0.0 0.0

positions typedPositions

0.0 0.0 1.0 0.0 0.0 1.0

Definiamo cosa disegnare

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

var positions = [ 0.0, 0.0, 1.0, 0.0, 0.0, 1.0 ];

var typedPositions = new Float32Array( positions );

0.0 1.0

0.0

1.0 0.0 0.0

positions

System RAM

(System RAM) (CPU RAM)

Definiamo cosa disegnare

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

var positions = [ 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ];

var typedPositions = new Float32Array( positions );

o, in alternativa:

var typedPositions = new Float32Array(6);

// 6 floats (3x2)

typedPositions[0] = 0.0; typedPositions[1] = 0.0;

typedPositions[2] = 1.0; typedPositions[3] = 0.0;

typedPositions[4] = 0.0; typedPositions[5] = 1.0;

comunque: typedPositions

0.0 0.0 1.0 0.0 0.0 1.0

Object Names (concetto generale in WebGL / OpenGL)

• Situazione: ho degli oggetti che abitano in Video RAM – tipicamente, duplicati da oggetti inizialmente in System RAM – es: array buffer, index buffer, programs, textures, etc…

• Q: come agisco su questi oggetti?

cioè, come mi riferisco ad essi?

– leggere, scrivere, etc, richiede di passare dal BUS!

• A: attraverso «object names» :

– un indice di una data istanza di quel tipo di oggetto (uno specifico array buffer, etc)

– in pratica, un NUMERO

– il name è in System RAM (quindi una variabile JS, per noi) e punta ad un oggetto in Video RAM

– i names vengono creati attraverso apposite chiamate

«create <something>» (che inizializza l’ogg) o «gen <something>»

– vengono distrutti (liberati per usi futuri) attraverso «delete <something>»

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

(8)

Binding (concetto generale in WebGL / OpenGL)

• Situazione:

– ∃ diversi comandi che agiscono su qualcosa (es: su un array buffer)

– ∃ istanze diverse di quel qualcosa (es: diversi array buffers, in Video ram)

• Q: come decido su quale delle istanza agisce un comando?

– Modo 1: passo sempre, a ciascun comando, (il name de) l’istanza su cui intendo agire,

– Modo 2: ∃ in un dato momento un’unica istanza «binded» (nello stato!)

(es: un array buffer binded, un program binded, etc) Esiste un comando “bind” per settare qual’è.

I comandi successivi agiscono implicitamente su quell’istanza.

• WebGL (OpenGL, etc): usa di solito il Modo 2 – nota: l’op di binding può avere un piccolo costo

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

actually,

«bound»

Carichiamo i dati del triangolo in un buffer sulla scheda video

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

var positions = [0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ];

var typedPositions = new Float32Array(positions);

var positionsBuffer = gl.createBuffer(); // crea un nome, es. 13 gl.bindBuffer(gl.ARRAY_BUFFER, positionsBuffer );

gl.bufferData(gl.ARRAY_BUFFER, typedPositions , gl.STATIC_DRAW);

motherboard video card

System RAM (“CPU RAM”) typedPositions

BUS

Video RAM (“GPU RAM”) 0.0 0.0 1.0 0.0 0.0 1.0

array buffer N.13

0.0 0.0 1.0 0.0 positionsBuffer

13

copy 0.0 1.0

Carichiamo i dati del triangolo in un buffer sulla scheda video (note)

• Copiare i dati in un oggetto WebGL in GPU-RAM:

un array buffer

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

var positionsBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, positionsBuffer );

gl.bufferData(gl.ARRAY_BUFFER, typedPositions , gl.STATIC_DRAW);

name per il buffer in Video RAM

• (verrà usato per riferirsi ad esso in futuro)

Bind: “from now on, my commands relative to array buffers must be applied to this one”

“credo che questo buffer verrà letto spesso, ma modificato di rado (please optimize stuff accordingly)”

dati (in system RAM) da cui copiare

Vertex Data in un buffer (in memoria video) :

spieghiamo al Vertex Puller come sono formattati

• In WebGL: vertex position = just another per-vertex attribute

• Scegliamo un index con cui riferirsi a questo “attribute” (facciamo, lo 0)

• Abilitiamolo

(«caro Vertex Puller: questo attributo va mandato al Vertex Shader»)

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

gl.vertexAttribPointer(

positionAttribIndex, 2, gl.FLOAT,

false, 0, 0 );

gl.vertexAttribPointer(

unsigned int index, int size, int type, bool normalized, unsigned int stride, unsigned int offset );

• Nel nostro caso:

gl.enableVertexAttribArray( positionAttribIndex );

const positionAttribIndex = 0; // global

• Specifichiamo il Context dell’attributo

(che tipo è + come accederlo)

(9)

Vertex Data in un buffer (in memoria video) :

spieghiamo al Vertex Puller come sono formattati

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

gl.vertexAttribPointer(

positionAttribIndex, 2, gl.FLOAT,

false, 0, 0 );

l’attributo di indice “0”…

…cosiste di 2 float successivi nel buffer (*)

(quindi un “vec2”) …

…storati direttamente come floating point

(non fixed point, cioè interi / 2^32) ...

… i due float per il vertice successivo li trovi dopo tot bytes (“stride”):

(qui è 0 ==> quanto ti aspetti: 2*size_of_float ) …

…a partire dalla posizione 0 del buffer (“offset”).

(*) : quello attualmente binded queste info saranno usate dal vertex puller

per passare gli attributi al vertex shader

Definiamo come disegnare

• Ora dobbiamo fornire due programmi (“shaders”):

– vertex shader (da eseguire per ogni vertice) – fragment shader (da eseguire per ogni frammento)

• Scritti nel linguaggio GLSL – simile al C («C-like»): no oggetti – alto livello (deve essere compliato)

– eseguito nella scheda video (nello stage corrispondente) – vec2, vec3, vec4, mat4, etc come tipi base

– in Direct3D si sarebbe usato il simile linguaggio «HLSL»

• Per il nostro hello-world, scriveremo shader minimali:

– che facciano solo in minimo indispensabile, e cioè – per il vertex shader:

produrre coodrinate clip del vertice (per il Rasterizzatore) – qui: usiamo quelle passate dal Vertex Puller come attributo,

che sono già in coord clip (niente transform) – per un fragment shader:

produrre il colore RGB per frammento (per l’Output Combiner) – qui: usiamo un colore costante

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Shaders minimali

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Primitive:

primitive assembler (& setup) Transformed

Vertex:

XYZW

(clip space)

transformed +

attributes vertex

shader Input

Vertex:

(object space)

XYZ input + attributes

GPU-RAM

Mesh:

vertex puller vertex buffer index

buffer rasterizer

rasterizer point

(1xV) (2xV)

line triangle

(3xV)

attribute vec2 aPosition;

void main(void) {

gl_Position = vec4( aPosition, 0.0, 1.0 );

}

G LS L

Shaders minimali

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a GPU-RAM

screento

Pixels:

RGBa + Depth + Stencil

RGBa buffer Depth buffer Stencil

buffer

output combiner

Fragments:

buffer pos (fixed, XY) +

interpolated attributes

fragment shader Primitive:

rasterizer lines rasterizer triangles rasterizer punti

void main(void) {

gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);

}

G LS L

(10)

Shaders minimali

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

attribute vec2 aPosition;

void main(void) {

gl_Position = vec4( aPosition, 0.0, 1.0 );

}

G LS L

void main(void) {

gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);

}

G LS L

vertex shader:

fragment shader:

X

&

Y W

(affine)

Z

Definiamo gli shaders

var

vsSource = "...";

var vertexShader = gl.createShader(gl.VERTEX_SHADER);

gl.shaderSource( vertexShader, vsSource);

gl.compileShader( vertexShader );

Poi, ripetere per il Fragment shader Costriuire e compilare il Vertex Shader:

Definiamo gli shaders

Qui va immesso il sorgente dello shader (come stringa JS!)

(un programma GLSL)

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var

vsSource = "...";

var vertexShader = gl.createShader(gl.VERTEX_SHADER);

gl.shaderSource( vertexShader, vsSource);

gl.compileShader( vertexShader );

Name dello shader (per riferirsi a lui in futuro)

“Questo shader ha questo sorgente”

Ebbene sì: compilazione (del GLSL) a tempo di esecuzione (del JS)!

• Risulato: un programma a basso livello che può essere eseguito sulla GPU.

• Può generare errori (di compilazione):

usare gl.glGetShaderInfoLog per farseli restituire

o FRAGMENT_

ovviamente

Piccolo problema pratico:

sorgenti come stringhe JavaScript

• Come definire la stringa che continene l’intero sorgente GLSL di uno shader?

– si potrebbe leggere (dinamicamente) da un file di testo – in questo primo progetto, usiamo strings literals

– come scrivere literals di tipo string di più righe?

• (es: in modo che i msg di errore di complilaz GLSL ci possano indicare a che riga sono avvenuti) 1. inserire caratteri newline "\n" (accapo) 2. per leggibilità, si può usare la

sitassi dei literals stringhe su più righe:

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

var nome = "Giuseppe" ; var eta = 32;

literal di tipo string literal di tipo int

var nome = "Giusep\

pe" ;

niente spazi

nè nulla

dopo la \ !

(11)

GL Programs

• 1 “Program” = 1 Vertex shader + 1 Fragment shader + (eventuali altri shader)

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var myProgram

= gl.createProgram();

gl.attachShader(myProgram, vertexShader);

gl.attachShader(myProgram, fragmentShader);

gl.bindAttribLocation(myProgram, positionAttribIndex,"aPosition");

gl.linkProgram(myProgram);

gl.useProgram(myProgram);

Costuiamo e settiamo un Program

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var myProgram

= gl.createProgram();

gl.attachShader(myProgram, vertexShader);

gl.attachShader(myProgram, fragmentShader);

gl.bindAttribLocation( myProgram, positionAttribIndex, // una const = 0

"aPosition"

);

gl.linkProgram(myProgram);

gl.useProgram(myProgram);

name per il program:

(per riferirsi ad esso in futuro) ecco i fragment e vertex shader di cui è composto quello che il vertex puller chiama

“attributo di indice 0”, negli shader di questo program

si chiama "aPosition" linking dei due shader

(controllando che siano compatibili) (può generare errori!)

ecco, fra tutti i program che ho definito fin’ora (uno solo in realtà) ora attiviamo questo (fino a contrordine)

Draw

• Alla fine, mandiamo il nostro primo triangolo

– (nella draw, dopo la cancellazione dello schermo):

– «manda nel pipeline 3 vertici,

assemblandoli tre-a-tre in primitive TRIANGOLO, prendendo i loro vertici

a partire dal primo (di indice 0)»

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

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

Per una visione d’insieme del codice, vedere l’implementazione sul sito:

lez 17

M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Riferimenti

Documenti correlati

Discutono: Fabio Folgheraiter, Università Cattolica del Sacro Cuore; Franca Olivetti Manou- kian, Studio Aps; amministratori e dirigenti pub- blici e del privato sociale,

Create a directory hello_ppu, write a hello world ppu program and create a Makefile, then compile and execute it as a standalone ppu program. Create a directory hello_spu, write

Di tutto ciò dobbiamo ringraziare la Direction Regionale de l’Education Nationale di Analamanga, la direttrice della scuola, signora Andriananja Felaniaina Razafindafrara,

Introduzione al Pascal. Hello World! Concetti fondamentali e struttura di un programma in Pascal. I

Vale come fondamento dell'ordinamento o come portatrice di certi valori anti-valori-precedenti (anti-totalitaristi, ecc.)?} , inoltre si potrebbe pensare

Il programma è disponibile sotto licenza GPL (“General Public License”); è quindi possibile copiarlo, distribuirlo ed utilizzarlo in modo completamente gratuito ed è anche

For the Pascal triangle, the rule is that the outside numbers on each row are 1s and the inside numbers are determined by the inverted triangle formula: South = West + East..

rappresentazioni delle esperienze vissute dalle generazioni adulte, costruite con il metodo della ricerca storico-didattica Formazione del secondo sapere cronologico come