Hello, guys.
I'm trying to make a program using C++ and OpenGL, but i'm facing some difficulties. I created a class that i called "Keyboard", in this class i've tryied to implement a callback called "keyPressed". When i try call "glutKeyboardFunc" of the GLUT in main method, i have this error message:
error: argument of type ‘void (Keyboard::)(unsigned char, int, int)’ does not match ‘void (*)(unsigned char, int, int)’
Below, you can see my code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//keyboard.h
#ifndef __keyboard_h__
#define __keyboard_h__
#include<iostream>
#include<GL/gl.h>
#include<GL/glut.h>
#include<GL/glx.h>
usingnamespace std;
class Keyboard
{
public:
Keyboard(void);
~Keyboard(void);
void keyPressed (unsignedchar key, int x, int y);
};
#endif
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//keyboard.cpp
#include"keyboard.h"
Keyboard :: Keyboard(void)
{
cout<<"Object created."<<endl;
}
Keyboard :: ~Keyboard(void)
{
cout<<"Object killed with success."<<endl;
}
void Keyboard :: keyPressed(unsignedchar key, int x, int y)
{
// Not yet implemented.
}
I've had this problem too, the thing is that OpenGL expects a C-style function callback, and you can make callbacks to member-functions. It sucks... If I remember exactly what I did I'll get back to you :P
EDIT:
Ok, so what I did was keeping a global instance of the class I wanted to register the callback with (in this case it would be an instance of your Keyboard-class), and then create a "normal" keyboard function that just called the keyboard-function in that global instance.
Ok man, but i have a new problem.
When i run y program, what i see is
Object created.
Object killed with success.
I thought the "main" method would be waiting i push a button on the keyboard. I'm saying this because of "glutMainLoop();".
Why it doesn't happen, and the "glutMainLoop();" method does not enter in loop?
I've changed the "keyPressed" method to do a simple test.
1 2 3 4 5 6 7 8
void Keyboard :: keyPressed(unsignedchar key, int x, int y)
{
switch(key)
{
case'j': cout<<"Nothing, just testing."<<endl;
break;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//Archive main.cpp
#include"keyboard.h"
Keyboard global_keyboard;
void keypress_wrapper(unsignedchar key, int x, int y)
{
global_keyboard.keyPressed(key, x, y);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutKeyboardFunc(keypress_wrapper);
glutMainLoop();
}
Have you registered a callback for glutIdleFunc? I think the glutMainLoop will exit immediately if you haven't, because there isn't really anything for it to run.
where renderScene is where you do all the drawing. This is strictly not recommended, because it will cause the program to redraw as fast as possible, but it will work fine to begin with.
But i'm not trying to draw nothing, yet. You said that i have to register a callback for glutIdleFunc. In my case is "keyPressed(unsigned char key, int x, int y)" as you can see, the arguments are different that glutIdleFunc accepct.
void glutIdleFunc(void (*func)(void));
I've tried: glutIdleFunc(keypress_wrapper);
And i have this error message:
invalid conversion from ‘void (*)(unsigned char, int, int)’ to ‘void (*)()’
Well, you don't need to draw anything yet, but you need to have an idlefunc, which is the function glut calls everytime it redraws. You can probably leave the function empty, but you need to have it. You can't register the keyboard function as the idle function, the way you were doing it before was correct. Putting this into your code from before we get:
So, i've asked this question in opengl forum,and a guy answered me.
Take a look in his answer:
You have to create a window.Until you have a window, you don't have a window message processing loop. And without that, you can't have idle time (ie: when you're not processing messages). You can't process keyboard messages because you can't process messages.
GUI programming is generally built around a window of some sort. In Win32 especially, the Window is what gets keyboard messages, not the application. That's why different windows of the same application can process keyboard messages differently.
Then i created a window and now everything is working fine.