Я создал класс C ++ ( myPixmap
) для инкапсуляции работы, выполняемой инструментарием OpenGL GLUT. Функция-член display ()
класса содержит большую часть кода, необходимого для настройки GLUT.
void myPixmap::display()
{
// open an OpenGL window if it hasn't already been opened
if (!openedWindow)
{
// command-line arguments to appease glut
char *argv[] = {"myPixmap"};
int argc = 1;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(30, 30);
glutCreateWindow("Experiment");
glutDisplayFunc(draw);
glClearColor(0.9f, 0.9f, 0.9f, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glutMainLoop();
openedWindow = true;
}
}
Функция отображения, переданная в glutDisplayFunc ()
, является другой функцией-членом класса :
void myPixmap::draw(void)
{
glDrawPixels( m,n,GL_RGB,GL_UNSIGNED_BYTE, pixel );
}
Однако gcc 4.2.1 в Mac OS X 10.6.4 отказывается компилировать этот код, утверждая, что:
аргумент типа 'void (myPixmap ::) ()' не соответствует 'void (*) ()»
Есть ли способ использовать инструментарий GLUT внутри функции-члена класса, или я должен вызывать все функции GLUT в функции main
программы?
Проблема в том, что указатель на связанную с экземпляром функцию-член должен включать указатель this
. OpenGL — это C API, и он ничего не знает об указателях this
. Вам придется использовать статическую функцию-член (которая не требует экземпляра и, следовательно, не this
) и установить некоторые статические элементы данных (для доступа к экземпляру), чтобы использовать GlutDisplayFunc
.
class myPixmap
{
private:
static myPixmap* currentInstance;
static void drawCallback()
{
currentInstance->draw();
}
void setupDrawCallback()
{
currentInstance = this;
::glutDisplayFunc(myPixmap::drawCallback);
}
};
У вас также могут возникнуть проблемы с компоновкой C и компоновкой C++, и в этом случае вам придется поиграть с extern "C"
. Если это так, вам, возможно, придется использовать глобальную функцию, а не статическую функцию-член в качестве обратного вызова, и иметь этот вызов myPixmap::draw
. Что-то вроде:
class myPixmap
{
public:
void draw();
private:
void setupDrawCallback();
};
myPixmap* g_CurrentInstance;
extern "C"
void drawCallback()
{
g_CurrentInstance->draw();
}
void myPixmap::setupDrawCallback();
{
::g_CurrentInstance = this;
::glutDisplayFunc(::drawCallback);
}
При всем при этом старайтесь вносить как можно меньше изменений, так как это действительно своего рода кладж, чтобы иметь дело с OpenGL, являющимся C API.
Если вам нужно несколько экземпляров (я не думаю, что большинство людей, использующих GLUT, создают несколько экземпляров, но, возможно, вы это делаете), вам придется найти решение, используя std::map для получения экземпляра:
static std::map<int, myPixmap> instanceMap;
Я не уверен, где вы получите int
для разрешения какого экземпляра :)
К вашему сведению, вы должны определить функции, которые не принимают никаких параметров:
void some_function() { }
not
void some_function(void) { }