web-dev-qa-db-ja.com

クラス内でのOpenGLglutDisplayFuncの使用

OpenGLGLUTツールキットによって実行される作業をカプセル化するためにC++クラス(myPixmap)を作成しました。クラスの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 );
}
_

ただし、Mac OS X10.6.4のgcc4.2.1は、次のように主張して、このコードのコンパイルを拒否します。

argument of type 'void (myPixmap::)()' does not match 'void (*)()'

クラスのメンバー関数内でGLUTツールキットを使用する方法はありますか、またはプログラムのmain関数内ですべてのGLUT関数を呼び出す必要がありますか?

27
Nicholas Kinar

問題は、インスタンスにバインドされたメンバー関数へのポインターにthisポインターを含める必要があることです。 OpenGLはCAPIであり、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"をいじる必要があります。その場合、コールバックとして静的メンバー関数ではなくグローバル関数を使用し、that call 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がCAPIである場合に対処するための一種の手間です。

複数のインスタンスが必要な場合(GLUTを使用しているほとんどの人が複数のインスタンスを作成するとは思いませんが、おそらくそうです)、std :: mapを使用してインスタンスを取得するソリューションを理解する必要があります。

static std::map<int, myPixmap> instanceMap;

intを解決する場所whichインスタンス、わかりません:)

参考までに、次のようにパラメータをとらない関数を定義する必要があります。

void some_function() { }

ない

void some_function(void) { }
32

このチュートリアルを確認してください。これがあなたが探しているものだと思います: http://paulsolt.com/2010/08/glut-object-ordinated-framework-on-github/

4
shox_de_coder

Merlynソリューションは私には機能しなかったので、currentInstanceをクラスの外に持ってくることによって少し変更を加え、それは機能しました:

Class myPixmap;
static myPixmap* currentInstance;
Class myPixmap {
...
}
2
Tqq

マーリンからの正解を理解するのに苦労したので、ここに簡略版を示します。

myPixmap.hで、表示関数をstaticメンバー関数に変更します。動作するはずです。

class myPixmap
{
  //...
  static void display();
  //...
};
1