• ベストアンサー

【OpenGL】オブジェクトを照らす照明(ライト)について

オブジェクトの周り360°を照明が回るようなプログラムを作りたいです。 その際、オブジェクトはもちろん固定された状態で、照明のライトは常にオブジェクトを照らした状態です。 照明に関する関数は、「glLightfv」があり,照明の位置を座標で設定できます。ですがこの関数では上の条件は実現できません。 また、対象が照明でなくオブジェクトならば、「glRotate」という関数で、あるオブジェクトの周囲を回す事はできるのですが.... どなたか、良い方法をご存知の方がいらっしゃいましたら、ご教授のほどよろしくお願いいたします。

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

  • ベストアンサー
  • kirinoma
  • ベストアンサー率53% (288/542)
回答No.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; }

参考URL:
http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html
unlonghorn
質問者

お礼

早々のご返答有難うございます。 ソースコードまで書いて頂き有難うございます。 やりたかった事はこの通りで、試してみたところできました! 出来なかった理由は、kirinomaさんに、ご指摘頂いた「2.円運動の式が書けなかった」です。私の頭の中では・・・ "light0pos[] = {0.0,0.0,0.0,1.0}" を "glLightfv"の第3引数に直接書くという発想しか思いつかなかったせいです。cos,sinを使用して"light0pos[0] = L * cos(deg);"のような書き方をするとできるいう事がわからなかったです。「GLUTによる「手抜き」OpenGL入門」も今後参考にさせて頂きます。本当にありがとうございました。

関連するQ&A

  • JavaScriptでArrayオブジェクトもどきの独自オブジェクトを作りたい!

    お世話になります。 JavaScriptを用いて、ある条件の下でArrayオブジェクトのような独自オブジェクトを定義したいのですが、ゆっくり調べている時間がなく、こちらの方を頼らせていただくことにしました。 【やりたいこと】 Arrayオブジェクトのような独自オブジェクトを定義したい。 【やりたいことの条件】 条件1: Arrayオブジェクトが戻り値として返ってくる既存の関数があり、その戻り値であるArrayオブジェクト自身を新たなオブジェクトとして定義したい。 この関数は、 ・Arrayオブジェクトの要素とは全く無関係の引数をとる。 ・この関数の仕様を変更することはできない。 という特徴があります。 条件2: 独自オブジェクトを作る際の引数は、上述の既存の関数の引数と同じ。 【サンプル】 上記の説明では、少々わかりにくいかもしれませんので、使い方のサンプルを以下に示します。 既存の関数: function immovableFunc(param1, param2) { var myArray = new Array; … return myArray; } 今回作りたいオブジェクト: PseudoArray 今回作りたいオブジェクトの使われ方: var pa = new PseudoArray(param1, param2); そもそも、このようなオブジェクトが作れるのか?、作れるとするならばどのように記述するのか?見当も付かない状態です。 皆さんのお知恵を拝借させていただければと思います。 どうぞ、よろしくお願いいたします。

  • C++でObjectの正面(Z+)に進む処理

    Objectを座標で動かす際、Z+に動かすとワールド座標でZ+に移動します。 ワールドでの移動はObjectのY軸に回転がかかっている状態でも動く方向は同じです。 それを例として、ObjectにY軸45度回転がかかっていたら そのObjectnの正面である、ワールド座標でZとXの間を斜め移動するようにしたいです。 三角関数などを利用すればできると思うのですがどうすればできるのか分りません。

  • OpenGLを使ったプログラムについて

    BorlandC++Builder4を使っています。 OpenGLを使って3次元グラフィックを扱うソフトの開発を目標にしており、勉強を始めたばかりなのですが、現在は最終目標の前段階として、OpenGLを使って2次元のペイントソフトを作ろうとしています。 【プログラムの機能・概要】 ・マウスを使っての描画 ・消しゴムのような消去機能 ・指定範囲内の描線の切り取り&移動機能 他にも色の取得や選択など機能を追加していく予定ではありますが、とりあえず上の3つの基本機能を作ろうとしています。切り取り&移動は消去機能が完成した後かな、という感じです。 【プログラムの骨子】 ・OpenGLPanelとTimerをForm上に配置 ・OnMouseDownイベント時に、左クリックで描画開始、右クリックでクリックした座標の指定した範囲の周囲にある描線を消去開始 ・OnMouseMoveイベント時に、左クリックしている間は描線表示、右クリックでクリックしている間は周囲の描線を消去 ・OnMouseUpイベント時に、左クリックUpで描画終了、右クリックUpで消去終了 ・Timerで、描画中のマウス座標を指定時間ごとに記録 考えたのはこんな感じなんですが、これでペイントソフトとして機能させることは可能でしょうか?足りない部分があれば指摘をお願いします。 【わからないこと】 ・座標の記録方法(どのような関数を用いてどんな風に記述すればよいか) ・OnMouseDown、OnMouseMoveの各イベントで、保存した座標を呼び出す方法 glVertex*()を使うことになると思うんですが、具体的にどのように記述すればいいのかわかりません。 ちょっと混乱していて質問自体におかしいところが多いかもしれませんが、どんなことでも構わないのでアドバイス宜しくお願いします。

  • blenderオブジェクトを任意の場所に複数コピー

    次のような操作をしたいと思っています。スクリプト等で行う方法をご存じありませんか? 【状況】 オブジェクト名「1」~「10」まで10個のオブジェクトをそれぞれ別の座標に配置。それらとは別にオブジェクト「A」を用意。 【操作】 オブジェクト「A」をオブジェクト「1」~「10」のある各座標に一括でコピーして配置。 (つまり、操作後にはコピー元のオブジェクト「A」が1つと、「1」~「10」の位置に移動しコピーしたオブジェクト「A」が計10個あり、編集しているblenderプロジェクト上にはオブジェクト「A」が11個存在することになる。) 一つ一つならば当然できます。オブジェクト「1」を選択してカーソルを選択物へ移動。オブジェクト「A」を選び複製してそれをカーソルの場所へ移動。これを10回繰り返せばできます。 これを一括で操作したいです。「1」~「10」までをすべて選択し、その状態で最後に「A」も追加で選択。コピー先の「1」~「10」のオブジェクトは橙色の選択状態で、コピーしたいオブジェクトが黄色で選択されている状態。ここで何かしらの操作をすればできそうな気がしますが、プログラミング等の知識がないため、スクリプトを自分で書くことができません。

  • openGLの回転の仕組みが分からなくて、困っています

    openGL初心者です。描画関数で以下のような書き方でx軸、y軸、z軸それぞれに角度を与えてオブジェクトを描画しているのですが、意図した角度に回転してくれません。 一応自分の認識では、openGLでは以下のような書き方をすると、まずオブジェクトの描画がされて、次にz軸の回転→y軸の回転→x軸の回転と、処理の順番とは逆に計算が行われると知ったのですが、まずその認識は正しいでしょうか? そこで、実際にx、y、z軸にそれぞれ角度を与えてオブジェクトを回転させてみるのですが、どうも意図した回転にならないのです。 例えばz軸に90度の値を与えて、オブジェクトを横に倒したとします。 まず、その状態でローカル座標系のx軸とy軸がz軸を中心に90度回っていると思っています。 その後、y軸に90度の値を与えても、ローカル座標系のy軸を中心に回らず、まるでワールド座標系のy軸を中心に90度回りまわっているように見えます。また、x軸も同様にワールド座標系のx軸を中心に90度回ります。 そこで、ワールド座標系で回るのかと思い、今度は、ニュートラルの状態から、y軸を90度回します。ローカル座標ではx軸、z軸がy軸を中心に90度回ると思います。次にx軸に対して、角度を与えてやると今度はローカル座標系のx軸を中心にまわるのです。 何故このような回転をするのかイメージできません。。どなたか回答いただけませんでしょうか? それと本当にやりたいことは、オブジェクトがどのような姿勢で回転していても(ローカル座標系がどうであれ)ワールド座標系のx、y、z軸を中心に回転させたいのですが、宜しければその辺も合わせて教えて頂けたら幸いです。 (数学の知識も乏しいので、数式がちゃんとあるのなら、その名前を教えていただければ直幸いです。) 乱文失礼します。 public void display(GLAutoDrawable drawable) { gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gluLookAt((double) 0.0f, (double) 0.0f, (double) 5.5f, (double) 0.0f, (double) 0.0f, (double) 0.0f, (double) 0.0f, (double) 1.0f, (double) 0.0f); gl.glEnableClientState(GL.GL_VERTEX_ARRAY); gl.glEnableClientState(GL.GL_COLOR_ARRAY); gl.glRotatef(AngleX, 1, 0, 0); gl.glRotatef(AngleY, 0, 1, 0); gl.glRotatef(AngleZ, 0, 0, 1); // オブジェクト描画 draw(gl); gl.glDisableClientState(GL.GL_COLOR_ARRAY); gl.glDisableClientState(GL.GL_VERTEX_ARRAY); }

  • キッチン照明に悩みます・・・

    現在、マイホームを購入しリフォームにかかろうとしています。 照明について教えて下さい。 キッチンは吊り戸棚がないオープンI型で背後は吊り戸棚と下にカップボード設置予定です。キッチンの左にダイニングテーブルがあります。 設計士サンと照明の話しになり今現在の案はキッチンとカップボードの間の天井にダウンライトを2つ、キッチンの上に1つか2つと話しがあります。参考までに→キッチンの奥に冷蔵庫があり(順番に冷蔵庫→ガス台→シンクと言うながれで)長さ3300はあります。 私の不安にアドバイス下さい。 1、今まで使っていた、吊り戸棚の下に蛍光灯が付く一般的なタイプに慣れているせいもありダウンライトになると天井からの位置に手元が照らされるのか不安もあります。 2、ダウンライトを付けるとすれば配置と電球の明るさ(ワット)商品のお勧めを教えていただきたいです。 3、ダウンライトに電球の角度を変えれる商品もありますが使われている方がいましたらご意見聞かせて下さい。常に向きを変える物でもないと思うので役にたつか?特に要らなかったか?      

  • body内で<script>の位置のオブジェクトを取得する方法

    javascriptで、下記状況でNode(もしくはObject)を取得する方法がないか探しています。 body内の所定の場所に、<script>タグによりJavaScriptが記述されており、 その<script>タグ内で、<input>を生成しそれに対しイベントの追加や所定の処理を行いたいのです。 例)-------------------------------------------------- <body> <input type="text" value=""> <script type="text/javascript"> /* ここで、inputを生成後そのObjectに対して処理を行うため、 inputのオブジェクトをnameやidを使わず取得したい。 */ </script> <input type="text" value=""> </body> -------------------------------------------------- document.writeでinputの生成はできますが、目的に合わないかなと思っています。 理由として、厳密にObjectは取得できない場合があると考えています。 document.write("<input type='button' name='hoe'..."); document.getElementsByName("hoe"); と行えば取得できるとおもいますが、nameでは重複しているときに、処理の対象が特定できない(と思っている)ためです。 idも、処理のためだけにid付するのは、避けたいなと考えています。 そこで、<script>の位置(もしくは親)のnodeを取得できれば,そこからappend出来る可能性があると、発想したのですが、その方法が分からず詰まってしまいました。 (対象ブラウザIE6以降) <body>内の<script>位置のnodeを取得する方法か、別の発想で上記を実現できる方法があれば、教えてください。

  • 防犯のための夜間照明(?)

    家を建てて30年を越えています。ずっと玄関照明にこだわり、勝手口にも照明をつけています。周囲にもセンサーライトを角ごとにつけて、数年前から玄関、勝手の照明もEEセンサーで夜間照明の常夜灯になって居ます。家内は、もったいない、必要ないとことあるごとに消して周るので、今はスイッチを接着剤で固定しています。 私の考えは、電気代はわずかなもので、泥棒に入られたら電気代どころではない、安心代だというのですが、家内は納得しません。 住み始めたころは向こう三軒両隣り、裏も含め全部空き地で、物騒だったこともあります。現在は私の家の周囲に3軒建ちました(が、残りのスペースは空き地のままです。 おかげさまで(かどうかわかりませんが)今までのところ泥棒に入られたことはありません。 私の町内(郊外)ではかなりの家が空き巣(昼間)に入られています。夜間入られた家も数年前一軒ありました(女ばかりの家で、うちよりも孤立した場所です。 以前空き巣に入られたとかで、民間のセキュリティに委託して警報(誤動作?)が時々なる家が2軒近所にありますが、ここも夜間外周は真っ暗で玄関灯もつけていません。 ここで質問です。 家内が言うには、泥棒は昼間はいるもので、夜間の照明は役に立っていない、というのです。これは本当でしょうか?単なる気休めに過ぎないのでしょうか?でなければどうして家内を説得したらいいのでしょうか?

  • オブジェクトごとに自由に配置したいのですが、うまくいきません。

    flashサイトを参考本を見ながら作っています。 頼れる人もいなくてここにたどり着きました。 やりたいことは、オブジェクトごとに配置したいのです。ロゴマークは左上、ボタンAは中央に、メニューは右下という風に。 問題は、ステージリサイズをしても、位置関係は常に保たれていると言うことです。ステージリサイズをしてもロゴは常に左上にあり、メニューは右下にあるという状態を作りたいのです。 どの本を見ても載ってません。どなたか良いアドバイス、もしくはこの本にあったよでもかまいません。よろしくお願いいたします。

  • 天井照明器具の交換

    現在、天井備え付けの照明(長方形で、蛍光管が4本のタイプ)を別の照明に交換しようと考えています。 カバーをあけてみたところ、照明のケーブル(?)は引っ掛けシーリングに接続されていましたが、 天井側の引っ掛けシーリングは天井に固定されておらず、天井にあいた穴から垂れ下がっている状態でした。 また、照明器具の四隅を天井に直接ネジ止めされていました。 穴が開いているところから見る限りでは、1cm~2cm程度の石膏ボードだと思われます。 天井に直接ネジ止めされている付近を指でたたいてみましたが、 石膏ボードの奥に木がある感触はありませんでした。 この状態の照明を、IKEAで販売されている照明に交換しようとおもっています。 IKEAの照明は引っ掛けシーリングに接続する部分と天井に固定する部分が別なので、 今回のようなケースに使用できるのではないかと考えています。 皆さんにアドバイスを頂きたいのですが、 うまく設置できるアイデア等ありませんでしょうか? ※既存のネジ穴を使う、等。(ネジ穴の位置はあいませんが・・・) 宜しくお願い致します。

専門家に質問してみよう