Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : VBOs dynamic... [ Linux / OpenGL ] (jojomillenium)

samedi 18 novembre 2006 à 18:06:46 | VBOs dynamic...

jojomillenium

Bonjour,

Je dois pouvoir dessiner plus de 300 000 polygons dont la pluspart son concave... J'utilise donc les gluTess, j'utilise actuellement les glList pour que mon rendering soit plus "fluide", seulement je dois pouvoir en temps reel modifier la hauteur de mes couches, la couleur (alpha compris)... bref, certain parametre de mes polygon doivent pouvoir etre changé en temps reel et la glList n offre pas cette possibilité et avec 300 000 polygon, a chaque fois reecrire la gllist ca prend du temp!!!
J'aimerai utiliser les VBOs, seulement je ne vois pas comment avec ma structure! J'ai lu le tuto nehe a ce sujet, mais je vois pas comment faire dans mon cas! quelqu'un pourrait il m aiguiller?
voici mon code correspondant au coordonnée de mes polygon et a l enregsitrement dans la list actuelle... comment faire ca avec les VBO?

Mes classes :


class QUAD                                // Build our Quads Structure
{
public:
    int num_pts;
    int type;
    GLdouble* bottom;  // Bottom est un tableau de coordonnée des sommets de mes polygons de la forme {x1,y1,z1,x2,y2,z2,x3, ...}
    int layer;
};

// CLASS D'UN COUCHE
class LAYER                                // Build our LAYER Class, correspond a une couche, j'en ai 10 differente a dessiner
{
public:
    int num_quads; //nombre de polygon dans cette couche
    bool visible, existe; // visible determine si la couche doit s afficher ou non, ce qui permet en temps réél de cacher une ou plusieur couche
    float hauteur, zstart, h, penetration; h et zstart doivent pouvoir etre changé en temps réél, zstart et la hauteur dela face du bas et zsart+h la hauteur de la face du dessus
    char* nom_cif;
    char* nom_couche;
    vec4 color; // doit aussi pouvoir etre changé en temps réél pour modifier la couleur ou l opacité d'une des couches!
    QUAD* quad;    // Tableau des polygons a dessiner dans la couche Layer

// ici se trouve les restes des methode : constructeur, ...

};

Enregistrement des polygon a dessiner dans les lists :

GLUtesselator *tobj;
    glListBase(DrawList);
    int num_pts;
    GLdouble pt_bottom[250][3];
    GLdouble pt_top[250][3];

    for(i=0; i<11; i++) // j'ai 10 couches différentes a dessiner
        {
            glNewList(DrawList+i+1, GL_COMPILE); // 10 listes de créé pour mes 10 couches différentes, ca me permet en temps réél de cacher une couche ou plusieur couche c'est actuellement la seul chose que j arrive a faire sur mes couche en temps réél
                for(int q=0; q<LLayer[i].num_quads; q++)
              {
                    num_pts = LLayer[i].quad[q].num_pts;
                       
                    for(int p=0; p<num_pts; p++)
                    {
                      // Enregistremen des sommets des faces du dessus et du dessous
                        pt_bottom[p][0]=LLayer[i].quad[q].bottom[p*2];
                        pt_bottom[p][1]=LLayer[i].zstart;
                        pt_bottom[p][2]=LLayer[i].quad[q].bottom[p*2+1];

                        pt_top[p][0]=LLayer[i].quad[q].bottom[p*2];
                        pt_top[p][1]=LLayer[i].zstart + LLayer[i].h;
                        pt_top[p][2]=LLayer[i].quad[q].bottom[p*2+1];
                    }

                    for(p=0; p<num_pts; p++)
                    {
                      // On dessiner les faces de coté
                        int p2 = p+1;
                        if(p2 == num_pts)
                            p2 = 0;
                        glColor4f(LLayer[i].color.r,LLayer[i].color.g,LLayer[i].color.b, LLayer[i].color.a);

                        glBegin(GL_POLYGON);
                            glVertex3f(pt_bottom[p][0],pt_bottom[p][1],pt_bottom[p][2]);
                            glVertex3f(pt_bottom[p2][0],pt_bottom[p2][1],pt_bottom[p2][2]);
                            glVertex3f(pt_top[p2][0],pt_top[p2][1],pt_top[p2][2]);
                            glVertex3f(pt_top[p][0],pt_top[p][1],pt_top[p][2]);
                        glEnd();
                       
                        // ON DESSINE TOUTES LES ARRETES
                       
                        glColor4f(0.0,0.0,0.0, 1.0);
                           
                        glBegin(GL_LINES);
                            glVertex3f(pt_bottom[p][0],pt_bottom[p][1],pt_bottom[p][2]);
                            glVertex3f(pt_bottom[p2][0],pt_bottom[p2][1],pt_bottom[p2][2]);
                   
                            if(p2!=0)
                            {
                                glVertex3f(pt_bottom[p2][0],pt_bottom[p2][1],pt_bottom[p2][2]);
                                glVertex3f(pt_top[p2][0],pt_top[p2][1],pt_top[p2][2]);
                            }
                            glVertex3f(pt_top[p2][0],pt_top[p2][1],pt_top[p2][2]);
                            glVertex3f(pt_top[p][0],pt_top[p][1],pt_top[p][2]);
                       
                            if(p==0)
                            {
                                glVertex3f(pt_top[p][0],pt_top[p][1],pt_top[p][2]);
                                glVertex3f(pt_bottom[p][0],pt_bottom[p][1],pt_bottom[p][2]);
                            }
                        glEnd();
                    }   

                    glColor4f(LLayer[i].color.r,LLayer[i].color.g,LLayer[i].color.b, LLayer[i].color.a);

                    tobj = gluNewTess();
                    gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid (CALLBACK*) ()) &glVertex3dv);
                    gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid (CALLBACK*) ())&beginCallback);
                    gluTessCallback(tobj, GLU_TESS_END, (GLvoid (CALLBACK*) ())    &endCallback);
                    gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (CALLBACK*) ())&errorCallback);
                    //glShadeModel(GL_FLAT);

                   // On dessine la face de dessous
                    gluTessBeginPolygon(tobj, NULL);
                        gluTessBeginContour(tobj);
                            for(int u=0; u<num_pts; u++)
                                gluTessVertex(tobj, pt_bottom[u], pt_bottom[u]);
                        gluTessEndContour(tobj);
                    gluTessEndPolygon(tobj);

                    // On dessine la face de dessus
                    gluTessBeginPolygon(tobj, NULL);
                        gluTessBeginContour(tobj);
                            for(u=0; u<num_pts; u++)
                                gluTessVertex(tobj, pt_top[u], pt_top[u]);
                        gluTessEndContour(tobj);
                    gluTessEndPolygon(tobj);

                    gluDeleteTess(tobj);               
                }
            glEndList();
        }



Comment puis je transformer ca en VBOs? C'est possible? Et apres comment j'interagis avec mes couches?
Par exemple mon pt_bottom et pt_top on en y une valeur qui est egale au zstart et h de la LLayer[] correspondant. Si en temps reel avec les VBOs je modifie dans mon LLayer[] le zstart et le h, ca changera automatiquement sur mon rendu? ou je devrai modifier ca directement dans le VBO?

Merci beaucoup pour votre aide!

Jojo

dimanche 19 novembre 2006 à 23:12:22 | Re : VBOs dynamic...

luhtor

La transformation en vbo est simple pour le début de ta fonction. Les glBegin/End (à proscrire absolument !) sont facilement intégrables dans un vbo.

Pour les fonctions de fragmentation de glu. Il faut redéfinir la fonction de callback;
gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid (CALLBACK*) ()) &glVertex3dv);

ainsi que les callback GLU_TESS_BEGIN et GLU_TESS_END, de facon a ce qu'ils n'appellent pas glBegin/End.
D'après le redbook "l'algorithme de fragmentation choisit le type de primitive trinagulaire le plus efficace". Donc impossible de forcer l'utilisation d'une primitive. Donc va falloir ruser un peu:

Dans ton callback "beginCallback", l'argument GLenum which va te donner le type de primitive qu'il s'apprete a créer. Donc tu stockes ca dans une variable globale accessible par le callback GLU_TESS_VERTEX et tu construits les triangles générés par l'objet de fragmentation. Donc ton callback GLU_TESS_VERTEX aura la forme suivante:

On définie deja le callback
gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid (CALLBACK*) ()) &MyCallBack);

puis, admettons que nb_vertex donne le nombre de vertex généré jusqu'a maintenant:

void MyCallBack(GLvoid * vertex)
{
static counter = 0;
counter++;     // Nous permet de savoir le numéro du vertex actuellement envoyé.

switch(type_de_primitive_actuel_généré_par_glutess)
{
case GL_TRIANGLES:
if (counter != 1) Annomalie, test a faire pour etre sur que tout est correct.
memcpy(Mon_tableau_de_vertex[nb_vertex], vertex, 4*sizeof(double));
nb_vertex++;
if (counter == 3) counter = 0;
break;

case GL_TRIANGLE_STRIP:
if (counter > 3)  Si counter > 3, chaque nouveau point est en fait un nouveau triangle
{
memcpy(Mon_tableau_de_vertex[nb_vertex], Mon_tableau_de_vertex[nb_vertex-2], 8*sizeof(double));
nb_vertex+=2;
memcpy(Mon_tableau_de_vertex[nb_vertex], vertex);
nb_vertex++;
}
else
{
memcpy(Mon_tableau_de_vertex[nb_vertex], vertex);
nb_vertex++;
}
break;

case GL_TRIANGLE_FAN:
...
break;
}
}

Apres, c'est simple, suffit de créer le tableau d'index qui est trivial a faire ici:
unsigned short * index = new unsigned short[nb_vertex/3];
for (int k = 0 ; k < nb_vertex ; ++k) index[k] = k;

Apres tu balances les deux tableaux (index, et vertex) et color éventuellement a la carte graphique.

Enfin voila a quoi j'en pensé en étudiant le pb.

lundi 20 novembre 2006 à 13:56:13 | Re : VBOs dynamic...

jojomillenium

Oki, je viens d'étudier ton idée, je commence a m'y lancer.
1 question cependant, le Mon_tableau_de_vertex[nb_vertex] doit etre declaré egalement en global comme etant une GLdouble * Mon_tableau_de_vertex, comme ca a chaque fois qu'on fait memcpy, ca ajoute dynamiquement les valeur a la suite?

Et a quoi sert le tableau d index?


lundi 20 novembre 2006 à 14:35:17 | Re : VBOs dynamic...

jojomillenium

Hello,

voila comment j'ai modifié mes callbacks, seulement j'ai des erreur au niveau des memcpy:
donc en fait la, normalement tous mes polygons sont enregistré dans TabVertex sous forme de tableau de triangles!?


GLenum TypePrimitive;
GLdouble * TabVertex;
int nb_vertex = 0;
bool trifan = false;

void CALLBACK beginCallback(GLenum which)
{
    //glBegin(which);
    TypePrimitive = which;

}
void CALLBACK endCallback(void)
{
    //glEnd();
}

void CALLBACK MyCallBack(GLvoid* vertex)
{
     static int counter = 0;
    static int nb_fan = 0;
    counter++;
    switch(TypePrimitive)
    {
        case GL_TRIANGLES:
            trifan=false;
            memcpy(TabVertex[nb_vertex], vertex, 4*sizeof(double));
            nb_vertex++;
            if(counter==3)
                counter=0;
            break;
        case GL_TRIANGLE_STRIP:
            trifan = false;
            if(counter>3)
            {
                memcpy(TabVertex[nb_vertex],TabVertex[nb_vertex-2],8*sizeof(double));
                nb_vertex+=2;
                memcpy(TabVertex[nb_vertex],vertex, 4*sizeof(double));
                nb_vertex++;
            }
            else
            {
                memcpy(TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            break;
        case GL_TRIANGLE_FAN :
            if(!trifan)
            {
                trifan=true;
                nb_fan = nb_vertex;
            }
            if(counter>3)
            {
                memcpy(TabVertex[nb_vertex],TabVertex[nb_fan],4*sizeof(double));
                nb_vertex++;
                memcpy(TabVertex[nb_vertex],TabVertex[nb_vertex-1],4*sizeof(double));
                nb_vertex++;
                memcpy(TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            else
            {
                memcpy(TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            break;
    }
}

voila l erreur pour tous mes memcpy :
c:\documents and settings\joh@n\mes documents\epfl\projet de semestre\3d_visu vbos\gestionfichier.cpp(45) : error C2664: 'memcpy' : cannot convert parameter 1 from 'double' to 'void *'
        There is no context in which this conversion is possible


lundi 20 novembre 2006 à 18:20:10 | Re : VBOs dynamic...

luhtor

Bas évidemment, suffit d'etre rigoureux au niveau des types. Lui il veut un pointeur et  toi, tu lui files un double ...
Faut lui filer l'adresse du double.

Pk un tableau d'index ? Car on va pas utiliser un vbo basic mais un vbo indexé (plus rapide). Les vbos se base ne sont plus utilisés toute facon, on fait systèmétiquement des buffers indexés. Cad un tableau de vertex puis un tableau d'index qui contient les indices de chaque vertex qui forment le triangle.

Sinon, oui, tout le tableau doit etre construit sur la base des triangles pour pouvoir utiliser les vbos pour l'ensemble.



lundi 20 novembre 2006 à 18:29:07 | Re : VBOs dynamic...

jojomillenium

J'ai reussi al enregistrer .. seulement faut que je donne une taille a mon TabVertex avant! on peut pas l ajouter simplement dedans, mais par contre mes trianlge s affichent n importe comment, pour tester j'ai simplement dans mon Draw ajouter la fonction glDrawArrays pour le TabVertex... et bref ca me donne n importe quoi, peut etre mon Callback est faux et que ca enregistre mal mes vertex!

GLenum TypePrimitive;

int nb_vertex = 0;
int counter = 0;

#ifndef CALLBACK
#define CALLBACK
#endif

void CALLBACK beginCallback(GLenum which)
{
    //glBegin(which);
    TypePrimitive = which;

}
void CALLBACK errorCallback(GLenum errorCode)
{
    const GLubyte *estring;
    estring = gluErrorString(errorCode);
    fprintf(stderr, "Tessellation Error: %s\n", estring);
    exit(0);
}
void CALLBACK endCallback(void)
{
   // glEnd();
    counter=0;
}

void CALLBACK MyCallBack(GLvoid* vertex)
{
    counter++;
    switch(TypePrimitive)
    {
        case GL_TRIANGLES:
            if(counter>3)
                counter = 1;
            memcpy(&TabVertex[nb_vertex], vertex, 4*sizeof(double));
            nb_vertex++;
            if(counter==3)
                counter=0;
            break;
        case GL_TRIANGLE_STRIP:
            if(counter>3)
            {
                memcpy(&TabVertex[nb_vertex],&TabVertex[nb_vertex-2],8*sizeof(double));
                nb_vertex+=2;
                memcpy(&TabVertex[nb_vertex],vertex, 4*sizeof(double));
                nb_vertex++;
            }
            else
            {
                memcpy(&TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            break;
        case GL_TRIANGLE_FAN :
            if(counter>3)
            {
                memcpy(&TabVertex[nb_vertex],&TabVertex[nb_vertex-3],4*sizeof(double));
                nb_vertex++;
                memcpy(&TabVertex[nb_vertex],&TabVertex[nb_vertex-1],4*sizeof(double));
                nb_vertex++;
                memcpy(&TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            else
            {
                memcpy(&TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            break;
    }

}

lundi 20 novembre 2006 à 18:31:51 | Re : VBOs dynamic...

luhtor

Donc le but, c'est de construire le tableau de vertex de facon a ce que :
Soit k, un entier positif inférieur au nombre de triangle total;
Les vertex 3*k, 3*k+1 et 3*k + 2 forment un triangle.

lundi 20 novembre 2006 à 19:19:36 | Re : VBOs dynamic...

jojomillenium

oui ca je comprend, mais pourquoi mes triangles s affichent n importe comment?
Apparement normalement MyCallBack() enregsitre dans TabVertex[] chaqu'un des vertex des triangle par 3! donc apres avec glDrawArrays qui parcour TabVertex par 3, ca devrai dessiner les triangles!!!!
Mes case sont ils juste?

lundi 20 novembre 2006 à 22:50:56 | Re : VBOs dynamic...

luhtor

Bas si ca affiche n'importe quoi, c'est que tes "case" sont faux...

       case GL_TRIANGLES:
            if(counter>3)
                counter = 1; // Faux pas mettre ca

Je te disais de gérer l'anomalie en avertissant le programmeur, pas en corrigeant discretement. C'est un cas qui doit jamais arriver, donc faut tout stopper si tu rencontres ca:

Pour le triangle fan, ca m'a l'air louche ton truc. Regarde comment sont contruite les primitives avec le mode "fan".

     case GL_TRIANGLE_FAN :
            if(counter>3)
            {
                memcpy(&TabVertex[nb_vertex],&TabVertex[nb_vertex-counter + 1],4*sizeof(double)); // ya un counter qui intervient forcément
                nb_vertex++;
                memcpy(&TabVertex[nb_vertex],&TabVertex[nb_vertex-1],4*sizeof(double));
                nb_vertex++;
                memcpy(&TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            else
            {
                memcpy(&TabVertex[nb_vertex],vertex,4*sizeof(double));
                nb_vertex++;
            }
            break;

Enfin bricole et test. Met des cout partout, pour savoir quelles sont les primitives utilisées. Si c'est tjs la meme... Si c'est le cas, concentre toi sur celle la jusqu'à la faire marcher.

mercredi 22 novembre 2006 à 15:31:53 | Re : VBOs dynamic...

jojomillenium

Ca y est! J'ai reussi !! .... a enregistrer dans un tableau toutes les coordonnées des mes triangles et a l es afficher par un glDrawArrays!
Maintenant, comment on fait pour envoyer ca dans le buffer de la carte? mais surtout en dynamique, que je puisse modifier la coordonnée y des chaque triangles si necessaire!

J'ai donc 10 tableau, un pour chacune de mes couches!

Merci encore pour ton aide! elle m a ete precieuse! Tres malin la ruse des CallBacks!

Jojo


1 2

Cette discussion est classé dans : p2, top, pt, bottom, llayer


Répondre à ce message

Sujets en rapport avec ce message

Optimiser la vitesse d affichage [ par jojomillenium ] Bonjour,J'ai une fonction de dessin que j appelle dans mon DrawGLScene(),elle lis un tableau de 11 elements d'une classe layer, et dans chaque element driver souris sous windows xp [ par frogeraie ] bonjour!je voudrais  reduire de facon important (facteur 100) le rapport entre le deplacement de la souris et celui du curseur. j'ai essaye ceci (avec objet dans une fonction [ par jfrag ] Bonjour,voila j'ai un gros problemeen fait j'ai un objet declarer dans une fonction le probleme est aue je veus recuperer une fonction de cette objet utilisation de la stl vector + la stl pair [ par anthony65 ] Bonjour,je voudrais savoir comment je peux lire les elements qui se trouve dans mon vector.Dans mon vector j'ajoute des pair, mon probleme est que je Le suivi des messages c'est pas le top [ par The_Guardian ] Je préfèrais autre evrsion, ça a beau peter à l'iris tout ce rénovation des murs de vos sites, mais sur le plan de la construction ben ca reste très l solution avec deux projets [ par isir ] bonjourdans une solution, j'ai deux projets  P1  et P2comment faire  pour que P2 s'execute a partir de P1autrement dit: comment acceder aux fonction d Interpolation de lagrange (suite et surtout fin) [ par highvoltage ] Bonjour à tous et à toutes (si il y en a ),j'ai créer un nouveau post suite à un précédent car le problème est carrément différent: au départ on était Trier une liste chainée [ par ango973 ] Bonjour,J'ai un probleme avec une fonction qui doit me trier une liste chainée selon le nom mais apres le passage dans ma fonction la liste reste iden strtok - probleme d'encapsulation? [ par Chris8412 ] Bonjour a toutes et a tous!Voici mon premiere message sur votre forum. Avant de poser ma question, félicitations et merci a tous pour cette source d'i bug de gcc ? (constructeur C++) [ par vinc1008881 ] Bonjour, je rencontre un problème de constructeur avec gcc, à n'y rien comprendre : J'ai : class point{public : point (int, int, int); //constructeur.


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,562 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.