Computer Graphics
Marco Tarini
Università dell’Insubria
Corso di Laurea in Informatica Anno Accademico 2016/17
Uniforms e interazione
Uniforms
• Uniforms: costanti (globali) negli shader settabili dall’applicazione
attribute vec2 laPosizione;
attribute vec3 colorePerVertice;
varying vec3 ccc;
uniform float howDark;
void main(void) {
gl_Position = vec4(laPosizione , 0.0, 1.0);
ccc = colAttribute * howDark ;
V E R TE X S ha de r
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 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Il linguaggio GLSL:
classi di allocazione
• const
– valori costanti, noti a compilaz
• uniform
– valori che sono uniformi su gruppi di primitive – per gli shader: costanti globali (sola lettura) – …ma per applicazione: impostabili
– (es: le matrici di trasformazione)
• attribute
– valore definito su ogni vertice
• varying
– valore che varia dentro la primitiva
• temporanea
– valori “usa e getta” (var locale o globale) uniform vec3 howDark ;
Uniforms
• Uniforms: costanti (globali) negli shader settabili dall’applicazione. Esempio
G LS L (G P U )
...
uniform float howdark;
...
var howdark_loc = gl.getUniformLocation(
myProg, "howdark"
);
...
gl.uniform1f( howdark_loc , 0.7 );
...
reneder(...); // sends the primitives
JS (C P U ) JS (C P U )
Settare lo uniform dal programma JavaScript 1) Trovare la locazione dello uniform nello shader:
– (una sola volta per shader) (locaz = un id numerico della var)
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 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
var howdark = 1.0;
// da mettere in setupShaders(), dopo aver linkato lo shader howdark_loc = gl.getUniformLocation(
programId, "howdark"
);
// da invocare nella draw, prima di mandare le primitive function setUniforms(){
gl.uniform1f( howdark_loc , howdark );
}
var howdark_loc; // loc in the shader (global)
2) Usarla per settare il valore dell’uniform:
Struttura programma tradizionale
• Struttura classica dei programmi a linea di comando:
main() {
init();
do_my_beautiful_algorithm();
exit();
}
non va bene per applicazioni
interattive !
Struttura programma nel paradigma Event-Based
• Sistema ad eventi
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 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
main() { init();
while (true) { get_event() ; process_event();
} }
eventi tipo:
• mouse, tastiera...
• sistema di finistre
• reshape, minimizzazione...
• generati dall'applicazione stessa
• o da thread differenti ciclo
degli eventi
Event-Based programmato con CallBacks
• CallBack:
– funzione preposta alla gestione di un evento
• il sistema si occupa del motore degli eventi, il programmatore si occupa solo
di definire e "registrare" le callback
– Registrare = assegnare alla gestione di un evento
• Es: Event-handler : motore che gestisce i DOM events
– in JavaScript / HTML5
DOM – Document Object Model
(JavaScript, XML, …)
• DOM events:
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 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
function myMouseMove( event ) {
/* posizione mouse: event.screenX e Y */
/* stato dei bottoni: event.buttons (bitmask) */
}
function myMouseDown( event ) {
/* e’ stato premuto il bottone event.button */
}
function myMouseUp( event ) { }
window.onload = main;
window.onmousemove = myMouseMove;
window.onmousedown = myMouseDown;
window.onmouseup = myMouseUp;
Callbacks (funzioni di risposta
agli eventi)
Parentesi JavaScript
• In JavaScript, anche le funzioni sono anche variabili, proprio come i numeri o le stringhe.
– comprese le funzioni che sono metodi di un oggetto
• Posso assegnarle liberamente - ad altre funzioni.
• La registrazione di una callback si implementa semplicemente sovrascrivendo i metodi degli elementi del DOM
– (finestra compresa, o elementi HTML) window.onmousemove = myMouseMove;
«sostituisco il metodo onmousemove di window
(quello che viene invocato quando il mouse si muove su essa) con la mia funzione myMouseMove »
Nota: sto solo assegnando una funzione ad un’altra,
e non sto invocandole alcuna: infatti non ci sono le !
Detect degli spostamenti del mouse
• Spostamento del mouse :
pos attuale meno pos dell’ultima volta
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 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
var lastMousePosX, lastMousePosY;
function myMouseDown( event ) { lastMousePosX = event.screenX;
lastMousePosY = event.screenY;
}
function myMouseMove( event ) {
if (event.buttons==0) return; // no button is held down var dx = event.screenX - lastMousePosX;
var dy = event.screenY - lastMousePosY;
lastMousePosX = event.screenX;
lastMousePosY = event.screenY;
/* fai qualcosa con dx e dy (sostamento mouse, in pixel) */
}
esempio:
drag mouse left & right to control brightness
var howDark = 1.0;
var lastMousePosX, lastMousePosY;
function myMouseDown( event ) { lastMousePosX = event.screenX;
lastMousePosY = event.screenY;
}
function myMouseMove( event ) {
if (event.buttons==0) return; // no button is held down var dx = event.screenX - lastMousePosX;
var dy = event.screenY - lastMousePosY;
lastMousePosX = event.screenX;
lastMousePosY = event.screenY;
howdark *= 1.0 + dx*0.0025;
if (howdark<0.1) howdark = 0.1;
if (howdark>1.0) howdark = 1.0;
doTheRendering(); // aggiorna!
}
Un dettaglio finale: HTML page
<html>
<body>
<canvas>…</canvas>
<li>Per vedere il codice: tasto destro, "view page source"</li>
<li> Per attivare la console di JavaScript (su molti browser): Ctrl+Shift+J</li>
<li>Tasto sinistro: trascina a destra / sinistra per + chiaro / + scuro </li>
</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 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a