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 :

petit problème de dessin de multiples objets


Sujet :

OpenGL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Janvier 2012
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 39
    Points : 28
    Points
    28
    Par défaut petit problème de dessin de multiples objets
    Bonjour,
    Voila j'utilise opengl 4.5,et je rencontre un petit soucis...
    mon objectif,est de dessiner a l'écran plusieurs objets (cubes,sphères etc,mais je reste en 2D pour l'instant,donc ça ne sera que des "planes") mais voila,le problème c'est que lorsque j'utilise la fonction glVertexAttribPointer dans la fonction main,ça fonctionne,mais lorsque j'essaye d'utiliser la programmation orientée objet,et de mettre les glVertexAttribPointer dans le constructeur de l'objet en lui meme,ça ne fonctionne plus.
    Je vous donne mes codes :
    ça c'est le main.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
    #include "Object.h"
    #define WINDOW_WIDTH 800
    #define WINDOW_HEIGHT 600
    using namespace glm;
    using namespace std;
    int main(int argc, char *argv[])
    {
     
     
        SDL_Init(SDL_INIT_EVERYTHING);
     
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
     
        Window window=Window(800,800,"Opengl");
     
       SDL_Event event;
       Textures *texture=new Textures("E:/Program Files/Blender Foundation/Public_Domain_Grunge_Textures/photorealistic/photorealistic_floor/floor043.jpg");
       Textures *texture1= new Textures("E:/Program Files/Blender Foundation/Public_Domain_Grunge_Textures/photorealistic/photorealistic_floor/floor047.jpg");
        bool ok=true;
        Shader *shader=new Shader("vertex.vert","fragment.frag");
        float t=0;
     
        glClearColor(0,0,0,0);
     
     
     
     
     
        mat4 projection,modelview;
     
        projection=perspective(70.,(double)WINDOW_WIDTH/WINDOW_HEIGHT,1.,100.);
        modelview=mat4(1.);
     
        Object *plane=new Object(0.5,0,1,2);
        Object *plane1=new Object(0.5,4,5,6);
     
        float x=0,y=0,z=0,x1=0,y1=0,z1=0,taille=0.5;
     
     
       while(ok){
         glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
       plane->Load(modelview,projection,shader,texture);
     
     
     
     
     
     
     
     
        while(SDL_PollEvent(&event)){
     
        if(event.window.event==SDL_WINDOWEVENT_CLOSE){
     
            ok=false;
        }
        else if(event.type==SDL_KEYDOWN){
        if(event.key.keysym.sym==SDLK_LEFT){
            x-=0.1;
           cout<<"x:"<<x<<endl;
        }
        else if(event.key.keysym.sym==SDLK_UP){
            y+=0.1;
            cout<<"y:"<<y<<endl;
        }
         else if(event.key.keysym.sym==SDLK_DOWN){
            y-=0.1;
            cout<<"y:"<<y<<endl;
     
     
        }
        else if(event.key.keysym.sym==SDLK_RIGHT){
            x+=0.1;
            cout<<"x:"<<x<<endl;
     
     
        }
        else if(event.key.keysym.sym==SDLK_z){
            y1+=0.1;
            cout<<"y1:"<<y1<<endl;
        }
     
        }
     
     
        }
     
        SDL_GL_SwapWindow(window.GetWindow());
     
        SDL_Delay(10);
     
       }
        return 0;
    }

    et ceci est objet.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
    #include "Object.h"
    using namespace glm;
    Object::Object(float taille,long vert,long col,long tex)
    {
        taille=taille;
     
        vertexID=vert;
        colorID=col;
        textureID=tex;
    float vertices[]={-taille,-taille , -taille,taille , taille,taille , taille,taille , -taille,-taille ,taille,-taille };
    float text[]={0,0        ,   0,1    , 1,1     , 1,1     , 0,0       ,   1,0};
    float color[]={1,0,0 ,0,1,0, 0,0,1 , 1,0,0 ,0,1,0, 0,0,1 };
     
     
    glVertexAttribPointer(vertexID,2,GL_FLOAT,GL_FALSE,0,vertices);
    glVertexAttribPointer(colorID,3,GL_FLOAT,GL_FALSE,0,color);
    glVertexAttribPointer(textureID,2,GL_FLOAT,GL_FALSE,0,text);
     
     
    }
     
    Object::~Object()
    {
        //dtor
    }
     
     
     
    void Object::Load(mat4 modelview,mat4 projection,Shader *shader,Textures *texture){
     
     
     
     
     
     
     
        shader->UseProgramVF();
        texture->Bind();
     
     
     
     
     
     
     
     
        glEnableVertexAttribArray(vertexID);
         glEnableVertexAttribArray(colorID);
        glEnableVertexAttribArray(textureID);
     
        glUniformMatrix4fv(glGetUniformLocation(shader->getProgram(),"projection"),1,GL_FALSE,value_ptr(projection));
        glUniformMatrix4fv(glGetUniformLocation(shader->getProgram(),"modelview"),1,GL_FALSE,value_ptr(modelview));
     
        glDrawArrays(GL_TRIANGLES,0,6);
     
        glDisableVertexAttribArray(textureID);
        glDisableVertexAttribArray(colorID);
        glDisableVertexAttribArray(vertexID);
     
        texture->UnBind();
        shader->Stop();
     
     
    }

    et objet.h:

    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
    #ifndef OBJECT_H
    #define OBJECT_H
    #include "Textures.h"
     
    class Object
    {
        public:
            Object(float,long,long,long);
            virtual ~Object();
            void Load(glm::mat4 modelview,glm::mat4 projection,Shader *Shader,Textures *texture);
        protected:
        private:
            float taille;
            long vertexID,colorID,textureID;
            float *vertices;
     
            float *vertice;
            float *color;
    };
     
    #endif // OBJECT_H
    normalement je suis censé faire plane1->Load();plane2->Load(); etc pour avoir de multiples objets...
    le problème,je le rappelle,c'est que je suis obligé de mettre la fonction glVertexAttribPointer dans la fonction main,sinon,l'application ne fait aucun rendu,l'écran est noir...et ceci est problématique si on veux profiter de la programmation objet.

    Merci de m'avoir lu.

  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 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Je vois des new, mais il n'y a jamais les delete approprié pour libérer les ressources. Je vous conseille fortement d'utiliser les pointeurs intelligents du C++11 (std::shared/std::unique).

    Dans votre main.cpp, je ne vois pas où vous faites l'affichage (le draw call) dans la boucle principale.

    En plus, d'après le code de object.cpp vous faites un affichage (draw call) dans une fonction qui s'appelle Load(). Ce n'est pas cohérent.
    Pour chaque fonction OpenGL, je vous conseille de vérifier les erreurs avec glGetError(). Ou d'utiliser les extensions de débogage.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Load(glm::mat4 modelview,glm::mat4 projection,Shader *Shader,Textures *texture);
    Vous pourriez utiliser les références constantes, pour éviter des copies de matrice.

    Je ne vois pas où vous avez créé les objets OpenGL pour vos tampons.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vertexID=vert;
    glVertexAttribPointer(vertexID,2,GL_FLOAT,GL_FALSE,0,vertices);
    L'identifiant du tampon de sommets doit être donné par OpenGL. Pas par vous, car c'est un élément du GPU, géré par le GPU.
    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
    Nouveau membre du Club
    Inscrit en
    Janvier 2012
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 39
    Points : 28
    Points
    28
    Par défaut
    mais si on ne peut faire de draw call dans des fonctions de chaque objet,comment faire pour dessiner un a un chaque objet?


    Concernant les objets OpenGL pour les tampons,on les genere de la meme manière que les VBO?
    perso je ne savais pas qu'il fallait les générer,généralement je leur donne des identifiants a la main,mais lorsqu'il s'agit de plusieurs objets,ça deviendrait assurément lourd.

  4. #4
    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 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par thy-sins Voir le message
    mais si on ne peut faire de draw call dans des fonctions de chaque objet,comment faire pour dessiner un a un chaque objet?
    Si, on peut le faire. Mais la fonction le faisant, il me semble plus logique qu'elle s'appelle "draw" et non Load().


    Citation Envoyé par thy-sins Voir le message
    Concernant les objets OpenGL pour les tampons,on les genere de la meme manière que les VBO?
    perso je ne savais pas qu'il fallait les générer,généralement je leur donne des identifiants a la main,mais lorsqu'il s'agit de plusieurs objets,ça deviendrait assurément lourd.
    Les VBO sont des tampons (buffer).
    Il faut utiliser glGenBuffers(), pour générer des identifiants de tampon. Cela demande au pilote de la carte graphique de préparer des éléments dans la mémoire de la carte graphique. Ensuite, l'identifiant permet à votre application, de spécifier quel tampon de la carte graphique vous voulez modifier.
    En résumé, ce n'est pas à vous de donner les identifiants, c'est à la carte graphique (enfin, son pilote) car c'est elle qui gère cela, pas vous.

    Si vous avez des soucis, je vous conseille cette série de tutoriels : http://jeux.developpez.com/tutoriels/OpenGL-moderne/
    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.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Janvier 2012
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 39
    Points : 28
    Points
    28
    Par défaut
    Bonjour,
    en fait j'ai suivi vos directives mais je me rend compte d'une chose...
    dans glVertexAttribPointer,le premier chiffre,l'index,correspond au layout du vertex shader...
    Autrement dit,il doit bel et bien etre donné a la main,comme le fait parfaitement l'auteur du tutoriel que vous m'avez linké...
    Parce que,je n'utilise pas de vbo ou de vao pour mon affichage,et si j'essaye de générer un identifiant de buffer pour un vertexattribpointer,l'appli crashe.
    Ceci dit,la n'est pas cela le problème...
    le problème c'est que j'ai remarqué que dans mon application,lorsque j'utilise glvertexattribpointer dans une autre fonction que le main(),il n'y a aucun rendu...que ça soit dans une méthode d'objet,ou dans une fonction dans le meme fichier que le main...
    car normalement,je devrais pouvoir faire quelque chose du type:

    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
    void fonction(){
     
    float v1[]=..... des coordonnées de vertex....
    //     v2[]=..... coordonnées de couleur....
     
     
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,v1);
    glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,v2);
     
     
    }
     
     
    puis,dans le main:
     
     
    int main(){
     
     
    fonction();
     
    while(1){
     
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
     
    glDrawArrays(GL_QUADS,0,4);
     
    glDisableVertexAttribArray(1);
    glDisable... ... .. (0);
     
     
     
    }
     
     
     
    }
    mais ça ne marche pas...l'écran est noir,comme si il n'y avait aucun drawcall

    voila ce que je veux faire...
    parce qu'avoir des glVertexAttribPointer condensés dans main devient vite illisible et surtout chargé.
    ce que je veux,c'est totalement décharger cette fonction du main et la mettre dans le constructeur de l'objet a dessiner en question...sauf que,quand elle est dans le main,le programme fait un rendu,quand elle est dans une autre fonction que dans le main,l'écran reste noir...

  6. #6
    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 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Êtes vous sur que la fonction est bien appelée ?
    Est ce que vous utilisez des threads.
    Avez vous rajoutez les appels à glGetError() ?
    Sinon, utilisez un débogueur OpenGL (gDEBugger, par exemple, ou vogl sinon).
    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
    Nouveau membre du Club
    Inscrit en
    Janvier 2012
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 39
    Points : 28
    Points
    28
    Par défaut
    la fonction est bien appelée,je n'utilise pas de threads,et enfin j'ai bel et bien fait appel a getError qui me renvoie partout "0".
    c'est assez bizarre comme problème.

  8. #8
    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
    Les attributs de vertex peuvent être définis à la main, mais il faut s'assurer qu'ils correspondent au layout de ton shader.
    Pour ne pas avoir à se casser la tête avec ça, je te conseille d'utiliser la fonction glGetAttribLocation qui te permet de récupérer ces indices, à partir d'un shader compilé et linké.
    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).

  9. #9
    Nouveau membre du Club
    Inscrit en
    Janvier 2012
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 39
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Les attributs de vertex peuvent être définis à la main, mais il faut s'assurer qu'ils correspondent au layout de ton shader.
    Pour ne pas avoir à se casser la tête avec ça, je te conseille d'utiliser la fonction glGetAttribLocation qui te permet de récupérer ces indices, à partir d'un shader compilé et linké.

    cela voudrait t'il dire que l'on peut faire quelque chose comme :


    glVertexAttribPointer(glGetAttribLocation(program,"vertex")),2,GL_FLOAT,GL_FALSE,0,vertex_tableau);

    ou "vertex" désigne les coordonnées des sommets dans le shader,en vec2 ?

  10. #10
    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
    Tout à fait, mais je te conseille de stocker le retour de glGetAttribLocation dans une variable liée à ton shader histoire de ne pas faire l'appel à chaque draw call.
    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. Petit problème ArrayList objet
    Par astran dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 29/04/2013, 10h27
  2. Problème de déplacement d'un objet dessiné
    Par mhamedbj dans le forum Graphisme
    Réponses: 4
    Dernier message: 04/05/2012, 17h32
  3. [Dessin]Petits problèmes
    Par WWarmbeam dans le forum 2D
    Réponses: 4
    Dernier message: 17/10/2005, 19h59
  4. petit problème premier plan, arrière plan
    Par gros bob dans le forum OpenGL
    Réponses: 4
    Dernier message: 19/04/2004, 12h00
  5. [jointure] Petit problème sur le type de jointure...
    Par SteelBox dans le forum Langage SQL
    Réponses: 13
    Dernier message: 13/02/2004, 18h55

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