Vous devez posséder les includes comme dans le tutorial précédent.
(Dispo en fin de post)
Je ne reviendrais pas sur le positionnement des vertex ainsi que la création de contexte et autres joyeuseté d’openGL

La particularité D’opengl & les textures :
OpenGl gère les textures un peu bizarrement, en fait, lorsque l’on charge une texture, elle est automatiquement inverser sur l’axe des y, ce qui nous donne :

Pour cela il va nous falloir créer une fonction toute simple pour faire une symétrie.
Avant d’aller plus loin je vous propose une petite explication sur les coordonnées des textures
Elles sont généralement nommées par deux axes : UV un peu comme XY, mais pour les textures, c’est UV.
Je vais aller directement au fait, prenez une face quelconque, lorsque que l’on applique une texture , on « accroche » les extrémités de la texture aux vertex de cette face (#Quads)
Si on veut accrocher le bord haut gauche, alors l’UV haut gauche de la texture sera de 0,0
Regardez le schéma :

Bien sur, on est pas obliger de mettre soit 0 ou 1, mais , si on met 2 à la place de 1 , qu’est ce qu’il se passe ?

Il se passe que la texture est répétée 2 fois ! Si on met 10 alors 10 fois etc.…, on peut mettre des nombres flottants, comme 0.5 qui aura comme effets de mettre le quart de la texture sur la face. Je vous rappelle quand même que dans ce tutorial nous allons modéliser un simple cube,
On ne vas pas texturé un modèle, d’ailleurs les modèles on des UV pré enregistrer dans un fichier.
Voilà pour la partie des UV, si vous avez compris cela , c’est tout bon !
On va maintenant attaquer le chargement en mémoire d’une texture. On va créer une fonction de toute pièces, on pourra charger les formats supportés par purebasic, on pourra gérer une couleur transparente.
Passons au codage

nous allons revoir une partie de l’initialisation d’opengl (Référez vous au premier tutos)
Il va nous falloir appeler glEnable_() avec la constante #GL_TEXTURE_2D en paramètre, cela va nous permettre par la suite d’utiliser les textures.
Puis la rappeler encore une fois avec la constante #GL_BLEND qui elle va nous permettre de jouer avec la transparence.
glEnable_(#GL_TEXTURE_2D)
glEnable_(#GL_BLEND)
ensuite il faut déclarer a opengl comment faire le blending , un peu comme les sprite3D sous pure ( Sprite3DBlendingMode() )
Voici la fonction et les constantes :
glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA)
Voici aussi le tableau des possibilité de cette fonction :
Ref :http://helios.univ-reims.fr/Labos/LERI/ ... /td07.html
GL_ZERO
GL_ONE
GL_DST_COLOR
GL_SRC_COLOR
GL_ONE_MINUS_DST_COLOR
GL_ONE_MINUS_SRC_COLOR
GL_SRC_ALPHA
GL_ONE_MINUS_SRC_ALPHA
GL_DST_ALPHA
GL_ONE_MINUS_DST_ALPHA
GL_SRC_ALPHA_SATURATE
Voilà pour l’initialisation.
Maintenant je vous file la fonction Brute : il n’est pas nécessaire de comprendre la fonction dans les détails :
Code : Tout sélectionner
Procedure LoadAlphaTexture(id, Filename.s, TransparentColor.l)
img.l = LoadImage(#PB_Any, Filename.s)
Width.l=ImageWidth(img)
Height.l=ImageHeight(img)
Size.l=Width * Height
Dim ImageData.b(Size*4)
StartDrawing(ImageOutput(img))
i = 0
For y = Height-1 To 0 Step -1 ; A l’envers , pour pallier l’effet mirroir
For x = 0 To Width-1
Color = Point(x,y)
ImageData(i)=Red(Color)
i+1
ImageData(i)=Green(Color)
i+1
ImageData(i)=Blue(Color)
i+1
If Color = TransparentColor
ImageData(i)=0
Else
ImageData(i)=$FF
EndIf
i+1
Next
Next
StopDrawing()
glGenTextures_(1, @Tex)
glBindTexture_(#GL_TEXTURE_2D, Tex)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGBA, Width, Height, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, @ImageData())
ProcedureReturn Tex
EndProcedure
Son utilisation est simple : LoadAlphaTexture(1,"Texture.tga",RGB(255,0,255))
Bien sur, vous chargez la texture en même temps que vous initialisez opengl
Vous devrez utilisé les commandes comme UsePNGImageDecoder() et autres….
On va pouvoir passez au chose sérieuse

Reprenez le code du cube dans le précédent tutorial et allez dans la fonction dessiner() :
Logiquement cela commence comme cela pour les faces :
Code : Tout sélectionner
glBegin_(#GL_QUADS)
glColor3ub_(255,0,0)
glVertex3d_(1,1,1)
glVertex3d_(1,1,-1)
glVertex3d_(-1,1,-1)
glVertex3d_(-1,1,1)
…
…
Comme ceci :
Code : Tout sélectionner
glBegin_(#GL_QUADS)
glColor3ub_(255,0,0)
glVertex3d_(1,1,1)
glVertex3d_(1,1,-1)
glVertex3d_(-1,1,-1)
glVertex3d_(-1,1,1)
glEnd_()
Au dessus de chaque glBegin_() il va falloir dire à opengl qu’il utilise tel ou tel texture
Exemple :
Code : Tout sélectionner
glBindTexture_(#GL_TEXTURE_2D, 1)
glBegin_(#GL_QUADS)
glColor3ub_(255,0,0)
glVertex3d_(1,1,1)
glVertex3d_(1,1,-1)
glVertex3d_(-1,1,-1)
glVertex3d_(-1,1,1)
glEnd_()
glBindTexture_(#GL_TEXTURE_2D, 1)
Le 1 Correspond à l’ID de la texture préalablement chargé
Cette commande permet de dire à OpenGL que les 4 prochains Vertex (#GL_QUADS) auront une textures.
Ensuite il nous reste plus qu’a définir les UV , cela s’effectue lorsque que l’on déclare la position des vertex :
Code : Tout sélectionner
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);
Voici le code complet :
Code : Tout sélectionner
IncludeFile "OpenGl.Pb"
IncludeFile "Windows.pb"
Declare Dessiner()
Declare LoadAlphaTexture(id, Filename.s, TransparentColor.l)
CreateScreen("OpenGL",800,600,32,#False)
glMatrixMode_( #GL_PROJECTION )
glLoadIdentity_()
gluPerspective_(70,1.33,1,500)
glEnable_(#GL_DEPTH_TEST)
glEnable_(#GL_TEXTURE_2D)
glEnable_(#GL_BLEND)
glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA);
UsePNGImageDecoder()
For i = 1 To 6
LoadAlphaTexture(i,"Texture"+Str(i)+".png",RGB(255,0,255))
Next
Repeat
Event.l = ScreenEvent()
Dessiner()
FlipAndClear()
Until Keys(#VK_ESCAPE)
DestroyScreen()
End
Procedure Dessiner()
Static angle.f
angle + 0.8
glClear_( #GL_COLOR_BUFFER_BIT )
glMatrixMode_( #GL_MODELVIEW )
glLoadIdentity_( )
gluLookAt_(5,0,0,0,0,0,0,0,1)
glRotated_(angle,0.5,0.1,1)
glBindTexture_(#GL_TEXTURE_2D,1)
glBegin_(#GL_QUADS)
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_()
glBindTexture_(#GL_TEXTURE_2D,2)
glBegin_(#GL_QUADS)
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_()
glBindTexture_(#GL_TEXTURE_2D,3)
glBegin_(#GL_QUADS)
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_()
glBindTexture_(#GL_TEXTURE_2D,4)
glBegin_(#GL_QUADS)
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_()
glBindTexture_(#GL_TEXTURE_2D,3)
glBegin_(#GL_QUADS)
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_()
glBindTexture_(#GL_TEXTURE_2D,1)
glBegin_(#GL_QUADS)
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_()
glFlush_()
EndProcedure
Procedure LoadAlphaTexture(id, Filename.s, TransparentColor.l)
img.l = LoadImage(#PB_Any, Filename.s)
Width.l=ImageWidth(img)
Height.l=ImageHeight(img)
Size.l=Width * Height
Dim ImageData.b(Size*4)
StartDrawing(ImageOutput(img))
i = 0
For y = Height-1 To 0 Step -1
For x = 0 To Width-1
Color = Point(x,y)
ImageData(i)=Red(Color)
i+1
ImageData(i)=Green(Color)
i+1
ImageData(i)=Blue(Color)
i+1
If Color = TransparentColor
ImageData(i)=0
Else
ImageData(i)=$FF
EndIf
i+1
Next
Next
StopDrawing()
glGenTextures_(1, @Tex)
glBindTexture_(#GL_TEXTURE_2D, Tex)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGBA, Width, Height, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, @ImageData())
ProcedureReturn Tex
EndProcedure
Je rappelle qu’il s’agit d’une approche simple de l’opengl sous purebasic, si vous désirez allez plus loin dans la 3D je vous conseille de vous documenter sur le net, et n’oublié pas : un programmeur n’a pas peur des math

Comme vous pourrez le constater, il y a des défauts de transparence, on ne voit pas toujours les faces qui se cachent derrière une face avec une partie transparente. Je viens de découvrir qu’il faut les afficher en derniers pour limité les défauts d’affichage. Je me pencherais sur la question. En attendant j’espère que ce tutorial vous à aider

File:1->Tut-OpenGL2.rar
