気まぐれLinux

なんかLinuxとかその他諸々について書くらしい

openGL難しい 〜光源〜

あるものを作ろうとしてCのopenGL APIを直接叩いている.Unityでもできるかもしれないが直接叩いている.

QtのウィンドウにGLWidgetを貼り付け,右にコントロールパネルを出す形にしようと思っている.

Qt をはじめよう! 第14回: GUI デザイナでのレイアウトに慣れよう! | Qt Japanese Blog

やはりopenGLは難しい.今日はまったのは(これ以外もあるけど)光源の設定.これまで光源を全く使ったことがなかった.

GLUTとOpenGLでライティングされた立方体を描画するプログラム | GLUTでOpenGL 3Dプログラミング

ここを参考にやったが,glEnable(GL_CULL_FACE);すると何も表示されなくなった.

LWJGL で Hello world してみる(ポリゴン表示編) / 桃缶食べたい。

どうやらこれは表示しない面を決める関数らしい.使用しなければ問題なくなるので使用しないことにした.

  // light1 平行光源
  const GLfloat light1Position[4] = {-30.0f, 100.0f, -30.0f, 0.0f};
  const GLfloat light1Diffuse[3] = {1.0f, 1.0f, 1.0f};   // white
  const GLfloat light1Specular[3] = {1.0f, 1.0f, 1.0f};  // white

  glEnable(GL_LIGHT0);
  glLightfv(GL_LIGHT0, GL_POSITION, light1Position);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light1Diffuse);
  glLightfv(GL_LIGHT0, GL_SPECULAR, light1Specular);

  // light2 環境光
  const GLfloat light2Position[4] = {0.0f, 10.0f, 0.0f, 1.0f};
  const GLfloat light2Ambient[3] = {0.5f, 0.5f, 0.5f};

  glEnable(GL_LIGHT1);
  glLightfv(GL_LIGHT1, GL_POSITION, light2Position);
  glLightfv(GL_LIGHT1, GL_AMBIENT, light2Ambient);

...
void GLWidget::paintObject() {
  static GLfloat diffuse[3] = {0.01960f, 0.40000f, 0.72157f};  // #0566b8
  static GLfloat ambient[3] = {0.01960f, 0.40000f, 0.72157f};  // #0566b8
  static GLfloat specular[3] = {1.0f, 1.0f, 1.0f};
  static GLfloat shininess[1] = {125.0f};

  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);

  glBegin(GL_POLYGON);
  {
    glNormal3f(0, 1, 0);
    glVertex3f(-50, 0, -50);
    glVertex3f(50, 0, -50);
    glVertex3f(50, 0, 50);
    glVertex3f(-50, 0, 50);
  }
  glEnd();
}

ここで,オブジェクト(平面)の向きが気になったので,反転させてみた.すると今度は真っ白になった.

f:id:yuntan_t:20140921214741p:plain

平行光源が効き過ぎたのかな?と思ったらこんな記事を見つけた.

OpenGL入門平面に光をあてるときの注意点

そこで,平面を分割すると

f:id:yuntan_t:20140921214820p:plain

望んでいたようになった.分割しないといけないことはなんとなく分かったが,真っ白になるのが解せない.

違う

色々間違ってた.法線ベクトルの計算と光源の配置が違ってた.直した.こうなった.いい感じ.

f:id:yuntan_t:20140922005746p:plain