PDA

View Full Version : Problem with polygon rendering



angusj
10-24-2011, 11:39 PM
I'm trying to draw self-intersecting polygons using GLU with GLU_TESS_WINDING_ODD winding rule but sometimes I get unexpected results.

For example, using the following coordinates

GLdouble poly[][2] = {{280.0, 290.0}, {170.0, 250.0}, {501.0, 188.0}, {140.0, 393.0}, {140.0, 61.0}};

I get this ...
http://www.angusj.com/temp/opengl_evenodd_fill.png

I've zipped up a very small C++ file - main.cpp (~150 lines) - which compiles in MS Visual C++ 2010 Express ...
main.zip (4KB) (http://www.angusj.com/temp/main.zip)

I'd be grateful for any help explaining why this isn't rendering properly.

ZbuffeR
10-25-2011, 02:00 AM
I did not open your zip, do you provide your own callback to resolve self-intersecting polygons ?
gluTessCallback (tess, GLU_TESS_COMBINE, tcbCombine);
http://glprogramming.com/red/chapter11.html
http://www.opengl.org/resources/faq/technical/glu.htm
http://www.songho.ca/opengl/gl_tessellation.html

angusj
10-25-2011, 02:31 AM
do you provide your own callback to resolve self-intersecting polygons ?
Yes.



#include <windows.h>

#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <vector>

#define array_len(a) ( sizeof ( a ) / sizeof ( *a ) )

//------------------------------------------------------------------------------
// heap memory management for GLUtesselator ...
//------------------------------------------------------------------------------

typedef std::vector< GLdouble* > Vectors;
Vectors vectors;

GLdouble* NewVector(GLdouble x, GLdouble y)
{
GLdouble *vert = new GLdouble[3];
vert[0] = x;
vert[1] = y;
vert[2] = 0;
vectors.push_back(vert);
return vert;
}
//------------------------------------------------------------------------------

void ClearVectors()
{
for (Vectors::size_type i = 0; i < vectors.size(); ++i)
delete[] vectors[i];
vectors.clear();
}

//------------------------------------------------------------------------------
// GLUtesselator callback functions ...
//------------------------------------------------------------------------------

void CALLBACK BeginCallback(GLenum type)
{
glBegin(type);
}
//------------------------------------------------------------------------------

void CALLBACK EndCallback()
{
glEnd();
}
//------------------------------------------------------------------------------

void CALLBACK VertexCallback(GLvoid *vertex)
{
glVertex3dv( (const double *)vertex );
}
//------------------------------------------------------------------------------

void CALLBACK CombineCallback(GLdouble coords[3],
GLdouble *data[4], GLfloat weight[4], GLdouble **dataOut )
{
GLdouble *vert = NewVector(coords[0], coords[1]);
*dataOut = vert;
}
//------------------------------------------------------------------------------

void CALLBACK ErrorCallback(GLenum errorCode)
{
fprintf(stderr,"Tessellation Error: %s\n", gluErrorString(errorCode));
exit(1);
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

void display()
{
//Erase the window and the depth buffer
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);

GLUtesselator* tess = gluNewTess();
gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK*)())&amp;BeginCallback);
gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK*)())&amp;VertexCallback);
gluTessCallback(tess, GLU_TESS_END, (void (CALLBACK*)())&amp;EndCallback);
gluTessCallback(tess, GLU_TESS_COMBINE, (void (CALLBACK*)())&amp;CombineCallback);
gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK*)())&amp;ErrorCallback);
gluTessNormal(tess, 0.0, 0.0, 1.0);

gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); //GL_FALSE
gluTessBeginPolygon(tess, NULL);
gluTessBeginContour(tess);

glColor4f(0.0f, 0.0f, 1.0f, 0.062f);
//these coordinates don't render the polygon as expected using the GLU_TESS_WINDING_ODD winding rule ...
GLdouble poly[][2] = {{280.0, 290.0}, {170.0, 250.0}, {501.0, 188.0}, {140.0, 393.0}, {140.0, 61.0}};
//however, repositioning the first coordinate above just a little, it does render as expected ...
//GLdouble poly[][2] = {{280.0, 330.0}, {170.0, 250.0}, {501.0, 188.0}, {140.0, 393.0}, {140.0, 61.0}};

for (int i = 0; i < array_len(poly); ++i)
{
GLdouble *vert = NewVector(poly[i][0], poly[i][1]);
gluTessVertex(tess, vert, vert);
}

gluTessEndContour(tess);
gluTessEndPolygon(tess);
ClearVectors();

glFlush();
glutSwapBuffers();
}
//------------------------------------------------------------------------------

void key(unsigned char ch,int x,int y)
{
// Exit on ESC
if (ch == 27) exit(0);
}
//------------------------------------------------------------------------------

void reshape(int width,int height)
{

//setup 2D projection with origin at top-left corner ...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//------------------------------------------------------------------------------

int main(int argc,char* argv[])
{

//Initialize GLUT
glutInit(&amp;argc, argv);

//Request double buffered, true color window with Z buffering at 600x600
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(600,600);
glutCreateWindow("Polygon test");

//Set callbacks
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);

glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTranslatef (0.375, 0.375, 0);

//Pass control to GLUT so it can interact with the user
glutMainLoop();
return 0;
}

angusj
10-25-2011, 12:48 PM
I'm now starting to suspect this might be a bug in the GLU library since I can duplicate the problem when I replace the polygon coordinates in the tesswind.c (http://www.opengl.org/resources/code/samples/redbook/tesswind.c) sample from the OpenGL Code samples (http://www.opengl.org/resources/code/samples/redbook/) with my polygon coordinates above. Also, if I change the starting coordinate to the third one, the polygon is rendered correctly.

Anyhow, could someone please verify that there is a problem either with my code or with the GLU library. If there's a problem with the GLU library, does it affect other platforms apart from Windows?

angusj
10-29-2011, 12:21 AM
Bump ... is anyone able to spot the bug in my code or is this a bug in the GLU library?