Dessiner sur un screen (avec tablette graphique)

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Dessiner sur un screen (avec tablette graphique)

Message par blendman »

salut

J'ai fait des tests pour dessiner sur un screen avec les sprites et finalement, ce n'est pas le screen qui bug avec la tablette graphique wacom mais les mousex() et mouseY() (initmouse()).
Donc, sans passer par mouseX() et MouseY(), on peut utiliser les screens et les sprites :D.

Bonne nouvelle :).

Par contre, j'ai quelques questions :
- comment faire dessiner un sprite sur un sprite de manière fluide, car sur mon test avec usebuffer(), ça rame énormément.
- Peut-on dessiner sur un sprite3D ? (je pense que non, mais bon), et sinon, peut-on dessiner avec un canal alpha sur 1 sprite (je crois que non, car seuls les sprites3D gèrent correctement l'alpha type png) et enregistrer le sprite avec ce canal alpha (et donc de la transparence).
- sur mon exemple, lorsque je sauvegarde mon image, ça ne marche pas, et je ne sais pas pourquoi, j'ai juste le fond noir.

Le code :

Code : Tout sélectionner

;{ init
ExamineDesktops()

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or InitSprite3D() = 0 Or UsePNGImageDecoder() =0 Or UsePNGImageEncoder()=0
  MessageRequester("Error", "Can't open the sprite system", 0)
  End
EndIf
;}

;{ declare
Declare CreateImageFromSprite(Image.l,Sprite.l)
;}

;{ variables
Global sprite_ok.b, playerX.w = -500, playerY.w = -500, usesprite.b
;}

;{ openwindow & create sprite
If OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "Dessiner sur un sprite", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_Maximize)
  
  ;{ menu
  If CreateMenu(0,WindowID(0))
    MenuTitle("mode")
    MenuItem(0,"Dessiner sur le sprite")
    MenuItem(1,"Utiliser Usebuffer()")
    MenuItem(2,"Dessiner sur le screen")    
  EndIf
  ;}
  
  ;{ screen & sprite
  If OpenWindowedScreen(WindowID(0), 150, 70, 800,600, 0, 0, 0)
    LoadSprite(0, "2.png",#PB_Sprite_AlphaBlending|#PB_Sprite_Texture)
    CreateSprite3D(0,0)
    Global centreX =SpriteWidth(0)/2
    Global centrey =SpriteHeight(0)/2
    CreateSprite(1,1024,1024,#PB_Sprite_AlphaBlending|#PB_Sprite_Texture)
    CreateSprite3D(1,1)    
  Else
    MessageRequester("Error", "Can't open windowed screen!", 0)
    End
  EndIf 
  ;}
  
EndIf
;}

;{ boucles
Repeat
  
  Repeat
    Event = WindowEvent()
    
    Select Event
        
      Case #WM_LBUTTONDOWN
        sprite_ok = 1
        
      Case #WM_LBUTTONUP
        sprite_ok = 0        
        GrabSprite(1,0,0,1000,1000,32)
        SaveSprite(1,"testsave.png",#PB_ImagePlugin_PNG)
        ;UseBuffer(#PB_Default)
        
      Case #WM_MOUSEMOVE
        If sprite_ok = 1
          playerX = WindowMouseX(0)-150 - centreX
          playerY = WindowMouseY(0)-70 - centreY
          If usesprite = 1
            UseBuffer(1)
            Start3D()
            DisplaySprite3D(0, playerX, playerY)
            Stop3D()          
          ElseIf usesprite = 0 ;<<<<<<<<<<<<<<<<<<<<-------------------- ici, ça bug            
            StartDrawing(SpriteOutput(1))
            ;DrawingMode(#PB_2DDrawing_Transparent)
            DisplaySprite(0,playerX, playerY)
            StopDrawing() 
          EndIf        
        EndIf  
                
      Case #PB_Event_CloseWindow
        Quit = 1
      Case #PB_Event_Menu     
        Select EventMenu()
          Case 0,1,2
            usesprite =  EventMenu()                     
        EndSelect        
    EndSelect
  Until Event = 0   
  ExamineKeyboard()  
  Start3D()
  DisplaySprite3D(0, playerX, playerY)
  Stop3D()          
  FlipBuffers() 
  
Until  Quit Or KeyboardPushed(#PB_Key_Escape)
;}

;{ procedures

Procedure CreateImageFromSprite(Image.l,Sprite.l)
  ;by octavius
  Protected hDC.l,Bmp.BITMAP,hBmp.l
  If IsSprite(Sprite)
    hDC=StartDrawing(SpriteOutput(Sprite))
    Bmp\bmWidth=SpriteWidth(Sprite)
    Bmp\bmHeight=SpriteHeight(Sprite)
    Bmp\bmPlanes=1
    Bmp\bmBitsPixel=GetDeviceCaps_(hDC,#BITSPIXEL)
    Bmp\bmBits=DrawingBuffer()
    Bmp\bmWidthBytes=DrawingBufferPitch()
    hBmp=CreateBitmapIndirect_(Bmp)
    StopDrawing()
    CreateImage(Image,SpriteWidth(Sprite),SpriteHeight(Sprite))
    StartDrawing(ImageOutput(Image))
    DrawImage(hBmp,0,0)
    StopDrawing()
    DeleteObject_(hBmp)
  EndIf
EndProcedure 
;}
Merci d'avance :D
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Dessiner sur un screen (avec tablette graphique)

Message par Backup »

......
Dernière modification par Backup le lun. 18/août/2014 17:02, modifié 1 fois.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Dessiner sur un screen (avec tablette graphique)

Message par blendman »

salut

Merci pour l'exemple, c'était ça que je voulais ;).
Pour les constantes, effectivement c'est mieux de les mettre, je les ai rajoutées.
Pour le elseif, c'est simple useprite pouvait prendre 3 valeurs (0,1,2) d'où le elseif.

Sinon, j'ai revu légèrement le code (en ajoutant des constantes, et en modifiant le mode "gomme"... enfin, je ne gomme pas vraiment car normalement pour gommer on enlève de l'alpha et là ça ne marche pas (enlever de l'apha au sprite, car les sprites ... n'ont pas vraiment d'alpha (alpha comme les png, pas de juste une couleur pour l'alpha).

Code : Tout sélectionner

;{ constantes
;-- window
Enumeration 
  #window  
EndEnumeration

;-- sprite
Enumeration 
  #brush
  #layer1
EndEnumeration

;-- image
Enumeration 
  #image
EndEnumeration

;}

;{ init
ExamineDesktops()

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or InitSprite3D() = 0 Or UsePNGImageDecoder() =0 Or UsePNGImageEncoder()=0
  MessageRequester("Error", "Can't open the sprite system", 0)
  End
EndIf
;}

;{ declare
Declare CreateImageFromSprite(Image.l,Sprite.l)
;}

;{ variables
Global sprite_ok.b, playerX.w = -500, playerY.w = -500, usesprite.b
; sprite
Global centreX.a, centreY.a
;blendmode
Global source.a = 5, destination.a =7
;}

;{ openwindow & create sprite
If OpenWindow(#window, 0, 0, DesktopWidth(0), DesktopHeight(0), "Dessiner sur un sprite", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_Maximize)
  
  ;{ menu
  If CreateMenu(0,WindowID(#window))
    MenuTitle("mode")
    MenuItem(0,"Dessiner sur le sprite")
    MenuItem(1,"Utiliser Usebuffer()")
    MenuItem(2,"Dessiner sur le screen")   
  EndIf
  ;}
  
  ;{ screen & sprite
  If OpenWindowedScreen(WindowID(#window), 150, 70, 800,600, 0, 0, 0)
    LoadSprite(#brush, "2.png",#PB_Sprite_AlphaBlending|#PB_Sprite_Texture)
    CreateSprite3D(#brush,#brush)
    centreX =SpriteWidth(#brush)/2
    centrey =SpriteHeight(#brush)/2
    CreateSprite(#layer1,1024,1024,#PB_Sprite_AlphaBlending|#PB_Sprite_Texture)
    CreateSprite3D(#layer1,#layer1)
    StartDrawing(SpriteOutput(#layer1))
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0,0,1024,1024,RGBA(255,255,255,0))
    StopDrawing()
    
    ClearScreen(RGB(255,255,255))
  Else
    MessageRequester("Error", "Can't open windowed screen!", 0)
    End
  EndIf
  ;}
  
EndIf
;}

;{ boucles
Repeat
  
  Repeat
    Event = WindowEvent()
    Delay(2)
    Select Event
      Case #WM_RBUTTONDOWN ; efface
        sprite_ok.b=2
        If usesprite = 1
          UseBuffer(#layer1)
        EndIf  
        
      Case #WM_LBUTTONDOWN ; dessine
        sprite_ok.b=1
        If usesprite = 1
          UseBuffer(#layer1)
        EndIf  
        
      Case #WM_LBUTTONUP, #WM_RBUTTONUP
        sprite_ok.b  =0
        SaveSprite(#layer1,"testsave.png",#PB_ImagePlugin_PNG) ;<<<<<<<<<<<<<<<<<<----- la sauvegarde pose des problème, l'image obtenue est toute noire.
        UseBuffer(#PB_Default)
        
        
      Case #WM_MOUSEMOVE
        playerX = WindowMouseX(0)-150 - centreX
        playerY = WindowMouseY(0)-70 - centreY
        
      Case #PB_Event_CloseWindow
        Quit = 1
      Case #PB_Event_Menu     
        Select EventMenu()
          Case 0,1,2
            usesprite =  EventMenu()                     
        EndSelect       
    EndSelect
  Until Event = 0 
  
  ;{ event keyboard
  ExamineKeyboard()
  If KeyboardReleased(#PB_Key_R)
    source + 1
    If source > 14
      source = 1
    EndIf
    SetWindowTitle(#window,"blendmode : "+Str(source)+"/"+Str(destination))
  EndIf
  If KeyboardReleased(#PB_Key_T)
    destination + 1
    If destination > 14
      destination = 1
    EndIf
    SetWindowTitle(#window,"blendmode : "+Str(source)+"/"+Str(destination))
  EndIf 
  ;}
  
  Start3D()
  If sprite_ok =1
    DisplaySprite3D(#brush, playerX, playerY) ; dessine
  ElseIf sprite_ok =2
    Sprite3DBlendingMode(source,destination) ; gomme
    DisplaySprite3D(#brush, playerX, playerY) ; efface
    Sprite3DBlendingMode(5,6)
  EndIf
  Stop3D() 
  FlipBuffers()
  
Until  Quit Or KeyboardPushed(#PB_Key_Escape)
;}

;{ procedures

Procedure CreateImageFromSprite(Image.l,Sprite.l)
  ;by octavius
  Protected hDC.l,Bmp.BITMAP,hBmp.l
  If IsSprite(Sprite)
    hDC=StartDrawing(SpriteOutput(Sprite))
    Bmp\bmWidth=SpriteWidth(Sprite)
    Bmp\bmHeight=SpriteHeight(Sprite)
    Bmp\bmPlanes=1
    Bmp\bmBitsPixel=GetDeviceCaps_(hDC,#BITSPIXEL)
    Bmp\bmBits=DrawingBuffer()
    Bmp\bmWidthBytes=DrawingBufferPitch()
    hBmp=CreateBitmapIndirect_(Bmp)
    StopDrawing()
    CreateImage(Image,SpriteWidth(Sprite),SpriteHeight(Sprite))
    StartDrawing(ImageOutput(Image))
    DrawImage(hBmp,0,0)
    StopDrawing()
    DeleteObject_(hBmp)
  EndIf
EndProcedure
;}
; EPB & ide :) 
le sprite si besoin :
Image

Par contre, j'ai 3 questions :
- en sauvegardant le sprite (#layer1, sur lequel je peins), j'ai une image toute noire, je ne comprends pas pourquoi.
- autre problème : comment dessiner et récupérer un sprite avec canal alpha, puisqu'on ne peut pas dessiner sur un sprite3D et visiblement seuls ceux-ci gèrent le canal alpha (style png) des images.
- normalement, pour gommer de l'alpha sur une surface directX, on utilise le blendmode (1/7, 2/7 ou 13/7), j'ai testé (touche R et T) et ça marche sur mon autre logiciel (en GM), mais pas là. J'imagine que c'est du au fait que les sprites n'ont pas d'alpha (style PNG). Bref, vraiment dommage pour ça...

En cherchant un peu, j'ai retrouvé ce sujet. Si je comprends bien screenoutput() et spriteoutput() utilisent les surface directX, mais ce n'est pas très clair :
http://www.purebasic.fr/french/viewtopic.php?f=4&t=4314

Encore merci ;)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Dessiner sur un screen (avec tablette graphique)

Message par Backup »

..
Dernière modification par Backup le lun. 18/août/2014 17:03, modifié 1 fois.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Dessiner sur un screen (avec tablette graphique)

Message par blendman »

Dobro a écrit :voila pour la sauvegarde de l'image ;)
Merci. J'ai testé, mais chez moi j'ai toujours une image noire en résultat. Ce serait du à la carte graphique ? ou à un autre problème ?


l'alpha est geré par Grabsprite() , mais en 256 couleurs je crois

il dois surement exister des codes sur le forum anglais pour contourner ça
(le Soldat inconnu a pas mal bossé sur les Alpha, il me semble ;) )
je vais regarder pour ce genre de chose, merci ;)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Dessiner sur un screen (avec tablette graphique)

Message par Backup »

blendman a écrit :
Dobro a écrit :voila pour la sauvegarde de l'image ;)
Merci. J'ai testé, mais chez moi j'ai toujours une image noire en résultat. Ce serait du à la carte graphique ? ou à un autre problème ?
chez moi ça marche niquel !

la seule limitation connu de certaines carte graphique c'est une limitation a propos des sprites

les sprites doivent etre de taille multiple de 256 (de memoire)

sinon remplace mon grabsprite par un grabimage, et sauve cette image :)

Code : Tout sélectionner

Grabimage(#layer1,************ )
Saveimage(***************) ;Corrigé :o)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Dessiner sur un screen (avec tablette graphique)

Message par blendman »

Bon, j'ai réussi :P

En fait, il y avait un usebuffer() en trop ici :

Code : Tout sélectionner

Case #WM_LBUTTONUP, #WM_RBUTTONUP
      sprite_ok.b  =0
      UseBuffer(#layer1);<<<<<<<<< ici en trop
      GrabSprite(#layer1,0,0,800,600,0 )
      SaveSprite(#layer1,"testsave.png",#PB_ImagePlugin_PNG) ;Corrigé :o)
Par contre, en testant, je trouve que cette méthode pose quelques problèmes pour un logiciel de dessin, et c'est dommage car ça va vraiment plus vite que dessiner sur une image :
- la gestion de l'alpha pose problème (j'ai trouvé des choses, mais pas encore une bonne gestion de l'alpha sur un sprite/sprite3D/sauvegarde avec transparence) : il faudrait un "RTT" (render to texture) comme en parlait G-rom sur un autre fil de discussion :). pouvoir dessiner sur un sprite3D et sauvegarder ce sprite3D (sans grab machin).
- les grabsprite ne peuvent se faire que sur des sprites qui sont inférieurs ou égaux à la taille du screen. Si on a une image en 4000*4000, il faut alors créer une procédure pour découper le sprite (le claque) dont on se sert pour le usebuffer() en morceau, puis recoller ces morceaux sur une image/ un sprite et sauvegarder ce sprite ou cette image.
- le grabsprite ne va pas de toutes façons car on perd l'alpha même si on en avait un (ce que pour le moment, je n'ai pas réussi). Donc, impossible d'enregistrer un calque avec alpha par exemple.

Je vais continuer mes tests, car c'est dommage, ça va très vite comparé au imageoutput(), mais il manque des choses en natif pour pouvoir utiliser cette méthode pour un logiciel de dessin.

D'ailleurs, je ne comprends pas pourquoi on est obligé de passer par un grabsprite() alors qu'avec le usebuffer() on est sensé dessiner sur le sprite et pas sur le screen, alors pourquoi copier ensuite le screen sur le sprite pour sauvegarder le sprite. Car sauvegarder le sprite directement ne marche pas.
C'est mal fait cette histoire-là, où il y a une technique qui permet de dessiner sur un sprite et sauvegarder ce sprite (et donc ce qu'ona dessiner dessus) sans passer par un grabsprite :) ?

Encore merci Dobro pour ton aide ;)
tonton
Messages : 315
Inscription : mar. 26/avr./2005 15:19

Re: Dessiner sur un screen (avec tablette graphique)

Message par tonton »

Ce n' est pas pour faire chier!
J' attends une démo jouable qui devrait être dispo selon les prévisons avec une marge d' erreur de 50% supérieur au temps
imparti. :mrgreen:
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Dessiner sur un screen (avec tablette graphique)

Message par djes »

Pour la petite histoire, les problèmes avec les sprites3d viennent surtout de la conversion de directx en "3d only". Avec DirectX7, c'était beaucoup plus simple pour les applis 2D (quoique que déjà, tout se passait dans la mémoire de la carte graphique, et pour récupérer les buffers il fallait passer par le port PCI/AGP qui ralentissait tout). En plus, les couleurs/texturages ne sont pas gérés de la mm façon selon les cartes graphiques, les pilotes, etc, donc il faut faire du code spaghetti partout pour corriger toutes les petites différences. A cela s'ajoute le "support" de ogre, qui ne doit rien gâcher au plaisir de l'équipe ;)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Dessiner sur un screen (avec tablette graphique)

Message par blendman »

tonton a écrit :Ce n' est pas pour faire chier!
J' attends une démo jouable qui devrait être dispo selon les prévisons avec une marge d' erreur de 50% supérieur au temps
imparti. :mrgreen:
Heu, désolé, mais je n'ai rien compris à ton message. Tu attends une démo jouable de quoi ?
djes a écrit :Pour la petite histoire, les problèmes avec les sprites3d viennent surtout de la conversion de directx en "3d only". Avec DirectX7, c'était beaucoup plus simple pour les applis 2D (quoique que déjà, tout se passait dans la mémoire de la carte graphique, et pour récupérer les buffers il fallait passer par le port PCI/AGP qui ralentissait tout). En plus, les couleurs/texturages ne sont pas gérés de la mm façon selon les cartes graphiques, les pilotes, etc, donc il faut faire du code spaghetti partout pour corriger toutes les petites différences. A cela s'ajoute le "support" de ogre, qui ne doit rien gâcher au plaisir de l'équipe ;)
En fait, c'est dommage, car je pense qu'il manque peu de choses à Purebasic pour pouvoir gérer les sprites et le screen pour une appli 2D.
Ce qui nous permettrait d'avoir des grandes images (au moins 5000*5000).
Lorsque j'ai "développé" mon soft 2D Animatoon, avec GM, j'utilisais les surfaces directX et les sprites. Mais j'avais de la transparence à la fois pour les sprites et pour les surfaces directX, donc ça marchait super bien, sur les ordinateurs ayant une carte compatible uniquement.

Là, en faisant des essais en purebasic, on peut faire pas mal de choses (voire mon sujet "animatoon", dans application). Cependant, niveau vitesse les stradrawing(imageoutput()) ne sont pas super rapides comparées au sprites, screen et même au canvas.
Et du coup, avec un document en 1500*1500 (donc pas hyper grand non plus), ça commence à ramer avec 1 seul calque déjà :(.
Alors, j'ai eu espoir de pouvoir utiliser les sprites et screen, mais sans alpha, je ne vois pas comment faire ça.
Il faut donc que je trouve le moyen d'utiliser et gérer convenablement l'alpha pour les calques : en écriture et lors d'une sauvegarde.
Car le screen serait un excellent compromis je pense :).
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Dessiner sur un screen (avec tablette graphique)

Message par djes »

Je t'ai déjà expliqué pour les grandes images. PB se repose sur l'OS, dont le système d'affichage n'est pas fait pour gérer des grandes images destinées à l'impression. Ce sont deux choses différentes.

Quant à PB, si tu bidouilles avec les images et que tu te fais quelques routines de bas niveau rapides, tu pourras faire aussi bien que les grands. Pour ce qui est des sprites, perso je ne les utiliserais pas pour un soft de dessin, le résultat est bien trop aléatoire en DX9. Peut-être en DX7 à la rigueur, ou en OpenGL. Mais c'est un poil plus compliqué, et c'est pour ça que la plupart des softs sont lents dans tout ce qui est tracé temps réel (à part TVPaint, qui a toujours été très optimisé)
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Dessiner sur un screen (avec tablette graphique)

Message par blendman »

djes a écrit :Quant à PB, si tu bidouilles avec les images et que tu te fais quelques routines de bas niveau rapides, tu pourras faire aussi bien que les grands.
qu'est-ce que tu entends par "routines de bas niveau rapides" ?
D'après toi, quelles seraient la/les techniques à utiliser ?
Je pense qu'il faut découper le document en plusieurs morceaux (genre 512*512), et n'afficher et ne travailler que ce qui est sur l'écran.

Mais je ne vois pas vraiment comment je peux faire ça pour le moment, ça ne doit pas être à ma portée :P.
Pour ce qui est des sprites, perso je ne les utiliserais pas pour un soft de dessin, le résultat est bien trop aléatoire en DX9. Peut-être en DX7 à la rigueur, ou en OpenGL. Mais c'est un poil plus compliqué,
oui, j'ai voulu tester pour la rapidité, mais de toutes façons, j'ai déjà des problèmes avec la gestion de l'alpha.
et c'est pour ça que la plupart des softs sont lents dans tout ce qui est tracé temps réel (à part TVPaint, qui a toujours été très optimisé)
par "tracé temps réel", tu veux parler de dessin bitmap ou vectoriel ou autre chose ?

Merci pour les infos en tout cas ;)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Dessiner sur un screen (avec tablette graphique)

Message par djes »

blendman a écrit :
djes a écrit :Quant à PB, si tu bidouilles avec les images et que tu te fais quelques routines de bas niveau rapides, tu pourras faire aussi bien que les grands.
qu'est-ce que tu entends par "routines de bas niveau rapides" ?
D'après toi, quelles seraient la/les techniques à utiliser ?
Je pense qu'il faut découper le document en plusieurs morceaux (genre 512*512), et n'afficher et ne travailler que ce qui est sur l'écran.

Mais je ne vois pas vraiment comment je peux faire ça pour le moment, ça ne doit pas être à ma portée :P.
Oui, les routines les plus proches de l'affichage : point, ligne, gestion mémoire doivent être modulaires, et gérer l'affichage "dallé". Faut pas te leurrer, un vrai programme de dessin "pro" n'utilise les api que pour des fonctions très basiques, tout le reste est entièrement recodé, c'est le seul moyen d'avoir le contrôle. Heureusement, beaucoup de ces softs sont en opensouce, rien ne t'empêche de jeter un oeil (the gimp par exemple!). Sinon, tu peux commencer doucement en essayant de faire en sorte que ton code puisse évoluer.
blendman a écrit :
et c'est pour ça que la plupart des softs sont lents dans tout ce qui est tracé temps réel (à part TVPaint, qui a toujours été très optimisé)
par "tracé temps réel", tu veux parler de dessin bitmap ou vectoriel ou autre chose ?

Merci pour les infos en tout cas ;)
Bitmap ou vectoriel, ça peut être temps réel. Quand tu dessines dans Photoshop avec une brosse, si tu vas vite, tu as toujours d'affreuses lignes, ça suit difficilement le mouvement. Dans illustrator ou flash, en général on est un peu plus dans le détail et le temps réel on s'en fiche un peu.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Dessiner sur un screen (avec tablette graphique)

Message par blendman »

djes a écrit :les routines les plus proches de l'affichage : point, ligne, gestion mémoire doivent être modulaires, et gérer l'affichage "dallé". Faut pas te leurrer, un vrai programme de dessin "pro" n'utilise les api que pour des fonctions très basiques, tout le reste est entièrement recodé, c'est le seul moyen d'avoir le contrôle.
j'ai bien compris tout ça ;).
Mais ce que je ne sais pas faire et je ne sais même pas comment faire ça c'est remplacer : point, ligne, etc. ou gérer l'affichage dallé...
Je vois bien la théorie, mais dès que j'essaye de partir vers la pratique (le développement en pb), je ne sais pas du tout comment faire ça, vu que j'utilise justement les fonctions de pb.
Ca veut dire que je dois passer par gdi+ par exemple ?

Comment faire en pure un affichage dallé, mais surtout qu'est-ce que cela signifie précisément :D :
1. est-ce un affichage où on dessine sur chaque dalle et chaque dalle est une image (comme mon exemple) : j'ai découpé mon document en plein de petites images (256*256) et lorsque la souris est dessus, je dessine sur l'image en question.
2. est-ce que cela signifie que lorsque l'on dessiner cela crée une image de la taille du dessin à la volée, puis qu'on update le canvas avec toutes ces dalles en les supprimant ensuite ? (je vais tester cette 2ème méthode par la suite).

Voici le petit essai rapide (méthode 1), c'est ce genre de chose que je dois faire ou pas du tout ? :

Code : Tout sélectionner

 ;{ infos
; test de dalle pour painting 2D
; animatoon 
; dev :blendman 08/2011
; pb  : 4.60 beta3
;}

;{ constantes 
;window
Enumeration
  #Win_0
EndEnumeration

; menu
Enumeration  
  #menu_Sortie
EndEnumeration

; gadget
Enumeration 
  #SA_surfaceDessin
  #canvas
EndEnumeration

; Image
Enumeration 
  #image_dessinfinal
  #imageDessin  = 1000
EndEnumeration
; 
;}

;{ Structures
Structure s_dalle
  id.a
  position.point
  image.w
  width.w
  height.w
EndStructure
Global NewList dalle.s_dalle()

;}

;{ variables
Global doc_H.w=2000, doc_W.w =2000, draw.b, xx.w, yy.w, globalID.a
;}

;{ declare
Declare update_drawing()
;}

;{ openwindow
ExamineDesktops()
winW = DesktopWidth(0)
winH = DesktopHeight(0)

If OpenWindow(#Win_0, 0,0,winW,winH,"Animatoon-test dalle", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_WindowCentered|#PB_Window_Maximize|#PB_Window_Minimize) 

  ;{ Menus 
  MenuBar=CreateMenu(#PB_Any,WindowID(#Win_0))
  MenuTitle("Fichier")
  MenuItem(#menu_Sortie,"Quitter")

  ;}
  ;{ Status barre 
  StatusBar=CreateStatusBar(#PB_Any,WindowID(#Win_0))
  AddStatusBarField(200)
  AddStatusBarField(200)
  ;}
  ;{ Gadget & images
  ; creation des dalles (256*256), en fonction de la taille du document
  nb_dalle_w = Round(doc_w/256,0)
  nb_dalle_h = Round(doc_h/256,0)  
  
  For i = 0 To nb_dalle_w ; on commence les images à 1000, ça laisse de la marge au cas où on aurait besoin de 1000 images pour le logiciel
    For j = 0 To nb_dalle_h      
      ; creation of the image for the dalle 
      CreateImage(#imageDessin+a, 256,256,32)
      StartDrawing(ImageOutput(#imageDessin+a))
      DrawingMode(#PB_2DDrawing_AlphaChannel)
      Box(0,0,256,256,RGBA(0,0,0,0))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      Box(0,0,256,256,RGBA(255-Random(50),255-Random(50),255-Random(50),255))
      StopDrawing()
      ; add the dalle on the list dalle()
      AddElement(dalle())
      dalle()\id = a  
      dalle()\position\y = j*256
      dalle()\position\x = i*256
      dalle()\width = 256
      dalle()\height = 256
      dalle()\image = #imageDessin+a 
      a + 1
    Next j
  Next i
  
;   ; creation de l'image (support) pour le dessin
    CreateImage(#image_dessinfinal,doc_w,doc_h,32)
  
  ; scrollareagadget & canvas // surface de dessin
  ScrollAreaGadget(#SA_surfaceDessin,150,10,winW-150-150,winH-120,doc_W,doc_H,10)
  CanvasGadget(#canvas,0,0,doc_W,doc_H, #PB_Canvas_ClipMouse)
  CloseGadgetList()
  update_drawing()
  
  ;}
  
EndIf

;}

;{ Boucle
Repeat
  EventID  =WaitWindowEvent()
  MenuID   =EventMenu()
  GadgetID =EventGadget()
  WindowID =EventWindow()
  
  ;{ general
  XX = WindowMouseX(#Win_0)-150 + GetGadgetAttribute(#SA_surfaceDessin,#PB_ScrollArea_X)
  YY = WindowMouseY(#Win_0) -10 + GetGadgetAttribute(#SA_surfaceDessin,#PB_ScrollArea_Y) 
  StatusBarText(StatusBar,0,"Coords : "+Str(XX)+","+Str(YY))
  ;}
  
  Select EventID
      
    Case #PB_Event_Menu
      Select MenuID
        Case #menu_Sortie
          quit.b=1
      EndSelect
      
    Case #PB_Event_Gadget
      Select GadgetID
          
        Case #canvas
          Select EventType()
            Case #PB_EventType_LeftButtonDown
              draw = 1
          
              
          EndSelect
          
        Case #SA_surfaceDessin
          
          
          
      EndSelect
    
      ;{ mouse & autres
    Case #PB_Event_CloseWindow
      If WindowID=#win_0
        quit.b=1
      EndIf
        
    Case #WM_MOUSEMOVE
      If draw = 1
        ForEach dalle()
          If XX > dalle()\position\x And XX < dalle()\position\x + dalle()\width And YY > dalle()\position\y And YY < dalle()\position\y + dalle()\height
            ;Debug "id : "+Str(dalle()\id)
            globalId = dalle()\id
            StartDrawing(ImageOutput(dalle()\image))
            Circle(XX-dalle()\position\x ,YY-dalle()\position\y,10,0)
            StopDrawing()
            update_drawing()
            Break
          EndIf
        Next        
      EndIf
      
    Case #WM_LBUTTONUP
      If draw = 1
        draw = 0
        Debug "Butoon_Up - Draw " +Str(draw)
        update_drawing()
      EndIf  
    ;}  
   
  EndSelect
Until quit
;}

End


Procedure  update_drawing()
  
;   StartDrawing(ImageOutput(#image_dessinfinal))
;   DrawingMode(#PB_2DDrawing_AlphaChannel)
;   Box(0,0,doc_W,doc_h,RGBA(0,0,0,0))
;   DrawingMode(#PB_2DDrawing_AlphaBlend)
;   ForEach dalle()    
;     DrawAlphaImage(ImageID(dalle()\image),dalle()\position\x,dalle()\position\y)    
;   Next  
;   StopDrawing()
  
  StartDrawing(CanvasOutput(#canvas))
  DrawingMode(#PB_2DDrawing_Default)
  Box(0,0,doc_w,doc_h,RGBA(255,255,255,255)) 
  ForEach dalle()   
    DrawAlphaImage(ImageID(dalle()\image),dalle()\position\x,dalle()\position\y)
  Next  
  ;DrawAlphaImage(ImageID(#image_dessinfinal),0,0)
  StopDrawing()

EndProcedure
Heureusement, beaucoup de ces softs sont en opensouce, rien ne t'empêche de jeter un oeil (the gimp par exemple!). Sinon, tu peux commencer doucement en essayant de faire en sorte que ton code puisse évoluer.
J'ai regardé un peu mypaint, c'est du C et du python, mais ils donnent des informations sur un système de dessin par dalle et c'est hyper fluide et rapide !
http://wiki.mypaint.info/index.php?titl ... Developers

Mais par contre, comment faire ce genre de choses en pb ou plutôt j'essaie de comprendre ce que veulent dire les images sur ce wiki (celles avec les dalles). j'ai l'impression que ça ressemble à ma méthode N°2 (voir un peu plus haut).
blendman a écrit :Bitmap ou vectoriel, ça peut être temps réel. Quand tu dessines dans Photoshop avec une brosse, si tu vas vite, tu as toujours d'affreuses lignes, ça suit difficilement le mouvement.
je n'ai pas ce soucis avec cs5, même en 4000*4000. ça doit dépendre de ta brosse j'imagine.
Moi, avec une brosse avec effets dynamiques, même si je zoom pour voir toute la surface de travail, ça reste fluide et je n'ai pas ces traits ou ces lignes horribles.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Dessiner sur un screen (avec tablette graphique)

Message par Backup »

..
Dernière modification par Backup le lun. 18/août/2014 17:03, modifié 1 fois.
Répondre