Giandomenico's page
home
La classe ClsOpenGL

di Giandomenico De Sanctis - gidesay@yahoo.com
versione 2.1 - 2000


La classe ClsOpenGL è una classe per Visual Basic 5 per interfacciare la libreria OpenGL / GLU.
OpenGL è una libreria per oggetti 3D professionale, originariamente prodotta da Silicon Graphics per le sue macchine ed ora portata su molti sistemi: UNIX, Macintosh e Window NT/95/98.
La versione della Microsoft è OpenGL 1.1, con due librerie: OPENGL32.DLL e GLU32.DLL. Queste sono fornite con Windows NT e Windows 98 nelle versioni più recenti, o sono scaricabili dal sito della Microsoft.
OpenGL ha molte funzioni, riguardanti tutti i tipi di manipolazioni 3d: disegno di oggetti, solido e wireframed; sfumatura del colore in base all'illuminazione, con il metodo di Phong ed altri; effetti speciali come la nebbia; primitive come sfera, cono, cilindro, prisma, toro, NURBS (Superfici Razionali Non Uniformi con curve 'spline'); ecc ecc..
Una guida di riferimento completa alle funzioni di OpenGL è disponibile alla Digital.
Questa classe è dedicata a facilitare l'uso di OpenGL standard: quando molte chiamate alle funzioni OpenGL sono richieste per ottenere un semplice effetto logico, la classe incapsula tutto in un singolo metodo, facile da usare. Ciò si verifica, per esempio, nell'inizializazione di un OpenGL 'rendering context' (l'ambiente di disegno di OpenGL), dove sono necessarie oltre 20 chiamate a differenti funzioni per definire tutti i parametri: memoria, luci, strutture, parametri di prospettiva, viewport, ecc.
Non tutte le funzioni OpenGL sono esposte da metodi corrispondenti della classe: per esempio GLpushmatrix e GLpopmatrix, per salvare e ricaricare le matrici PROJECTION e MODELVIEW. Non di meno, è sempre possibile chiamare direttamente una funzione di OpenGL (come indicato negli esempi), aggirando la classe, per ottenere effetti speciali.
E' anche inclusa la libreria BMPTEX.DLL: questa serve a caricare rapidamente immagini BMP come textures, ed a salvare disegni fatti con OpenGL, sempre in formato BMP.
Per usare la classe bisogna caricare nel progetto di VB le librerie di riferimento a OpenGL:
- OpenGL 1.1 v 1.2 (OPENGL32.TLB)
- GLUT 3.5 v 1.0 (GLUT32.TLB)
di Patrice Scribe - @1997 - (visitate il suo grande sito dedicato a VB ed a OpenGL)
e caricare il file CLSOPENGL.CLS, e BMPTEXDLL.BAS che contiene i riferimenti alla BMPTEX.DLL.

Nelle tabelle successive sono elencati le proprietà ed i metodi esposti dalla classe.

/P/ = Property /S/ = Method/Sub /F/ = Method/Function /E/ = Event

Proprietà
/P/ hGLRC As Long
puntatore al rendering context OpenGL
/P/ hPalette As Long
puntatore alla palette di colori usata
/P/ colorbits As Integer
numero di bit di colore usati dal contesto OpenGL: 2 = 2 colori; 4 = 16 colori; 8 = 256 colori; 16 = 65535 colori; 24 = 16 milioni
/P/ textured As Boolean
vale TRUE se le facce degli oggetti/superfici 3D sono ricoperte da texture
/P/ wireframed As Boolean
vale TRUE se le facce degli oggetti/superfici 3D sono disegnate solo con i bordi (wireframe)
/P/ shaded As Boolean
vale TRUE se le facce degli oggetti/superfici 3D sono disegnate con la sfumatura di colore
/P/ texBitmap As Collection
collezione degli indici delle textures formato BMP caricate con il metodo LoadBMPImage. Ogni texture ha un indice unico identificativo, associato con un nome.
/P/ GLlist As Collection
collezione degli indici delle liste OpenGL create con vari metodi
/P/ nurb As GLUnurbs
puntatore al rendering context corrente per le NURBS (per disegnare superfici interpolate)
/P/ filter_enabled As Boolean
vale TRUE se il filtro visivo è abilitato
/P/ background_enabled As Boolean
vale TRUE se lo sfondo fisso è abilitato

Metodi

/S/ completedraw ()
mostra la finestra OpenGL con tutti gli oggetti disegnati prima
/S/ deleteNURBS ()
cancella il rendering context per le NURBS
/S/ drawall ()
disegna tutti gli oggetti memorizzati nelle liste raccolte nella GLlist della classe
/S/ drawlist (lista)
disegna la lista di indice 'lista'


/F/ drawterrain ( y ( ) As GLfloat, nx As Integer, nz As Integer, lx As Single, lz As Single, x0 As Integer, z0 As Integer, lista As Integer, scal As Single, tex1d ( ) As Byte, flag_triangle As Boolean, alpha As Single ) As Integer
DRAWTERRAIN - memorizza in una lista OpenGL una griglia regolare di quote, approssimata con una serie di quadrilateri o triangoli. La griglia è colorata usando una texture 1D, che assegna un colore a ciascuna quota, digitalizzata nel range 0-255.
y(): una matrice con 'nx' righe e 'nz' colonne, ogni valore y(ix, iz) è l'altezza Y della griglia nel punto del piano X-Z avente coordinate: x=x0 + lx * ix; z=z0 + lz * iz (ix e iz = 1);
nx = righe della griglia;
nz = colonne della griglia;
lx = intervallo tra due punti consecutivi lungo l'asse X;
lz = intervallo tra due punti consecutivi lungo l'asse Z;
x0 = coordinata X del punto di origine della griglia;
z0 = coordinata Z del punto di origine della griglia;
lista = indice dell'elemento nella GLlist che identificherà la griglia in ogni operazione di disegno successiva; se lista=0, DRAWTERRAIN ritorna l'indice associato alla griglia, altrimenti ritorna un valore uguale a 'lista'
scal = scala di riferimento delle quote; ogni valore Y è diviso per 'scal', poi il risultato (>=0 e <=255) è usato per assegnare la coordinata della texture 1D
tx1d(0 to 2, 0 to 255) = un vettore di 256 valori, ognuno contenente le componenti RGB del colore della texture 1D da assegnare ad ogni quota Y.
flag_triangle = se TRUE, ogni cella rettangolare della griglia è disegnata con 4 triangoli, che hanno i vertici rispettivamente nei 4 vertici della cella e nel punto di mezzo, se è FALSE, la cella è disegnata come un quads OpenGL
alpha = parametro della trasparenza dell'oggetto, 0 = totalmente trasparente; 1 = totalmente opaco

/F/ drawNURBS (ctrlpoint() As GLfloat, precision As Single, matcolor() As GLfloat, lista As Integer) as integer
DRAWNURBS - memorizza in una lista OpenGL una superfice NURBS del terzo ordine: questo richiede 16 punti di controllo, nella matrice 'ctrlpoint'. Questa matrice ha 3 dimensioni: ctrlpoint(0 to 2, 0 to 3, 0 to 3). Il primo indice identifica le coordinate x, y, z: il secondo e terzo identificano righe e colonne dei punti di controllo.
precision = valore che controlla l'accuratezza delle superfici NURBS usate: valori più grandi danno accuratezza minore;
matcolor(0 to 3) = un vettore a 4 elementi contenente i valori RGB (da 0 ad 1.0) del colore del materiale, il quarto elemento è il parametro alfa, normalmente vale 1.0;
lista = indice dell'elemento nella GLlist che identificherà la griglia in ogni operazione di disegno successiva; se lista=0, DRAWMESH ritorna l'indice associato alla griglia, altrimenti ritorna un valore uguale a 'lista'


/F/ createbackground ( baseradius As Single, heigh As Single, precision As Integer, tex ( ) As String, skytex As String, collist ( ) As Single, lista As Integer ) As Integer
CREATEBACKGROUND - definisce uno sfondo laterale per la scena, in forma di un cilindro ottagonale, con le facce con texture nella parte interna. Ogni faccia può avere differenti texture o colore. Lo sfondo è completato da un piano di "cielo", con la sua texture o colore. Lo sfondo per default è centrato nell'origine (x=0, y=0, z=0).
baseradius = raggio del cerchio di base
heigh = altezza dello sfondo lungo l'asse Y
precision = parametro che misura il numero di sottopunti che hanno le facce, valore minimo = 1.
tex(1 to 8) = nomi di textures precedentemente caricate per ciascuna faccia; se qualche faccia non ha texture, porre tex() = "" per quella faccia
skytex = nome di una texture precedentemente caricata da applicare al piano di copertura. Se skytex = "", il "cielo" viene colorato con un blu-celeste
collist(1 to 8, 0 to 2) = colori RGB di ogni faccia, usati solo se tex() = ""
lista = indice dell'elemento nella GLlist che identificherà l'oggetto in ogni operazione di disegno successiva; se lista=0, la funzione ritorna l'indice associato all'oggetto, altrimenti ritorna un valore uguale a 'lista'

/F/ createcylinder ( baseradius As Single, topradius As Single, heigh As Single, precision As Integer, tex As String, colore ( ) As Single, lista As Integer ) As Integer
CREATECYLINDER - crea un nuovo cilindro generalizzato, con base centrata sull'origine (0, 0, 0), ed asse parallelo alla coordinata Z. Il cilindro è aperto alle estremità.
baseradius, topradius = raggio della base e dell'altra estremità del cilindro; se non sono uguali, l'oggetto diventa un tronco di cono. Se uno è zero, l'oggetto è un cono.
heigh = altezza del cilindro lungo l'asse Z
precision = parametro che misura il numero di facce che ha il cilindro generalizzato, valore minimo = 3. Con 3 = un prisma con base triangolare, 4 = prisma con base quadrata, e così via. Se precision >= 15, l'oggetto diventa un cilindro (o cono) vero e proprio.
tex = nome di una texture precedentemente caricata; ponendo tex = "" l'oggetto non viene ricoperto da texture
colore(0 to 2) = colore RGB dell'oggetto, usato solo se tex = ""
lista = indice dell'elemento nella GLlist che identificherà l'oggetto in ogni operazione di disegno successiva; se lista=0, la funzione ritorna l'indice associato all'oggetto, altrimenti ritorna un valore uguale a 'lista'

/F/ createsphere ( radius As Single, precision As Integer, tex As String, colore ( ) As Single, alpha As Single, lista As Integer ) As Integer
CREATESPHERE - crea una nuova sfera generalizzata, con centro nell'origine (0, 0, 0).
radius = raggio della sfera
precision = parametro che misura il numero di facce che ha la sfera, un valore >= 15 genera una sfera vera e propria.
tex = nome di una texture precedentemente caricata; ponendo tex = "" l'oggetto non viene ricoperto da texture
colore(0 to 2) = colore RGB dell'oggetto, usato solo se tex = ""
alpha = parametro della trasparenza dell'oggetto, 0 = totalmente trasparente; 1 = totalmente opaco
lista = indice dell'elemento nella GLlist che identificherà l'oggetto in ogni operazione di disegno successiva; se lista=0, la funzione ritorna l'indice associato all'oggetto, altrimenti ritorna un valore uguale a 'lista'

/F/ createprysm ( widt As Single, dept As Single, heigh1 As Single, heigh2 As Single, precision As Integer, texlist ( ) As String, collist ( ) As Single, lista As Integer ) As Integer
CREATEPRYSM - definisce un prisma retto, con base nel piano X-Z ed uno dei vertici nell'origine (0, 0, 0), con tetto inclinato se heigh1 diverso da heigh2. La texture od il colore può essere differente per ogni faccia. Per ogni faccia ed ogni asse, definisce un numero di sottopunti pari a 'precision + 1'. Se precision = 1, solo i 4 vertici d'angolo di ogni faccia sono definiti. Questo è utile perchè la OpenGL effettua i calcoli di luminosità su ogni vertice, quindi avendo solo i 4 vertici d'angolo gli effetti d'illuminazione potrebbe essere di scarsa qualità.
widt = dimensione del prisma lungo X
dept = dimensione del prisma lungo Y
heigh1, heigh2 = dimensioni anteriore e posteriore del prisma lungo Z
precision = parametro che misura il numero di sottopunti che hanno le facce, valore minimo = 1.
texlist(1 to 6) = nomi di textures precedentemente caricate per ciascuna faccia; se qualche faccia non ha texture, porre tex() = "" per quella faccia
collist(1 to 6, 0 to 2) = colori RGB di ogni faccia, usati solo se tex() = ""
lista = indice dell'elemento nella GLlist che identificherà l'oggetto in ogni operazione di disegno successiva; se lista=0, la funzione ritorna l'indice associato all'oggetto, altrimenti ritorna un valore uguale a 'lista'

/F/ createfloor ( widt As Single, dept As Single, heigh As Single, precision As Integer, tex As String, colore ( ) As Single, lista As Integer ) As Integer
CREATEFLOOR - definisce un fondo (o pavimento) rettangolare per la scena, parallelo al piano X-Z, e con un angolo nell'origine (0, 0, 0).
widt = dimensione lungo X
dept = dimensione lungo Z
heigh = posizione lungo Y
precision = parametro che misura il numero di sottopunti che ha il fondo, minimo = 1
tex = nome di una texture precedentemente caricata; ponendo tex = "" l'oggetto non viene ricoperto da texture. La texture è applicata ad ogni cella definita dal parametro 'precision', come se il fondo fosse piastrellato. Per esempio, precision = 4 significa che il fondo ha 4 x 4 piastrelle, ciascuna ricoperta con l'intera texture.
colore(0 to 2) = colore RGB dell'oggetto, usato solo se tex = ""
lista = indice dell'elemento nella GLlist che identificherà l'oggetto in ogni operazione di disegno successiva; se lista=0, la funzione ritorna l'indice associato all'oggetto, altrimenti ritorna un valore uguale a 'lista'

/F/ createtorus ( r1 As Double, r2 As Double, precision As Integer, tex As String, colore ( ) As Single, lista As Integer ) As Integer
CREATETORUS - crea un nuovo oggetto toroidale, a sezione circolare, attorno all'origine delle coordinate (0, 0, 0).
r1 = raggio dell'asse circolare del toro
r2 = raggio della sezione circolare del toro
precision = parametro che misura il numero di "fette" del toro, più grande è precision maggiore è l'approssimazione ad un toro perfettamente regolare
tex = nome di una texture precedentemente caricata; ponendo tex = "" l'oggetto non viene ricoperto da texture
colore(0 to 2) = colore RGB dell'oggetto, usato solo se tex = ""
lista = indice dell'elemento nella GLlist che identificherà l'oggetto in ogni operazione di disegno successiva; se lista=0, la funzione ritorna l'indice associato all'oggetto, altrimenti ritorna un valore uguale a 'lista'

/S/ Glinit (obj)
inizializza il rendering context OpenGL, collegandolo all'oggetto fornito in input: un form, od una picturebox. I disegni successivamente saranno perciò visualizzati dentro quest'oggetto. Molti parametri sono assegnati con valori di default; le proprietà 'textured', wireframe', 'shaded' sono lette per dare il corretto aspetto agli oggetti 3D disegnati. La proprietà 'hGLRC' contiene il puntatore al rendering context OpenGL assegnato dalle funzioni di inizializzazione.

/S/ initdraw ( )
cancella i buffers del colore e della profondità per un nuovo ciclo di disegni

/S/ LoadBMPImage (nome As String, nomebitmap As String)
LOADBMPIMAGE - carica una immagine BMP dal file 'filename', e la memorizza nella collezione texBitmap con il nome-chiave 'nomebitmap', pronta per essere usata negli oggetti 3D. Utilizza funzioni della BMPTEX.DLL


/F/ LoadDXFobj ( nomedxf As String, dxftex As String, scalex As Single, scaley As Single, scalez As Single, col_r As Single, col_g As Single, col_b As Single ) As Integer
LOADDXFOBJ - carica un oggetto 3D definito in un file formato DXF, come gruppo di paragrafi 3DFACE; l'oggetto è memorizzato in una lista, il cui indice è il valore ritornato dalla funzione.
nomedxf = nome del file DXF da caricare;
dxftex = nome-chiave di una texture precedentemente caricata con LoadBMPImage, questa texture viene applicata sopra l'oggetto; se dxftex = "", all'oggetto non viene applicata nessuna texture;
scalex, scaley, scalez = fattori di scala per cui viene moltiplicata la relativa coordinata di ogni vertice dell'oggetto
col_r, col_g, col_b = componenti RGB del colore dell'oggetto

/S/ modrotate (xAngle As Single, yAngle As Single, zAngle As Single)
MODROTATE - ruota gli assi correnti (chiamati 'MODELVIEW' nella OpenGL) degli angoli xAngle, yAngle, zAngle, in gradi. Il precedente orientamento degli assi non è salvato.

/S/ modtranslate (xDelta As Single, yDelta As Single, zDelta As Single)
MODTRANSLATE - sposta gli assi correnti (chiamati 'MODELVIEW' nella OpenGL) delle distanze xDelta, yDelta, zDelta, in unità OpenGL. Il precedente orientamento degli assi non è salvato.


/S/ setlight (lnum As Integer, lspot As Boolean, lcolor() As Single, lposition() As Single)
SETLIGHT - imposta ed attiva una sorgente luminosa OpenGL di indice 'lnum' (l'indice può essere uno tra le costanti GL_LIGHT0, GL_LIGHT1, ...., GL_LIGHT7. GL_LIGHT0 e GL_LIGHT1 sono definite di default dal metodo GLInit).
lspot = vale TRUE se questa è una sorgente 'spot', cioè a riflettore;
lcolor(0 to 3) = un vettore a 4 elementi contenente i valori RGB (da 0 ad 1.0) del colore della luce, il quarto elemento è il parametro alfa, normalmente vale 1.0;
lposition(0 to 3)= un vettore a 4 elementi contenente le coordinate x, y, e z della posizione della sorgente; il quarto valore è impostato ad 1.0 se si tratta di una luce posizionale (puntiforme), è impostato a zero se si tratta di una luce direzionale (tutti i raggi sono paralleli tra loro). In questo caso, la direzione dei raggi è parallela al vettore che va dalla posizione della luce all'origine degli assi (0, 0, 0)

/S/ setmaterial (matprop() As Single)
SETMATERIAL - imposta le caratteristiche di riflessione della luce per il materiale corrente (AMBIENT e DIFFUSE);
matprop(0 to 3) = un vettore a 4 elementi contenente i valori RGB (da 0 ad 1.0) del colore della luce riflessa, il quarto elemento è il parametro alfa, normalmente vale 1.0;

/S/ saveimage ( namefile As String )
SAVEIMAGE - salva il contenuto del buffer OpenGL nel file 'namefile', in formato BMP non compresso a 16 milioni di colori

/S/ getcamerapos ( camerax As Single, cameray As Single, cameraz As Single )
GETCAMERAPOS - ritorna la posizione della camera, in coordinate dello spazio MODELVIEW
camerax, cameray, cameraz = le coordinate correnti della camera

/S/ setcamerapos ( ByVal newx As Single, ByVal newy As Single, ByVal newz As Single )
SETCAMERAPOS - imposta la posizione della camera, in coordinate dello spazio MODELVIEW. La direzione di vista è parallela al piano X-Z, verso un punto avente coordinate xc = newx, zc = newz - 1, cioè rivolto verso l'asse Z negativo
newx, newy, newz = le nuove coordinate della camera

/S/ cameragoup ( ByVal incrY As Single )
CAMERAGOUP - sposta la camera e la direzione di vista verso l'alto o verso il basso
incry = incremento della coordinata Y

/S/ cameraupdown ( ByVal incrY As Single )
CAMERAUPDOWN - ruota la direzione di vista verso l'alto o verso il basso
incry = incremento della coordinata Y del centro di vista

/S/ camerarolling ( ByVal angleZ As Single )
CAMERAROLLING - ruota la direzione di vista attorno all'asse Z del MODELVIEW, generando un rollio
angleZ = rotazione in gradi

/S/ camerarot ( ByVal angleY As Single )
CAMERAROT - ruota la direzione di vista attorno all'asse Y del MODELVIEW, verso destra o verso sinistra
angleY = rotazione in gradi

/S/ cameraforwback ( ByVal incr As Single )
CAMERAFORBACK - sposta la camera in avanti od indietro, lungo la direzione di vista
incr = spostamento delle coordinate della camera

/S/ cameraleftright ( ByVal incr As Single )
CAMERALEFTRIGHT - sposta la camera a sinistra od a destra, rispetto alla direzione di vista
incr = spostamento delle coordinate della camera

/S/ setobjpos ( dx As Single, dy As Single, dz As Single )
SETOBJPOS - imposta la traslazione corrente per la matrice MODELVIEW
dx, dy, dz = traslazioni delle coordinate

/S/ setobjrot ( rx As Single, ry As Single, rz As Single )
SETOBJROT - imposta la rotazione corrente per la matrice MODELVIEW
rx = rotazione attorno all'asse X, in gradi
ry = rotazione attorno all'asse Y, in gradi
rz = rotazione attorno all'asse Z, in gradi

/S/ initlist ( lista As Integer, tex As String, colore ( ) As Single, ftex As Boolean, fcol As Boolean, Optional alpha As Single )
INITLIST - cambia le caratteristiche principali di un oggetto memorizzato in una lista OpenGL, senza la necessità di rigenerare l'intera descrizione dell'oggetto. Le proprietà dell'oggetto che possono essere cambiate sono: texture, colore, posizione (precedentemente impostata con una chiamata a SETOBJPOS), rotazione (precedentemente impostata con una chiamata a SETOBJROT)
lista = indice dell'elemento nella GLList che identifica l'oggetto da cambiare
tex = nome di una texture precedentemente caricata
colore(0 to 2) = colore RGB dell'oggetto
ftex = se TRUE, la texture 'tex' viene applicata all'oggetto
fcol = se TRUE, il colore() viene applicato all'oggetto come colore del materiale
alpha = parametro di trasparenza dell'oggetto, opzionale, 0 = indica nessun valore passato, è equivalente ad 1 = totalmente opaco; valori minori di 1 e maggiori di 0 attivano la trasparenza nell'oggetto

/S/ selectobj ( mx As Double, my As Double )
SELECTOBJ - usa le funzioni speciali della OpenGL per trovare l'oggetto 3D sotto un punto nella finestra di disegno, avente le coordinate mx ed my (in unità della finestra). Utile se chiamato con le coordinate del mouse. Questa sub imposta la proprietà di classe 'selected' con l'indice di lista, corrispondente ad uno degli oggetti 3D precedentemente registrati con altre funzioni.

/S/ drawcursor ( )
DRAWCURSOR - disegna un cursore conico giallo nella posizione impostata con una chiamata a MOVECURSOR

/S/ movecursor ( dx As Single, dy As Single, dz As Single )
MOVECURSOR - imposta la posizione di un cursore, disegnato con una chiamata a DRAWCURSOR
dx, dy, dz = coordinate del cursore


/S/ filter ( tex As String, colore ( ) As Single, alpha As Single )
FILTER - disegna un filtro visivo davanti alla camera. Questo può essere un filtro colorato, oppure un filtro con texture, ponendo che alpha sia minore di 1, altrimenti il filtro risulta totalmente opaco!
tex = nome di una texture precedentemente caricata
colore(0 to 2) = colore RGB dell'oggetto, viene mescolato con la texture
alpha = parametro di trasparenza del filtro, 0 = totalmente trasparente, 1 = totalmente opaco

/S/ background ( tex As String, colore ( ) As Single, alpha As Single )
BACKGROUND - disegna uno sfondo fisso dietro tutti gli oggetti. Lo sfondo non è soggetto alle trasformazioni prospettiche.
tex = nome di una texture precedentemente caricata
colore(0 to 2) = colore RGB dell'oggetto, viene mescolato con la texture
alpha = parametro di trasparenza del filtro, 0 = totalmente trasparente, 1 = totalmente opaco



Programmi di esempio
I programmi di esempio sono:
TXOPENGL crea un oggetto clsOpenGL e lo collega ad una picturebox, poi richiede il caricamento di un oggetto 3D DXF e di una texture BMP; l'oggetto 3D è disegnato nella picturebox, e può essere ruotato e traslato da menù o da tastiera
TXMESH crea un oggetto clsOpenGL e lo collega ad una picturebox, poi disegna una superfice con quote casuali usando il methodo DRAWMESH; da menù la griglia è impostabile come solida o wireframed, e con precisione di interpolazione maggiore o minore.