OpenGLのglNormal系は、currentの法線を設定する関数である。

これはかなり当り前の話。ところが、OpenGLはステートマシンなので、「currentの」というところが意外なところで効いてくる。
OpenGLではglNormal系の関数に初期値が設定してある。(0, 0, 1)、すなわちz軸の方向になっている。

つまり、glNormal系の関数を使っていない場合は、すべての面がz軸を向いているという設定が採用されるわけです。たとえば、glMaterial系の関数はこの法線情報を利用するので、明らかにおかしな描画になります。当たり前といえば当たり前なのですが、全部が黒く描画されるとかではないので意外と気づかなかったりするものです。

もっとたちが悪いことに、glutSolidTeapotやGLUQuadricなどを使うと、「currentの」法線が書き換えられて返ってくるので(0, 0, 1)ですらなくなってしまいます。

これは、VBOを使っていても同じ。normal有りのVBOを使わないときちんと描画されません。

で、なんでこんなことに躓いたかというと、COLLADAのデータを読み込んで描画した際にCOLLADAのデータに法線情報が入っていないのにmaterialが設定してあって、馬鹿正直にそのデータ通りレンダリングしたら、なんだかおかしい感じになっちゃったからですw

OpenGLでテクスチャを張るとき、テクスチャの初期化時に

glTexGeni(
	GL_S, GL_TEXTURE_GEN_MODE,
	GL_SPHERE_MAP);
glTexGeni(
	GL_T, GL_TEXTURE_GEN_MODE,
	GL_SPHERE_MAP);

と書いて、描画時に

glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);

と書くと、基本的にテクスチャを自動生成してくれるわけですが(参考サイト:
床井研究室「第5回」, 床井研究室「第10回」)、

これだと、テクスチャがオブジェクトにはりついてくれていないので、球を回転させてもテクスチャが動いてくれないわけです。

このやり方はそもそも、glutSolidSphereがテクスチャ座標を生成してくれていないので、「自動生成」に頼るということなのですが、

gluSphereにはテクスチャ座標の生成がちゃんとあるので、それを使えばちゃんとテクスチャが晴れるわけです。

GLUquadricObj*の宣言

 GLUquadricObj* _sphere;
 

に対し、

_sphere = gluNewQuadric();
gluQuadricDrawStyle(_sphere, GLU_FILL);
gluQuadricNormals(_sphere, GLU_SMOOTH);
gluQuadricTexture(_sphere, GL_TRUE);

と、パラメータを設定。重要なのはgluQuadricTexture。ここで、GL_TRUEを設定することで、テクスチャ座標がちゃんと生成されます。

描画時には

glEnable(GL_TEXTURE_2D);
gluSphere(_sphere, 1.0, 32, 32);

とすればいいわけです。このとき、gluSphereが作ってくれるテクスチャ座標をさっきのテクスチャ自動生成が上書きしちゃわないように、glTexGeniやglEnable(GL_TEXTURE_GEN_S/T)はコメントアウト(というか削除)しておく必要があります。

テクスチャの生成やバインドはglGenTexturesやglBindTextureでふつうにやればOKです。

このときのテクスチャは作ったテクスチャに対して、photoshopなんかで「フィルタ」>「極座標変換」を選んで、極座標から直交座標へ変換を行って作りましょう。

で、個人的にはマルチテクスチャを球に張りたいのですが、さすがにマルチテクスチャ座標をgluQuadricが生成してくれそうにないんで、困ってます(笑)

さすがに自分で作りますかねぇw