17.11.2005, 14:22 Uhr
Mad_Dog
Posts: 1944
Nutzer
|
Ich habe gerade folgendes Problem:
Ich habe ein Programm, welches ein 3D Objekt von Disk liest und darstellt. Nun ergibt sich das Problem, daß manche Polygone nicht konvex sind, was für OpenGL Grafikprimitiven ein Problem darstellt.
Da ja glu eine entsprechende Funktion bietet, hab ich mir mal einige Beispiele angeschaut und versucht, dies in meinen Code einzubauen - hat aber leider nicht vernünftig funktioniert.
Die folgende Funktion erzeugt Display Listen aus den Daten der Datei:
code:
// Liste generieren
GLuint buildlist(GeoData* geodat, clut colors)
{
int layernr, layer;
unsigned long i;
int j;
GLuint display_list;
GLUtesselator *tobj;
tobj = gluNewTess();
GLdouble v[1][3];
display_list = glGenLists(geodat->num_metal_layers+1);
// Display List für die Umrisse der Polygone
glNewList(display_list,GL_COMPILE);
glColor3f (1.0, 1.0, 1.0);
for (i=0; i<geodat->num_polygons; i++) {
glBegin (GL_LINE_LOOP);
for (j=0;j<geodat->polygon[i].num_vertices;j++) {
glVertex3f( geodat->polygon[i].vertex[j].x,
geodat->polygon[i].vertex[j].z,
geodat->polygon[i].vertex[j].y);
}
glEnd();
}
glEndList();
// Gehe alle Metal Layer durch
// Für jeden Metal Layer wird ein eigener Eintrag in
// der Display Liste erzeugt.
for (layer=0; layer < geodat->num_metal_layers; layer++)
{
// Display List für die Polygone
glNewList(display_list+(layer+1),GL_COMPILE);
// Gehe alle Polygone durch
for (i=0; i < geodat->num_polygons; i++)
{
layernr = geodat->polygon[i].layer_num;
// Falls Polygon zu diesem Layer gehört
if (layernr == layer)
{
if (geodat->polygon[i].is3d==true) colors.setcolor(0);
else colors.setcolor(layernr);
switch (geodat->polygon[i].num_vertices)
{
case 3:
// Falls das Polygon 3 Ecken hat, benutze
// OpenGL Grafikprimitive GL_TRIANGLES
glBegin(GL_TRIANGLES);
glVertex3d( geodat->polygon[i].vertex[0].x,
geodat->polygon[i].vertex[0].z,
geodat->polygon[i].vertex[0].y);
glVertex3d( geodat->polygon[i].vertex[1].x,
geodat->polygon[i].vertex[1].z,
geodat->polygon[i].vertex[1].y);
glVertex3d( geodat->polygon[i].vertex[2].x,
geodat->polygon[i].vertex[2].z,
geodat->polygon[i].vertex[2].y);
glEnd();
break;
case 4:
// Falls das Polygon 4 Ecken hat, benutze
// OpenGL Grafikprimitive GL_QUADS
glBegin(GL_QUADS);
glVertex3d( geodat->polygon[i].vertex[0].x,
geodat->polygon[i].vertex[0].z,
geodat->polygon[i].vertex[0].y);
glVertex3d( geodat->polygon[i].vertex[1].x,
geodat->polygon[i].vertex[1].z,
geodat->polygon[i].vertex[1].y);
glVertex3d( geodat->polygon[i].vertex[2].x,
geodat->polygon[i].vertex[2].z,
geodat->polygon[i].vertex[2].y);
glVertex3d( geodat->polygon[i].vertex[3].x,
geodat->polygon[i].vertex[3].z,
geodat->polygon[i].vertex[3].y);
glEnd();
break;
default:
// Ansonsten benutze OpenGL Grafikprimitive GL_POLYGONS
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);
gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
//
// glBegin (GL_POLYGON);
gluTessBeginPolygon(tobj, NULL);
gluTessBeginContour(tobj);
// Gehe alle Punkte des Polygons durch und zeichne es
for (j=0;j<geodat->polygon[i].num_vertices;j++)
{
// glVertex3d( geodat->polygon[i].vertex[j].x,
// geodat->polygon[i].vertex[j].z,
// geodat->polygon[i].vertex[j].y);
v[0][0] = geodat->polygon[i].vertex[j].x;
v[0][1] = geodat->polygon[i].vertex[j].z;
v[0][2] = geodat->polygon[i].vertex[j].y;
// cout << "Polygon " << i << ": " << v[0][0] << " "
// << v[0][1] << " "
// << v[0][2] << endl;
gluTessVertex(tobj, v[0], v[0]);
} // for
// glEnd();
gluTessEndContour(tobj);
gluTessEndPolygon(tobj);
break;
}// switch
} // if
} // for
glEndList();
cout << "Display list entry " << layer << " ready" << endl;
} // for
cout << "Display list ready" << endl;
gluDeleteTess(tobj);
return display_list;
}
Im falle vom mehr wie 4 Eckpunkten versuche ich hier, das Polygon zu zerlegen. Leider erscheinen die entsprechenden Polygone dann überhaupt nicht.
Den ursprünglichen Code habe ich auskommentiert.
Die Callback-Funktionen sehen wie folgt aus:
code:
void CALLBACK beginCallback(GLenum which)
{
glBegin(which);
}
void CALLBACK errorCallback(GLenum errorCode)
{
const GLubyte *estring;
estring = gluErrorString(errorCode);
fprintf(stderr, "Tessellation Error: %sn", estring);
exit(0);
}
void CALLBACK endCallback(void)
{
glEnd();
}
void CALLBACK vertexCallback(GLvoid *vertex)
{
const GLdouble *pointer;
//pointer = (GLdouble *) vertex;
//glColor3dv(pointer+3);
glVertex3dv((GLdouble *)vertex);
}
--
http://www.norman-interactive.com
[ Dieser Beitrag wurde von Mad_Dog am 17.11.2005 um 16:33 Uhr editiert. ]
[ - Antworten - Zitieren - Direktlink - ]
|