Tut [OpenGL 03] Texture animée dans un cube
Publié : mar. 06/nov./2007 2:18
Salut 
Je débute l'OpenGL et j'ai vraiment apprécié les tutos de Cpl.Bator. Je compte faire beaucoup d'OpenGL cette année, peut être même toucher à Opengl 2.0 et + ;\ (il faut importer des instructions?)
J'espère qu'il y aura d'autre tutos !

Le fichier compilé + bonus : http://stanz05.free.fr/blobs.zip
Les includes: http://purebasic.myftp.org/?filename=fi ... OpenGL.rar
La source est très proche du "hello world" des premiers tutos. Pour mettre d'autre textures, il faudra faire comme dans le tuto précédant. Si c'est un problème, n'hésitez pas.
Pour l'effet "metaball" ou "blob", n'en tenez pas trop compte, autrement c'est juste une formule qui se dessine au point par point*, comme certains plasmas.
*idéal avec la routine LoadAlphaTexture
Il y a évidement d'autre méthodes, je sais que l'on peut copier une zone de l'écran. Perso je n'ai pas encore essayé, ca doit être très interressant pour faire des mirroirs ou l'effet "glow".
Pour l'instant je prèfère m'attaquer aux lumières ainsi qu'au "points" qui ont besoin d'OpenGL 2.0 si on veut leurs appliquer une texture. (éffet neige saybientonoyel)
merci Cpl.Bator.

Je débute l'OpenGL et j'ai vraiment apprécié les tutos de Cpl.Bator. Je compte faire beaucoup d'OpenGL cette année, peut être même toucher à Opengl 2.0 et + ;\ (il faut importer des instructions?)
J'espère qu'il y aura d'autre tutos !

Le fichier compilé + bonus : http://stanz05.free.fr/blobs.zip
Les includes: http://purebasic.myftp.org/?filename=fi ... OpenGL.rar
La source est très proche du "hello world" des premiers tutos. Pour mettre d'autre textures, il faudra faire comme dans le tuto précédant. Si c'est un problème, n'hésitez pas.
Pour l'effet "metaball" ou "blob", n'en tenez pas trop compte, autrement c'est juste une formule qui se dessine au point par point*, comme certains plasmas.
*idéal avec la routine LoadAlphaTexture
Il y a évidement d'autre méthodes, je sais que l'on peut copier une zone de l'écran. Perso je n'ai pas encore essayé, ca doit être très interressant pour faire des mirroirs ou l'effet "glow".
Pour l'instant je prèfère m'attaquer aux lumières ainsi qu'au "points" qui ont besoin d'OpenGL 2.0 si on veut leurs appliquer une texture. (éffet neige saybientonoyel)

merci Cpl.Bator.

Code : Tout sélectionner
; Tut [OpenGL 03] Texture animée dans un cube.
; ou "texture procédurale"
; Il y a plusieurs méthodes, étant moi même débutant, je prèfère pour le moment m'exercer sur des choses simple.
; - - - - -
; Les tutos OpenGL de Cpl.Bator:
; Tut [OPENGL 01] Cube3D : -----> http://www.purebasic.fr/french/viewtopic.php?t=5334
; Tut [OpenGL 02] Les bases du texturing -----> http://www.purebasic.fr/french/viewtopic.php?t=5339&highlight=tut+opengl
;- # INIT
;---------------------------------------------------------------------------------------------------------------------------------------------------
IncludeFile "OpenGl.Pb"
; On déclare les procédures en bas du code, tuto de Cpl.Bator ;)
Declare Dessiner()
Declare LoadAlphaTexture(id) ; id sert ici à incrémenter la variable pour la metaball. (la texture animée)
; Le buffer pour la texture "metaball"
; Initialement j'avais utilisé pleins d'instructions pour dessinner dans "l'image" dans la proc Loadalphatexture.
; c'était inutile mais curieusement si je retire createimage, la demo est beaucoup plus lente.
CreateImage(1,128,128)
;---------------------------------------------------------------------------------------------------------------------------------------------------
;- # GL FENETRE
;---------------------------------------------------------------------------------------------------------------------------------------------------
; Ouvre une window maximizée (plein écran mais pas un Fullscreen) en fonction de la résolution du bureau.
; Sans bordure ni titlebar, l'avantage c'est d'être (normallement) en resolution native sur les LCD's
; Par contre un petit dialog affichant les résolutions c'est mieux ;)
; Auld's "4kb framework" pb-conversion by benny!weltenkonstrukteur.de (Thx Benny)
ExamineDesktops()
Sx = DesktopWidth(0)
Sy = DesktopHeight(0)
pfd.PIXELFORMATDESCRIPTOR
pfd\cColorBits = 32
pfd\cDepthBits = 32
pfd\dwFlags = #PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER
hDC = GetDC_ ( CreateWindow_("edit", 0, #WS_POPUP | #WS_VISIBLE | #WS_MAXIMIZE, 0, 0 ,0 ,0, 0 ,0 ,0, 0 ) )
SetPixelFormat_ ( hDC, ChoosePixelFormat_( hDC, pfd), pfd )
wglMakeCurrent_ ( hDC, wglCreateContext_(hDC) )
ShowCursor_(#False);
;---------------------------------------------------------------------------------------------------------------------------------------------------
;- # GL INIT
;---------------------------------------------------------------------------------------------------------------------------------------------------
glMatrixMode_(#GL_PROJECTION)
; Important, Sx/Sy c'est le ratio pour le moniteur. Sur un 22" wide LCD et un 17" 4/3 RTC un cube n'est plus forcement carré en fonction du ratio.
; En 1600*1200, ratio = 1.66. 1.3 est plus courant.
; 500 c'est le clipping sur Z (au fond)
; On met 1 de preference pour le clipping devant. Notez que ce sont des chiffres positif.
; 52 le "field of view angle" ou FOV, tentez d'autre valeurs, plus c'est petit plus on tend vers une perspective orthogonale.
gluPerspective_(52,Sx/Sy,1,500)
glMatrixMode_(#GL_MODELVIEW)
glEnable_(#GL_TEXTURE_2D)
glHint_(#GL_PERSPECTIVE_CORRECTION_HINT,#GL_NICEST) ; Correction de perspective pour le mapping (Obligatoire avec les damiers, "checkerboard" ;p)
glEnable_(#GL_DEPTH_TEST) ;Z buffer, car il y a plusieurs cube (entre autre)
glEnable_(#GL_CULL_FACE) ; Back face culling, on aura jamais plus de 3 faces sur un cube à afficher grace à cette technique.
; Comme je ne maitrise pas les lumières, qui semblent devoir être "controllées" comme le objets, j'utilise le FOG
; qui est facile à implémenter.
; Le fog, R,G,B et Alpha. Puis l'intensité.
Dim fFogColor.f(4) : fFogColor(0) = 0.05: fFogColor(1) = 0.025 : fFogColor(2) = 0.035 : fFogColor(3) = 0.0
fFogDensity.f = 0.02
glEnable_ (#GL_FOG)
glFogi_ (#GL_FOG_MODE, #GL_EXP2)
glFogfv_ (#GL_FOG_COLOR, fFogColor());
glFogf_ (#GL_FOG_DENSITY, fFogDensity.f);
glHint_ (#GL_FOG_HINT, #GL_NICEST);
;---------------------------------------------------------------------------------------------------------------------------------------------------
;- # MAIN
;---------------------------------------------------------------------------------------------------------------------------------------------------
Repeat
angle+1
;Appel de la routine qui "charge" la texture. Elle ne lira rien sur le disque dur, vue que c'est une texture générée en temps réel.
LoadAlphaTexture(angle) ; texture metaball 2D, angle sert juste à incrémenter l'effet (variable à double emploi)
; On efface l'écran avec de la couleur.
; Notez que j'ai rencontré un problème avec les premier tutos et mes routines, il manquait #GL_COLOR_BUFFER_BIT.
glClearColor_(0.2 ,0.0 , 0.1 ,0)
glClear_(#GL_DEPTH_BUFFER_BIT | #GL_COLOR_BUFFER_BIT )
;- ## Caméra
glLoadIdentity_( )
gluLookAt_(45,0,0,0,0,0,0,0,1) ; position
glRotated_(360*Sin(angle/512),0.0,1.0,0.0) ; mal de mer
;glRotated_(360*Sin(angle/256),0.0,0.0,1.0) ; donnait l'illusion que les cubes tournent autour du plus gros.
;- ## Ceinture de petits cubes
glEnable_ (#GL_FOG)
For t = 0 To 24
glPushMatrix_() ; pose la matrice courante sur une pile.
; Pas la meilleur technique, mais ca permet quand même de faire tourner les cubes, au lieu de le faire via la caméra.
glTranslatef_(0,0,0)
glRotated_(angle,0.0,0.0,1.0)
glTranslatef_(26*Cos(t/4),26*Sin(t/4),0)
glRotated_(360/24*t,0.0,0.0,1.0) ; angle pour que les cubes se suivent
Dessiner() ; Dessine le cube
glPopMatrix_() ; récupère la matrice courante sur une pile. Ce qui revient à retrouver la matrice précedente pour la boucle.
Next
;-## Big Cube
glDisable_ (#GL_FOG) ; je trouve que ca ne va pas avec le cube du milieu.
glRotatef_(360*Abs(Sin(angle/200+t)),0.0,0.0,1.0)
glScalef_(10,10,10) ; Le cube est grossi
Dessiner()
; Vsync et sortie/gestion clavier
SwapBuffers_ ( hDC )
Until (GetAsyncKeyState_(#VK_ESCAPE))
End
;---------------------------------------------------------------------------------------------------------------------------------------------------
; Les procs
; Merci Cpl.Bator
; J'ai ajouté les normales, pour les lumières...
Procedure Dessiner()
glBegin_(#GL_QUADS)
;glNormal3d_(-1.0,0.0,0.0) ;face gauche
glTexCoord2d_(0,1) : glVertex3d_(-1,1,1)
glTexCoord2d_(0,0) : glVertex3d_(-1,1,-1)
glTexCoord2d_(1,0) : glVertex3d_(-1,-1,-1)
glTexCoord2d_(1,1) : glVertex3d_(-1,-1,1)
;glNormal3d_(0.0,1.0,0.0) ;face haut
glTexCoord2d_(0,1) : glVertex3d_(-1,1,1)
glTexCoord2d_(0,0) : glVertex3d_(1,1,1)
glTexCoord2d_(1,0) : glVertex3d_(1,1,-1)
glTexCoord2d_(1,1) : glVertex3d_(-1,1,-1)
;glNormal3d_(0.0,-1.0,0.0) ;face bas
glTexCoord2d_(0,1) : glVertex3d_(-1,-1,1)
glTexCoord2d_(0,0) : glVertex3d_(-1,-1,-1)
glTexCoord2d_(1,0) : glVertex3d_(1,-1,-1)
glTexCoord2d_(1,1) : glVertex3d_(1,-1,1)
;glNormal3d_(0.0,0.0,-1.0) ;face arriere
glTexCoord2d_(0,1) : glVertex3d_(1,1,-1)
glTexCoord2d_(0,0) : glVertex3d_(1,-1,-1)
glTexCoord2d_(1,0) : glVertex3d_(-1,-1,-1)
glTexCoord2d_(1,1) : glVertex3d_(-1,1,-1)
;glNormal3d_(1.0,0.0,0.0) ;face gauche
glTexCoord2d_(0,1) : glVertex3d_(1,1,1)
glTexCoord2d_(0,0) : glVertex3d_(1,-1,1)
glTexCoord2d_(1,0) : glVertex3d_(1,-1,-1)
glTexCoord2d_(1,1) : glVertex3d_(1,1,-1)
;glNormal3d_(0.0,0.0,1.0) ; Face avant
glTexCoord2d_(0,1) : glVertex3d_(-1,1,1)
glTexCoord2d_(0,0) : glVertex3d_(-1,-1,1)
glTexCoord2d_(1,0) : glVertex3d_(1,-1,1)
glTexCoord2d_(1,1) : glVertex3d_(1,1,1)
glEnd_()
EndProcedure
; La texture = 128*128, plus vraiment Alpha ;P
Procedure LoadAlphaTexture(id)
;img.l = 1
Width.l = 128
Height.l = 128
Size.l = Width * Height
Dim ImageData.b(Size*4)
For y = 0 To 127
n = 64*id ; pour la metaball
For x = 0 To 127
; Calcul metaball (3 dans c)
k.f = -8 * Sin(2*n/4192)
l.f = 8 * Cos(-2*n/8192)
m.f = 8 * Sin(4*n/4192)
c = (1000000/(Pow(-64+x+4*k,2)+Pow(-64+y+2*m,2)) + 1000000/(Pow(-64+x-4*k,2)+1*Pow(-64+y-8*l,2)) + 1000000/(Pow(-64+x-2*m,2)+Pow(-64+y-4*l,2))) / 16
If c > 255 : c = 255 : Else : c = c : EndIf
; --/fin metaball
ImageData(i)= c : i+1
ImageData(i)= c/10 : i+1
ImageData(i)= c/2 : i+2
Next
Next
; glGenTextures_(1, @Tex)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGBA, Width, Height, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, @ImageData())
ProcedureReturn Tex
EndProcedure