Nella scorsa lezione di questo corso su OpenGL abbiamo introdotto la piattaforma ed abbiamo presentato le librerie principali con cui lavoreremo. Esistono principalmente due approcci per programmare con OpenGL: il primo è quello di appoggiarci a GLUT ed avere una finestra basilare per le piccole applicazioni, il secondo è quello di integrare OpenGL nella programmazione standard del nostro gestore di finestre. All’inizio del corso svilupperemo dei semplici esempi su GLUT, mentre nella seconda parte del corso, quando parleremo di argomenti più complessi, creeremo i disegni 3D nelle finestre create per il nostro gestore standard.
La programmazione in un ambiente grafico, sia esso Windows o Linux, ha come punto focale la gestione degli eventi. In particolare l’applicazione avrà un determinato comportamento a seconda della pressione di un particolare tasto o lo scatenarsi di altro evento di sistema. La strutturazione di un’applicazione assumerà la forma di un ciclo infinito e di tanto in tanto verrà controllata la coda dei messaggi dell’applicazione affinché la stessa possa comportarsi in determinati modi. Questo ciclo viene chiamato event-loop, che GLUT fornisce di default, a noi solo il compito di scrivere il programma di disegno.
// File FirstWin.cpp #include "GL/glut.h" float fStep, fPos; void Init() { fStep = 0.1f; fPos = 0.0f; 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); glColor3f(0.0, 1.0, 0.0); glBegin(GL_TRIANGLES); glVertex3f(-45.0, 0.0, 0.0); glVertex3f(-35.0, -20.0, 0.0); glVertex3f(-35.0, 20.0, 0.0); glVertex3f(45.0, 0.0, 0.0); glVertex3f(35.0, 20.0, 0.0); glVertex3f(35.0, -20.0, 0.0); glEnd(); glColor3f(1.0, 0.0, 0.0); glRectf((GLfloat)(-10.0 + fPos), -10.0, (GLfloat)(10.0 + fPos), 10.0); glutSwapBuffers(); } void Resize(int iWidth, int iHeight) { glViewport(0, 0, (GLsizei)iWidth, (GLsizei)iHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void Animation() { fPos += fStep; if (fPos > 30.0) fStep = -0.1f; if (fPos < -30.0) fStep = 0.1f; glutPostRedisplay(); } void KeyPress(unsigned char uKey, int x, int y) { if (uKey == 'q') glClearColor(0.0, 0.0, 0.0, 0.0); else if (uKey == 'w') glClearColor(0.0, 1.0, 1.0, 0.0); else if (uKey == 'e') glClearColor(1.0, 1.0, 0.0, 0.0); if (uKey == 'a') glutIdleFunc(Animation); else if (uKey == 'z') glutIdleFunc(NULL); 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 - Prima Esperienza"); Init(); glutDisplayFunc(Draw); glutReshapeFunc(Resize); glutKeyboardFunc(KeyPress); glutMainLoop(); }
In questo semplice esempio viene aperta una finestra e disegnati due triangoli verdi con un quadrato centrale rosso, con i tasti “q”, “w” ed “e” si cambia il colore di sfondo, mentre con i tasti “a” e “z” rispettivamente si inizia e ferma il movimento del quadrato tra i due triangoli.
Nella funzione main abbiamo la creazione della finestra con doppio buffer, la gestione dei colori RGB e il depth-buffer. Il doppio buffer serve ad un’applicazione grafica per una migliore gestione del disegno: si disegna sul buffer in memoria e poi quando pronto si sostituisce ( swap ) al visibile e via di questo ciclo.
Gli eventi gestibili tramite GLUT sono numerosi e vengono gestiti attraverso alcune funzioni che accettano come argomento funzioni callback:
Per un buon disegno è prima necessario cancellare il contenuto del buffer nel quale andremo a disegnare: questo avviene con la funzione glClear che azzera il depth-buffer e riempie il buffer di disegno con il colore che è stato specificato in precedenza con il comando glClearColor. Il colore che viene utilizzato per il disegno è specificato tramite il comando glColor3f. Al termine del disegno nel buffer si alterna con il video tramite la funzione glutSwapBuffers.
L’animazione è ottenuta semplicemente inserendo una funzione in idle e poi congelarla inserendo un valore nullo. Il programma presentato può sembrare scarno, ma farà da base per i prossimi esempi che faremo in quanto contiene tutti gli elementi più comuni di OpenGL. Per ora basta avere una visione d’insieme e generale, nel prosecuzione del corso analizzeremo i vari aspetti delle librerie parlando delle primitive grafiche.
Sono arrivato alla convinzione che un abbonamento per tutti i miei software gestionali sia il…
MerciGest è un software per la gestione del magazzino completamente gratuito. Continua a leggere→
In ufficio può capitare di doversi allontanare dal proprio posto di lavoro, ecco che allora…
In questo articolo vedremo quando è più o meno utile togliere la corrente ad un…
Dopo la pausa invernale dovuta al lavoro che devo fare per sostentarmi, eccomi di nuovo…
Vediamo come eliminare i files direttamente da Windows senza utilizzare il cestino. Continua a leggere→