OpenGLで登録したコールバック関数の引数

このQ&Aのポイント
  • OpenGLで画面を描画する際にglutDisplayFuncに関数を登録する方法について
  • 画面描画に関するコールバック関数の引数についての質問です
  • グローバル変数を使用せずに、ポインタや引数を使用してコールバック関数に値を渡す方法について教えてください
回答を見る
  • ベストアンサー

OpenGLで登録したコールバック関数の引数

OpenGLで画面を描画をする際に, 以下のソースのように,glutDisplayFuncに関数を登録しています. main関数で,定義した定数や,そのポインタを display_funcに渡したいと思うのですが, どのような方法があるのでしょうか? 現在,私は,グローバル変数を定義して,それをmain関数とdisplay関数で いじっています. ソースコードの整理,関数化のため,できれば,ポインタや引数を渡したいです. どうぞよろしくお願いします. --------------------------------------------- #include <GL/glut.h> void display_func(void) { 描画内容を記述 } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display_func); glutMainLoop(); return 0; } ---------------------------------------------

質問者が選んだベストアンサー

  • ベストアンサー
  • qwertfk
  • ベストアンサー率67% (55/81)
回答No.2

> OpenGLを使用した3Dゲームなどは,グローバル変数,構造体がたくさんあるのですかね? ちょっとこれは説明が難しいのですが、たとえば // 建物 typedef struct {  // 略 } Building; // 道 typedef struct {  // 略 } Road; // 地形 typedef struct {  // 複数の建物  Building* buildings;  int numBuildings;  // 複数の道  Road* roads;  int numRoads; } Terrain; // 車 typedef struct {  // 略 } Car; // シーン全体を表す. // シーンには地形があり, そこに何台かの車が走っている. typedef struct {  // 地形  Terrain* terrain;  // 複数の車  Car* cars;  int numCars; } Scene; Scene g_scene; void display_scene(Scene* scene) {  display_terrain(scene->terrain); // 実装は略  for( int i = 0 ; i < scene->numCars ; ++i )  {   display_car( &scene->cars[i] ); // 実装は略  } } void display_func(void) {  display_scene(&g_scene); } ちょっと長くなってしまいましたが、たとえばこのようにデータ構造を作っていくとグローバルにもつ値はシーンを表す1つの変数があれば良いことになります。 また、関数も上記のように階層上に作っておけば、実質的にはグローバル変数は1つだけで、それを参照する関数もdisplay_func()1つだけで良くなります。 glutを使う場合ある程度グローバル変数を使うのはやむを得ないのですが、データ構造を正しく設計できている場合、グローバル変数はほんの数個、グローバル変数へアクセスする箇所も極一部に抑えることができます。

hhsato
質問者

お礼

丁寧な回答をありがとうございます. なるほど!! とても勉強になりました. C++のクラスのようなものですか. 長々とソースを書いていただき,ありがとうございました. 教えていただいた知識をもとに,私のソースを書き直していこうと思います. 本当にありがとうございました.

その他の回答 (1)

  • qwertfk
  • ベストアンサー率67% (55/81)
回答No.1

直接渡すのは無理です。 typedef struct {  int i; } Values; Values g_values; void display_main(Values* v) { } void display_func(void) {  display_main(&g_values); } こんな感じにするしかないと思います。

hhsato
質問者

お礼

丁寧なご回答ありがとうございます. やはり,無理なのですか.. 残念です. OpenGLを使用した3Dゲームなどは,グローバル変数,構造体がたくさんあるのですかね?

関連するQ&A

  • openGLについて

    最近プログラムを学んでいる初心者の者です。 私は床井研究室の”GLUTによる「手抜き」OpenGL入門”というサイトを使い学んでいるのですが、最初の段階でつまずいてしまいました。 最初のウィンドウを開く段階で #include <GL/glut.h> void display(void) { } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; } とすると書いてあるのですが、 最初の#includeのところがペーストしてもエラーが出ます。 あと他のサイトを見ると#includeが複数書かれているようです。 何か解決する方法はありますでしょうか。 ちなみに 私が使っているのはwindows7です。 どうかお願いします。

  • BCCDeveloperでのOpenGLのコンパイルについて

    環境は BorlandC++Compiler Version 5.5 Developer Version1.2.21 GLUT Version 3.7 OS WindowsXP PC NEC LL730/7 です。 GLUTをインストールし、次のプログラムをコンパイルしたのですが、コンパイルエラーは出なかったのですが、実行時に 「プロシージャ エントリ ポイント _glutCreateWindow@4がダイナミック リンク ライブラリ GLUT32.DLL から見つかりませんでした。」 と言うエラーメッセージが出ました。 原因がわかる方がいれば教えてください。 #include <GL/glut.h> void display(void) { } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }

  • OpenGLでのプログラミングについて質問です

    http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#7.2 上記URLのソースについて幾つか質問です。 1.以下の用に記述すると、何故以前のラバーバンドを消去することになるのでしょうか? if (rubberband) { /* 以前のラバーバンドを消す */ glVertex2iv(point[pointnum - 1]); glVertex2iv(savepoint); } 2.以下の部分の、staticはどういう役割をしているのでしょうか? void motion(int x, int y) { static GLint savepoint[2]; /* 以前のラバーバンドの端点 */ 3.メインは、以下のように記述されているのですが、OpenGLは通常のCプログラミングと違い、上から下に順次処理されて行っているだけでなく、見えない部分でも何か処理をやっているようなのですが、どういう順序でこのmainは処理されているのでしょうか? int main(int argc, char *argv[]) { glutInitWindowPosition(100, 100); glutInitWindowSize(320, 240); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); glutMouseFunc(mouse); glutMotionFunc(motion); init(); glutMainLoop(); return 0; } あと、 http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#6.1 に書かれている、 glOrtho(-w / 200.0, w / 200.0, -h / 200.0, h / 200.0, -1.0, 1.0); という関数の意味がよく分かりません。 どなたか、どれか一つだけでも良いので解答をお願いします。

  • OpenGLについて質問があります。

    底から見上げているように立方体がみえるように実行したいんですけどここからどうしていいかわからなくてわかる方いたら教えてください。お願いします。 #include <GL/glut.h> GLdouble vertex[][3] = { { 0.0, 0.0, 0.0 }, /* A */ { 1.0, 0.0, 0.0 }, /* B */ { 1.0, 1.0, 0.0 }, /* C */ { 0.0, 1.0, 0.0 }, /* D */ { 0.0, 0.0, 1.0 }, /* E */ { 1.0, 0.0, 1.0 }, /* F */ { 1.0, 1.0, 1.0 }, /* G */ { 0.0, 1.0, 1.0 } /* H */ }; int edge[][2] = { { 0, 1 }, /* ア (A-B) */ { 1, 2 }, /* イ (B-C) */ { 2, 3 }, /* ウ (C-D) */ { 3, 0 }, /* エ (D-A) */ { 4, 5 }, /* オ (E-F) */ { 5, 6 }, /* カ (F-G) */ { 6, 7 }, /* キ (G-H) */ { 7, 4 }, /* ク (H-E) */ { 0, 4 }, /* ケ (A-E) */ { 1, 5 }, /* コ (B-F) */ { 2, 6 }, /* サ (C-G) */ { 3, 7 } /* シ (D-H) */ }; void display(void) { int i; glClear(GL_COLOR_BUFFER_BIT); /* 図形の描画 */ glColor3d(0.0, 0.0, 0.0); glBegin(GL_LINES); for (i = 0; i < 12; ++i) { glVertex3dv(vertex[edge[i][0]]); glVertex3dv(vertex[edge[i][1]]); } glEnd(); glFlush(); } void resize(int w, int h) { glViewport(0, 0, w, h); glLoadIdentity(); // glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0); gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0); //glTranslated(0.0, 0.0, -5.0); gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void init(void) { glClearColor(1.0, 1.0, 1.0, 1.0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

  • OpenGLでウィンドウハンドルの取得

    コンソールアプリで作ることが前提です。 glut関数で作成したウィンドウのハンドルを取得し、その画面上に文字を表示しようとTextOutやDrawTextやらを使ってみたんですが、背景色しか表示されません。DrawTextの戻り値が18だったので成功していると思うのですが。どこがおかしいのかご指摘をお願いします。 #include<stdio.h> #include<windows.h> #include<GL/glut.h> HWND hwnd; void display(){ glClearColor(0.5,0.5,0.5,1); glClear(GL_COLOR_BUFFER_BIT); hwnd=GetActiveWindow(); PAINTSTRUCT ps; HDC hdc; RECT rect; LPCSTR str = TEXT("あああ"); GetClientRect(hwnd, &rect); hdc = BeginPaint(hwnd, &ps); SetRect( &rect, 10, 10, 100, 100); TextOut(hdc, 10, 10, str, lstrlen(str));    DrawText(hdc, TEXT("あああ"), -1, &rect,DT_CENTER); EndPaint(hwnd, &ps); glFlush(); } int main(int argc,char **argv){ glutInit(&argc,argv); glutInitWindowSize(640,480); glutCreateWindow("aaa"); glutDisplayFunc(display); glutMainLoop(); return(0); }

  • C言語での関数の引数の受け渡しについて

    C言語での関数の引数の受け渡しについて教えてもらいたいのです。 char *p=Goo;  というポインタpがmain関数で定義され、このポインタpをある関数 void func(・・・) に渡すことは出来ますか? つまりポインタを実引数として扱うことはできるのかという事ですが・・・ int p=10; とかだったら、 void func(int test) の関数には、main関数で func(p) で仮引数testにわたせると思うんですが・・・ もし出来るようでしたら、関数の渡し方と定義の記述を教えてください。 どうか宜しくお願いします。

  • コマンドライン引数argv[]について

    C言語初心者です。以下のようなプログラムを書いたのですが、コンパイルで来ません。関数func1, func2を分けずに全てメインに書けば動作するのですが、なぜ関数に分けてしまうとコンパイル出来ないのかがわかりません。エラー内容は、argvが宣言されていない、といった内容です。 #include <stdio.h> void func1(void){ printf("%s\n", argv[1]); } void func2(void){ printf("%s\n", argv[2]); } int main(int argc, char *argv[]){ if(strcmp(argv[1], "abc")==0){ func1(); } else{ func2(); } }

  • 関数の引数の書き方。

    AとBのどちらの書き方でもよいのですか? 私が読んだ本(やさしいC)には、 Aパターンのみだったような? Aパターン ------------------ void main(int argc,char *argv[]) { int i; ・・・・ } Bパターン ------------------ void main(argc, argv) int argc; char *argv[]; { int i; ・・・・ } http://ash.jp/db/ora_c.htm

  • メイン関数

    メイン関数には int main(void) と int main(int argc, char** argv) がありますが、後者のint argc, char** argv はどういう意味なのでしょうか?

  • OpenGLの惑星プログラム

    /* p4-MovingPlanet.c * Animation for a solar system ( see p3-planet.c ) using by glutTimerFunc(). */ #include <stdlib.h> #include <GL/glut.h> #include <math.h> int year = 0, day = 0; int samplingTime = 50; void myKeyboard(unsigned char key, int x, int y) { if ( key == 27) exit (0); } void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3d(1.0, 1.0, 1.0); glPushMatrix(); glutWireSphere(1.0, 20, 16); // sun glRotated((double)year, 0.0, 1.0, 0.0); glTranslated(3.0, 0.0, 0.0); glRotated((double)day, 0.0, 1.0, 0.0); glutWireSphere(0.2, 10, 8); // planet glPopMatrix(); glutSwapBuffers(); } void myInit(char *progname) { int width = 500, height = 500; glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(width, height); glutInitWindowPosition(0, 0); glutCreateWindow(progname); glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.0, (double)width / (double)height, 0.1, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void myTimer(int value) { if (value==1) { glutTimerFunc(samplingTime,myTimer,1); year = (year+1) % 360; day = (day+5) % 360; glutPostRedisplay(); } } int main(int argc, char** argv) { glutInit(&argc, argv); myInit(argv[0]); glutKeyboardFunc(myKeyboard); glutTimerFunc(samplingTime, myTimer, 1); glutDisplayFunc(myDisplay); glutMainLoop(); return 0; } このプログラムを改良して太陽系(水星~天王星)のプログラムを作成したいです。何を加えればいいんですか?教えてください><よろしくお願いします!!!

専門家に質問してみよう