描画結果が黒くなる理由は様々考えられます.
以下のような事柄を確認してみてはどうでしょう.
提示コードには glEnable(GL_LIGHTNING);
がありますが,各光源の有効化処理はありません.
glEnable( GL_LIGHT0 );
のようなことを行っていますか?
- 法線が光源の方を向いていない とか 物体に届く光が弱すぎる とか
使用する光源の位置とかタイプとかの設定はどうなっていますか?
デフォルト状態がどうなってるのかを私は知りませんが,明示的に設定していないならばしてみてはどうでしょうか.
その上で,法線が光源の方向に向いているのかどうか等をチェックすると良いでしょう.
(そんなことになっているとは思えませんが,原因のひとつとして一応挙げてみる)
ライティングON状態で三角形を1個描画するだけのコードを示します.
とりあえず↓のコードで,三角形がそれなりに白く描画されてます.
GLFW と GLM を使ったコードになってはいますが,
- GLFW の部分は本件の内容とは無関係なのでどうでもいいところ
- GLM については glm::vec3 という float3要素なベクトル型を使っているだけです
…という感じなので,特にこれらのせいでコードの意味がわからんとかいうことにはならないだろうと思います.
このコードで,例えば以下のいずれかを行えば,三角形は黒くなりますね.
(その場合の光源設定がどうなるのか私は知らないけども)なんか光が当たらん感じの設定になるのだと思われ.
glEnable( GL_LIGHT0 );
をやらない:
光源が有効化されないので.
例えば Normal = -Normal;
とかすると,法線が光源が無い方向に向くことになるので.
int main()
{
//※GLFW ウィンドウ準備処理
GLFWwindow *pWindow = nullptr;
{
if( !(pWindow = glfwCreateWindow( 640, 480, "GLFW", NULL, NULL )) )return 1; //ウィンドウ生成
glfwMakeContextCurrent( pWindow ); //ウィンドウをGLの処理対象にする
}
//Clear Color 設定 : ※てきとーに「黒」とかとは区別がつく色にしている
glClearColor( 0.1f, 0.35f, 0.1f, 0.0f );
//三角形の3つの頂点の座標
const glm::vec3 Vtx[3] =
{
{ -0.7, -0.7, 0 },
{ -0.5, 0.75, 0 },
{ 0.8, 0, 0 }
};
//法線を求む(3頂点で同一値を使用)
glm::vec3 Normal = glm::cross( Vtx[1]-Vtx[0], Vtx[2]-Vtx[0] ); //外積
Normal = glm::normalize( Normal ); //正規化.→結果は(0,0,-1)になっている.
{//光源 LIGHT0 の設定.
float LightPos[] = { 0,0,-1, 0 }; //平行光源
glLightfv(GL_LIGHT0, GL_POSITION, LightPos );
}
//※念のためマトリクスを単位行列にしておく
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
//※GLFW的なメインループ
while( glfwWindowShouldClose( pWindow ) == 0 )
{
//※ESCキーで終了するためのGLFW的な記述
if( glfwGetKey( pWindow, GLFW_KEY_ESCAPE ) == GLFW_PRESS ){ glfwDestroyWindow( pWindow ); break; }
//描画処理
glClear( GL_COLOR_BUFFER_BIT );
glEnable( GL_LIGHTING ); //ライティング処理有効化
glEnable( GL_LIGHT0 ); //光源 LIGHT0 有効化
glBegin( GL_TRIANGLES );
{
for( int i=0; i<3; ++i )
{
glNormal3f( Normal.x, Normal.y, Normal.z );
glVertex3f( Vtx[i].x, Vtx[i].y, Vtx[i].z );
}
}
glEnd();
glDisable( GL_LIGHTING ); //ライティング処理無効化
//※GLFWの処理
glfwSwapBuffers( pWindow );
glfwWaitEvents();
}
return 0;
}
[編集:コメント欄の内容のうち,質問内容への回答的な要素がある部分を以下に移植しておく]
質問文記載の法線計算方法の話について
1と2どちらがただしいでしょうか。
とのことですが…
1.追記ベクトルA=(2,-1,3)のベクトルAを正規化しなさい
これは,単なる ベクトルの単位化 の話ですね.
L2ノルムで全要素を除すことで単位ベクトルが得られる,という普通の話です.
2.ポリゴンの3頂点をv1=(1,0,0),v2=(0,1,0),v3=(0,0,1)として法線を正規化しなさい
こっちは,三角形の法線方向ベクトルを外積で求めて,
その後でそれを前記1の話で単位化する,という話.
…なので,1と2の関係性というのは「2の計算は1の話を用いている」であり,「どちらが正しいか」という関係性ではないですよね.
1, 2 の話自体はごくごく普通の内容と見えます.
glScale の影響の話
glSacle のスケーリングが,glNormal3f で設定している値にまで効果を及ぼしてしまう,ということなんだと思います.
例えば,
glScalef( 2, 2, 2 );
...
glNormal3f( /*単位法線ベクトルのx,y,z*/ );
という形で書くと,結果として法線が長さ2になってしまうんでしょうね.
(で,変な単位ベクトルでない変な値で計算されてしまって,結果の色がおかしくなる,と.)
GL_NOMALIZE
とかいうのはこの嫌らしい効果に対抗するための手段…ということなのかな.
(ライティング処理の前に法線を正規化してくれる機能っぽい)