Subject: still a tessellation problem with OpenGL
From: <[email-masked]>
To: [email-masked]
Cc: [email-masked]
Date: Sun, 6 Feb 2005 19:12:38 -0100 (MET)

Hi,

using an advice by Andre Bleau a year ago, I got the two
tessellation examples (tess.c and tesswind.c) from OpenGL working.
However, the example below, slightly different from
tess.c doesn't work. I get a segmentation fault, but I have no idea
how to solve the problem. I would appreciate any help as this is
a reduced case of a larger program which works well on linux,
and that I'd love to port on cygwin. I suspect this problem is 
related with tessellation, but I am not sure.

Thanks in advance,

Denis

$ gcc -g -o mytess mytess.c -lopengl32 -lglu32 -lglut32

$mytess.exe
Ok here
Segmentation fault (core dumped)

$ gdb mytess.exe
GNU gdb 6.3.50_2004-12-28-cvs (cygwin-special)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are welcome to change it and/or distribute copies of it under certain
conditions. Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details. This GDB was configured as "i686-pc-cygwin"...
(gdb) r
Starting program: /home/denis/opengl/redbook/mytess.exe 
Ok here

Program received signal SIGSEGV, Segmentation fault.
0x68f82d23 in gluTessEndPolygon () from
/cygdrive/c/WINDOWS/System32/glu32.dll (gdb) bt
#0  0x68f82d23 in gluTessEndPolygon () from
/cygdrive/c/WINDOWS/System32/glu32.dll
#1  0x004014a4 in init () at mytess.c:102
#2  0x004015c8 in main (argc=1, argv=0x10041590) at mytess.c:130
(gdb)

-------------------------------------------------------------------------
// adapted from tess.c

#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef CALLBACK 
#define CALLBACK __attribute__ ((__stdcall__))
#endif

void display (void) {
   glClear(GL_COLOR_BUFFER_BIT);
   glColor3f(1.0, 1.0, 1.0);
   glFlush();
}

void CALLBACK beginCallback(GLenum which)
{
   glBegin(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();
}

void CALLBACK vertexCallback(GLvoid *vertex)
{
   const GLdouble *pointer;

   pointer = (GLdouble *) vertex;
   glColor3dv(pointer+3);
   glVertex3dv(vertex);
}

/*  combineCallback is used to create a new vertex when edges
 *  intersect.  coordinate location is trivial to calculate,
 *  but weight[4] may be used to average color, normal, or texture * 
 coordinate data.  In this program, color is weighted.
 */
void CALLBACK combineCallback(GLdouble coords[3], 
                     GLdouble *vertex_data[4],
                     GLfloat weight[4], GLdouble **dataOut )
{
   GLdouble *vertex;
   int i;

   vertex = (GLdouble *) malloc(7 * sizeof(GLdouble));

   vertex[0] = coords[0];
   vertex[1] = coords[1];
   vertex[2] = coords[2];
   for (i = 3; i < 7; i++)
      vertex[i] = weight[0] * vertex_data[0][i] 
                  + weight[1] * vertex_data[1][i]
                  + weight[2] * vertex_data[2][i] 
                  + weight[3] * vertex_data[3][i];
   *dataOut = vertex;
}

void Contour(GLUtesselator *tobj,GLdouble v[][3],GLint n) {
  GLint i;
  gluTessBeginContour(tobj);
  for (i=n-1;i>=0;i--) {
    v[i][0]=cos((2*3.14159*i)/n);
    v[i][1]=sin((2*3.14159*i)/n);
    v[i][2]=0.0;
    gluTessVertex(tobj, v[i], v[i]);
  }
  gluTessEndContour(tobj);
}

void tess_properties(GLUtesselator *tobj) {
   gluTessProperty (tobj, GLU_TESS_WINDING_RULE,
   GLU_TESS_WINDING_POSITIVE);  gluTessCallback(tobj,
   GLU_TESS_VERTEX,(_GLUfuncptr)glVertex3dv); gluTessCallback(tobj,
   GLU_TESS_BEGIN,(_GLUfuncptr)beginCallback); gluTessCallback(tobj,
   GLU_TESS_END,(_GLUfuncptr)endCallback);
   gluTessCallback(tobj, GLU_TESS_ERROR,(_GLUfuncptr)errorCallback);
   gluTessCallback(tobj, GLU_TESS_COMBINE, (_GLUfuncptr)combineCallback);
   gluTessCallback(tobj,
   GLU_TESS_VERTEX_DATA,(_GLUfuncptr)&vertexCallback);
}

void init() {
   GLUtesselator *tobj;
   GLdouble v0[100][3];
   tobj = gluNewTess();
   tess_properties(tobj);
   gluTessBeginPolygon(tobj, NULL);
     gluTessNormal(tobj,0.0,0.0,-1.0);
     glNormal3f(0.0,0.0,-1.0); 
     Contour(tobj,v0,50);
     printf("Ok here\n");fflush(stdout);
     gluTessEndPolygon(tobj); // this produces a segfault
   printf("Not Ok here\n");fflush(stdout);
   gluDeleteTess(tobj);
}

void reshape (int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize(500, 500);
   glutCreateWindow(argv[0]);
   init();
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutMainLoop();
   return 0;  
}

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/