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 :

Changement de texture en temps réel


Sujet :

OpenGL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2014
    Messages : 22
    Points : 15
    Points
    15
    Par défaut Changement de texture en temps réel
    Bonjour à tous,

    Je suis en train de développer une application qui est censée afficher une heightmap en 3D, et simuler la propagation d'un incendie sur celle-ci. Tout cela sur Qt en C++.
    Actuellement, je suis capable d'afficher la heightmap, de projeter une texture 2D dessus.
    Mon soucis est le suivant :
    Je ne sais pas comment (avec OpenGL) modifier des points précis de cette texture, qui changeraient toutes les 2/3 secondes (au début on a un point en feu, puis il se propage etc..). Donc l'idée serait d'appliquer un petit sprite de feu sur les pixels en feu de la texture de fond (en gros remplacer la texture pour ces points précis, ou dessiner par dessus je ne sais pas). Si j'ai bien compris il faut que j'utilise un Frame Buffer Object, seul soucis j'ai un peu de mal à trouver une explication claire sur la toile. J'ai à peu près compris comment l'initialiser dans la fonction initializeGL() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        glGenFramebuffers(1,FBOID);
        glBindFramebuffer(GL_FRAMEBUFFER, FBOID[0]);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
    Dans textures[1] j'ai déjà mon sprite de feu qui est chargé (et je peux déjà l'utiliser, l'afficher sur la map si je le souhaite).
    J'ai en fait l'impression qu'une fois compilé la texture en soi ne peut plus trop changer..

    Cordialement,
    Etienne

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


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

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Déjà pour les ressources sur les FBO :


    Ensuite, je propose une solution un peu plus simple pour commencer. Je vous conseille de faire le rendu avec deux textures. Une pour le relief, qui ne change jamais et une pour le feu, qui est généré du côté CPU et que l'on modifiera autant qu'on le souhaite. Pour l'instant, pas besoin de FBO. Par contre, il y a besoin de multitexturing
    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.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2014
    Messages : 22
    Points : 15
    Points
    15
    Par défaut
    Bonjour et merci de votre réponse.

    Pour ce qui est de votre suggestion de multi-texturing. J'ai réussi à charger deux textures, et à les utiliser dans le GLSL shader (les afficher toutes les deux).
    Voici comment je charge une texture dans initializeGL() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        textures = new GLuint[1];
        glGenTextures(2,textures);
        background = QImage(":/terrains/paris_map_texture.png");
        background = QGLWidget::convertToGLFormat(background);
        glActiveTexture(GL_TEXTURE0); //switch to texture image unit 0
        glBindTexture(GL_TEXTURE_2D, textures[0]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, background.width(), background.height(),
                     0, GL_RGBA, GL_UNSIGNED_BYTE, background.bits());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glBindTexture(GL_TEXTURE_2D, 0);   //Bind a different texture to this unit
    Comment je l'utilise dans paintGL() la bind quoi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       glActiveTexture(GL_TEXTURE0); //switch to texture image unit 0
        glEnable(GL_TEXTURE_2D);
        glUniform1i(glGetUniformLocation(shaderProgram->programId(), "tex0"), 0);
        glBindTexture(GL_TEXTURE_2D, textures[0]);   //Bind a texture to this unit
    Je fais exactement la meme chose pour la 2eme texture de flamme, avec tex1 au lieu de tex0.
    Donc jusqu'ici tout va bien, le soucis est qu'ensuite c'est dans le GLSL que je les utilse.
    J'utilise dans le glsl du fragment la variable gl_FragColor pour mettre les textures.
    Le code de vertex.glsl :

    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
    #version 130
     
    in vec4 vertex;
    in vec4 normal;
    in vec2 texture_coordonnees;
     
    out float color_factor;
     
    uniform mat4 matrixpmv;
    uniform vec4 light_direction;
    out vec2 TexCoord;
     
    void main(void)
    {
        color_factor = max(dot(normal, light_direction), 0.0);
     
        TexCoord = texture_coordonnees;
     
        gl_Position = matrixpmv * vertex;
    }
    Le code de fragment.glsl :

    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
    #version 130
     
    in float color_factor;
    in vec2 TexCoord;
     
    in vec4 color;
    uniform vec4 ambiant_color;
     
    uniform sampler2D tex0;
    uniform sampler2D tex1;
     
     
    void main(void)
    {
        vec4 blanc = {1.0,1.0,1.0,1.0};
     
        gl_FragColor = ambiant_color + (blanc * 0.2 * color_factor) + (blanc * 0.6 * texture(tex0,TexCoord) );
    }
    Ici, je met donc gl_FragColor à la valeur de ma première texture, qui va recouvrir toute ma heightMap.
    Mon soucis est que je en sais pas comment appliquer ma flamme uniquement à une partie de ma heightMap via cette méthode.
    En effet, je peux mixer les deux textures, avec la fonction mix, mais la flamme va prendre toute la taille de la heightMap.
    Je me doute que c'est du à la variable TexCoord que j'utilise qui est les coordonnées de texture de ma heightMap.
    Toutes les secondes je vais avoir des points en Feu qui vont varier, mais je parle bien de POINT!! Il faut donc que j'applique mon sprite de flamme uniquement sur un pixel, puis les autres pixels qui vont s'enflammer etc..

    Merci pour ton aide.

  4. #4
    Expert éminent sénior

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

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    Salut! Elle fait quelle taille, ta map?
    Un point dans ta visualisation 3D correspond à 1 texel dans ta height map?

    Si c'est le cas, tu peux commencer en n'utilisant pas un sprite de flamme, mais une texture des mêmes dimensions que ta heightmap, transparente au départ, et pour chaque point où un incendie se déclare, tu colories ce point en rouge dans ta texture de flammes.
    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 à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2014
    Messages : 22
    Points : 15
    Points
    15
    Par défaut
    Salut!
    Ma carte fait à la base 256*256 et j'ai choisi une MAP_SIZE de 5 pour mon programme.
    Chaque texel ou vertice correspond effectivement à un point de ma carte 3D.

    J'ai réussi à implémenter ce que je voulais en utilisant la méthode glTexSubImade2D mais ca rame assez fortement sur la fin (quand il y a beaucoup de points).
    Ton idée est bonne et semble etre moins couteuse en mémoire.

    J'ai donc créé une texture vierge comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        ///Texture vierge dans laquelle on va "allumer" des points
        glActiveTexture(GL_TEXTURE1); //switch to texture image unit 0
        glBindTexture(GL_TEXTURE_2D, textures[1]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, background.width(), background.height(),
                     0, GL_RGBA, GL_UNSIGNED_BYTE, 0);//derniere valeur à 0 = vierge
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glBindTexture(GL_TEXTURE_2D, 0);   //Bind a different texture to this unit
    Puis dans paintGL() je la bind comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        glActiveTexture(GL_TEXTURE1);
        glEnable(GL_TEXTURE_2D);
        glUniform1i(glGetUniformLocation(shaderProgram->programId(), "tex1"), 0);
        glBindTexture(GL_TEXTURE_2D, textures[1]);
    Par contre dans mon render loop je ne sais pas comment modifier UN point de ma texture ? J'ai les coordonnées des points incendiés etc il ne me manque que cette méthode ..

  6. #6
    Expert éminent sénior

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

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    Il faut que tu gardes en interne un buffer contenant les données de ta texture de flammes, pour pouvoir le modifier à l'envi et renvoyer les modifications avec glTexSubImage2D.
    D'ailleurs, à propos de glTexSubImage2D, pour améliorer les performances, tu peux utiliser les Pixel Buffer Object (cf ce lien: http://www.songho.ca/opengl/gl_pbo.html)
    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).

Discussions similaires

  1. Réponses: 10
    Dernier message: 18/03/2014, 17h17
  2. Textures procédurales temps réel
    Par idmapria dans le forum DirectX
    Réponses: 35
    Dernier message: 08/06/2012, 19h40
  3. modification textures en temps réel
    Par Jérém08 dans le forum OpenGL
    Réponses: 8
    Dernier message: 26/04/2012, 23h18
  4. Ecouter changement taille fenêtre en temps réel
    Par dark0502 dans le forum Interfaces Graphiques en Java
    Réponses: 2
    Dernier message: 02/07/2011, 16h48
  5. Changement en temps réel avec liste déroulante
    Par Truthy dans le forum Général JavaScript
    Réponses: 22
    Dernier message: 28/08/2009, 13h01

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