• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 858
  • Last Modified:

Can't convert unsigned integer

I'm following a programming example from "OpenGL Programming Guide" 4th edition by Shreiner, Woo, Neider and Davis. I've typed the program as I see it in the book, however, I keep getting an error when I try to complie the code. Please help.
-------------------
Error Message:
c:\documents and settings\owner\desktop\project438\project438.cpp(54) : error C2664: 'gluQuadricCallback' : cannot convert parameter 3 from 'void (unsigned int)' to 'void (__stdcall *)(void)'
------------------

The Program Code:
#include <windows.h>
#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#include <gl/glut.h>

#ifndef CALLBACK
#define CALLBACK
#endif

GLuint startList;

void CALLBACK errorCallback(GLenum errorCode)
{
      const GLubyte *estring;

      estring=gluErrorString(errorCode);
      fprintf(stderr, "Quadric Error: %s\n", estring);
      exit(0);
}

void init(void)
{
      GLUquadricObj *qobj;
      GLfloat mat_ambient[]={0.5, 0.5, 0.5, 1.0};
      GLfloat mat_specular[]={1.0, 1.0, 1.0, 1.0};
      GLfloat mat_shininess[]={50.0};
      GLfloat light_position[]={1.0, 1.0, 1.0, 0.0};
      GLfloat model_ambient[]={0.5, 0.5, 0.5, 1.0};

      glClearColor(0.0, 0.0, 0.0, 0.0);

      glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
      glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
      glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
      glLightfv(GL_LIGHT0, GL_POSITION, light_position);
      glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model_ambient);

      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      glEnable(GL_DEPTH_TEST);

      /*Create 4 display lists, each with a different quadric object.
      *Different drawing styles and surface normal specifications
      *are demonstrated.
      */

      startList=glGenLists(4);
      qobj=gluNewQuadric();
      gluQuadricCallback(qobj, GLU_ERROR, errorCallback); //<---This is the line in question<<<<<<<<<<

      gluQuadricDrawStyle(qobj, GLU_FILL); /*smooth shading*/
      gluQuadricNormals(qobj, GLU_SMOOTH);
      glNewList(startList, GL_COMPILE);
            gluSphere(qobj, 0.75, 15, 10);
      glEndList();

      gluQuadricDrawStyle(qobj, GLU_FILL); /*flat shading*/
      gluQuadricNormals(qobj, GLU_FLAT);
      glNewList(startList+1, GL_COMPILE);
            gluCylinder(qobj, 0.5, 0.3, 1.0, 15, 5);
      glEndList();

      gluQuadricDrawStyle(qobj, GLU_LINE); /*wireframe*/
      gluQuadricNormals(qobj, GLU_NONE);
      glNewList(startList+2, GL_COMPILE);
            gluDisk(qobj, 0.25, 1.0, 20, 4);
      glEndList();

      gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); /*smooth shading*/
      gluQuadricNormals(qobj, GLU_NONE);
      glNewList(startList+3, GL_COMPILE);
            gluPartialDisk(qobj, 0.0, 1.0, 20, 4, 0.0, 225.0);
      glEndList();
}


void display(void)
{
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glPushMatrix();

      glEnable(GL_LIGHTING);
      glShadeModel(GL_SMOOTH);
      glTranslatef(-1.0, -1.0, 0.0);
      glCallList(startList);

      glShadeModel(GL_FLAT);
      glTranslatef(0.0, 2.0, 0.0);
      glPushMatrix();
      glRotatef(300.0, 1.0, 0.0, 0.0);
      glCallList(startList+1);
      glPopMatrix();

      glDisable(GL_LIGHTING);
      glColor3f(0.0, 1.0, 1.0);
      glTranslatef(2.0, -2.0, 0.0);
      glCallList(startList+3);

      glPopMatrix();
      glFlush();
}


void reshape(int w, int h)
{
      glViewport(0,0, (GLsizei) w, (GLsizei) h);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      if (w<=h)
            glOrtho(-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w,
            2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
}


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 | GLUT_DEPTH);
      glutInitWindowSize(500, 500);
      glutInitWindowPosition(200, 100);
      glutCreateWindow(argv[0]);
      init();
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutKeyboardFunc(keyboard);
      glutMainLoop();
      return 0;
}
0
map6
Asked:
map6
  • 4
  • 4
  • 4
  • +1
1 Solution
 
akshayxxCommented:
void CALLBACK errorCallback(GLenum errorCode)
..
try changing above function to
void CALLBACK errorCallback(void)

i suppose the callback function ptr should be of type
void (*fptr)(void)

good luck
akshay
0
 
akshayxxCommented:
its evident from the error message also.. that the call back function that u are setting is of the type

void (*fptr)(GLenum )...
while it expects
void (*fpt)(void)..

where GLenum == unsigned int
good luck
akshay
0
 
map6Author Commented:
Akshay I don't follow...
I should change the callback function from:
void CALLBACK errorCallback(GLenum errorCode)

TO:
void CALLBACK errorCallback(void)

and then what about the pointer?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
jerry_jeremiahCommented:
The bit about __stdcall means that the callback function must use stdcall calling convention instead of cdecl calling convention.  In short change the

#define CALLBACK

to

#define CALLBACK __stdcall
0
 
akshayxxCommented:
>>TO:
>>void CALLBACK errorCallback(void)

>>and then what about the pointer?
need not worry abt it.. just change the declaration and definition of the callback function.. as the "gluQuadricCallback" function expects that format only for the callback function

akshay
0
 
agri_amitCommented:
hi
make changes to this function like
void CALLBACK errorCallback(void * errorCode)
{
     const GLubyte *estring;

     estring=gluErrorString(errorCode);
     fprintf(stderr, "Quadric Error: %s\n", estring);
     exit(0);
}

//and if require, replace
estring=gluErrorString(errorCode);
with
estring=gluErrorString((GLenum )errorCode);
and with these changes also need to change the prototype of cooreponding functions.

Does this solve your problem?

Regards,
Amit

0
 
akshayxxCommented:
Did you try out any of the suggestions mentioned here? let us know if u need futher help

Akshay
0
 
map6Author Commented:
Still getting the same error.

If I take this route:
void CALLBACK errorCallback(void * errorCode)
{
     const GLubyte *estring;

     estring=gluErrorString(errorCode);
     fprintf(stderr, "Quadric Error: %s\n", estring);
     exit(0);
}
----> I still get the original error and a new one which requires me to replace
estring=gluErrorString(errorCode);
with
estring=gluErrorString((GLenum )errorCode);



...So still same error about trying to convert the unsigned integer
0
 
jerry_jeremiahCommented:

If the error is:

error C2664: 'gluQuadricCallback' : cannot convert parameter 3 from 'void (unsigned int)' to 'void (__stdcall *)(void)'

Then, just as akshayxx said, you need to define errorCallback as

#define CALLBACK __stdcall
void CALLBACK errorCallback(void)

Because the third parameter of gluQuadricCallback must be of type "void (__stdcall *)(void)"

That means no variable is passed into the callback.  But gluGetError should provide the error code that you were thinking would be passed into the callback.

Jerry
0
 
agri_amitCommented:
u can also use approach suggested by jerry_jeremiah.
In this case u also need to call a function in errorCallback, which retreive last error occured.
So try to find  "GetLastError" equivalent function in OpenGL Programming Guide.
0
 
jerry_jeremiahCommented:
Maybe I'm confused but isn't that what the  gluGetError()  function that I suggested actually does?

Jerry
0
 
map6Author Commented:
I made changes to the definition of CALLBACK, and that segment of the code looks as follows:
------------------------------------------------
#define CALLBACK_stdcall


GLuint startList;

void CALLBACK errorCallback(void)
{

      const GLubyte *estring;

      estring=gluErrorString((GLenum)errorCode);
      fprintf(stderr, "Quadric Error: %s\n", estring);
      exit(0);
}
---------------------------

However, now I get a declaration error:

C:\..........: error C2065: 'errorCode' : undeclared identifier
0
 
jerry_jeremiahCommented:

Ok, so I am wrong.  You need to have the error code in
the declaration of the callback because according to
http://www.mevis.de/~uwe/opengl/gluQuadricCallback.html
the callback has the error code passed as a parameter.
But you can't use the name of the callback as a parameter
to gluQuadricCallback because its expecting a callback
function that takes no arguments.

I am sorry for leading you down the wrong path.
I assumed (wrongly) that if the callback passed
in had to take zero arguments that the callback
itself when called wouldn't take any arguments...

So the only way to fix this is to cast the function
pointer while passing it into gluQuadricCallback.
Not a good situation.  Really gluQuadricCallback
should take a pointer to a function taking an argument...

So try this and see if it works:

gluQuadricCallback(qobj, GLU_ERROR,(void*)errorCallback);

If that doesn't work try this:

gluQuadricCallback(qobj, GLU_ERROR,
     (void(CALLBACK*)())errorCallback);

Where errorCallback is:

void CALLBACK errorCallback(GLenum errorCode)
{
     const GLubyte *estring;

     estring=gluErrorString(errorCode);
     fprintf(stderr, "Quadric Error: %s\n", estring);
     exit(0);
}


The most confusing this is, here is some code I found on the internet:

http://meru.cecs.missouri.edu/courses/cecs361/projects/ws98/binary_solar/planet.c

Jerry
0
 
map6Author Commented:
OK this worked!!!
gluQuadricCallback(qobj, GLU_ERROR,
     (void(CALLBACK*)())errorCallback);

with;
void CALLBACK errorCallback(GLenum errorCode)
{
     const GLubyte *estring;

     estring=gluErrorString(errorCode);
     fprintf(stderr, "Quadric Error: %s\n", estring);
     exit(0);
}

Great, Thanks for all your help
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 4
  • 4
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now