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 :

Changer opacité d'une surface Blended (ex problème)


Sujet :

SDL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut Changer opacité d'une surface Blended (ex problème)
    Bonjour,
    voilà, j'ai un problème et pas la solution

    J'ai des SDL_Surfaces* chargés par la fonction TTF_RenderText_Blended et je veux faire des dégradés avec, donc je change leurs opacités entre 0 et 255.
    Le problème est que la fonction pour l'opacité SDL_SetAlpha ne fonctionne pas avec les surfaces chargés avec TTF.

    Donc étant un novice de la SDL, je sais pas si l'on peut convertir la surface ou autre pour pouvoir gerer l'opacité.

    Merci à ceux qui me répondront

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 104
    Par défaut
    Salut, a mon avis il faut que tu vois de ce côté ci

    Avec la source de Jean Christophe Beyler sur la Gestion de texte OpenGL.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut
    Merci pour le lien mais enfaite je viens de coder une petite partie qui me permet de faire des dégradés (positifs ou négatifs) à volonté sur des surfaces sdl chargés par le mode TTF Blended.

    Pour ceux qui veulent (et surtout qui arrive à me relire vu que j'ai coder ça vite en commentant juste l'essentiel pour moi, mais si vous voulez des explications ou des commentaires sur le code, dites le moi).

    Le fichier d'en tête :
    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
     
     
    #ifndef H_PIXELS_MANIP
    #define H_PIXELS_MANIP
     
    #include <SDL/SDL.h>
     
    /* Cette classe est caché à l'utilisateur, elle intervient juste dans le
    fonctionnement de la classe SurfTextBlended */
    class PixelTextBlended {
     
        public:
        PixelTextBlended();
     
        void initialiser(unsigned int x, unsigned y, Uint8 r, Uint8 v, Uint8 b, Uint8 a,
                                                                        double q);
     
        unsigned int getX();
        unsigned int getY();
        Uint8 getR();       /* Rq : RVB st tjr les mêmes en mode Blended */
        Uint8 getV();       /* juste alpha change, c'est pourquoi la fonction */
        Uint8 getB();       /* SDL générique ne marche pas */
        double getQ();
     
        private:
        unsigned int _x, _y;
        Uint8 _R, _V, _B, _A;
     
        /* _quotient est tout l'interet de cette classe, il conserve les proportions
        de l'alpha de la figure original */
        double _quotient;
    };
     
     
    class SurfTextBlended {
     
        public:
        SurfTextBlended();
        ~SurfTextBlended();
     
        /* Initialise le tableau de pixels */
        void initialiser(unsigned int nb_e);
     
        /* Initialise la liste des pixels et met ts les pixels à l'alpha alphaDepart */
        void tarrage(SDL_Surface* src, Uint8 alphaDepart);
     
        /* change l'Alpha de la surface */
        void changerAlpha(SDL_Surface* src, Uint8 alphaDelta);
     
        private:
        unsigned int _nb_elements; /* Pour créer le tableau _pixels */
        PixelTextBlended* _pixels;
     
    };
     
    /*
     * Return the pixel value at (x, y)
     * NOTE: The surface must be locked before calling this!
     */
    Uint32 getpixel(SDL_Surface *surface, int x, int y);
     
    /*
     * Set the pixel at (x, y) to the given value
     * NOTE: The surface must be locked before calling this!
     */
    void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
     
    #endif
    Le fichier .cpp
    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
    191
    192
    193
    194
    195
    196
     
    #include "pixels_manip.h"
     
    /**
        Classe SurfTextBlended
    */
    SurfTextBlended::SurfTextBlended() : _nb_elements(0), _pixels(NULL) { }
     
    /* On libère le tableau en fonction de ce qu'il a alloué */
    SurfTextBlended::~SurfTextBlended()
    {
        if(_nb_elements > 1)
        delete[] _pixels;
        else
        delete _pixels;
    }
     
    /* Alloue nb_e pixels */
    void SurfTextBlended::initialiser(unsigned int nb_e)
    {
        _nb_elements = nb_e;
        _pixels = new PixelTextBlended[nb_e];
    }
     
    /*
        Initialise la liste des pixels de la classe et met ts les pixels de la
        surface envoyé à l'alpha alphaDepart (utile pour les dégradés)
    */
    void SurfTextBlended::tarrage(SDL_Surface* src, Uint8 alphaDepart)
    {
        if(src) {
            SDL_LockSurface(src);
     
            unsigned int x, y = {0};
            Uint32 pixel;
            Uint8 r, v, b, a;
            float q = 0;
     
            /* On compte les pixels ayant un alpha > 0 */
            for(x=0; x<src->w; x++) {
                for(y=0; y<src->h; y++) {
                    pixel=getpixel(src,x,y);
                    SDL_GetRGBA(pixel, src->format, &r, &v, &b, &a);
     
                    if(a > 0) { _nb_elements++; }
                }
            }
     
            _pixels = new PixelTextBlended[_nb_elements];
     
            /* On récupère les pixels ayant alpha > 0 et on met l'alpha de la surface
            entière = 0 */
            unsigned int listage = 0;
            for(x=0; x<src->w; x++) {
                for(y=0; y<src->h; y++) {
                    pixel=getpixel(src,x,y);
                    SDL_GetRGBA(pixel, src->format, &r, &v, &b, &a);
     
                    if(a > 0) {
                        q = (double) (100 * a)/255; // % de alpha
                        _pixels[listage].initialiser(x, y, r, v, b, a, q);
                        pixel=SDL_MapRGBA(src->format, r, v, b, alphaDepart);
                        putpixel(src, x, y, pixel);
                        listage++;
                    }
                }
            }
     
            SDL_UnlockSurface(src);
        }
    }
     
    /* change les alphas des pixels de la surface proportionnellement à ce qu'il
    était au départ */
    void SurfTextBlended::changerAlpha(SDL_Surface* src, Uint8 alphaDelta)
    {
        if(src) {
            SDL_LockSurface(src);
     
            Uint32 pixel;
            Uint8 r, v, b;
            unsigned int x, y = {0};
            Uint8 alphaFinal;
            double q;
     
            for(int i=0; i<_nb_elements; i++)
            {
                x = _pixels[i].getX();
                y = _pixels[i].getY();
                r = _pixels[i].getR();
                v = _pixels[i].getV();
                b = _pixels[i].getB();
                q = _pixels[i].getQ();
                alphaFinal = (Uint8) ((alphaDelta * q)/100);
                if(alphaFinal > 255) alphaFinal = 255; // pr la sécurité
                pixel=SDL_MapRGBA(src->format, r, v, b, alphaFinal);
                putpixel(src, x, y, pixel);
            }
     
            SDL_UnlockSurface(src);
        }
    }
     
    /**
        Classe PixelTextBlended
    */
    PixelTextBlended::PixelTextBlended() : _x(0), _y(0), _R(0), _V(0), _B(0), _A(0),
                                                _quotient(0) { }
     
    void PixelTextBlended::initialiser(unsigned int x, unsigned y, Uint8 r, Uint8 v,
                                        Uint8 b, Uint8 a, double q)
    {
        _x = x;
        _y = y;
        _R = r;
        _V = v;
        _B = b;
        _A = a;
        _quotient = q;
    }
     
    /* Accesseurs */
    unsigned int PixelTextBlended::getX() { return _x; }
    unsigned int PixelTextBlended::getY() { return _y; }
    Uint8 PixelTextBlended::getR() { return _R; }
    Uint8 PixelTextBlended::getV() { return _V; }
    Uint8 PixelTextBlended::getB() { return _B; }
    double PixelTextBlended::getQ() { return _quotient; }
     
    /*
     * Return the pixel value at (x, y)
     * NOTE: The surface must be locked before calling this!
     */
    Uint32 getpixel(SDL_Surface *surface, int x, int y)
    {
        int bpp = surface->format->BytesPerPixel;
        /* Here p is the address to the pixel we want to retrieve */
        Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
     
        switch(bpp) {
        case 1:
            return *p;
     
        case 2:
            return *(Uint16 *)p;
     
        case 3:
            if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
                return p[0] << 16 | p[1] << 8 | p[2];
            else
                return p[0] | p[1] << 8 | p[2] << 16;
     
        case 4:
            return *(Uint32 *)p;
     
        default:
            return 0;       /* shouldn't happen, but avoids warnings */
        }
    }
     
    /*
     * Set the pixel at (x, y) to the given value
     * NOTE: The surface must be locked before calling this!
     */
    void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
    {
        int bpp = surface->format->BytesPerPixel;
        /* Here p is the address to the pixel we want to set */
        Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
     
        switch(bpp) {
        case 1:
            *p = pixel;
            break;
     
        case 2:
            *(Uint16 *)p = pixel;
            break;
     
        case 3:
            if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
                p[0] = (pixel >> 16) & 0xff;
                p[1] = (pixel >> 8) & 0xff;
                p[2] = pixel & 0xff;
            } else {
                p[0] = pixel & 0xff;
                p[1] = (pixel >> 8) & 0xff;
                p[2] = (pixel >> 16) & 0xff;
            }
            break;
     
        case 4:
            *(Uint32 *)p = pixel;
            break;
        }
    }

    Voici un exemple d'utilisation (peut contenir des erreurs, je vous la fait sans compiler juste pour vous montrer à quoi ça ressemble) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void degradePositif() {
        SDL_Surface* surfaceBlended = TTF_RenderText_Blended(...);
        SurfTextBlended classeBlended;
     
        /* Dégradé positif, on tare tous les pixels à Alpha = 0 */
        classeBlended.tarrage(surfaceBlended, 0);
        for(int i=0; i<255; i++) {
            classeBlended.changerAlpha(surfaceBlended, i);
            SDL_BlitSurface(surfaceBlended, NULL, ecran, &position);
        }
    }
    Il faut juste faire attention à bien toujours envoyer la même surface à la classe (j'aurai pu inclure la surface à la classe mais bon ...

    Pour un dégradé négatif, on aurait fait un tarage à 255, et changerAlpha de 255 à 0.

    Voilà, bonne journée, et merci pour les liens, je vais voir ce que c'est.

  4. #4
    Membre éclairé
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Par défaut
    Citation Envoyé par Willy S. Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SurfTextBlended classeBlended;
     
    (...)
        classeBlended.~SurfTextBlended(); // destructeur, pour être sûr
    }
    Pour être sur de quoi ?
    de l'appeller deux fois ? (une fois manuellement et une fois quand on arrive à l'accolade... a la ligne suivante)
    Corrigez-moi, mais il me semble le destructeur est appellé automatiquement des que la visibilité de la variable se termine? non.
    en tous cas, j'ai jamais vu d'appel de destructeur manuel.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 9
    Par défaut
    Woops , merci de me le faire remarquer, c'est vrai que dans l'exemple ça ne sert à rien.

    Enfaite c'est que ma fonction originel est récursive et il y a un tableau de SurfTextBlended déclaré static, donc la fonction ne sais pas quand il faut le désallouer, alors je l'ai fait main.

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

Discussions similaires

  1. Changer l'opacité d'une div après scroll
    Par dhillig dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 21/11/2014, 21h27
  2. Changer l'opacité d'une image
    Par noussa_nouha dans le forum Android
    Réponses: 1
    Dernier message: 19/12/2011, 19h04
  3. [CSS 2.1] Changer l'opacité d'une cadre, sans toucher à son texte
    Par Otyugh dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 16/04/2010, 15h43
  4. Problème pour afficher une surface
    Par jenfree dans le forum MATLAB
    Réponses: 2
    Dernier message: 08/05/2007, 21h55
  5. Réponses: 2
    Dernier message: 30/03/2007, 13h17

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