Stavo ripassando gran parte delle API delle OpenGL. Stavo facendo piccoli schemi e riassunti ed allora ho pensato: perché non condividere un po’ di questo lavoro? Così ci trascrivo qualche piccolo cenno di OpenGL senza nessuna intenzione di portare alla luce chissà quale serie di tutorial. Se poi esce qualcosa di appetibile meglio così.
Innanzitutto devo fare due appunti: il primo è che, per mia semplicità, userò il Python come linguaggio per il codice, tuttavia le API sono identiche sia in pyOpenGL che nell’OpenGL standard quindi anche se programmate in C potete facilmente convertire il tutto nel linguaggio a voi più familiare. Secondo, le libreria OpenGL prese da sole sono un po’ complicate, infatti di solito ci si appoggia alle librerie collegate GLUT. Queste librerie si incaricano di fare tutto il lavoro “esterno” alla visualizzazione grafica come gestione degli input e integrazione nel sistema a finestre. Usare GLUT è proprio l’approccio che userò anche io.
Iniziamo mostrando un piccolo programma che disegna un quadrato bianco su uno sfondo nero.
from OpenGL.GL import *
def init():
glClearColor(0,0,0,0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0,1,0,1,-1,1)
def display():
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(1,1,1)
glBegin(GL_POLYGON)
glVertex3f(0.25, 0.25, 0)
glVertex3f(0.75, 0.25, 0)
glVertex3f(0.75, 0.75, 0)
glVertex3f(0.25, 0.75, 0)
glEnd()
glFlush()
if __name__ == '__main__' :
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize(250, 250)
glutInitWindowPosition(100, 100)
glutCreateWindow("Hello World")
init()
glutDisplayFunc(display)
glutMainLoop()
Partiamo quindi a spiegare il codice cominciando da l main. La prima funzione che incontriamo è glutInit(). Questa funzione si incarica di inizializzare GLUT. La versione canonica di questa funzione prende per argomento gli argomenti del main (argc e argv per chi conosce il C).
La seconda funzione è glutInitDisplayMode(). Questa funzione prende per parametri delle opzioni di visualizzazione. Nel nostro caso GLUT_SINGLE e GLUT_RGB i quali impostano la visualizzazione a singolo buffer (capiremo la differenza con il doppio buffer la prossima volta) e la visualizzazione RGB (ovvero con i colori tradizionalmente usati nei pc).
Gli altri tre comandi invece creano la finestra impostandone dimensione, posizione e titolo.
A questo punto entriamo in init(). In questa funzione vengono preimpostate alcune variabili di OpenGL. Non entrerò nel dettaglio ora, vi basti sapere che glClearColor() è la funzione per il colore di “sfondo” ovvero per quello usato durante la cancellazione. Questa funzione prende 4 parametri (rosso, verde, blu e trasparenza).
Un altra funzione importantissima è glutDisplayFunc() questa è la funzione che indica al motore grafico quale funzione chiamare nel momento in cui c’è bisogno di disegnare sullo schermo. In questo esempio passiamo semplicemente la funzione display la quale non fa altro che disegnare un quadrato bianco.
Come? Semplice. Per disegnare qualcosa bisogna passare al sistema le coordinate dei vertici secondo un algoritmo del tipo:
- Si imposta il colore.
- Si avverte il sistema che stiamo inserendo i vertici con glBegin().
- Si passano le coordinate dei vertici con glVertex3f()
- Si avverte il sistema che abbiamo terminato con glEnd()
Il parametro di glBegin è molto importante ma capiremo meglio il suo significato successivamente.
La funzione glFlush() è inutile per molte applicazioni. Ma voi mettetela. Così sarete sicuri che il vostro codice funzioni, ad esempio, in applicazioni di rete.
Alla fine, per chiudere in bellezza si lancia glutMainLoop() per avviare il programma.
Questo è solo un piccolo esempio. Disegnare un quadrato immobile non è ne bello ne utile. Ma questo esempio, nella sua semplicità, racchiude l’essenza di ogni programma OpenGL. La prossima volta vedremo come far ruotare questo dannato quadrato.
Grazie mille per aver pubblicato questa introduzione a OpenGl! 🙂
Non si trovano molti tutorial in giro, e quelli che ci sono sembrano complicati per un neofita… la tua spiegazione invece sembra a prova di niubbo 😀
Hai ragione riguardo le API, ho tradotto il codice in C e ha funzionato subito! Solo non capisco questo if:
if __name__ == ‘__main__’ :
cosa significa… forse dipende dal fatto che non conosco il python 🙁
Ovviamente attendo con ansia il codice per far ruotare il quadrato bianco 😀
ciao!
Quella è roba è roba puramente python :). Serve a impedire che il main venga eseguito quando il modulo è importato con “import X”.
Quel codice lo posto domani, massimo lunedì. Approfitto del fatto che un bug di Ubuntu mi impedisce di provare nuovi script -.- perché Python crasha di colpo.
inoltre non volevo essere molto educativo nella scrittura. Ho seguito la linea guida della “praticità” 😀 Sono contento che nonostante tutto funzioni a meraviglia! 😀
Grazie del commento!