Le Matrici di Trasformazione in OpenGL

L’argomento che andremo ad affrontare in questa lezione del corso su OpenGL è molto ostico, le matrici di trasformazione, che ci permettono di spostare i nostri oggetti poligonali nella scena. Finora abbiamo inserito dei semplici disegni nella scena e li abbiamo fatti muovere, questo è un compito semplice con oggetti semplici come un quadrato, se però dobbiamo calcolare i movimenti dei vertici di oggetti più complicati, la difficoltà del nostro compito aumenterebbe tantissimo al punto da diventare proibitivo. Abbiamo detto che il nostro punto di vista è dietro la scena, lungo la parte negativa dell’asse z, inoltre la proiezione vista finora è ortogonale; con le matrici di trasformazione possiamo avere il movimento lungo l’asse z e la vista prospettica.
Il modo più semplice per costruire un oggetto è quello di pensarlo diritto all’origine, un cubo per esempio deve avere il centro nell’origine e le facce perpendicolari agli assi, se avessimo voluto costruire il cubo ruotato sarebbe stato molto più complicato. Le coordinate dei vertici specificate in questo modo sono dette coordinate locali, in quanto si riferiscono ad un sistema di riferimento locale all’oggetto. Ora, se vogliamo che il nostro oggetto compaia in un determinato punto della scena, basterà specificare dove si trova l’origine del nostro sistema per conoscere le coordinate assolute nel nuovo. Se però il punto di vista non si trova nell’origine, dobbiamo sapere anche le coordinate camera rispetto al nostro punto di vista. Sul video, essendo bidimensionale, si estrarranno le coordinate schermo a due dimensioni. OpenGL fornisce due matrici per queste trasformazioni:

  • GL_MODELVIEW – Racchiude le prime due trasformazioni
  • GL_PROJECTION – Racchiude la terza trasformazione

Vediamo queste nozioni in pratica con un semplice esempio sulle trasformazioni:

// File FirstWin.cpp per le trasformazioni

#include "GL/glut.h"

void Init()
{
      glClearColor(0.0, 0.0, 0.0, 0.0);
      glShadeModel(GL_FLAT);
      glEnable(GL_DEPTH_TEST);
}

void Draw()
{
      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();

      glTranslatef(15.0f, 0.0f, 0.0f);
      glRotatef(45.0f, 0.0f, 0.0f, 1.0f);

      glColor3f(0.0f, 1.0f, 0.0f);
      glBegin(GL_TRIANGLES);
        glVertex3f(-6.0f, -2.0f, -1.0f);
        glVertex3f(0.0f, 16.0f, -1.0f);
        glVertex3f(6.0f, -2.0f, -1.0f);
      glEnd();

      glutSwapBuffers();
}

void Resize(int iWidth, int iHeight)
{
      glViewport(0, 0, (GLsizei)iWidth, (GLsizei)iHeight);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-50.0f, 50.0f, -50.0f, 50.0f, 0.0f, 100.0f);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
}

void Tastiera(unsigned char key, int x, int y)
{
       if (key == 27)
           exit(0);
       glutPostRedisplay();
}

int main(int argc, char** argv)
{
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
      glutInitWindowSize(350, 350);
      glutInitWindowPosition(100, 100);
      glutCreateWindow("OpenGL - Trasformazioni");
      Init();
      glutDisplayFunc(Draw);
      glutReshapeFunc(Resize);
      glutKeyboardFunc(Tastiera);
      glutMainLoop();
}

La funzione glLoadIdentity serve ad azzerare qualsiasi trasformazione contenuta nella matrice corrente. Nella funzione di disegno abbiamo selezionato la matrice di modelview, eliminando le eventuali trasformazioni e poi applichiamo una traslazione ed una rotazione. Nella funzione di ridimensionamento della finestra selezioniamo la matrice di proiezione, eliminando le eventuali trasformazioni presenti e poi applichiamo la proiezione da utilizzare; al termine selezioniamo la matrice di modelview ed eliminiamo anche da essa le possibili traformazioni applicate in precedenza.
Le prime trasformazioni che andremo ad analizzare saranno quelle relative alla posizione dell’oggetto:

  • Traslazione – Il comando glTranslatef(dx, dy, dz) sposta l’oggetto delle distanze specificate lungo la direzione dei vari assi.
  • Rotazione – Il comando glRotatef(ang, ax, ay, az) ruota l’oggetto lungo i vari assi, ad esempio per ruotare l’oggetto di 45° sull’asse y si scriverà: glRotatef(45.0f, 0.0f, 1.0f, 0.0f).
  • Scalatura – Il comando glScalef(sx, sy, sz) consente di alterare le dimensioni dell’oggetto lungo i tre assi.

Provate a fare delle prove modificando ed inserendo nuove trasformazioni al triangolo dell’esempio.

<< Lezione Precedente – Lezione Successiva >>

Informazioni su Giampaolo Rossi

Sviluppatore di software gestionale da oltre 28 anni.
Questa voce è stata pubblicata in Grafica, Programmazione e contrassegnata con . Contrassegna il permalink.