Problème de loupe

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ollivier
Messages : 3751
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Problème de loupe

Message par Ollivier »

Voici un petit code avec une loupe un peu loupée. Au bout d'une heure à tâtonner, j'ai arrêtè. Pour éviter de jeter dans les limbes ce code foireux, je partage ! Le prog vous demande de sélectionner une image pour la passer "au crible", puis vous déplacer la loupe mal façonnée avec la souris.
Si ça ne donne rien, vous pouvez m'informer.

Code : Tout sélectionner

UseJPEGImageDecoder()
UsePNGImageDecoder()
imgIni = LoadImage(#PB_Any, OpenFileRequester("Image", "", "*.JPG", 0) )
InitSprite()
InitKeyboard()
InitMouse()
ExamineDesktops()
OpenScreen(DesktopWidth(0), DesktopHeight(0), 32, "", #PB_Screen_SmartSynchronization, DesktopFrequency(0) )
Global.I tileW = 48, tileH = 48
Global.I scrW = ScreenWidth(), scrH = ScreenHeight()
Global.I scrW2 = scrW / 2
Global.I scrH2 = scrH / 2
Global.I Xmax, Ymax
spChk = CreateSprite(#PB_Any, tileW, tileH)
If StartDrawing(SpriteOutput(spChk) )
  Box(0, 0, tileW, tileH, RGB(255, 255, 255) )
  Box(1, 1, tileW - 2, tileH - 2, RGB(0, 0, 0) )
  StopDrawing()
EndIf
Xmax = scrW / tileW
Ymax = scrH / tileH
Global Dim X(Xmax, Ymax)
Global Dim Y(Xmax, Ymax)
Global Dim Sp(Xmax, Ymax)
imgW = ImageWidth(imgIni) / Xmax
imgH = ImageHeight(imgIni) / Ymax
For yi = 0 To Ymax
  For xi = 0 To Xmax
    sp(xi, yi) = CreateSprite(#PB_Any, tileW, tileH)
imgTmp = GrabImage(imgIni, #PB_Any, xi * imgW, yi * imgH, imgW, imgH)
If StartDrawing(SpriteOutput(sp(xi, yi) ) )
  DrawImage(ImageID(imgTmp), 0, 0, tileW, tileH)
  StopDrawing()
EndIf
FreeImage(imgTmp)
Next
Next
Define R.D = 400
cx = scrW2
cy = scrH2
Repeat
    Delay(14)
  ExamineKeyboard()
  ExamineMouse()
  cx = MouseX()
  cy = MouseY()
  For Y = 0 To Ymax
    For  X = 0 To Xmax
      X(X, Y) = X * tileW
      Y(X, Y) = Y * tileH
      DX = X(X, Y) - cx
      DY = Y(X, Y) - cy
      D.D = Sqr(DX * DX + DY * DY)
      A.D = ATan2(DX, DY)
      If D < R
        If D
          D * (R / D)
        EndIf        
        Tx.D = Cos(A) * D
        Ty.D = Sin(A) * D
        X(X, Y) = cx + Tx
        Y(X, Y) = cy + Ty
      EndIf
    Next
  Next
  Y = 0
  Repeat
    X = 0
    Repeat
      X1 = X(X, Y)
      Y1 = Y(X, Y)
      X2 = X(X + 1, Y)
      Y2 = Y(X + 1, Y)
      X3 = X(X + 1, Y + 1)
      Y3 = Y(X + 1, Y + 1)
      X4 = X(X, Y + 1)
      Y4 = Y(X, Y + 1)
      TransformSprite(sp(X, Y), X1, Y1, X2, Y2, X3, Y3, X4, Y4)
      DisplaySprite(sp(X, Y), 0, 0)
      X + 1
    Until X >= Xmax
    Y + 1
  Until Y >= Ymax
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Avatar de l’utilisateur
Ar-S
Messages : 9155
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Problème de loupe

Message par Ar-S »

ça marche mais effectivement le rendu est vilain :).
Je ne sais pas si c'est ma souris ou ton delay mais ça lag quand je bouge la souris.
enfin, le rendu on dirait pas une loupe mais une sphere rempli de triangle qui essayent d'afficher les grab.
je vais pas plus loin, j'ai pas le temps de tester plus avant.
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.6x / 5.7x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Ollivier
Messages : 3751
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de loupe

Message par Ollivier »

Pour la souris, je ne sais pas : il n'y a que la souris qui manifeste quelque chose de visible à l'écran, donc le problème peut être plus général. Et Delay peut laisser libre une tâche externe (anti-virus, tâche réseau, etc...), et donc s'accaparer du temps cpu.

Pour les polygones, c'est plus pragmatique : je posterai un code bien plus court et simple pour te demander un screenshoot. C'est sûrement TransformSprite().
Ollivier
Messages : 3751
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de loupe

Message par Ollivier »

J'ai une petite idée de loupe originale : le but est de tester transformSprite() dont le fonctionnement varie selon les versions et la plate-forme, malgré les efforts de Fred... Le code arrive "incessamment sous peu" si j'ai l'énergie et le temps...
Avatar de l’utilisateur
Guillot
Messages : 383
Inscription : jeu. 25/juin/2015 16:18

Re: Problème de loupe

Message par Guillot »

tiens, voilà comment je m'y prendrai :
(enlever le debogueur)

Code : Tout sélectionner

UseJPEGImageDecoder()
UsePNGImageDecoder()
LoadImage(0, OpenFileRequester("Image", "", "*.JPG", 0) )

InitSprite()
InitKeyboard()
InitMouse()
ExamineDesktops()
OpenScreen(DesktopWidth(0), DesktopHeight(0), 32, "", #PB_Screen_SmartSynchronization, DesktopFrequency(0) )
Global sdx = ScreenWidth(), sdy = ScreenHeight()
Global ldx=sdx/4
Global Dim bmps.l(sdy-1,sdx-1)
Global Dim bmpl.l(ldx-1,ldx-1)
Global Dim lx(ldx-1,ldx-1)
Global Dim ly(ldx-1,ldx-1)
Define.f x,y,l,h
For j=0 To ldx-1
	For i=0 To ldx-1
		x=i/ldx*2-1
		y=j/ldx*2-1
		l=Sqr(x*x+y*y)
		If l<=1:h=Sqr(1-l)*4:Else:h=2:EndIf
		lx(j,i)=(x/h)*ldx
		ly(j,i)=(y/h)*ldx
	Next
Next

CreateSprite(0,sdx,sdx,#PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(0))
DrawImage(ImageID(0),0,0,sdx,sdy)
CopyMemory(DrawingBuffer(),@bmps(0,0),sdx*sdy*4)
StopDrawing()

CreateSprite(1,ldx,ldx,#PB_Sprite_AlphaBlending)
Repeat
	ExamineKeyboard()
	ExamineMouse()
	cx = MouseX()
	cy = MouseY()
	StartDrawing(SpriteOutput(1))
	For j=0 To ldx-1
		For i=0 To ldx-1
			ii=lx(j,i)+cx:If ii<0:ii=0:ElseIf ii>sdx-1:ii=sdx-1:EndIf
			jj=ly(j,i)+cy:If jj<0:jj=0:ElseIf jj>sdy-1:jj=sdy-1:EndIf
			bmpl(j,i)=bmps(jj,ii)
		Next
	Next
	CopyMemory(@bmpl(0,0),DrawingBuffer(),ldx*ldx*4)
	StopDrawing()
	DisplaySprite(0,0,0)
	DisplaySprite(1,cx-ldx/2,cy-ldx/2)
	FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Avatar de l’utilisateur
venom
Messages : 3026
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Problème de loupe

Message par venom »

8O Bravo Guillot,

Comme a ton habitude, toujours des codes époustouflants 8) Je pense que c’était l'effet rechercher par Ollivier :)






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Ollivier
Messages : 3751
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de loupe

Message par Ollivier »

Alors, pas exactement. Mais, de toute façon, si je précise, Guillot va réussir à faire le code ! Là, il utilise le sprite un peu comme un boulet : réécriture permanente du contenu.

Le résultat est évidemment bon ! Mais ça pompe en ressources. Il y a des méthodes pour ne pas réécrire le sprite, juste le transformer (par calcul des sommets).

Par sûr que Guillot ne réussisse pas à le pondre avant moi, surtout que je n'ai pas accès à un ordinateur...
Avatar de l’utilisateur
Guillot
Messages : 383
Inscription : jeu. 25/juin/2015 16:18

Re: Problème de loupe

Message par Guillot »

j'ai bien compris que tu voulais faire ça via "transformsprite"
mais pas sur que ce soit plus rapide si tu veux que les défauts ne soit pas perceptible (tu vas devoir faire des tuiles tres petites)
de plus ma routine peut etre bien ameliorée
- on pourrait se passer des clamp (If ii<0:ii=0:ElseIf ii>sdx-1:ii=sdx-1:EndIf) via une addition
- les tableaux 2d pourrait etre remplacer par des tableau 1D, voir des "poke" (mais comme ça, je trouve plus élégant)
et puis, avec la compilation c on pouvoir faire x2 au minimum pour ce genre de code

mais curieux de voir ton code corrigé
Ollivier
Messages : 3751
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de loupe

Message par Ollivier »

Salut Guillot,

on peut même le faire avec les SIMD. Mais le sprite a 2 avantages :
1) il fait tourner le GPU
2) il est moins gourmand en taille que l'inclusion OGRE qui, elle, fait la loupe "à l'aise" (il y a plusieurs méthodes et ça ne prend aucune ressource CPU).

On a quand même pas mal de pixels qui sont calculés par la carte graphique (texture). Allez, je vais me lancer, histoire de te faire rire un peu... (Après tout, les shadoks misent la réussite sur le nombre d'essais, du moins << plus y'a d'échecs, plus on se rapproche de la victoire ! >>)
Ollivier
Messages : 3751
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Problème de loupe

Message par Ollivier »

Je renonce ce soir, faute de temps. Il y a peu de chance que ça tourne sans pomper un minimum significatif de ressources CPU : il n'y a que le ClipSprite() pour régler les facteurs uv de texturing et le quadrilatère de "clipage" est seulement rectangle (x, y, w, h) et orthogonal (ne tourne pas) : ClipSprite() ne permet pas de dessiner un quadrilatère quelconque. Il faut donc faire un premier aperçu pour chaque polygône dans le buffer écran non visible et "graber" un sprite affichable, ceci pour chaque face affichée.

Je serai curieux de savoir si ta loupe est suffisamment optimisable en SIMD pour pomper moins de ressources que le fait de façonner les sprites un par un...
Répondre