Page 1 sur 1

probleme de texture

Publié : dim. 20/oct./2024 19:40
par manababel
bonjour
Je fais un peu de 3d à 'l’ancienne (cpu) mixée a opengl.
J’essaie de faire une rotation 3d de type carte 2d ( style jeu de carte ).
Niveau rotation , pas de problème , mais niveau texture , celle-ci se déforme.
Connaissez vous ce type de problème et comment le résoudre?
Merci.

Code : Tout sélectionner

UseJPEGImageDecoder() 
UseJPEG2000ImageDecoder() 
UsePNGImageDecoder() 
UseTIFFImageDecoder() 
UseTGAImageDecoder() 
UseGIFImageDecoder() 

buffertotal = 4
Global Dim ig.l(0)
Global gl2d_TextureHandle
Structure gl2d_coordonnees
  x.f
  y.f
EndStructure	
Structure gl2d_coordonnees_tex
  tx.f
  ty.f
EndStructure	
Structure gl2d_coordonnees_color
  rgba.l
EndStructure
Global Dim gl2d_Vertex.gl2d_coordonnees(buffertotal)
Global Dim gl2d_Vertextex.gl2d_coordonnees_tex(buffertotal)
Global Dim gl2d_Vertexcolor.gl2d_coordonnees_color(buffertotal)

Procedure load_image(t$)
  img = LoadImage(0,t$)
  If img = 0 : Debug " image non trouveé" : EndIf 
  ResizeImage(0,64,64)
  StartDrawing(ImageOutput(0))
  pos = DrawingBuffer()
  lg = ImageWidth(0)
  ht = ImageHeight(0)
  ReDim ig(lg * ht)
  For y = 0 To ht - 1 : For x = 0 To lg - 1 : ig((x + y * lg)) = Point(x,y) | $ff000000 : Next : Next
  StopDrawing()
  glGenTextures_(1, @gl2d_TextureHandle)
  glBindTexture_(#GL_TEXTURE_2D, gl2d_TextureHandle);
  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, ImageWidth(0), ImageHeight(0), 0,#GL_RGBA, #GL_UNSIGNED_BYTE, @ig())
  If img <> 0 :FreeImage(0):EndIf
  ProcedureReturn gl2d_TextureHandle
EndProcedure

Procedure OpenWindow2d(px , py , lg , ht , t$ , opt = 0)
	ResizeWindow(0, 0, 0, lg, ht)
	OpenGLGadget(0,0,0,lg,ht,#PB_OpenGL_Keyboard | #PB_OpenGL_FlipSynchronization )
	SetGadgetAttribute(0, #PB_OpenGL_SetContext, #True)
	
	glMatrixMode_(#GL_PROJECTION)
	glLoadIdentity_()
	glOrtho_(0, lg, 0 , ht, -100, 100)
	glMatrixMode_(#GL_MODELVIEW)
	glLoadIdentity_()
	  ;glViewport_(0, 0, lg, ht);
    ;glMatrixMode_(#GL_PROJECTION);
    ;glLoadIdentity_();
    ;gluPerspective_(45.0, l/h, 1.0, 3000.0);
    ;glMatrixMode_(#GL_MODELVIEW);
    ;glLoadIdentity_();
    ;glTranslatef_(0.0, 0.0, -1000);
	glTexCoordPointer_(2, #GL_FLOAT, SizeOf(gl2d_coordonnees_tex), @gl2d_Vertextex(0) )
	glVertexPointer_(2, #GL_FLOAT, SizeOf(gl2d_coordonnees), @gl2d_vertex(0))
	glColorPointer_(4, #GL_UNSIGNED_BYTE, SizeOf(gl2d_coordonnees_color), @gl2d_Vertexcolor())
EndProcedure

Procedure update(a1.f,a2.f,a3.f,px,py)	
  glEnable_(#GL_TEXTURE_2D)
  glBindTexture_(#GL_TEXTURE_2D, gl2d_TextureHandle)
	glEnableClientState_(#GL_VERTEX_ARRAY)
	glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
	glEnableClientState_(#GL_COLOR_ARRAY)		 
	glClear_(#GL_COLOR_BUFFER_BIT)
	
	For i = 0 To 3 :	gl2d_Vertexcolor(i)\rgba = $ffffffff : Next
	Restore Donnees
	For i = 0 To 3
	  Read a.q : Read b.q : Read c.q : Read d.q
	  gl2d_Vertextex(i)\tx = a
	  gl2d_Vertextex(i)\ty = b
	  gl2d_vertex(i)\x = c
	  gl2d_vertex(i)\y = d
	Next
	
	cx.f = Cos(Radian(a1))
	sx.f = Sin(Radian(a1))
	cy.f = Cos(Radian(a2))
	sy.f = Sin(Radian(a2))
	cz.f = Cos(Radian(a3))
	sz.f = Sin(Radian(a3))
	x1.f = cz * cy 
	y1.f = sz * cy
	z1.f = - sy
	x2.f = cz * sy * sx - sz * cx
	y2.f = sz * sy * sx + cx * cz
	z2.f= sx * cy
	x3.f = cz * sy * cx + sz * sx
	y3.f = sz * sy * cx - cz * sx
	z3.f = cx * cy
	
	t0.f = 5
	t1.f = 0
 	For i = 0 To 3
 		a1 = x1 * gl2d_Vertex(i)\x  + y1 * gl2d_Vertex(i)\y
 		a2 = x2 * gl2d_Vertex(i)\x  + y2 * gl2d_Vertex(i)\y
 		a3 = x3 * gl2d_Vertex(i)\x  + y3 * gl2d_Vertex(i)\y
 		t1 = t0 / ( a3 + t0 ) 
    ;t1 = 1
  	gl2d_Vertex(i)\x = (a1 * t1) * 200 + px
  	gl2d_Vertex(i)\y = (a2 * t1) * 200 + py		
  Next

  glDrawArrays_(#GL_QUADS, 0, 4)
  glDisableClientState_(#GL_COLOR_ARRAY) 
  glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY)
  glDisable_(#GL_TEXTURE_2D)
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  Delay(1)
 EndProcedure

lg = 800
ht = 600
OpenWindow(0,0,0,0,0,"")
OpenWindow2d(0,0,lg,ht,"test")
img1 = Load_Image(#PB_Compiler_Home+"examples/3D/Data/Textures/caisse.png")
a1.f = 0
Repeat 
	Repeat 
		Event = WindowEvent() 
		Select Event      
			Case #PB_Event_CloseWindow 
				CloseWindow(0) 
				End   
			Case #PB_Event_Gadget
				Select EventType()
					Case #PB_EventType_LeftClick   
					Case #PB_EventType_RightClick   
				EndSelect
		EndSelect 
	Until Event = 0
	a1 + 1
	If a1 > 360 : a1 = 0 : EndIf
	update(0,a1,0,lg * 0.5 , ht * 0.5)
ForEver
End

DataSection
  Donnees:    
  Data.q 0 , 1 , -1 , -1 , 0 , 0 , 1 , -1 , 1 , 0 , 1 , 1 , 1 , 1 , -1 , 1
EndDataSection

Re: probleme de texture

Publié : mer. 23/oct./2024 11:12
par Guillot
chez moi, y'a rien qui s'affiche (j'ai pas creusé plus)
mais je pense savoir de quoi tu parle par "déformation"
si le calcul des coordonnées gere la projection sur l'ecran en prenant en compte la profondeur, le texturage ne le fais pas
tu dois envoyer également les z

Re: probleme de texture

Publié : mer. 23/oct./2024 12:13
par SPH
De coté, la caisse est 'tordue'.

Capture :
https://zupimages.net/viewer.php?id=24/43/23wm.bmp

Re: probleme de texture

Publié : mer. 23/oct./2024 19:39
par manababel
pour etre plus claire , voici ce que veut faire , j'utilise la meme methode.(rotation et projection)

code :

Code : Tout sélectionner

Procedure HyperTransformSprite(Sprite.i, Width.f, Height.f, Depth.f, Roll.f, Yaw.f, Pitch.f, AlignX.f=0.5, AlignY.f=0.5)
   Protected CosZ.f = Cos(Radian(Roll)), CosY.f = Cos(Radian(Yaw)), CosX.f = Cos(Radian(Pitch))
   Protected SinZ.f = Sin(Radian(Roll)), SinY.f = Sin(Radian(Yaw)), SinX.f = Sin(Radian(Pitch))  
   Protected A11.f =  CosY*CosZ,                A12.f = -CosY*SinZ,                A13.f =  SinY
   Protected A21.f =  SinX*SinY*CosZ+CosX*SinZ, A22.f = -SinX*SinY*SinZ+CosX*CosZ, A23.f = -SinX*CosY
   Protected A31.f = -CosX*SinY*CosZ+SinX*SinZ, A32.f =  CosX*SinY*SinZ+SinX*CosZ, A33.f =  CosX*CosY  
   Protected U0.f = -AlignX*Width,  U1.f = (1-AlignX)*Width
   Protected V0.f = -AlignY*Height, V1.f = (1-AlignY)*Height
   Protected Z1.f = U0*A31 + V0*A32 + Depth
   Protected Y1.f = ( U0*A21 + V0*A22 ) * Depth / Z1
   Protected X1.f = ( U0*A11 + V0*A12 ) * Depth / Z1
   Protected Z2.f = U1*A31 + V0*A32 + Depth
   Protected Y2.f = ( U1*A21 + V0*A22 ) * Depth / Z2
   Protected X2.f = ( U1*A11 + V0*A12 ) * Depth / Z2
   Protected Z3.f = U1*A31 + V1*A32 + Depth
   Protected Y3.f = ( U1*A21 + V1*A22 ) * Depth / Z3
   Protected X3.f = ( U1*A11 + V1*A12 ) * Depth / Z3
   Protected Z4.f = U0*A31 + V1*A32 + Depth
   Protected Y4.f = ( U0*A21 + V1*A22 ) * Depth / Z4
   Protected X4.f = ( U0*A11 + V1*A12 ) * Depth / Z4
   TransformSprite(Sprite, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4)
   ;TransformSprite(Sprite, X1, Y1, X2, Y2, X3, Y3, X4, Y4)  
EndProcedure

InitSprite()
UsePNGImageDecoder()
Enumeration
   #Window
   #SpriteFront
   #SpriteBack
EndEnumeration
OpenWindow(#Window, 0, 0, 600, 400, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)
SpriteQuality(#PB_Sprite_BilinearFiltering)
CatchSprite(#SpriteFront, ReceiveHTTPMemory("http://data.unionbytes.de/10.png"), #PB_Sprite_AlphaBlending)
CatchSprite(#SpriteBack, ReceiveHTTPMemory("http://data.unionbytes.de/Deck.png"), #PB_Sprite_AlphaBlending)

Repeat
   Repeat
      Select WindowEvent()
         Case #PB_Event_CloseWindow
            End
         Case #Null
            Break
      EndSelect
   ForEver
   ClearScreen(0)
   HyperTransformSprite(#SpriteFront, 160, 220, 500, 0, Sin(ElapsedMilliseconds()/1000)*180+180, 0) ; this sprite is rotated 180° more
   HyperTransformSprite(#SpriteBack, 160, 220, 500, 0, Sin(ElapsedMilliseconds()/1000)*180, 0)
   DisplayTransparentSprite(#SpriteFront, 200, 150) ; display both sprites
   DisplayTransparentSprite(#SpriteBack, 200, 150) 
   FlipBuffers()
ForEver
source : https://www.purebasic.fr/english/viewto ... te#p572384

remplacez le ligne 21 par la 22 , c'est ce que fait mon programme.
( "TransformSprite(Sprite, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4)" par "TransformSprite(Sprite, X1, Y1, X2, Y2, X3, Y3, X4, Y4)" )

je ne vois pas comment utiliser z pour le texturage , à la base je laisse gerer ca à opengl.

Re: probleme de texture

Publié : mer. 23/oct./2024 22:05
par Guillot
ben ton tableau de vertex est en 2D
glVertexPointer_(2, #GL_FLOAT, SizeOf(gl2d_coordonnees), @gl2d_vertex(0))
tu dois avoir l'équivalent en 3d

Re: probleme de texture

Publié : jeu. 24/oct./2024 13:26
par manababel
j'utile par defaut le mode de projection orthogonale , car à la base c'est pour un rendu 2d
je veux aussi connaitre toutes les coordonnes de mes polygones , donc j'utilise ma propre matrice de rotation pour cela.
de ce fait , que j'utile le mode de projection orthogonale (2d) ou le mode de Projection en perspective (3d), j'obiens le meme rendu ( donc "z" ne me sert pas )
que ce soit en orthogonale or perspective , avec le programme suivant , le resultat est identique ( pas d'effet de profondeur )
z = 0
a1 = x1 * gl2d_Vertex(i)\x + y1 * gl2d_Vertex(i)\y
a2 = x2 * gl2d_Vertex(i)\x + y2 * gl2d_Vertex(i)\y
gl2d_Vertex(i)\x = a1
gl2d_Vertex(i)\y = a2

pour avoir un effet "3d"
t =
z = 0
a1 = x1 * gl2d_Vertex(i)\x + y1 * gl2d_Vertex(i)\y + z1 * gl2d_Vertexz(i)\z
a2 = x2 * gl2d_Vertex(i)\x + y2 * gl2d_Vertex(i)\y + z2 * gl2d_Vertexz(i)\z
a3 = x3 * gl2d_Vertex(i)\x + y3 * gl2d_Vertex(i)\y + z3 * gl2d_Vertexz(i)\z
gl2d_Vertex(i)\x = * t / (a3 + t)
gl2d_Vertex(i)\y = * t / (a3 + t)
gl2d_Vertex(i)\z = a3

par defaut les coordonnees de la texture est appliquée de la facon suivante : 0,0 , 0,1 , 1,1 , 1,0 , je ne comprends pas integrer z ?

je ne sais pas comment s'appelle ce probleme et ne trouve pas de documentation dessus

par rapport au programme cité plus haut trouvé dans le forum de purebasic
comment passer de ca :
TransformSprite(Sprite, X1, Y1, X2, Y2, X3, Y3, X4, Y4)
à ca :
TransformSprite(Sprite, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4)