Tessellation

Hello!

In the past I’ve requested help w/ the following in the “Beginners” forum, but to no avail. I now post in the “Windows Specific” forum hoping that a more focused audience might shed more light. :slight_smile:

I’ve been puzzling over a problem with polygon tessellation for some time, and would appreciate some help. I am trying to use the GLU tessellation functions to render a non-convex polygon. My program compiles w/ no errors using MinGW. But, when I run it, Windows XP says it has “encountered a problem & needs to close.”
If anyone is able to get my program to run on their machine, or can see my error, I would be most thankful for your reply.

JeffBozeman

/* --------------------------------------------------------------------
File: PolygonTessellation.cpp
Goal: Display a non-convex polygon (the famous "Star Trek" badge).
Problem: I get the "... has encountered a problem and need to close"
error from Windows XP as soon as I include a 3rd vertex in
my contour.
Compiled: c:\MinGW\bin\g++.exe PolygonTessellation.cpp
-o PolygonTessellation.exe -lopengl32 -lglu32 -lglut32
Platform: Windows XP Pro, Version 2002, Service Pack 1
Graphics: NVIDIA GeForce FX Go5200
-------------------------------------------------------------------- */


// --------------- namespaces --------------- //
using namespace std ;


// ---------------- includes ---------------- //
#include <iostream>
#include <GL/glut.h>


// ---------------- typedefs ---------------- //
typedef void (__stdcall * TessFuncPtr) ( ) ;


// ---------- function prototypes ----------- //
void myGLUTInitializationFunction ( int* AddrArgc, char* argv [] ) ;
void myTessellationInitializationFunction ( void ) ;
void myDisplayCallbackFunction ( void ) ;


// ----------- global variables ------------ //
GLuint starTrekDisplayList ;


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


int main ( int argc, char* argv [] )
{
myGLUTInitializationFunction ( &argc, argv ) ;
myTessellationInitializationFunction ( ) ;
glutMainLoop ( ) ;
} // end main


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


void myGLUTInitializationFunction ( int* AddrArgc, char* argv [] )
{
glutInit ( AddrArgc, argv ) ;
glutInitDisplayMode ( GLUT_RGB ) ;
glutInitWindowPosition ( 250, 150 ) ;
glutInitWindowSize ( 600, 400 ) ;
glutCreateWindow ( "PolygonTessellation" ) ;
glutDisplayFunc ( myDisplayCallbackFunction ) ;
} // end myGLUTInitializationFunction


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


void myTessellationInitializationFunction ( void )
{
// create tesselator object ...
GLUtesselator *myTesselator = gluNewTess ( ) ;


// function prototypes ...
TessFuncPtr beginCallback ( GLenum which ) ;
TessFuncPtr endCallback ( void ) ;
TessFuncPtr errorCallback ( GLenum errorCode ) ;


// register callback functions ...
gluTessCallback ( myTesselator, GLU_TESS_VERTEX, (TessFuncPtr) glVertex3dv ) ;
gluTessCallback ( myTesselator, GLU_TESS_BEGIN, (TessFuncPtr) beginCallback ) ;
gluTessCallback ( myTesselator, GLU_TESS_END, (TessFuncPtr) endCallback ) ;
gluTessCallback ( myTesselator, GLU_TESS_ERROR, (TessFuncPtr) errorCallback ) ;


// compile a display list for future execution ...
GLdouble starTrek [4] [3]
= { { +0.4, -0.7, 0.0 },
{ 0.0, +0.7, 0.0 },
{ -0.4, -0.7, 0.0 },
{ 0.0, 0.0, 0.0 } } ;
starTrekDisplayList = glGenLists ( 1 ) ;
glNewList ( starTrekDisplayList, GL_COMPILE ) ;
gluTessBeginPolygon ( myTesselator, NULL ) ;
gluTessBeginContour ( myTesselator ) ;
gluTessVertex ( myTesselator, starTrek[0], starTrek[0] ) ;
gluTessVertex ( myTesselator, starTrek[1], starTrek[1] ) ;
gluTessVertex ( myTesselator, starTrek[2], starTrek[2] ) ;
gluTessVertex ( myTesselator, starTrek[3], starTrek[3] ) ;
gluTessEndContour ( myTesselator ) ;
gluTessEndPolygon ( myTesselator ) ;
glEndList ( ) ;
} // end myTessellationInitializationFunction


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


TessFuncPtr beginCallback ( GLenum which )
{
glBegin ( which ) ;
} // end beginCallback


TessFuncPtr endCallback ( void )
{
glEnd ( ) ;
} // end endCallback


TessFuncPtr errorCallback ( GLenum errorCode )
{
cout << "Tessellation error: " << gluErrorString(errorCode) << endl ;
} // end errorCallback


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


void myDisplayCallbackFunction ( void )
{
glClear ( GL_COLOR_BUFFER_BIT ) ;
glCallList ( starTrekDisplayList ) ;
glFlush ( ) ;
} // end myDisplayCallbackFunction


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

Jeff,

I have good news and I have bad news.

I do not have any experience with MinGW so I imported the source from your post into a Win32 project using Visual C++ .net (2002) with the intention of walking through with the debugger to find the crash. I had a few complaints from the compiler, so I did the following:

Changed your Main function to a WinMain

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)

and used CommandLineToArgvW to create the argc and argv style variables needed to call you initialization function.

I also changed the definition of the second parameter of your myGLUTInitializationFunction: from char* argv[] to just char* argv

I changed the argv parameter calling glutInit: from argv to &argv

Lastly the callback functions were complaining about having to return a value (when they aren’t supposed to). I left your typedef for TessFuncPtr as is, but for each callback function I used CALLBACK like this example:

void CALLBACK beginCallback ( GLenum which )
{
	glBegin ( which ) ;
} // end beginCallback

After those minor changes it compiled fine. When I ran it to find the crashing bug, it did not crash. The Star Trek emblem displayed as expected.

Not sure if all of those changes are correct, I just made them off the top of my head. I didn’t take the time to look them all up in the docs, but it worked and one or more of the changes might have fixed the crashing problem.

robosport,

Thank you very much for your reply.

I don’t have Visual C++ here, so couldn’t try out your modifications as of yet. I have a copy of Visual C++ back at my office, so might try it later.

I’m a bit confused about glutInit. The Red Book (4th edition) says on page 17 that its parameters are (int *, char **), but later (on page 684) that the parameters are (int, char **). I’ve been assuming the former (without problem) in a variety of OpenGL programs for several months now.

I was a little confused as to why you’d changed the 2nd parameter of myGLUTInitializationFunction to char *argv. I had been under the impression that “main”, when it has parameters, are (int, char * []), and, hence, myGLUTInitializationFunction receives a char** when invoked (which it just passes on to glutInit).

Also, I tried using CALLBACK as you suggest (also as shown on Red Book’s page 493). That did not fix it on my machine, either.

In any case, I am encouraged that you got the programming running properly with fairly little trouble. It’s my hypothesis that my problem stems from my (mis)use of MinGW and/or improper DLL’s (esp. glu32.dll, which XP cites as the “ModName” in it “Error signature”).

Again, thank you very much, robosport, for taking the time to help me on this problem. I’ll keep plugging away.

JeffBozeman

Jeff,

My changes to the argv parameter were strictly related to the different parameters/types used by WinMain vs. main as the program’s entry point.

I am dynamically linking to the standard glu32.dll that comes with XP Pro, and the glu32.lib import lib that comes with the compiler I’m using.

If changing the callback function declarations to CALLBACK had no effect, at least it helps narrow your search. Also, now you know the tesselation part of your code works.

Good luck.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.