sprite sous linux pb4.41

Archive.
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

sprite sous linux pb4.41

Message par Scrat »

Bonjour

Un truc bizarre avec les sprites.
Si la largeur d'un sprite n'est pas une puissance de 2 le sprite ne s'affiche pas et le programme freeze.
pas de message d'erreur, rien !
Pour la hauteur du sprite n'importe quelle dimension fonctionne

Code : Tout sélectionner

If InitSprite()

  If OpenWindow(0,10,10,800,600,"",#PB_Window_SystemMenu )
    If OpenWindowedScreen(WindowID(0),0,0,800,600,0,0,0)

      If CreateImage(1,66,127,32)
      StartDrawing(ImageOutput(1))
      Box(0,0,64,127,RGB(255,0,0))
      StopDrawing()

      Ws=96;doit être une puissance de 2
      Hs=79;peut importe
        If CreateSprite(2,Ws,Hs)
        StartDrawing(SpriteOutput(2))
        DrawImage(ImageID(1),0,0,Ws,Hs)
        StopDrawing()
        Else
        Debug "error sprite"
        End
        EndIf


Repeat
E=WindowEvent()

DisplaySprite(2,0,0)
FlipBuffers()
ClearScreen(RGB(0,0,0))
Delay(1)

Until E=#PB_Event_CloseWindow

      EndIf
    EndIf
  EndIf
EndIf
End

essayer avec Ws=95 par exemple

A+
Fred
Site Admin
Messages : 2648
Inscription : mer. 21/janv./2004 11:03

Re: sprite sous linux pb4.41

Message par Fred »

C'est quoi ta carte graphique ? Si c'est une vieille, utilise le subsystem DirectX7
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

Re: sprite sous linux pb4.41

Message par Scrat »

J'ai testé sur une Ati 9100 pas trés jeune et sur Une Nvidia ION et sur un poulsbo meme resultat sur les 3

A+

Edit 1
Heu c'est sous linux donc OpenGl

Edit 2
en utilisant loadsprite() avec une image de 35x35 le programme affiche bien le sprite
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

Re: sprite sous linux pb4.41

Message par Scrat »

Nouveau test sur une geforce 8500GT et ça ne fonctionne pas non plus

Ca sent quand même un peu le bug !

A
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: sprite sous linux pb4.41

Message par G-Rom »

Ta carte graphique ne supporte pas les textures non puissance de 2.

dans ce cas :

tu ne charge pas le sprites qui est de taille "carré"
tu la charges en tant qu'image
tu prends le coté le plus grand ( largeur ou hauteur )
tu créer un sprite carré
tu colles ton image rectangle dedans

Voici une procédure qui fait ce que je viens de cité plus haut :

Code : Tout sélectionner

Procedure LoadSprite_EX(SpriteID.l , filename.s , Mode=0)

ImageSRC = LoadImage(#PB_Any,filename)
Width    = ImageWidth(ImageSRC)
Height   = ImageHeight(ImageSRC)


If Width>Height : Square = Width  : EndIf 
If Width<Height : Square = Height : EndIf 
If Width=Height : Square = Height : EndIf 


Resultat = CreateSprite(SpriteID,Square,Square,Mode)
StartDrawing(SpriteOutput(SpriteID))
  DrawImage(ImageID(ImageSRC),0,0)
StopDrawing()


ProcedureReturn Resultat
EndProcedure
Ce n'est pas un "Bug" propre à purebasic , mais une facon conventionnel de le faire , cherche PowerOfTwo SDL & OPENGL sur google , tu trouveras le même genre de procédure en c / c++ pour le soucis des carte ne supportant pas les textures non n²

@+
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

Re: sprite sous linux pb4.41

Message par Scrat »

Salut G-Rom

Je veux bien, mais y'a un truc bizarre quand même
Si je crée une image de 129X73 donc pas carré et pas pussance de 2, que je la sauvegarde et qu'ensuite j'utilise loadsprite() il n'y a aucun souci.
Si maintenat je crée un sprite de 129X73 et que je trace dessus le programme freeze au niveau du stopdrawing()

Et des cartes graphiques j'en ai essayé un paquet y'en a aucune qui fonctionne !

Code : Tout sélectionner

Enumeration
#Img
#Spr
#Spr2
EndEnumeration

UsePNGImageEncoder()
UsePNGImageDecoder()

If InitSprite()

  If OpenWindow(0,10,10,800,600,"",#PB_Window_SystemMenu )
    If OpenWindowedScreen(WindowID(0),0,0,800,600,0,0,0)

      W=129
      H=73
      If CreateImage(#Img,W,H,32)
      StartDrawing(ImageOutput(#Img))
      Box(0,0,W,H,RGB(255,0,0))
      StopDrawing()
      SaveImage(#Img,"test",#PB_ImagePlugin_PNG)
      EndIf
  
  
       LoadSprite(#Spr,"test",#PB_ImagePlugin_PNG)

; CreateSprite(#Spr2,W,H)
; StartDrawing(SpriteOutput(#Spr2))
; DrawImage(ImageID(#Img),0,0)
; StopDrawing()




Repeat
E=WindowEvent()

DisplaySprite(#Spr,0,0)
;DisplaySprite(#Spr2,250,0)
FlipBuffers()
ClearScreen(RGB(0,0,0))
Delay(1)

Until E=#PB_Event_CloseWindow

      EndIf
      EndIf
      EndIf
 
Active le subsystem opengl et essaye ce code ca fonctionne sur toute carte graphique du poulsbo a des Nvidia dernier cri.
Maintenant décommente les quelques lignes et là plantage assuré sur n'importe quel carte.

En sdl cela fonctionne, hormis l'ecran graphique qui n'est pas solidaire de la gui (bug marqué comme corrigé par Fred sur le forum english)

A+


EDIT:
Il semble que pour cela fonctionne, la largeur du sprite doit etre divisble par 4.
Pour la hauteur peu importe tout passe
Ca ecarte le probleme de puissance de 2
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: sprite sous linux pb4.41

Message par G-Rom »

Oui , c'est logique , ta pas bien lu ce que je t'ai dit.


-Tu charges une image de taille quelconque ( pas un sprite , car sinon ca part dans la CG dans la plupart des cas )
-Tu vérifie la taille de l'image , par exemple , si ton image fait 179x73 ,bah tu créer un sprite de 192x192 par exemple.
- tu dessine ton image dedans , et hop , ta ton sprite de taille n²

Pas de plantage , ca passe partout.

@+
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

Re: sprite sous linux pb4.41

Message par Scrat »

Ben non c'est toi qui n'a pas bien lu. :wink:

ici je crée une image de 129x73 (pas carré, pas puissance de 2) et je la sauvegarde

Code : Tout sélectionner

     W=129
      H=73
      If CreateImage(#Img,W,H,32)
      StartDrawing(ImageOutput(#Img))
      Box(0,0,W,H,RGB(255,0,0))
      StopDrawing()
      SaveImage(#Img,"test",#PB_ImagePlugin_PNG)
      EndIf
ici je la load en sprite donc dans la cg (je pense)

Code : Tout sélectionner

 LoadSprite(#Spr,"test",#PB_ImagePlugin_PNG)
Et cette methode fonctionne sur toutes les cartes graphiques


Par contre si je crée directement le sprite avec les memes dimenssions de 129x73

Code : Tout sélectionner

 CreateSprite(#Spr2,W,H)
 StartDrawing(SpriteOutput(#Spr2))
 DrawImage(ImageID(#Img),0,0)
 StopDrawing()
là ça plante au niveau du stopdrawing() et sur toutes les cartes graphique que j'ai essayé

Pour que ça fonctionne il faut que la largeur du sprite soit un multiple de 4
En gros j'ai fait une fonction qui test si le modulo de la largeur par 4 est nul, sinon j' ajuste la largeur.

C'est un contournement mais pas une solution, car adieu les fonctions de collision,les spritewith etc ...

A+
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: sprite sous linux pb4.41

Message par G-Rom »

Par contre si je crée directement le sprite avec les memes dimenssions de 129x73
Code:
CreateSprite(#Spr2,W,H)
StartDrawing(SpriteOutput(#Spr2))
DrawImage(ImageID(#Img),0,0)
StopDrawing()

là ça plante au niveau du stopdrawing() et sur toutes les cartes graphique que j'ai essayé

Pour que ça fonctionne il faut que la largeur du sprite soit un multiple de 4
En gros j'ai fait une fonction qui test si le modulo de la largeur par 4 est nul, sinon j' ajuste la largeur.

C'est un contournement mais pas une solution, car adieu les fonctions de collision,les spritewith etc ...

A+
C'est exactement le problème , ton sprite doit être puissance de 2 , LoadSprite() quand à lui , doit avoir en interne une fct° qui rend "carré" le sprite pour ne pas planté.
C'est un contournement mais pas une solution, car adieu les fonctions de collision,les spritewith etc ...
Et pourquoi ?

Tu te créer une petite structure contenant les Infos :

Structure SPRITE_EXT
SpriteID.l
W.l
H.l
Etc.l
endstructure
Quand tu passes ton image à la moulinette pour le rendre "carré" tu informes cette structure , tu retournes un pointeur dessus. tu refait les fonctions ( ou macro ) pour pouvoir utilisé ton sprite "normalement"
macro DisplaySprite_EXT(SpriteID,x,y)
DisplaySprite(SpriteID\SpriteID,x,y)
endmacro

macro SpriteWidth_EXT(SpriteID)
SpriteID\W
endmacro

etc...
C'est une sorte d'héritage , fastidieux en Basic , mais le top en c++ par exemple.

Dans tout les cas , ce n'est pas un Bug de PureBasic.

@+
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

Re: sprite sous linux pb4.41

Message par Scrat »

Donc on est d'accord

Ca fonctionne avec loadsprite mais pas avec createsprite
Pour moi cela s'appelle un bug

Sinon il faut documenter le fait que le sprite doit etre un multiple de 4 en largeur et pas forcement une puissance de 2 (par exemple un sprite de w=80 x h=33 fonctionnera)
Supprimer les fonctions de collision inutilisables
Supprimer spritewith()
etc ......

Puis si il faut refaire toutes les fonctions autant quelles soient incluses correctement dans le compilo.

Non autant sous win Pb est un regal autant sous linux c'est quasiment inutilisable en mode screen

A+
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: sprite sous linux pb4.41

Message par G-Rom »

Non autant sous win Pb est un regal autant sous linux c'est quasiment inutilisable en mode screen
Pas du tout , mon jeu tourne très bien dessus.
Ca fonctionne avec loadsprite mais pas avec createsprite
Pour moi cela s'appelle un bug
Comme je t'ai dit , pb n'a rien n'a voir avec ca. avec SDL , si ta carte le supporte il me semble que la mise en n² est automatique
donc loadsprite() fonctionnera dans tout les cas de figure ( a vérifié car je ne suis pas si sur que ca , (voir des vieux post avec Dr.Dri) ) . Par contre , CreateSprite() ne met aprioris pas en n² d'après tes soucis. c'est donc à toi de le mettre à l'échelle avant le chargement en sprite.

Je pense aussi qu'il est possible de modifier la structure pb du sprite standard afin de réajusté la taille pour les commandes de collisions , mais je ne connais pas le contenu de cette dite structure.
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

Re: sprite sous linux pb4.41

Message par Scrat »

Pas du tout , mon jeu tourne très bien dessus.
Tant mieux, je suis trés content pour toi

Moi, a chaque fois que je contourne un bug j' en trouve un autre

Test ça

Code : Tout sélectionner

Enumeration
#Spr
EndEnumeration

If InitSprite() And InitMouse() And InitKeyboard()

  If OpenWindow(0,10,10,800,600,"",#PB_Window_SystemMenu )
    If OpenWindowedScreen(WindowID(0),0,0,800,600,0,0,0)

W=80
H=40
CreateSprite(#Spr,W,H)
W2=W/2
H2=H/2

R=0
G=0
B=0 
Repeat

ExamineMouse()
ExamineKeyboard()
X=MouseX()
y=MouseY()

R+1
If R=255:R=0:EndIf
StartDrawing(SpriteOutput(#Spr))
Circle(W2,H2,10,RGB(R,G,B))
StopDrawing()
TransparentSpriteColor(#Spr,0)
DisplayTransparentSprite(#Spr,x,y)


FlipBuffers()
ClearScreen(RGB(128,128,128))
Delay(1)

Until KeyboardPushed(#PB_Key_Escape)

      EndIf
    EndIf
  EndIf
End 

le TransparentSpriteColor(#Spr,0) provoque une fuite mémoire colossale
Dans la precedente version je ne m'en été pas apperçu car le noir était transparent par défaut, maintenant ce n'est plus le cas

A+
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: sprite sous linux pb4.41

Message par G-Rom »

TransparentSpriteColor(#Spr,0) provoque une fuite mémoire colossale
j'ai constaté aucune fuite avec ton code avec SDL , en revanche , avec le subsystem OpenGL , bah , on à faire à un trou noir pour la ram du pc :mrgreen:
je confirme le bug.
Le subsystem OpenGL à un soucis de fuite , c'est sur , même en supprimant l'instruction concerné , on constate une autre petite fuite , mais d'ou ??
Scrat
Messages : 86
Inscription : sam. 15/mars/2008 16:00

Re: sprite sous linux pb4.41

Message par Scrat »

Bon ben je vais laisser bosser Fred
Je testerai la 4.50

A+
Edit :
Tant qu'on y est des fois que Fred passe par là
Essayer de permuter

Code : Tout sélectionner

ExamineMouse()
ExamineKeyboard()
par

Code : Tout sélectionner

ExamineKeyboard()
ExamineMouse()
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: sprite sous linux pb4.41

Message par G-Rom »

Fred est déjà au courant pour le keyboard() & mouse()
si tu as des soucis avec le clavier ( touche fléché par reconnue par ex ) utilise la commande KeyboardMode(#???International)
Répondre