- ベストアンサー
【OpenGL】オブジェクトを照らす照明(ライト)について
オブジェクトの周り360°を照明が回るようなプログラムを作りたいです。 その際、オブジェクトはもちろん固定された状態で、照明のライトは常にオブジェクトを照らした状態です。 照明に関する関数は、「glLightfv」があり,照明の位置を座標で設定できます。ですがこの関数では上の条件は実現できません。 また、対象が照明でなくオブジェクトならば、「glRotate」という関数で、あるオブジェクトの周囲を回す事はできるのですが.... どなたか、良い方法をご存知の方がいらっしゃいましたら、ご教授のほどよろしくお願いいたします。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
glLightfvを使用してでっち上げてみましたが,これでは駄目なんでしょうか? 理由はいろいろ考えられますが... 1.こういう意味ではない. 2.円運動の式が書けなかった. 3.ライティングを有効にしていなかった. 4.面の法線ベクトルを適切に設定していなかった. 参考に挙げさせて頂いた「GLUTによる「手抜き」OpenGL入門」はとてもわかりやすいので, もし未読でしたらおすすめさせて頂きます. /* * 「GLUTによる「手抜き」OpenGL入門」様 より引用・改変 * http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html */ #include <GL/glut.h> #include <math.h> GLdouble vertex[][3] = { { 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 1.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 1.0, 0.0, 1.0 }, { 1.0, 1.0, 1.0 }, { 0.0, 1.0, 1.0 } }; int face[][4] = { { 0, 1, 2, 3 }, { 1, 5, 6, 2 }, { 5, 4, 7, 6 }, { 4, 0, 3, 7 }, { 4, 5, 1, 0 }, { 3, 2, 6, 7 } }; GLdouble normal[][3] = { { 0.0, 0.0,-1.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, {-1.0, 0.0, 0.0 }, { 0.0,-1.0, 0.0 }, { 0.0, 1.0, 0.0 } }; GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 }; GLfloat red[] = { 1.0, 0.5, 0.5, 1.0 }; void idle(void) { /* 描画を繰り返す */ glutPostRedisplay(); } void display(void) { int i; int j; GLfloat light0pos[] = { 0.0, 0.0, 0.0, 1.0 }; static double deg = 0; float L = 10; // 円の半径 float deg_add = 0.1; // 描画ごとの角度変化 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 光源の位置設定 */ light0pos[0] = L * cos(deg); light0pos[2] = L * sin(deg); deg += deg_add; glLightfv(GL_LIGHT0, GL_POSITION, light0pos); /* 図形の色 (赤) */ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, red); /* 図形の描画 */ glColor3d(0.0, 0.0, 0.0); glBegin(GL_QUADS); for (j = 0; j < 6; ++j) { /* 法線ベクトルの設定 */ glNormal3dv(normal[j]); for (i = 0; i < 4; ++i) { glVertex3dv(vertex[face[j][i]]); } } glEnd(); glutSwapBuffers(); } void resize(int w, int h) { glViewport(0, 0, w, h); /* 透視変換行列の設定 */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); 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); /* モデルビュー変換行列の設定 */ glMatrixMode(GL_MODELVIEW); } void init(void) { glClearColor(1.0, 1.0, 1.0, 1.0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, green); glLightfv(GL_LIGHT0, GL_SPECULAR, green); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); glutIdleFunc(idle); init(); glutMainLoop(); return 0; }
お礼
早々のご返答有難うございます。 ソースコードまで書いて頂き有難うございます。 やりたかった事はこの通りで、試してみたところできました! 出来なかった理由は、kirinomaさんに、ご指摘頂いた「2.円運動の式が書けなかった」です。私の頭の中では・・・ "light0pos[] = {0.0,0.0,0.0,1.0}" を "glLightfv"の第3引数に直接書くという発想しか思いつかなかったせいです。cos,sinを使用して"light0pos[0] = L * cos(deg);"のような書き方をするとできるいう事がわからなかったです。「GLUTによる「手抜き」OpenGL入門」も今後参考にさせて頂きます。本当にありがとうございました。