Ruotare una sfera usando OpenGL: differenze tra le versioni
Vai alla navigazione
Vai alla ricerca
(Creata pagina con "Mostreremo un possibile codice, usando OpenGL, con il quale verrà disegnata una sfera blu che ruota in 3D in senso antiorario. E' necessario attivare una ''GLArea'', un ''Ti...") |
Nessun oggetto della modifica |
||
| Riga 129: | Riga 129: | ||
<FONT Color=gray>' ''Riavvolge dopo un giro completo:''</font> | <FONT Color=gray>' ''Riavvolge dopo un giro completo:''</font> | ||
If angle >= 360 Then angle = 0 | If angle >= 360 Then angle = 0 | ||
<FONT Color=gray>' ''Richiede il ridisegno della scena | <FONT Color=gray>' ''Richiede il ridisegno della scena:''</font> | ||
GLArea1.Refresh() | GLArea1.Refresh() | ||
End | End | ||
Versione delle 09:39, 19 lug 2025
Mostreremo un possibile codice, usando OpenGL, con il quale verrà disegnata una sfera blu che ruota in 3D in senso antiorario.
E' necessario attivare una GLArea, un Timer, il Componente grafico per la compatibilità con OpenGL (ad esempio: gb.gui.qt.opengl), nonché i Componenti:
- gb.opengl
- gb.opengl.glu
' Variabile per tenere traccia dell'ngolo di rotazione per far ruotare la sfera
Private angle As Float
Public Sub Form_Open()
With Me
.Title = "Sfera che ruota in senso antiorario"
.Move(0, 0, Screen.AvailableWidth, Screen.AvailableHeight)
.Arrangement = Arrange.Fill
End With
Timer1.Delay = 16 ' ~60 FPS
Timer1.Start()
End
Public Sub GLArea1_Draw()
' Pulisce il buffer del colore e della profondità (Z-buffer):
GL.Clear(GL.COLOR_BUFFER_BIT Or GL.DEPTH_BUFFER_BIT)
' Abilita il test di profondità (necessario per disegnare correttamente gli oggetti 3D sovrapposti):
GL.Enable(GL.DEPTH_TEST)
' Abilita il sistema di illuminazione OpenGL:
GL.Enable(GL.LIGHTING)
' Abilita la luce numero 0:
GL.Enable(GL.LIGHT0)
' Imposta la luce come direzionale (ultimo valore = 0.0):
Dim lightPos As Float[] = [1.0, 1.0, 1.0, 0.0]
' Componenti della luce: ambientale, diffusa e speculare:
Dim ambient As Float[] = [0.2, 0.2, 0.2, 1.0] ' luce "globale"
Dim diffuse As Float[] = [0.8, 0.8, 0.8, 1.0] ' luce diretta
Dim specular As Float[] = [1.0, 1.0, 1.0, 1.0] ' riflessi brillanti
' Applica luce:
GL.Lightfv(GL.LIGHT0, GL.POSITION, lightPos)
GL.Lightfv(GL.LIGHT0, GL.AMBIENT, ambient)
GL.Lightfv(GL.LIGHT0, GL.DIFFUSE, diffuse)
GL.Lightfv(GL.LIGHT0, GL.SPECULAR, specular)
' === Definizione materiale della sfera ===
' Colore e riflessi del materiale della sfera:
Dim matAmbient As Float[] = [0.1, 0.1, 0.3, 1.0] ' colore in ombra
Dim matDiffuse As Float[] = [0.2, 0.4, 1.0, 1.0] ' colore principale
Dim matSpecular As Float[] = [1.0, 1.0, 1.0, 1.0] ' riflesso tipo "metallo"
Dim shininess As Float = 64.0 ' intensità del riflesso
' Applica il materiale alla superficie FRONT (anteriore):
GL.Materialfv(GL.FRONT, GL.AMBIENT, matAmbient)
GL.Materialfv(GL.FRONT, GL.DIFFUSE, matDiffuse)
GL.Materialfv(GL.FRONT, GL.SPECULAR, matSpecular)
GL.Materialf(GL.FRONT, GL.SHININESS, shininess)
' === Imposta la proiezione (visione prospettica) ===
GL.MatrixMode(GL.PROJECTION)
GL.LoadIdentity()
' FOV = 45°, rapporto larghezza/altezza, clip vicino/lontano:
Glu.Perspective(45.0, GLArea1.Width / GLArea1.Height, 0.1, 100.0)
' === Trasformazioni vista ===
GL.MatrixMode(GL.MODELVIEW)
GL.LoadIdentity()
GL.Translatef(0.0, 0.0, -4.0) ' Sposta la scena indietro (zoom out)
GL.Rotatef(angle, 0.0, 1.0, 0.0) ' Ruota attorno all'asse Y (in senso antiorario)
' === Disegna la sfera ===
' raggio = 1.0, 30 suddivisioni in altezza e larghezza:
DrawSphere(1.0, 30, 30)
' Forza l'esecuzione immediata dei comandi:
GL.Flush()
End
Private Procedure DrawSphere(radius As Float, slices As Integer, stacks As Integer)
' Disegna manualmente una sfera usando coordinate sferiche
' slices = numero di "colonne" (longitudine), stacks = "righe" (latitudine)
Dim i, j As Integer
Dim theta1, theta2, phi As Float
Dim x, y, z As Float
For i = 0 To stacks - 1
theta1 = Pi * i / stacks ' latitudine corrente
theta2 = Pi * (i + 1) / stacks ' latitudine successiva
GL.Begin(GL.QUAD_STRIP) ' Usa strisce di quadrilateri
For j = 0 To slices
phi = 2 * Pi * j / slices ' longitudine corrente
' Primo punto sul "parallelo" corrente:
x = Cos(phi) * Sin(theta1)
y = Cos(theta1)
z = Sin(phi) * Sin(theta1)
GL.Normal3f(x, y, z) ' Normale per illuminazione
GL.Vertex3f(radius * x, radius * y, radius * z)
' Secondo punto sul "parallelo" successivo:
x = Cos(phi) * Sin(theta2)
y = Cos(theta2)
z = Sin(phi) * Sin(theta2)
GL.Normal3f(x, y, z)
GL.Vertex3f(radius * x, radius * y, radius * z)
Next
GL.End()
Next
End
Public Sub Timer1_Timer()
' Ruota di 1 grado a ogni fotogramma (~60 FPS):
angle += 1.0
' Riavvolge dopo un giro completo:
If angle >= 360 Then angle = 0
' Richiede il ridisegno della scena:
GLArea1.Refresh()
End