Sto imparando OpenGL e le esercitazioni ( 1 , 2 ) Sto leggendo insegnami che per ridimensionare / ruotare / tradurre un oggetto devi conoscere la moltiplicazione della matrice. Perché? Invece di 3x3 matrix puoi usare 6 float: scale_x
, scale_y
, sin_a
, cos_a
, mov_x
e mov_y
. Risulterebbero in ...
- Meno GPU e utilizzo della CPU (la moltiplicazione della matrice richiede 9 moltiplicazioni e 6 aggiunte mentre le singole variabili richiedono 6 moltiplicazioni e 4 aggiunte. Inoltre, se si desidera spostare l'oggetto, invece di dover moltiplicare l'intera matrice, si modificano solo i valori di due galleggianti.
- Minore larghezza di banda della memoria (1/3 di taglio!)
- Più facile da manipolare (almeno in C, nessuna necessità di funzioni di manipolazione della matrice)
- Estrazione più semplice delle informazioni per ottenere la rotazione dell'oggetto o l'offset o la scala
Gli unici svantaggi che conosco sono:
- Non è possibile modificare l'ordine delle trasformazioni, soprattutto la rotazione attorno ad un punto, non l'origine della coordinata. Puoi comunque simularlo modificando
mov_x
emov_y
di conseguenza. - Altro codice. Potresti metterli in un array, ma questo significherebbe perdere la possibilità di aggiornarli uno per uno e solo aggiornarli tutti o l'inizio dell'array, non il centro o la fine. Potrei sbagliarmi su questo, però.
Qualcuno potrebbe dirmi cosa mi manca?
Modifica: aggiunto il mio shader di seguito.
#version 330
layout (location = 0) in vec2 pos;
layout (location = 1) in vec3 clr_in;
uniform float osclx, oscly, osina, ocosa, omovx, omovy;
uniform float msclx, mscly, msina, mcosa, mmovx, mmovy;
float oldx, oldy, x, y;
out vec3 clr_out;
void main() {
x = pos.x;
y = pos.y;
x = x * oscly;
y = y * osclx;
oldx = x;
oldy = y;
x = oldx * ocosa - oldy * osina;
y = oldx * osina + oldy * ocosa;
x = x + omovx;
y = y + omovy;
x = x * msclx;
y = y * mscly;
oldx = x;
oldy = y;
x = oldx * mcosa - oldy * msina;
y = oldx * msina + oldy * mcosa;
x = x + mmovx;
y = y + mmovy;
gl_Position = vec4(x, y, 0.0f, 1.0f);
clr_out = clr_in; }