Ask Your Question
0

Use setOpenGlDrawCallback with a function inside a class?

asked 2013-07-26 12:48:52 -0600

Elador gravatar image

updated 2013-07-26 12:50:57 -0600

Hi,

When I use

void on_opengl(void* userdata)
{
  // do stuff
}

int main(int argc, char *argv[])
{
  // stuff
  cv::setOpenGlDrawCallback("window", on_opengl, (void *)0);
  // stuff
}

it works fine. But when I try to move the callback-function inside a class:

Header:

namespace mylib {
class MyClass
{
public:
  MyClass();
private:
  void openGlDrawCallbackFunc(void* userdata);
};

CPP:

namespace mylib {

MyClass::MyClass()
{
  // stuff
  cv::setOpenGlDrawCallback("window", openGlDrawCallbackFunc, (void *)0); // errors on this line, on "openGlDrawCallbackFunc"
}

void MyClass::openGlDrawCallbackFunc(void* userdata)
{
  // stuff
}
}

it doesn't compile. The compiler gives the error

error C3867: 'mylib::MyClass::openGlDrawCallbackFunc': function call missing argument list; use '&mylib::MyClass::openGlDrawCallbackFunc' to create a pointer to member

Of course adding the "&" doesn't help. Intellisense shows a slightly different error,

Error: argument of type "void (mylib::MyClass::*)(void *userdata)" is incompatible with parameter of type "cv::OpenGlDrawCallback".

I included "opencv2/core/opengl_interop.hpp" and "opencv2/highgui/highgui.hpp", although the relevant stuff seems to be in highgui.hpp.

What is going wrong here and how can I do this?

edit retag flag offensive close merge delete

Comments

1 answer

Sort by ยป oldest newest most voted
1

answered 2013-07-26 14:32:05 -0600

berak gravatar image

it works with a class, it just needs some work with the indirection:

namespace mylib {
class MyClass
{
public:
  MyClass();
private:
  // note static, this-ptr cames per userdata
  static void openGlDrawCallbackFunc(void* userdata); 

  void realdraw(); // can call class data
};
}

namespace mylib {

MyClass::MyClass()
{
  // it needs a static callback function, and to save the instance pointer for later use:
  cv::setOpenGlDrawCallback("window", openGlDrawCallbackFunc, this); 
}

void MyClass::openGlDrawCallbackFunc(void* userdata)
{
   // we get back, what we passed in above,just cast it back:
   MyClass * ptr = static_cast<MyClass*>(userdata);
   ptr->realdraw();
}
void MyClass::realdraw()
{
}

}
edit flag offensive delete link more

Comments

Thank you, I perfectly understand the problem now! I was now just wondering, could this be done with boost::bind/function? I've used bind before but only for very simple things, nothing like this.

Elador gravatar imageElador ( 2013-07-26 17:03:05 -0600 )edit

ah, doubt it's worth the trouble.

also note, that you can only set the callback on the indow only once (unless you do your own chaining there). so it's kinda a singleton anyway.

berak gravatar imageberak ( 2013-07-27 02:07:05 -0600 )edit

I was just thinking about the case when I have two windows and two instances MyClass, each having their draw-method bound to one of the windows. But I guess your proposed code also works in that case.

Elador gravatar imageElador ( 2013-07-29 17:56:30 -0600 )edit

Question Tools

Stats

Asked: 2013-07-26 12:48:52 -0600

Seen: 1,088 times

Last updated: Jul 26 '13