Page 1 sur 3

OpenGLGadget() Charger BMP ou PNG mode Dessin, Zoom, Rot

Publié : sam. 16/août/2014 9:56
par kernadec
bonjour à tous

Charger une image BMP dans un OpenGLGadget() n'est pas si facile que ça!
Alors Voilà un essai dont le début qui est inspiré d'un code d' applePi que je remercie passage
pour sa contribution aux utilisateurs de Purebasic

[réédit} Ajout de utilisation des parametres Zoom Wheel et Rotation Key OpenGL :D
Ajout de la commande glScalef() plus propre :D mais donne le même résultat que la multi. avec z sur les glVertex3f()
Cordialement

Code : Tout sélectionner

; ------ exemple de chargement d'image Applepi forum englais
; Ajout affichage d' une image2D avec zoom wheel et rotation key avec dessin sur image  kernadec

#ImagePath = #PB_Compiler_Home + "examples/sources/Data/"

Define *BMPHeader
Define *BMPImage
Define ImageHeight.I
Define ImageSize.I
Define ImageWidth.I
Define TextureID.I

If ReadFile(0, #ImagePath + "Geebee2.bmp") = 0
  MessageRequester("Error", "Loading of texture image failed!")
  End
EndIf

*BMPHeader = AllocateMemory(54)
ReadData(0, *BMPHeader, MemorySize(*BMPHeader))
ImageWidth = PeekL(*BMPHeader + 18)
ImageHeight = PeekL(*BMPHeader + 22)
ImageSize = PeekL(*BMPHeader + 34)
FreeMemory(*BMPHeader)

*BMPImage = AllocateMemory(ImageSize)
ReadData(0, *BMPImage, ImageSize)
CloseFile(0)
; --------

Procedure affiche(z.f,ang.d,TextureID)
  ; ----- suite  procedure affiche  kernadec
  
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT);
  glLoadIdentity_()                                    ;
  glPushMatrix_()  
  
  
  glEnable_(#GL_TEXTURE_2D);
  glBindTexture_(#GL_TEXTURE_2D, TextureID)
  glTranslatef_(GadgetWidth(0) / 2, GadgetWidth(0) / 2, 0.0)                      ; centre l'image
  glRotatef_(ang, 0.0, 0.0, 1.0)                                                  ; angle de l'image
  glNormal3f_( 0.0, 0.0, 1.0)                                        
  
  glScalef_(z, z, 1.0)                                                            ; zoom objets
  Xechelle.d = GadgetWidth(0) / 2
  Yechelle.d = GadgetWidth(0) / 2 
  
  glBegin_(#GL_QUADS)                                                             ; dessin et mise à l' échelle de la texture                                  
                                                                                  ; glColor3f_(0, 0.35, 0.5)                                       ; ajout de couleur 
  glTexCoord2f_(0.0, 0.0):  glVertex3f_(-Xechelle, -Yechelle,  1.0)               ; Bas  Gauche depuis le centre
  glTexCoord2f_(1.0, 0.0):  glVertex3f_( Xechelle, -Yechelle,  1.0)               ; Bas  Droit         "
  glTexCoord2f_(1.0, 1.0):  glVertex3f_( Xechelle,  Yechelle,  1.0)               ; Haut Droit         "
  glTexCoord2f_(0.0, 1.0):  glVertex3f_(-Xechelle,  Yechelle,  1.0)               ; haut Gauche        "
  glEnd_()                                                                        ;
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)                            ; affiche l'image
  
  
EndProcedure


If OpenWindow(0, 0, 0, 320, 320, "BMP to OpenGLGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenGLGadget(0, 10, 10, 300, 300, #PB_OpenGL_Keyboard)
  
  ; ----- Generate texture  exemple Appelpi suite
  glGenTextures_(1, @TextureID)
  glBindTexture_(#GL_TEXTURE_2D, TextureID)
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
  glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth, ImageHeight, 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *BMPImage)
  FreeMemory(*BMPImage)
  
  ;  ------ suite kernadec  affiche l'image dans l'OpenGLGadget() converti à partir d'un code C++
  ; 	
  glViewport_(0, 0, GadgetWidth(0), GadgetHeight(0));
  glMatrixMode_(#GL_PROJECTION)                     ;
  glLoadIdentity_()                                 ;
  glOrtho_(GadgetX(0)-10, GadgetWidth(0) ,GadgetHeight(0),GadgetY(0)-10 , GadgetWidth(0)/2,-GadgetHeight(0)/2)   ; Axe de l'OpenGLGadget()
                                                                                                                 ;
  glMatrixMode_(#GL_MODELVIEW)                                                                                   ;
  glClearColor_(1.0, 1.0, 1.0, 1.0)                                                                              ;
  
  glEnable_(#GL_DEPTH_TEST);
  glDepthMask_(#GL_TRUE)   ;
  
  
  z.f = 0.75
  ang.d = 45
  SetActiveGadget(0)
  
  ;glDrawBuffer_(#GL_FRONT_AND_BACK)                                     ; activer avec windows 8 pour éviter le scintillement
  
  
  affiche(z,ang,TextureID)                                              
  
  
  Repeat 
    
    event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget And EventGadget() = 0 
      If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
        
        
        x = GetGadgetAttribute(0, #PB_OpenGL_MouseX)                     ; coordonnées souris
        y = GetGadgetAttribute(0, #PB_OpenGL_MouseY)
        
        
        glDisable_(#GL_TEXTURE_2D)                                       ;
        glPopMatrix_()                                                   ; la matrice revient  a l'état du dernier glPushMatrix()  
        
        glEnable_(#GL_POINT_SMOOTH)                                      ; mode point arrondi
        glDepthMask_(#GL_FALSE)                                          ; premier plan
        
        glPointSize_(20 * z)                                             ; entrer la taille avant mode dessin 
        glBegin_(#GL_POINTS)                                             ; mode dessin points
        
        glColor3ub_(Random(255),Random(255),Random(255))                 ; couleur
        
        glVertex3f_(x,y,0)                                               ; dessine le points
        glEnd_()
        glDepthMask_(#GL_TRUE)                                           ; arrière plan
        
        SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
        
      EndIf
    EndIf  
    
    
    
    If Event = #PB_Event_Gadget And EventGadget() = 0 
      If EventType() = #PB_EventType_MouseWheel
        glColor3ub_(255,255,255)                                          ; restore la couleur de base en mode zoom 
        Z + (GetGadgetAttribute(0, #PB_OpenGL_WheelDelta ) /10)           ; mode rotation molette souris
        affiche(z,ang,TextureID)                                          
      EndIf
      
      If EventType() = #PB_EventType_KeyDown
        glColor3ub_(255,255,255)                                         ; restore la couleur de base en mode zoom key
        key = GetGadgetAttribute(0,#PB_OpenGL_Key )
        
        If key = #PB_Shortcut_Right                                       ;  flàche droite clavier 
          ang=Mod(ang - 5,360)
          affiche(z,ang,TextureID)
          
        ElseIf key = #PB_Shortcut_Left                                   ;  flàche gauche clavier 
          ang=Mod(ang + 5,360)
          affiche(z,ang,TextureID)
          
        ElseIf key = #PB_Shortcut_Escape                                  ;  Esc = End
          CloseWindow(0)
          End
        EndIf  
      EndIf
    EndIf      
    
  Until  event = #PB_Event_CloseWindow
  
EndIf

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : dim. 17/août/2014 14:06
par kernadec
bonjour à tous
Fred a eu une très bonne idée de mettre a notre disposition OpenGLGadget(), c'est vraiment un truc de ouf :D

le code précèdent mis à jour,
ajout du mode dessin sur la texture sans l'appliquer définitivement à la texture pour le moment :wink:

Cordialement

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : dim. 17/août/2014 16:02
par Micoute
Tout à fait d'accord !

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : dim. 17/août/2014 18:48
par graph100
Merci pour ces exemples Kernadec ! continue comme ça :mrgreen:

Le mieux avec les fonctions de dessin OpenGl, c'est qu'elles sont gérées par la carte graphique !
Ce qui veux dire plus temps CPU pour autre chose :wink:

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : dim. 17/août/2014 22:27
par falsam
kernadec a écrit :Fred a eu une très bonne idée de mettre a notre disposition OpenGLGadget(), c'est vraiment un truc de ouf :D
J'ai fait quelques essais avec ce OpenGLGadget() et je trouve que c'est beaucoup de lignes de code pour afficher quelques chose de simple.

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : dim. 17/août/2014 23:15
par Fred
C'est fait surtout pour ceux qui sont deja à l'aise avec OpenGL

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : lun. 18/août/2014 0:01
par kernadec
@Falsam
Je pense que ça ne va pas être facile de l'éviter, car même si on lui trouve un remplaçant, il ne sera peut-être pas mieux!

Cordialement

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : lun. 18/août/2014 7:39
par Micoute
Fred a écrit :C'est fait surtout pour ceux qui sont deja à l'aise avec OpenGL
Bonjour Fred, ce n'est pas vraiment que je sois à l'aise avec OpenGL, mais il n'y a que ça qui fonctionne sur mon système, alors il vaut mieux s'adapter en attendant une compatibilité avec DirectX, mais je ne m'inquiète pas, car tout vient à point pour qui sait attendre !

En attendant, il y a les tutoriel NéHé qui sont un peu anciens, mais de très bonne qualité.

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : lun. 18/août/2014 11:04
par falsam
Fred a écrit :C'est fait surtout pour ceux qui sont deja à l'aise avec OpenGL
Et je confirme .... je ne suis pas à l'aise avec les fonctionnalités OpenGL.

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : lun. 18/août/2014 22:41
par graph100
Certes ! Mais quand je vois une rotation d'image effectuée simplement, et avec le processeur qui ne lève pas le sourcil, je suis content :mrgreen:

Sinon, je n'avais pas testé, mais ça scintille à mort chez moi ! (quand on dessine à la souris uniquement)

Il faut ajouter ça après avoir créer le gadget openGL

Code : Tout sélectionner

glDrawBuffer_(#GL_FRONT_AND_BACK)	
en même temps tu as mal gérer ton affaire (je viens de détailler le code) : tu flip le buffer plus d'une fois par boucle !! il faut modifier ça !

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : mar. 19/août/2014 8:51
par kernadec
bonjour graph100
en même temps tu as mal gérer ton affaire (je viens de détailler le code) : tu flip le buffer plus d'une fois par boucle !! il faut modifier ça !
Comme je l'ai dit dans mon précédent post avec OpenGL je débute :wink:
Alors pour les flip-buffers, j' en est un pour le dessin et l'autre pour les points, et ils ne sont pas activés en même temps il me semble,
mais si tu as une idée :mrgreen:

En ce moment je teste le dessin copié sur la Texture elle même copiée également,
Alors c'est pas gagné!!! car quand je dessine sur un niveau et qu' ensuite je change de niveau pour le dessin, je suis confronté au même soucis
de dégradation de l'image qu' on retrouve avec les zooms successifs sur une image sans reprendre la celle de base.

Pour l'instant je suis perplexe :? car quand on copie le dessin de la souris il subit encore plus de dégradations pixels dans le zoom que la texture 8O

Alors la solution serait de travailler sur une texture de base hors zoom dans un buffers qui recevrait le dessin de la souris avec son échelle,
enfin un truc comme ça.
j'ai regardé des codes pour cela mais beaucoup d' exemples avec buffers utilisent GLUT :(
Donc, si je rajoute truc à machin truc, on va vite se retrouvé avec un mode Python :?

Cordialement

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : mar. 19/août/2014 10:46
par poshu
Merci de défricher un peu le terrain pour nous.

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : mer. 20/août/2014 9:23
par graph100
kernadec a écrit :Alors pour les flip-buffers, j' en est un pour le dessin et l'autre pour les points, et ils ne sont pas activés en même temps il me semble,
mais si tu as une idée :mrgreen:
Il me semble que lorsqu'on dessine un point, les 2 flips sont activés.

Je ferais un seul flip à la fin du dessin, controlé par un flag.

Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : mer. 20/août/2014 9:28
par graph100

Code : Tout sélectionner

; ------ exemple de chargement d'image Applepi forum englais
; Ajout affichage d' une image2D avec zoom wheel et rotation key avec dessin sur image  kernadec

#ImagePath = #PB_Compiler_Home + "examples/sources/Data/"

Define *BMPHeader
Define *BMPImage
Define ImageHeight.I
Define ImageSize.I
Define ImageWidth.I
Define TextureID.I

If ReadFile(0, #ImagePath + "Geebee2.bmp") = 0
	MessageRequester("Error", "Loading of texture image failed!")
	End
EndIf

*BMPHeader = AllocateMemory(54)
ReadData(0, *BMPHeader, MemorySize(*BMPHeader))
ImageWidth = PeekL(*BMPHeader + 18)
ImageHeight = PeekL(*BMPHeader + 22)
ImageSize = PeekL(*BMPHeader + 34)
FreeMemory(*BMPHeader)

*BMPImage = AllocateMemory(ImageSize)
ReadData(0, *BMPImage, ImageSize)
CloseFile(0)
; --------

Procedure affiche(z.f,ang.d,TextureID)
	; ----- suite  procedure affiche  kernadec
	
	glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT);
	glLoadIdentity_()																		 ;
	glPushMatrix_()  
	
	
	glEnable_(#GL_TEXTURE_2D);
	glBindTexture_(#GL_TEXTURE_2D, TextureID)
	glTranslatef_(GadgetWidth(0) / 2, GadgetWidth(0) / 2, 0.0)                      ; centre l'image
	glRotatef_(ang, 0.0, 0.0, 1.0)																									; angle de l'image
	glNormal3f_( 0.0, 0.0, 1.0)                                        
	
	glScalef_(z, z, 1.0)                                                            ; zoom objets
	Xechelle.d = GadgetWidth(0) / 2
	Yechelle.d = GadgetWidth(0) / 2 
	
	glBegin_(#GL_QUADS)                                                             ; dessin et mise à l' échelle de la texture                                  
																																									; glColor3f_(0, 0.35, 0.5)                                       ; ajout de couleur 
	glTexCoord2f_(0.0, 0.0):  glVertex3f_(-Xechelle, -Yechelle,  1.0)								; Bas  Gauche depuis le centre
	glTexCoord2f_(1.0, 0.0):  glVertex3f_( Xechelle, -Yechelle,  1.0)								; Bas  Droit         "
	glTexCoord2f_(1.0, 1.0):  glVertex3f_( Xechelle,  Yechelle,  1.0)								; Haut Droit         "
	glTexCoord2f_(0.0, 1.0):  glVertex3f_(-Xechelle,  Yechelle,  1.0)								; haut Gauche        "
	glEnd_()																																				;
	
	;SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)                            ; affiche l'image
	
	
EndProcedure


If OpenWindow(0, 0, 0, 320, 320, "BMP to OpenGLGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0
	End
EndIf

OpenGLGadget(0, 10, 10, 300, 300, #PB_OpenGL_Keyboard)

glDrawBuffer_(#GL_FRONT_AND_BACK)                                     ; activer avec windows 8 pour éviter le scintillement

; ----- Generate texture  exemple Appelpi suite
glGenTextures_(1, @TextureID)
glBindTexture_(#GL_TEXTURE_2D, TextureID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth, ImageHeight, 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *BMPImage)
FreeMemory(*BMPImage)

;  ------ suite kernadec  affiche l'image dans l'OpenGLGadget() converti à partir d'un code C++
;    
glViewport_(0, 0, GadgetWidth(0), GadgetHeight(0));
glMatrixMode_(#GL_PROJECTION)											;
glLoadIdentity_()																	;
glOrtho_(GadgetX(0)-10, GadgetWidth(0) ,GadgetHeight(0),GadgetY(0)-10 , GadgetWidth(0)/2,-GadgetHeight(0)/2)   ; Axe de l'OpenGLGadget()
																																																							 ;
glMatrixMode_(#GL_MODELVIEW)																																									 ;
glClearColor_(1.0, 1.0, 1.0, 1.0)																																							 ;

glEnable_(#GL_DEPTH_TEST);
glDepthMask_(#GL_TRUE)	 ;


z.f = 0.75
ang.d = 45
SetActiveGadget(0)


affiche(z,ang,TextureID)                                              

FLAG_flip.b = #True

Repeat 
	
	event = WaitWindowEvent()
	
	If Event = #PB_Event_Gadget And EventGadget() = 0 
		If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
			
			
			x = GetGadgetAttribute(0, #PB_OpenGL_MouseX)                     ; coordonnées souris
			y = GetGadgetAttribute(0, #PB_OpenGL_MouseY)
			
			
			glDisable_(#GL_TEXTURE_2D)                                       ;
			glPopMatrix_()																									 ; la matrice revient  a l'état du dernier glPushMatrix()  
			
			glEnable_(#GL_POINT_SMOOTH)                                      ; mode point arrondi
			glDepthMask_(#GL_FALSE)																					 ; premier plan
			
			glPointSize_(20 * z)                                             ; entrer la taille avant mode dessin 
			glBegin_(#GL_POINTS)																						 ; mode dessin points
			
			glColor3ub_(Random(255),Random(255),Random(255))                 ; couleur
			
			glVertex3f_(x,y,0)                                               ; dessine le points
			glEnd_()
			glDepthMask_(#GL_TRUE)                                           ; arrière plan
			
			FLAG_flip = #True
			
		EndIf
	EndIf  
	
	
	
	If Event = #PB_Event_Gadget And EventGadget() = 0 
		If EventType() = #PB_EventType_MouseWheel
			glColor3ub_(255,255,255)                                          ; restore la couleur de base en mode zoom 
			Z + (GetGadgetAttribute(0, #PB_OpenGL_WheelDelta ) /10)						; mode rotation molette souris
			affiche(z,ang,TextureID)                                          
			FLAG_flip = #True
		EndIf
		
		If EventType() = #PB_EventType_KeyDown
			glColor3ub_(255,255,255)                                         ; restore la couleur de base en mode zoom key
			key = GetGadgetAttribute(0,#PB_OpenGL_Key )
			
			If key = #PB_Shortcut_Right                                       ;  flàche droite clavier 
				ang=Mod(ang - 5,360)
				affiche(z,ang,TextureID)
				FLAG_flip = #True
				
			ElseIf key = #PB_Shortcut_Left                                   ;  flàche gauche clavier 
				ang=Mod(ang + 5,360)
				affiche(z,ang,TextureID)
				FLAG_flip = #True
				
			ElseIf key = #PB_Shortcut_Escape                                  ;  Esc = End
				CloseWindow(0)
				End
			EndIf  
		EndIf
	EndIf
	
	If FLAG_flip
		SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
		FLAG_flip = #False
	EndIf
	
Until  event = #PB_Event_CloseWindow


Re: OpenGLGadget() Charger une Image.BMP mode Dessin, Zoom,

Publié : mer. 20/août/2014 18:29
par kernadec
Bonjour

Merci graph100 pour le Flag, car je n'y avait pas pensé :?

Cordialement