:: PlayerAdvance.org ::  

Précédent   :: PlayerAdvance.org :: > :: Forums Hébergés :: > OldSchool Library > Aide au développement

Aide au développement Aide sur l'utilisation d'OSLib

Publicité

Réponse
 
Outils de la discussion Modes d'affichage
Vieux 14/02/2007, 06h13   #1
ninjaglowskulls
 
Messages: n/a
Par défaut draw images on images

I'm using OSL to make a basic 2d game. My character is built by using different peices, ie. one Image for the head, one image for the torso, etc. When I draw to the screen, I want to draw all the smaller images onto I big image. This way, when I change direction, I only have to mirror the big image, instead of mirroring each image, then moving the front and back arms to match the new torso.

Anyway, When I draw the images onto the new one, nothing shows up.
Code:
//the big image
charc = oslCreateImage(53, 83, OSL_IN_VRAM, OSL_PF_8888); 
//.  while loop, etc.
//.
//.
oslStartDrawing();
oslSetDrawBuffer(charc);

//a function to draw each of the pieces
//basically an oslDrawImage(bodyPart) for each peice
mainChar->drawCharacter();
oslSetDrawBuffer(OSL_DEFAULT_BUFFER);
oslDrawImage(charc);
oslEndDrawing();
now, if I load an image from a file (for charc), then clear it with a colour, drawing my smaller images seems to work fine...the only problem is that I now have a red rectangle (red was the colour I used) behing my character. Is there a way to initialize my main image with transparent pixels, so that I can draw my other pictures on top of it?

PS sorry about the long post
  Réponse avec citation

Publicité

Vieux 15/02/2007, 00h22   #2
Yodajr
Administrateur
 
Date d'inscription: 09/11/2005
Messages: 3 750
Par défaut

I don't know if I understand...
But if you want to make a color transparent, it's like that :

Code PHP:
oslSetTransparentColor(RGB(255,0,255)); //pink color

image oslLoadImageFile("image.png"OSL_IN_RAMOSL_PF_5551); //each pink pixel in this image will be transparent

oslDisableTransparentColor(); 
Don't be sorry, you can even post screenshoot for better explanation of your problem
Yodajr est déconnecté   Réponse avec citation
Vieux 15/02/2007, 05h10   #3
ninjaglowskulls
 
Messages: n/a
Par défaut

the code in my first post doesn't work. Basically all the pixels in the "charc" image are transparent, and when I try to draw to it with another image, all my new pixels are transparent as well. So there is nothing on the screen.

I used:
oslClearImage(charc, RGB(128,0,128)); //pink colour
oslSetTransparentColour(RGB128,0,128);

and it kinda did what I was looking for. The only problem is that on my original PNG file, there are semi-transparent pixels, so everything gets drawn with a pinkish border. What I was wondering, is there a way to initialize my "charc" image, without using a colour, and draw my other images on to it.
Could I set the oslSetAlpha(int, int) function to one of the flags, and draw it that way? And If so which one should I use?

This is my only problem, and it's been bugging me for about 3 days now. grrr. The worst part is, I'm just being and don't want to do the math to re-align everything everytime my picture changes direction.
  Réponse avec citation
Vieux 15/02/2007, 05h43   #4
Yodajr
Administrateur
 
Date d'inscription: 09/11/2005
Messages: 3 750
Par défaut

Sorry, I don't understand what you want to do.
So please try to explain to me what you want with images and code...
Or wait Brunni, maybe he will be able to help you.
Yodajr est déconnecté   Réponse avec citation
Vieux 04/06/2007, 16h17   #5
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

Citation:
Envoyé par ninjaglowskulls Voir le message
the code in my first post doesn't work. Basically all the pixels in the "charc" image are transparent, and when I try to draw to it with another image, all my new pixels are transparent as well. So there is nothing on the screen.

I used:
oslClearImage(charc, RGB(128,0,128)); //pink colour
oslSetTransparentColour(RGB128,0,128);

and it kinda did what I was looking for. The only problem is that on my original PNG file, there are semi-transparent pixels, so everything gets drawn with a pinkish border. What I was wondering, is there a way to initialize my "charc" image, without using a colour, and draw my other images on to it.
Could I set the oslSetAlpha(int, int) function to one of the flags, and draw it that way? And If so which one should I use?
I have never tried, but I would say that when you draw ON charc, which is pink, you should use oslSetAlpha(OSL_FX_NONE, 0); 2nd param is not used I think. So you'll have on charc only plain pink pixels, or the others, but no pinkish pixels.

Also isn't that possible:
Code:
oslClearImage(charc, RGB(0,0,0,0)); //transparent
//oslSetTransparentColour(RGB(0,0,0)); //not needed as it is already transparent
I haven't tried "complex" drawing like this so it's just a guess.
daaa57150 est déconnecté   Réponse avec citation
Vieux 04/06/2007, 17h25   #6
Brunni
Super Modérateur
 
Date d'inscription: 10/11/2005
Localisation: Un pays avec beaucoup de banques
Messages: 3 225
Par défaut

Citation:
Envoyé par ninjaglowskulls Voir le message
the code in my first post doesn't work. Basically all the pixels in the "charc" image are transparent, and when I try to draw to it with another image, all my new pixels are transparent as well. So there is nothing on the screen.

I used:
oslClearImage(charc, RGB(128,0,128)); //pink colour
oslSetTransparentColour(RGB128,0,128);

and it kinda did what I was looking for. The only problem is that on my original PNG file, there are semi-transparent pixels, so everything gets drawn with a pinkish border. What I was wondering, is there a way to initialize my "charc" image, without using a colour, and draw my other images on to it.
Could I set the oslSetAlpha(int, int) function to one of the flags, and draw it that way? And If so which one should I use?

This is my only problem, and it's been bugging me for about 3 days now. grrr. The worst part is, I'm just being and don't want to do the math to re-align everything everytime my picture changes direction.
This has really been a big problem for me when designing OSLib, because it's a limitation from the hardware and this behaviour seems not very logical. Basically the hardware will write red, green and blue components to the current drawbuffer, but won't write the alpha channel.
In the version 2.0 there's an experimental function that would allow you to do it, search in the documentation in the Images, Drawbuffers section, you may be able to do what you want with alpha testing and alpha write (which is basically a tricky method using the fact that the stencil buffer is shared with the alpha buffer on PSP; it won't work on the PC version btw).
Brunni est déconnecté   Réponse avec citation
Vieux 13/01/2008, 16h05   #7
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

I managed to draw an image on another with that function, which doesn't use the oslSetDrawBuffer things.
It works for me for the moment, I haven't tested more than that so it may not work for some images, I don't know..

Spoiler

So this function draws the part starting at (srcX, srcY) and sized (width, height) from image src to image dest at the point (destX, destY)

I suppose it doesn't use the GU so it's not meant to be used every frame.

edit: the code was awful it worked only when things didn't overlap so I changed it with the one you see now, that takes transparent pixels into account; but if alpha>0 the pixel replaces the old one. still bad but a bit better.
I think I know how to do it perfectly I'll test it when I've time.
__________________
Essayez mon dernier jeu sur iPhone:


Dernière modification par daaa57150 ; 15/01/2008 à 12h23.
daaa57150 est déconnecté   Réponse avec citation
Vieux 14/01/2008, 17h24   #8
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

Voilà je me suis penché sur la question d'un peu plus près et la bonne fonction est la suivante:
Spoiler

C'est vraiment pas optimisé mais ca fonctionne vraiment bien, j'ai testé sur des images et le résultat est chouette. Je sais pas si c'est totalement parfait puisque les formules sont de moi, mais c'est déjà mieux que rien.
Et attention c'est vraiment lent, donc c'est bien pour préparer des images en mémoire mais si c'est utilisé chaque frame la PSP va souffrir

Si quelqu'un veut optimiser le bordel, allez-y perso elle me satisfait comme elle est cette fonction.

edit: ooops je suis repassé en français... tant pis
__________________
Essayez mon dernier jeu sur iPhone:


Dernière modification par daaa57150 ; 15/01/2008 à 12h23.
daaa57150 est déconnecté   Réponse avec citation
Vieux 15/01/2008, 11h01   #9
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

Allez, dernière version de cette fonction (la précédente est fausse finalement):
Spoiler


J'espère que ca servira à quelqu'un quand même, j'ai un peu l'impression d'être tout seul ici
Et quelqu'un peut me dire comment on met des balises spoil histoire de cacher les fonctions précédentes?
__________________
Essayez mon dernier jeu sur iPhone:


Dernière modification par daaa57150 ; 18/07/2008 à 19h23.
daaa57150 est déconnecté   Réponse avec citation
Vieux 15/01/2008, 11h47   #10
Brunni
Super Modérateur
 
Date d'inscription: 10/11/2005
Localisation: Un pays avec beaucoup de banques
Messages: 3 225
Par défaut

Spoiler

Sisi on passe mais on poste pas forcément merci de nous faire partager ton code
Brunni est déconnecté   Réponse avec citation
Vieux 15/01/2008, 12h56   #11
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

Citation:
Envoyé par Brunni Voir le message
Spoiler
c'etait donc une balise "spoiler" et non "spoil" merci.
__________________
Essayez mon dernier jeu sur iPhone:

daaa57150 est déconnecté   Réponse avec citation
Vieux 15/01/2008, 14h53   #12
Yodajr
Administrateur
 
Date d'inscription: 09/11/2005
Messages: 3 750
Par défaut

C'est vrai, c'est pas cool de passer sans poster, donc merci
Yodajr est déconnecté   Réponse avec citation
Vieux 15/01/2008, 15h03   #13
Dr.Vince
Administrateur
 
Date d'inscription: 10/11/2005
Messages: 4 962
Voir les codes amis Nintendo DS Voir les codes amis Wii
Par défaut

bah faut pas oublier aussi que le topic est vu par pas mal d'invités, donc ce n'est pas inutile
__________________
Projets Abandonnés: [Arcomage Advance] [Puzznic] [PA Card Games] [Blob Runner]
Projet en cours: [Ne plus abandonner de projet...]
Dr.Vince est déconnecté   Réponse avec citation
Vieux 15/01/2008, 16h16   #14
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

haha merci chers membres du staff, je me sens moins seul d'un coup
__________________
Essayez mon dernier jeu sur iPhone:

daaa57150 est déconnecté   Réponse avec citation
Vieux 18/07/2008, 19h30   #15
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

Finalement c'était encore faux, j'en ai eu besoin quelque part et tout etait un peu translucide, ce que j'ai corrigé comme cela:

Code PHP:
void utils::drawImageOnImage(OSL_IMAGE *srcint srcXint srcYint widthint heightOSL_IMAGE *destint destXint destY)
{
    
oslLockImage(src);
    
oslLockImage(dest);
    for(
int x=0x<widthx++)
    {
        for(
int y=0y<heighty++)
        {
            
int putX=destX+x;
            
int putY=destY+y;
            if(
putX<dest->sizeX && putY<dest->sizeY)
            {
                
int getX=srcX+x;
                
int getY=srcY+y;
                
                
int pixeldest=oslGetImagePixel(destputXputY);
                
int pixel8888dest=oslConvertColorEx(dest->paletteOSL_PF_8888dest->pixelFormatpixeldest);
                
                
int drdgdbda//d: dest
                
oslRgbaGet8888(pixel8888destdrdgdbda);
                
float fdr=float(dr);
                
float fdg=float(dg);
                
float fdb=float(db);
                
float fda=float(da);
                
                
int pixelsrc=oslGetImagePixel(srcgetXgetY);
                
int pixel8888src=oslConvertColorEx(src->paletteOSL_PF_8888src->pixelFormatpixelsrc);
                
int srsgsbsa//s: src
                
oslRgbaGet8888(pixel8888srcsrsgsbsa);
                
float fsr=float(sr);
                
float fsg=float(sg);
                
float fsb=float(sb);
                
float fsa=float(sa);
                
                
float a_sum=fsa+fda//somme des alphas
                                        
                
int pixel8888result;
                if(
a_sum>0)
                {
                    
float da_left=255.0f-fsa//alpha left
                    
                    
int rrrgrbra//r: result
                    
                    
rr=int((fdr*da_left fsr*fsa)/255.0f);
                    
rg=int((fdg*da_left fsg*fsa)/255.0f);
                    
rb=int((fdb*da_left fsb*fsa)/255.0f);
                    
ra=int(fsa + (da_left*fda)/255.0f);
                    
pixel8888result=RGBA(rr,rg,rb,ra);
                }
                else
                {
                    
pixel8888result=RGBA(0,0,0,0);
                }
                
                
int pixelresult oslConvertColorEx(dest->palettedest->pixelFormatOSL_PF_8888pixel8888result);
                
                
oslSetImagePixel(destputXputYpixelresult);
            }
        }
    }
    
oslUnlockImage(dest);
    
oslUnlockImage(src);

j'en profite pour partager une fonction de copie du buffer parce que c'est super chiant (soit ca dessine pas, soit l'alpha n'est pas pris en compte, super pénible!!):
Code PHP:
OSL_IMAGE *utils::getBufferCopy()
{
    
OSL_IMAGE *pixelcopy=oslCreateImage(480272OSL_IN_RAMOSL_PF_8888);
    
oslLockImage(OSL_DEFAULT_BUFFER);
    for(
int i=0;i<480;i++)
    {
        for(
int j=0;j<272;j++)
        {
            
int pixelsrc=oslGetImagePixel(OSL_DEFAULT_BUFFERij);
            
int pixel8888src=oslConvertColorEx(OSL_DEFAULT_BUFFER->paletteOSL_PF_8888OSL_DEFAULT_BUFFER->pixelFormatpixelsrc);
            
int rgba;
            
oslRgbaGet8888(pixel8888srcrgba);
            
int pixel8888result=RGBA(r,g,b,255);
            
            
oslSetImagePixel(pixelcopyijpixel8888result);
        }
    }
    
oslUnlockImage(OSL_DEFAULT_BUFFER);
    
    return 
pixelcopy;

l'image sera forcément en mode 8888 à la sortie mais la base est là. comme l'autre fonction celle ci est un peu lente mais si c'est pour l'exécuter 1x c'est suffisant.
__________________
Essayez mon dernier jeu sur iPhone:

daaa57150 est déconnecté   Réponse avec citation
Vieux 19/07/2008, 05h18   #16
Nesgba
Membre confirmé
 
Date d'inscription: 10/11/2005
Messages: 830
Par défaut

un trop grand nombre de flottants/divisions sur ce topic à eu un effet trop attractif pour que je puisse y résister

Code PHP:
void drawSprite_RGBA32(unsigned long *pdstunsigned long *psrclong xlong ylong srcwidthlong srcheightlong dstwidthlong dstheight){
long r0,g0,b0,a0r1,g1,b1,a1 ;
long srcoff,dstoff ;

pdst  += (y*dstwidth)+;
dstoff dstwidth-srcwidth ;

while(
srcheight-->0){
srcwidth ;

while(
x-->0){
a0 = *psrc ;
r0 = (a0)&0xff ;
g0 = (a0>>8)&0xff ;
b0 = (a0>>16)&0xff ;
a0 255-((a0>>24)&0xff) ;

a1 = *pdst ;
r1 = (a1)&0xff ;
g1 = (a1>>8)&0xff ;
b1 = (a1>>16)&0xff ;
a1 = (a1>>24)&0xff ;

// fusionne les composantes
*pdst = ( r0 + (a0*(r1-r0)>>8) )
      | ( 
g0 + (a0*(g1-g0)>>8) )<<8
      
| ( b0 + (a0*(b1-b0)>>8) )<<16
      
| ( (255-a0) + (a0*(a1-(255-a0))>>8) )<<24 ;

psrc++ ;
pdst++ ;
}

pdst += dstoff ;
}


c'est du code générique donc il faut l'appeller d'une manière particulière, pour OSlib j'imagine que ça dois être un truc dans ce genre là:

Code PHP:
oslLockImage(src) ;
oslLockImage(dest) ;

drawSprite_RGBA32(dest->data,src->data0,0src->sizeX,src->sizeYdest->sizeX,dest->sizeY) ;

oslUnlockImage(src) ;
oslUnlockImage(dest) ; 
ça gère ni le clipping ni le stockage de pixels en mode swizzle...
Nesgba est déconnecté   Réponse avec citation
Vieux 19/07/2008, 11h45   #17
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

La pêche au Nesgba a été bonne
Merci pour tes optimisations je les ai intégrées à ma fonction pour avoir un compromis (pour gérer le swizzle entre autres) et ça marche très bien.
Tu peux juste m'expliquer pourquoi &0xff dans tes extractions de composantes? Brunni le fait aussi dans sa macro:
#define oslRgbaGet8888(data, r, g, b, a) ((r)=((data)&0xff), (g)=(((data)>>8)&0xff), (b)=(((data)>>16)&0xff), (a)=(((data)>>24)&0xff))
Pour ce qui est de la performance des fonctions, j'ai pas testé mais il va de soi que la mienne était vachement + lente
__________________
Essayez mon dernier jeu sur iPhone:

daaa57150 est déconnecté   Réponse avec citation
Vieux 19/07/2008, 18h28   #18
Nesgba
Membre confirmé
 
Date d'inscription: 10/11/2005
Messages: 830
Par défaut

Citation:
Envoyé par daaa57150 Voir le message
La pêche au Nesgba a été bonne
Merci pour tes optimisations je les ai intégrées à ma fonction pour avoir un compromis (pour gérer le swizzle entre autres) et ça marche très bien.
Tu peux juste m'expliquer pourquoi &0xff dans tes extractions de composantes? Brunni le fait aussi dans sa macro:
#define oslRgbaGet8888(data, r, g, b, a) ((r)=((data)&0xff), (g)=(((data)>>8)&0xff), (b)=(((data)>>16)&0xff), (a)=(((data)>>24)&0xff))
Pour ce qui est de la performance des fonctions, j'ai pas testé mais il va de soi que la mienne était vachement + lente
re,
0xff(hexa) est en fait un masque qui conserve les 8 bits de poid faible (les 8 premiers), après pour chaque composante il faut décaler pour y accéder.
Code PHP:
a1 = *pdst ;
r1 = (a1)&0xff ;
g1 = (a1>>8)&0xff ;
b1 = (a1>>16)&0xff ;
a1 = (a1>>24)&0xff // masque obligatoire ici aussi 
on peut aussi préférer décaler le masque d'abort, mais généralement le compillo le ferra de lui même si c'est préférable en terme d'optimisation. (puis c'est plus long à tapper ;p)
Code PHP:
a1 = *pdst ;
r1 = (a1&0xff) ;
g1 = (a1&0xff00)>>;
b1 = (a1&0xff0000)>>16 ;
a1 = (a1&0xff000000)>>24 
Nesgba est déconnecté   Réponse avec citation
Vieux 20/07/2008, 09h55   #19
daaa57150
Membre confirmé
 
Date d'inscription: 16/05/2007
Messages: 411
Voir l'identifiant PSN
Par défaut

merci, j'ai pigé maintenant
__________________
Essayez mon dernier jeu sur iPhone:

daaa57150 est déconnecté   Réponse avec citation
Réponse

Liens sociaux

Publicité



Utilisateurs regardant la discussion actuelle : 1 (0 membre(s) et 1 invité(s))
 
Outils de la discussion
Modes d'affichage

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 18h54.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Tous droits réservés.
Version française #16 par l'association vBulletin francophone
Design par Ass-Itch, DJP et Dr.Vince