Tut [OpenGL 02] Les bases du texturing

Généralités sur la programmation 3D
Anonyme

Tut [OpenGL 02] Les bases du texturing

Message par Anonyme »

Comme promis, nous allons voir les bases du texturing sous OpenGL.
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 :D


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 :

Image

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 :

Image

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 ?

Image

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 :D

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 :D
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)

…
…
à la fin de la première série de vertex rajouté glend_()
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_()
Faites de même pour toutes les faces, et n’oubliez pas de remettre glBegin_() lorsque vous allez commencer à mettre une nouvelle série de vertex. ca va nous permettre de travailler sur chaque faces indépendament des autres.
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);
N’ayez pas peur, je vous ai mâcher le travail :
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 :D
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 :wink:


File:1->Tut-OpenGL2.rar
Image
Dernière modification par Anonyme le dim. 09/juil./2006 10:41, modifié 3 fois.
Avatar de l’utilisateur
SPH
Messages : 4944
Inscription : mer. 09/nov./2005 9:53

Message par SPH »

ERROR : ton rar ne contient pas les bonnes images listé dans ton code...

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Anonyme

Message par Anonyme »

Corrigé :wink:
ca n'empechait pas le rar et son code de fonctionner
Avatar de l’utilisateur
SPH
Messages : 4944
Inscription : mer. 09/nov./2005 9:53

Message par SPH »

Impressionnant. Tres bon debut. Finalement, je commence a accrocher a la 3D grace a ces tous premiers tutos !!

thxxxx

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Message par flaith »

tout pareil ! :)
Buckethead
Messages : 122
Inscription : jeu. 27/sept./2007 20:25

Message par Buckethead »

Petite precision sur la texture. En haut à droite c'est 0,1 ;)

Image
Anonyme

Message par Anonyme »

non, tout dépends comment tu créer tes façes, ici , c'est dans le sens des aiguilles d'une montre , donc le dessin est bon ainsi que le reste de mon post.

++
RV
Messages : 209
Inscription : sam. 18/nov./2006 15:16

Message par RV »

Donc en bas à gauche c'est UV 0,1! :wink:
Anonyme

Message par Anonyme »

oui effectivement , pas vu l'erreur :oops: m'en va me pendre :D
RV
Messages : 209
Inscription : sam. 18/nov./2006 15:16

Message par RV »

m'en va me pendre :D
T'es fou!
Primo, ça fait mal!
Deuxio, c'est à cause d'un copier/coller pas modifié!
Troisio, je crois que tu manquerais à beaucoup ici vu que tu es un 'caïd' du forum!

On peut s'arranger! :D
Tu modifies en speed ton image et on demande à Dobro de virer les derniers post et de banir à vie de ce forum Buchethead dit 'Le témoin'! 8)
Et voilà, l'affaire est classée! :D
Buckethead
Messages : 122
Inscription : jeu. 27/sept./2007 20:25

Message par Buckethead »

:lol:

Je m'en suis aperçu que dernièrement avec les cubes-lettres ci contre, en participant à un concours "xmas" sur le site anglophone "dbf", je vais bientôt finaliser ma demo.
Image
Anonyme

Message par Anonyme »

Cela à l'air super sympa ! j'éspère que tu as pensé au utilisateur du pinguoin :D
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

je commence a préparer le beton !! :lol: :lol:

j'attends que vous ayez tout bien rectifié, les erreurs, et je nettoierai ce tuto
des remarques, comme celle-ci par exemple, de façon a ne laisser que le Tuto .. :D
Répondre