J'utilise les fonctions gluTess * pour dessiner des polygones non-convexes. Pour éviter de refaire la tesselation à chaque étape, je stocke le résultat dans un tableau et j'utilise les capacités de tableau de vertex d'OpenGL pour dessiner.Pourquoi gluTess ne fonctionne pas au premier appel?
Mon problème est que, pour une raison ou une autre, la première fois que j'utilise le gluTess *, seule une partie des triangles est dessinée. Si je force à recréer le gluTess *, alors tout va bien.
Notez que, pour recréer le gluTess *, je détruis complètement l'objet contenant le tableau de vertex et le recréer (ce qui force le recalcul de l'objet tableau de vertex).
Une idée de pourquoi ce serait le cas?
Quelques idées au hasard:
- pourrait-il être parce que pour la première OpenGL appeler la fenêtre est pas encore à sa pleine taille?
- Dois-je définir un état OpenGL, ce qui sera fait plus tard, mais pas lors du premier appel?
Merci.
Édition: En tant que test, je viens de créer, détruire et recréer la matrice de vertex. Cela résout le problème. Ce qui signifie: sans aucun changement dans l'état OpenGL, le premier appel à gluTess * ne corrige pas correctement le polygone. Mais le second réussit. Quelqu'un a-t-il remarqué cela avant?
Edit (2): Voici le code:
VA va;
GLUtesselator *t = gluNewTess();
gluTessCallback(t, GLU_TESS_BEGIN_DATA, (GLvoid (*)())beginVA);
gluTessCallback(t, GLU_TESS_END_DATA, (GLvoid (*)())endVA);
gluTessCallback(t, GLU_TESS_VERTEX_DATA, (GLvoid (*)())vertexVA);
gluTessCallback(t, GLU_TESS_ERROR, (GLvoid (*)())&tessError);
gluTessCallback(t, GLU_TESS_COMBINE, (GLvoid (*)())&tessCombine);
gluTessProperty(t, GLU_TESS_BOUNDARY_ONLY, GL_FALSE);
gluTessProperty(t, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
gluTessBeginPolygon(t, &va);
gluTessBeginContour(t);
foreach(Point3d& p, points)
gluTessVertex(t, const_cast<GLdouble*>(p.c_data()), (void*)&p);
gluTessEndContour(t);
gluTessEndPolygon(t);
gluDeleteTess(t);
Comme le second appel réussit, je soupçonne que beginVA, endVA et vertexVA fonctionnent très bien (comme je l'ai dit, le deuxième appel est fait par détruire la structure de données VA, qui contient principalement le tableau de vertex).
Edit (3): Voici le code manquant:
struct VA
{
std::vector<Point3d> positions; // Vertex array
GLenum current_mode; // Drawing mode (GL_TRIANGLE, *_FAN or *_STRIP)
Point3d v1, v2; // Two last vertices for _FAN or _STRIP
bool has_v1, has_v2; // did we get the two last vertices?
int n; // Index of the vertex, for *_STRIP
};
void beginVA(GLenum mode, VA *va)
{
va->current_mode = mode; // Store the mode
va->has_v1 = va->has_v2 = false; // We haven't had any vertex yet
va->n = 0;
}
void endVA(VA *va)
{
va->current_mode = 0; // Not really necessary, but cleaner
}
void vertexVA(Point3d *p, VA *va)
{
++va->n;
if(va->current_mode == GL_TRIANGLES) // The simple case
va->positions.push_back(*p);
else if(!va->has_v1) {
va->v1 = *p;
va->has_v1 = true;
} else if(!va->has_v2) {
va->v2 = *p;
va->has_v2 = true;
} else if(va->current_mode == GL_TRIANGLE_STRIP) {
if(va->n%2 == 1) {
va->positions.push_back(va->v1);
va->positions.push_back(va->v2);
va->positions.push_back(*p);
} else {
va->positions.push_back(va->v2);
va->positions.push_back(va->v1);
va->positions.push_back(*p);
}
va->v1 = va->v2;
va->v2 = *p;
} else { // GL_TRIANGLE_FAN
va->positions.push_back(va->v1);
va->positions.push_back(va->v2);
va->positions.push_back(*p);
va->v2 = *p;
}
}
Edit (4): En fin de compte, l'erreur était ailleurs. Je devais être fatigué, j'ai utilisé un std :: vector pour stocker le résultat de la fonction de combinaison. Je ne sais pas pourquoi ça a marché plus tard, mais c'était normal que ça ne marche pas la première fois! Désolé à ce sujet, je vais maintenant fermer ce sujet.
J'ai mis le code de tessellation comme une modification à mon poste. Mais qu'entendez-vous par "redessiner sans recréer les données tesselées"? Mon objet est constamment redessiné, car je peux le contourner. Le dessin est parfaitement cohérent, il n'y a pas de scintillement, les triangles ne sont vraiment pas là. – PierreBdR
@PierreBdR: certaines personnes relisent leur maillage pour chaque itération de la fonction de dessin; puisque vous avez dit que vous avez stocké vos vertices une question stupide par moi cependant. – datenwolf
mmmh .. Je préfère ne pas, car j'aurais beaucoup de polygones à dessiner, et l'utilisation de _STRIP ou _FAN implique un appel à glDrawElements par bande ou fan. – PierreBdR