Thread: gluTess functions and callback problems

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    8

    gluTess functions and callback problems

    I've been working with OpenGL and the gluTess functions to creating primitives with holes inside them. Simple enough right? From the red book's tess.c I've modified it to work with C++, VS2005 if that matters, and I'm having major problems.

    The problem I have is resulting from the changes from the original tess.c to c++ code, I think.

    After debugging, I saw that gluTessVertex is not calling my vertex function so that is why the primitives are never being drawn. Can anyone tell me how I can do this?

    Code:
    GLdouble rec1[3] = {0.0, 0.0, 0.0};
    GLdouble rec2[3] = {250.0, 0.0, 0.0};
    GLdouble rec3[3] = {250.0, 65.0, 0.0};
    GLdouble rec4[3] = {0.0, 65.0, 0.0};
    
    GLdouble win1[3] = {5.0, 5.0, 0.0};
    GLdouble win2[3] = {25.0, 5.0, 0.0};
    GLdouble win3[3] = {25.0, 25.0, 0.0};
    GLdouble win4[3] = {5.0, 25.0, 0};
    
    GLdouble* outer[4] = {rec1, rec2, rec3, rec4};
    GLdouble* inner[4] = {win1, win2, win3, win4};
    
    GLvoid tcbBegin(GLenum type)
    {
    	glBegin(type);
    }
    
    GLvoid tcbVertex(GLvoid *vertex)
    {
    	glVertex3dv((GLdouble*)vertex);
    }
    
    GLvoid tcbEnd()
    {
    	glEnd();
    }
    
    GLvoid combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut )
    {
    	GLdouble *vertex;
    	vertex = (GLdouble *) malloc(3 * sizeof(GLdouble));
    	vertex[0] = coords[0];
    	vertex[1] = coords[1];
    	vertex[2] = coords[2];
    	*dataOut = vertex;
    }
    
    GLvoid errorCallback(GLenum errorCode)
    {
    	const GLubyte *estring;
    	estring = gluErrorString(errorCode);
    	fprintf(stderr, "Tessellation Error: %s\n", estring);
    }
    
    
    //init()
    	wall1 = gluNewTess();
    	gluTessCallback(wall1, GLU_TESS_VERTEX, (GLvoid)tcbVertex);
    	gluTessCallback(wall1, GLU_TESS_BEGIN, (GLvoid)tcbBegin);
    	gluTessCallback(wall1, GLU_TESS_END, (GLvoid)tcbEnd);
    	gluTessCallback(wall1, GLU_TESS_COMBINE, (GLvoid)combineCallback);
    	gluTessCallback(wall1, GLU_TESS_ERROR, (GLvoid)errorCallback);
    	glShadeModel(GL_FLAT);
    
    
    //display()
    	gluTessNormal(wall1, 0.0, 0.0, 1.0);
    	gluTessProperty(wall1, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
    	gluTessBeginPolygon(wall1, NULL);
    		gluTessBeginContour(wall1);
    		for (int i = 0; i < 4; i++)
    			gluTessVertex(wall1, outer[i], outer[i]);
    		gluTessEndContour(wall1);
    		gluTessBeginContour(wall1);
    		for (int i = 0; i < 4; i++)
    			gluTessVertex(wall1, inner[i], inner[i]);
    		gluTessEndContour(wall1);
    	gluTessEndPolygon(wall1);
    I suspect it has something to do with the (GLvoid) casts I have to add to the gluTessCallBack function parameters to eliminate the compile errors. Specifically:
    error C2664: 'gluTessCallback' : cannot convert parameter 3 from 'GLvoid (__cdecl *)(GLvoid *)' to 'void (__stdcall *)(void)'

    I dont really understand what __stdcall is. Other than this problem, I cant see anything else wrong with this code. Suggestion?

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you look for calling conventions in your settings, under compiler and advanced, you should see calling convention. Set it to __stdcall.
    And another tip for you: Do not cast function pointers. Only in very specific situations should you do that. Casts will mask problems with your functions not matching.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    8
    I did change the calling convention from __cdecl (/Gd) to __stdcall (/Gz) but apparently all the rest of the OpenGL functions, including the necessary glutDisplayFunc require the colling convention to be the former.

    Code:
    error C2664: 'glutDisplayFunc' : cannot convert parameter 1 from 'void (__stdcall *)(void)' to 'void (__cdecl *)(void)'
    Also got this (scary):
    Code:
    warning C4007: 'main' : must be '__cdecl'
    2 of the gluTessCallback calls remained in error:

    Code:
    error C2664: 'gluTessCallback' : cannot convert parameter 3 from 'GLvoid (__stdcall *)(GLdouble [],GLdouble *[],GLfloat [],GLdouble **)' to 'void (__stdcall *)(void)'
    I wouldn't think the compiler would have a problem with GLvoid to void.
    In windef.h, which I had open looking what the heck CALLBACK was, I see
    Code:
    #define CALLBACK    __stdcall
    #define WINAPI      __stdcall
    #define WINAPIV     __cdecl
    The c source I took most of this code from used CALLBACK (how it works I still don't know) but I suspect if the glut functions use __cdecl, I should try replacing CALLBACK with WINAPIV? Again, I'm really lost as to what exactly they do, so elaborate please.

    And to make sure the GLvoid wasn't causing problems I went back and changed my callback functions such as
    Code:
    void CALLBACK tcbVertex(GLdouble* vertex)
    {
    	glVertex3dv(vertex);
    }
    But they still generate

    Code:
    error C2664: 'gluTessCallback' : cannot convert parameter 3 from 'void (__stdcall *)(GLdouble *)' to 'void (__stdcall *)(void)'
    More suggestions?

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Probably this
    tcbEnd
    is still
    void (__stdcall *)(void)
    while
    gluTessCallback wants 'void (__stdcall *)(GLdouble *)

    what line is this error about?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you change back to __cdecl and do
    GLvoid __stdcall errorCallback(GLenum errorCode)
    Then?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jan 2008
    Posts
    8
    im taking some advice from elsewhere and scrapping gluTess and using the stencil buffer to achieve the same thing. Apparently gluTess are really outdated?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing structs to callback functions (GTK+ related)
    By Raskalnikov in forum C Programming
    Replies: 2
    Last Post: 03-21-2009, 12:46 PM
  2. Callback functions concept
    By bhupesh.kec in forum C Programming
    Replies: 8
    Last Post: 10-16-2007, 12:58 AM
  3. Callback functions from dll
    By Calthun in forum Windows Programming
    Replies: 2
    Last Post: 07-09-2004, 04:13 PM
  4. Callback functions
    By linuxdude in forum C Programming
    Replies: 2
    Last Post: 01-03-2004, 06:23 PM
  5. Callback functions
    By WebmasterMattD in forum C++ Programming
    Replies: 3
    Last Post: 11-07-2003, 07:45 PM