IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Existence d'une fonction pour renverser une image


Sujet :

SDL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 140
    Points
    140
    Par défaut Existence d'une fonction pour renverser une image
    Bonjour,

    J'aurais aimé savoir si il existait quelque part dans l'api SDL, ou autre une fonction qui permettait de renverser une image.

    J'aurais aimé savoir si cela était conseillé dans le cas d'un jeu, pour ne pas doubler les desssins d'animation.

    Merci

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Non, et le faire en temps réel sera énormément lent. Donc préfère toujours utiliser plus de mémoire plutôt que sacrifier les perfs de ton appli.

    Par contre tu peux très bien générer avec une fonction très simple ces sprites retournés, mais seulement au chargement. Ca t'évitera de le faire à la main avec Toshop.

    Par contre je sais qu'il existe des bibliothèques SDL qui optimisent certaines opérations de ce genre, peut-être proposent-elles un effet miroir un peu moins coûteux.

    Voir la FAQ pour quelques liens.

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Drannor
    Bonjour,

    J'aurais aimé savoir si il existait quelque part dans l'api SDL, ou autre une fonction qui permettait de renverser une image.
    Ben si tu utilises OpenGL, tu n'en aurais pas besoin... Lors du dessin du quad, il suffirait d'inverser quelques coordoonnées.

    Mais en SDL pur, il faudra le faire à la main...

  4. #4
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Laurent Gomila
    Par contre je sais qu'il existe des bibliothèques SDL qui optimisent certaines opérations de ce genre, peut-être proposent-elles un effet miroir un peu moins coûteux.
    Non, pas que je sache, on peut faire des rotations et des zooms, mais c'est tout...

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 140
    Points
    140
    Par défaut
    Merci beaucoup
    Mais j'ai aps encore appris OpenGl, je m'y mettrais bientot. Pour le moment mon moteur est en C++/SDL et exclusivement reservé à la 2D.

    ps : j'ai une derniere question lorsque l'on met en plein écran, comment peut-on connaiître la resolution de l'écran ?

    Pour être plus precis j'aurais aimé savoir si quand on donne à SDL_SetVideoMode une résolution, lorsqu'on le met en plein écran, cette résolution est toujours conservé.

    Merci

  6. #6
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Voici le code qui permet de faire un flip vertical...

    Comme l'a fait remarquer Laurent, c'est à faire au moment du chargement pas dans la boucle qui s'occupe du rendu...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    SDL_Surface *MonFlipV(SDL_Surface *im)
    {
            SDL_Surface *res;
            int i,j,src,dest;
     
            int bytesperpix;
            unsigned char *srcpixels, *destpixels;
     
            if(im==NULL)
                    return NULL;
     
            bytesperpix = im->format->BytesPerPixel;
     
            // Creation d'une surface de meme taille
            res = SDL_CreateRGBSurface(SDL_HWSURFACE, im->w, im->h, im->format->BitsPerPixel,
                            im->format->Rmask, im->format->Gmask, im->format->Bmask, im->format->Amask);
     
            if(res == NULL)
                    return NULL;
     
            // Maintenant on inverse les pixels
            srcpixels = (unsigned char*) im->pixels;
            destpixels = (unsigned char*) res->pixels;
     
            for(i=0;i<im->h;i++)
                    for(j=0;j<im->w;j++)
                    {
                            src = getPixel(i,j,im->w,bytesperpix);
                            dest = getPixel(im->h-1-i,j,im->w,bytesperpix);
     
                            destpixels[dest] = srcpixels[src];
                            dest++;src++;
     
                            destpixels[dest] = srcpixels[src];
                            dest++;src++;
     
                            destpixels[dest] = srcpixels[src];
                            dest++;src++;
     
                            if(bytesperpix==4)
                                    {
                                    destpixels[dest] = srcpixels[src];
                                    dest++;src++;
                                    }
                    }
            return res;
    }
    Cette fonction utilise une fonction inline :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inline int getPixel(int i, int j, int w, int bytesperPix)
    {
            return (i*w + j)*bytesperPix;
    }
    Enfin, j'attache un petit programme qui fait aussi le flip horizontal...

    Poses des questions si tu ne comprends pas...
    Jc
    Fichiers attachés Fichiers attachés

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Cool, tu peux peut-être le poster sur le forum contribuez pour les pages Sources ?

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 140
    Points
    140
    Par défaut
    Y'a une chose que j'ai du mal a comprendre c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Maintenant on inverse les pixels
            srcpixels = (unsigned char*) im->pixels;
            destpixels = (unsigned char*) res->pixels;
    Je comprend pas trop à quoi cela sert et pourquoi on le cast.


    Par contre c'est impressionnant comment tu réalises ça en usant de toutes les fonctions SDL, la moitié des arguments se trouvant dans la structure surface me sont inconnus.
    *me sens newb snif*

    D'ailleurs je me demandais comment acceder à la matrice que contient SDl_Surface pour les recopiers dans une nouvelle mais à l'envers. Mais je vois qu'en faites il fallait utiliser SDL-getPixel();

    Merci pour ce code.

    ps je la repose : j'ai une derniere question lorsque l'on met en plein écran, comment peut-on connaiître la resolution de l'écran ?

    Pour être plus precis j'aurais aimé savoir si quand on donne à SDL_SetVideoMode une résolution, lorsqu'on le met en plein écran, cette résolution est toujours conservé.

    Merci

  9. #9
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Drannor
    Y'a une chose que j'ai du mal a comprendre c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // Maintenant on inverse les pixels
            srcpixels = (unsigned char*) im->pixels;
            destpixels = (unsigned char*) res->pixels;
    Je comprend pas trop à quoi cela sert et pourquoi on le cast.
    En fait, le tableau de pixel est en void * et pour faire le passage à des unsigned char, il faut passer par un transtypage (pas en C pur)...

    Par contre c'est impressionnant comment tu réalises ça en usant de toutes les fonctions SDL, la moitié des arguments se trouvant dans la structure surface me sont inconnus.
    J'ai simplement regardé la documentation et le fichier SDL_video.h...

    *me sens newb snif*
    On est tous passé par là

    D'ailleurs je me demandais comment acceder à la matrice que contient SDl_Surface pour les recopiers dans une nouvelle mais à l'envers. Mais je vois qu'en faites il fallait utiliser SDL-getPixel();
    Pas obligatoire, mais c'est plus simple...

    Merci pour ce code.
    De rien!

    ps je la repose : j'ai une derniere question lorsque l'on met en plein écran, comment peut-on connaiître la resolution de l'écran ?

    Pour être plus precis j'aurais aimé savoir si quand on donne à SDL_SetVideoMode une résolution, lorsqu'on le met en plein écran, cette résolution est toujours conservé.
    Tu peux utiliser les champs w et h de la surface rendue par SDL_SetVideoMode, et oui cette résolution sera conservée (si possible bien sûr).

    Jc

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 140
    Points
    140
    Par défaut
    Merci encore beaucoup
    Je pensais que la teableau de pixel était un int* c'est pour cette raison que je comprenais pas le unsigned char

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 140
    Points
    140
    Par défaut
    Hmm j'ai une mauvaise nouvelle, il semblerait qu'il y ait un bug dans le code du mirror.
    Enfin à confirmer mais je l'ai testé avec une photo couleur bmp de 150*150 et là ça rend pas le même résultat que le G.
    J'ai essayé de chercher mais je vois pas ce qu'il cloche.

    Pour le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
     
    /*
     * Fichier de base pour ouvrir une fenetre SDL, si l'utilisateur appuie sur 'q', on quitte le programme
     */
     
    #include <SDL.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
     
    #define WIDTH 300
    #define HEIGHT 300 
     
    inline int getPixel(int i, int j, int w, int bytesperPix)
    {
    	return (i*w + j)*bytesperPix;
    }
     
     
    SDL_Surface *MonFlipV(SDL_Surface *im)
    {
    	SDL_Surface *res;
    	int i,j,src,dest;
     
    	int bytesperpix;
    	unsigned char *srcpixels, *destpixels;
     
    	if(im==NULL)
    		return NULL;
     
           	bytesperpix = im->format->BytesPerPixel;
     
    	// Creation d'une surface de meme taille 
    	res = SDL_CreateRGBSurface(SDL_HWSURFACE, im->w, im->h, im->format->BitsPerPixel,
    			im->format->Rmask, im->format->Gmask, im->format->Bmask, im->format->Amask);
     
    	if(res == NULL)
    		return NULL;
     
    	// Maintenant on inverse les pixels 
    	srcpixels = (unsigned char*) im->pixels;
    	destpixels = (unsigned char*) res->pixels;
     
    	for(i=0;i<im->h;i++)	
    		for(j=0;j<im->w;j++)
    		{
    			src = getPixel(i,j,im->w,bytesperpix);
    			dest = getPixel(im->h-1-i,j,im->w,bytesperpix);
     
    			destpixels[dest] = srcpixels[src];
    			dest++;src++;
     
    			destpixels[dest] = srcpixels[src];
    			dest++;src++;
     
    			destpixels[dest] = srcpixels[src];
    			dest++;src++;
     
    			if(bytesperpix==4)
    				{
    				destpixels[dest] = srcpixels[src];
    				dest++;src++;
    				}
    		}
    	return res;
    }
     
    SDL_Surface *MonFlipH(SDL_Surface *im)
    {
    	SDL_Surface *res;
    	int i,j,src,dest;
     
    	int bytesperpix;
    	unsigned char *srcpixels, *destpixels;
     
    	if(im==NULL)
    		return NULL;
     
           	bytesperpix = im->format->BytesPerPixel;
     
    	// Creation d'une surface de meme taille 
    	res = SDL_CreateRGBSurface(SDL_HWSURFACE, im->w, im->h, im->format->BitsPerPixel,
    			im->format->Rmask, im->format->Gmask, im->format->Bmask, im->format->Amask);
     
    	if(res == NULL)
    		return NULL;
     
    	// Maintenant on inverse les pixels 
    	srcpixels = (unsigned char*) im->pixels;
    	destpixels = (unsigned char*) res->pixels;
     
    	for(i=0;i<im->h;i++)	
    		for(j=0;j<im->w;j++)
    		{
    			src = getPixel(i,j,im->w,bytesperpix);
    			dest = getPixel(i,im->w-1-j,im->w,bytesperpix);
     
    			destpixels[dest] = srcpixels[src];
    			dest++;src++;
     
    			destpixels[dest] = srcpixels[src];
    			dest++;src++;
     
    			destpixels[dest] = srcpixels[src];
    			dest++;src++;
     
    			if(bytesperpix==4)
    				{
    				destpixels[dest] = srcpixels[src];
    				dest++;src++;
    				}
    		}
    	return res;
    }
     
    int main()
    {
        SDL_Event event;
        SDL_Surface *screen,*image[4];
        int done = 0;
        int lequel;
        SDL_Rect rect;   
        //Initialisation
        if(SDL_Init(SDL_INIT_VIDEO)!=0) {
    	printf("Probleme pour initialiser SDL: %s",SDL_GetError());
    	return EXIT_FAILURE;
        }
     
        //Mettre un titre �la fen�re
        SDL_WM_SetCaption("Images Version 1.0", NULL);
     
        //Ouvrir une fenetre
        screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
        if(screen==NULL)
          	done = 1;
     
        // Chargement de l'image et creation des 3 autres
        image[0] = SDL_LoadBMP("tata.bmp");
        image[1] = MonFlipV(image[0]);
        image[2] = MonFlipH(image[0]);
        image[3] = MonFlipH(image[1]);
     
        if((image[0] == NULL) || (image[1] == NULL) || (image[2] == NULL) || (image[3] == NULL))
        {
    	    printf("Erreur dans le chargement et le flip des images\n");
    	    return EXIT_FAILURE;
        }
     
        //Boucle generale
        while(!done)
        {
            //Traiter les evenements
    	while(SDL_PollEvent(&event))
    	{
    		switch(event.type)
    		{
    			case SDL_QUIT:
    				done=1;
    				break;
      			case SDL_KEYUP:
    				if(event.key.keysym.sym==SDLK_q)
    					done=1;
    				break;
    			default:
    				break;
    		}
    	}
     
        // Affichage 
        // On remet �z�o
        SDL_FillRect(screen,NULL,0);
        for(int i=0;i<2;i++)
    	    for(int j=0;j<2;j++)
    	    {
    		    lequel = 2*i+j ; //lequel prendra les valeurs : 0,1,2,3
        		    rect.x = j*image[lequel]->w;
    		    rect.y = i*image[lequel]->h;
     
    		    SDL_BlitSurface(image[lequel],NULL,screen,&rect);
    	    }
        SDL_Flip(screen);
        }
     
        for(int k=0;k<4;k++)
    	    SDL_FreeSurface(image[k]);
     
        SDL_FreeSurface(screen);
        SDL_Quit();
        return EXIT_SUCCESS;
    }
    C'est le même sauf que la resolution est de 300*300 et qu'il prend le fichier tata.bmp
    J'ai testé avec d'autres images toutes en bmp, si elles sont petites ça passe et dès qu'elles sont assez conséquentes le bug apparait.

  12. #12
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    C'est ma faute, j'ai oublié le pitch dans le calcul et ce n'est qu'en regardant la réponse à cette question

    http://jeux.developpez.com/faq/sdl/?...odifier_pixels

    que j'ai compris que la fonction getPixel devait se définir comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inline int getPixel(int i, int j, int bytesperPix, int pitch)
    {
    	return i*pitch + j*bytesperPix;
    }
    Remarque j'ai changé le prototype de la fonction, on passe la surface en paramètre, les appels deviennent donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    src = getPixel(im,i,j,bytesperpix, im->pitch);
    dest = getPixel(im,im->h-1-i,j,bytesperpix, im->pitch);
    Cela fonctionne chez moi,
    Jc

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Points : 140
    Points
    140
    Par défaut
    Merci je vais tester

    edit : merci ça marche impec sauf que j'ai enlevé la surface vu que ton getPixel ne la prend pas en paramètre.

    Si quelqu'un passe un jour lire ce code :

    Pour flipV :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    src = getPixel(im,i,j,bytesperpix, im->pitch);
    dest = getPixel(im,im->h-1-i,j,bytesperpix, im->pitch);
    Pour flipH:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    src = getPixel(im,i,j,bytesperpix, im->pitch);
    dest = getPixel(im,i,im->w-1-i,bytesperpix, im->pitch);

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/10/2008, 21h05
  2. Réponses: 2
    Dernier message: 13/04/2007, 02h22
  3. Existe t il une fonction pour effacer une page
    Par teen6517 dans le forum Langage
    Réponses: 4
    Dernier message: 26/02/2007, 14h20
  4. Réponses: 8
    Dernier message: 02/12/2005, 18h07
  5. Utiliser une touche pour appeller une fonction
    Par Hide dans le forum Langage
    Réponses: 2
    Dernier message: 13/10/2005, 16h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo