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

OpenGL Discussion :

Texture Affiche 2D Transparence [OpenGL 1.x]


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut Texture Affiche 2D Transparence
    Bonjour à tous et à toutes.

    Je me suis mis à faire une petite bibliothèque de dessin 2d de sprites et de primitives en utilisant OpenGl 1.x.

    J'utilise comme langage le C# et une vieille bibliothèque nommée TAO qui me fait un mapping 1-1 avec l'OpenGl classique (ce qui est mon but).

    J'ai réussit (mais c'est simple) à faire des tracés de rectangles (pleins ou vides), de cercles, de lignes, de points.

    Je me suis penché sur la problématique d'affichage de sprite 2d (purement).

    J'utilise la séquence d'initialisation suivante :
    Elle utilise un fichier de mon cru qui contient les infos qu'il me faut pour charger une texture (qui est une classe aussi de mon cru) en plus des initialisations pour un affichage 2d 640 par 480.

    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
    
     public static bool InitGL()
            {
                Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                Gl.glGenTextures(1, _textureIds);
    
                _currentTexture = LoadTexture("A.pof");  // Chargement de mon fichier perso
                                                                                          // dans ma classe Texture perso
                Gl.glEnable(Gl.GL_TEXTURE_2D);
                Gl.glEnable(Gl.GL_ALPHA_TEST);
                Gl.glAlphaFunc(Gl.GL_GREATER, 0);
    
                Gl.glDisable(Gl.GL_DEPTH_TEST);
                Gl.glDisable(Gl.GL_LIGHTING);
                Gl.glDisable(Gl.GL_DITHER);
    
                Gl.glMatrixMode(Gl.GL_PROJECTION);
                Gl.glLoadIdentity();
                Gl.glOrtho(0, 640, 480, 0, 0, 1);
                Gl.glMatrixMode(Gl.GL_MODELVIEW);
    
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);
               
                return true;
            }
    J'utilise la fonction suivante pour afficher un sprite :
    Je passe une référence à ma classe Texture qui en fait contient l'identifiant OpenGl de la texture, une structure Point pour l'emplacement d'affichage et enfin un byte qui est censé donner l'alpha d'affichage : 0 (sprite invisible) ---- 128 (translucide) --- 255 (silde) etc..

    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
     
     
     public static void DrawTexture(Texture texture, Point point, byte alpha)
            {
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture.GetIndex());
     
                Gl.glBegin(Gl.GL_QUADS);
     
                Gl.glTexCoord2d(0, 0);
                Gl.glVertex2f(point.X, point.Y);
     
                Gl.glTexCoord2d(1, 0);
                Gl.glVertex2f(point.X + texture.GetWidth(), point.Y);
     
                Gl.glTexCoord2d(1, 1);
                Gl.glVertex2f(point.X + texture.GetWidth(), point.Y + texture.GetHeight());
     
                Gl.glTexCoord2d(0, 1);
                Gl.glVertex2f(point.X, point.Y + texture.GetHeight());
     
                Gl.glEnd();
            }
    Voici ma classe perso texture

    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
     
     
        public sealed class Texture
        {        
            private Color _alphaColor;
            private int _width;
            private int _height;
            private int _index;
     
            public Color GetAlphaColor()
            {
                return _alphaColor;
            }
     
            public int GetWidth()
            {
                return _width;
            }
     
            public int GetHeight()
            {
                return _height;
            }
     
            public int GetIndex()
            {
                return _index;
            }
     
            public Texture(int width, int height, int index, ref Color alphaColor)
            {
                _alphaColor = alphaColor;
                _width = width;
                _height = height;
                _index = index;
            }
        }

    Mon problème est le suivant :

    Dans ma petite bibliothèque, je voudrais afficher des sprites qui ont des parties invisible et avec un degré de transparence. Par exemple, imaginons une piece de monnaie dans une image carré dont le fond serait en rouge.

    Il faudrait que le fond rouge ne s'affiche pas et que la piece de monnaie puisse s'afficher avec des degré de transparence paramétré.

    Jusqu'ici, j'ai réussit à rendre le fond de mon image invisible grace à

    Gl.glEnable(Gl.GL_ALPHA_TEST);
    Gl.glAlphaFunc(Gl.GL_GREATER, 0);

    et

    Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);

    mais je ne vois pas comment faire pour faire varier la transparence avec mon paramètre alpha dans ma fonction

    public static void DrawTexture(Texture texture, Point point, byte alpha)


    J'ai tournée en rond et je vous demande humblement votre aide .....


    Marci à tous !

  2. #2
    Membre chevronné
    Inscrit en
    Février 2008
    Messages
    413
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Février 2008
    Messages : 413
    Par défaut
    Bonjour,

    dans votre exemple vous utilisez l'Alpha test, mais pour ce que vous voulez obtenir c'est le Blending qu'il faut utiliser.

    Remplacez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Gl.glEnable(Gl.GL_ALPHA_TEST);
                Gl.glAlphaFunc(Gl.GL_GREATER, 0);

    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Gl.glEnable(Gl.GL_BLEND);
                Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
    Et dans ce cas votre Alpha correspondra au degré de transparence du pixel correspondant.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Bonjour,

    Merci de votre aide, voici ce qui arrive avec votre suggestion :

    EXPERIENCE 1
    -------------

    Avec l'initialisation suivante :

    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
     
     
    public static bool InitGL()
            {            
                Gl.glClearColor(0, 0, 0, 1);
                Gl.glGenTextures(1, _textureIds);
     
                _currentTexture = LoadTexture("A.pof");
     
                Gl.glEnable(Gl.GL_TEXTURE_2D);
     
                Gl.glDisable(Gl.GL_DEPTH_TEST);
                Gl.glDisable(Gl.GL_LIGHTING);
                Gl.glDisable(Gl.GL_DITHER);
     
                Gl.glMatrixMode(Gl.GL_PROJECTION);
                Gl.glLoadIdentity();
                Gl.glOrtho(0, 640, 480, 0, 0, 1);
                Gl.glMatrixMode(Gl.GL_MODELVIEW);
     
                Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);
     
                return true;
            }
    Et le code de dessin suivant :

    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
     
     
     public static void DrawTexture(Texture texture, Point point, byte alpha)
            {
                Gl.glEnable(Gl.GL_ALPHA_TEST);                               //Code de suppresion du fond bleu de l'image
                Gl.glAlphaFunc(Gl.GL_GREATER, 0);
     
                Gl.glEnable(Gl.GL_BLEND);
     
                Gl.glColor4b(255, 255, 255, alpha);                          //Utilisation de la valeur alpha ? 
     
                Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);  //Votre suggestion
     
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture.GetIndex());
     
                Gl.glBegin(Gl.GL_QUADS);
     
                Gl.glTexCoord2d(0, 0);
                Gl.glVertex2i(point.X, point.Y);
     
                Gl.glTexCoord2d(1, 0);
                Gl.glVertex2i(point.X + texture.GetWidth(), point.Y);
     
                Gl.glTexCoord2d(1, 1);
                Gl.glVertex2i(point.X + texture.GetWidth(), point.Y + texture.GetHeight());
     
                Gl.glTexCoord2d(0, 1);
                Gl.glVertex2i(point.X, point.Y + texture.GetHeight());
     
                Gl.glEnd();
     
                Gl.glDisable(Gl.GL_ALPHA_TEST);
                Gl.glDisable(Gl.GL_BLEND);
            }
    Et l'appel au dessin suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    public static bool DrawGLScene()
            {
                Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
     
                Point p1 = new Point(0, 0);
                Point p2 = new Point(30, 200);
     
                DrawTexture(_currentTexture, p1, 255);  
                DrawTexture(_currentTexture, p2, 64);  //Tentative de transparence 
     
                return true;
            }
    J'obtiens le résultat montré imageA.png.
    L'appel au dessin de la deuxieme texture devrait la rendre transparente mais ce n'est pas la cas.



    EXPERIENCE 2
    --------------------

    Si je modifie dans le code de dessin comme ceci :

    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
     
     
    public static void DrawTexture(Texture texture, Point point, byte alpha)
            {
                Gl.glEnable(Gl.GL_ALPHA_TEST);
                Gl.glAlphaFunc(Gl.GL_GREATER, 0);
     
                Gl.glEnable(Gl.GL_BLEND);
     
                Gl.glColor4b(255, 255, 255, alpha);
     
                Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_COLOR);  // Un essai trouvé au hasard
     
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture.GetIndex());
     
                Gl.glBegin(Gl.GL_QUADS);
     
                Gl.glTexCoord2d(0, 0);
                Gl.glVertex2i(point.X, point.Y);
     
                Gl.glTexCoord2d(1, 0);
                Gl.glVertex2i(point.X + texture.GetWidth(), point.Y);
     
                Gl.glTexCoord2d(1, 1);
                Gl.glVertex2i(point.X + texture.GetWidth(), point.Y + texture.GetHeight());
     
                Gl.glTexCoord2d(0, 1);
                Gl.glVertex2i(point.X, point.Y + texture.GetHeight());
     
                Gl.glEnd();
     
                Gl.glDisable(Gl.GL_ALPHA_TEST);
                Gl.glDisable(Gl.GL_BLEND);
            }
    J'obtiens le résultat imageB.png.

    Là ça marche mais uniquement dans la zone d'intersection des deux textures, ce que j'aurais aimé c'est que la texture transparente le soit aussi comme sur l'exemple imageC.png.



    REMARQUE :
    -----------------

    J'utilise le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    Gl.glEnable(Gl.GL_ALPHA_TEST);                          //Code de suppresion du fond bleu de l'image
    Gl.glAlphaFunc(Gl.GL_GREATER, 0);
    Pour éliminer le fond de ma texture, effectivement je voudrais avoir des texture avec fond invisible et degré de transparence paramétrée pour le reste de l'image.

    Si jamais j'élimine le code ci dessus du code de dessin j'obtiens l'imageD.png.
    Images attachées Images attachées     

  4. #4
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    L'idéal pour avoir le rendu que tu souhaites serait d'avoir le canal alpha dans l'image et de faire le blending avec GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Juste une idée qui me vient comme ça ...

    On ne pourrait pas utiliser une "texture vide" intermédiaire avec notre valeur alpha et la combiner à la texture à dessiner pour obtenir l'effet de transparence ?

    La texture dite pourrait être de la taille de un pixel et extensible ...

    Une sorte de masque ... par contre je ne sais pas du tout comment faire ...

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 129
    Billets dans le blog
    149
    Par défaut
    Bonjour,

    Cette nouvelle solution est possible principalement en utilisant des shaders (OpenGL 2/3 et 4). En OpenGL 1, je ne vois pas comment cela est possible.
    D'ailleurs, avez vous une raison de rester en OpenGL 1 ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Merci pour toutes vos suggestions.

    Effectivement, je voudrais rester en OpenGl 1.x pour des raisons de compatibilités avec des vieux machins que j'aime bien.

    Je viens du monde M$ et je suis un peu fatigué de la politique habituelle de mise en avant d'une technologie puis d'abandon soudain dont fait preuve cette firme.

    Du coup ayant des connaissances XNA 3.1, je me suis dit que OpenGl serait plus stable ce qui est le cas puisque les versions nouvelles englobent les versions précédentes.

    C'est quand même plus simple à suivre ...

    Cependant, je suis très étonné que la possibilité de faire varier la transparence d'un texture déjà chargé ne soit pas présente directement dans cette version d'OpenGL.

    Autant que je me souvienne, OpenGl a été crée en 1992 et la version 1.2 date de 1998 or en 1998, les jeux contenaient des textures à alpha variable ne serait ce qu'en affichage 2D "Please Wait ".... "Loading" ... "Get Ready" ....

    https://www.opengl.org/wiki/History_...1.0_.281992.29

    Pour le problème qui nous concerne, je n'ai pas trouvé d'autre méthode que de recharger la texture avec des données mises à jour.

    Le truc est de garder en ram une seule texture OpenGL générée une fois et ensuite de la rafraichir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, 4, texture.GetWidth(), texture.GetHeight(), 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, texture.GetUpdatedDatas(alpha));
    Bien évidement ce n'est pas terrible car on perd des cycles sur les opérations de mises à jour et de rafraichissement : il me semble en fait que je viens de faire un "shader software"

    Sur XNA 3.1 l'opération de dessin avec alpha paramétré prend 1000 fois moins de temps mais je les soupçonne de faire un appel à un shader encapsulé et caché dans leur framework.

    Je vais encore fouiller un peu et si je ne trouve rien de plus je fermerais cette discussion.

    Merci à tous.

  8. #8
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 129
    Billets dans le blog
    149
    Par défaut
    Je viens de tilter (j'étais perdu à cause du rouge, un moment, enfin bref).

    Pour information, si vous aimez XNA : http://jeux.developpez.com/index/red...andre-Laurent/ (rien n'est perdu )

    Pour OpenGL, il faut utiliser la technique de matériel coloré. On en trouvera une explication dans le tutoriel de NeHe : http://nehe.developpez.com/tutoriel/12-liste-affichage/

    Il utilise une texture (de boite) et peut changer la couleur de rendu à la volée (sorte de teinte). Cela marche aussi pour la composante alpha
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Est il possible d'avoir un exemple moins complexe ? Parce que là je suis un peu perdu ...

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 129
    Billets dans le blog
    149
    Par défaut
    ...

    ->

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // A l'initialisation
    glEnable(GL_COLOR_MATERIAL);    // Activation du coloriage matériel
     
    glColor4f(/*votre couleur*/);
    // Dessin de votre objet
    À peu près.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    merci ! ça suffira pour ma problématique.

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

Discussions similaires

  1. Texture avec trous transparent
    Par Davidlouiz dans le forum OpenGL
    Réponses: 5
    Dernier message: 14/03/2011, 14h32
  2. Réponses: 10
    Dernier message: 07/11/2006, 10h45
  3. pb de transparence/texture/sprite
    Par Fikus dans le forum DirectX
    Réponses: 6
    Dernier message: 15/05/2004, 22h38
  4. Texture Transparence
    Par Cartman dans le forum DirectX
    Réponses: 1
    Dernier message: 02/03/2004, 22h02
  5. Afficher une image sans passer par les textures
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/05/2003, 19h13

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