OpenGL初期化glBegin()までのデフォルトコード


OpenGLSimpleAdapter などを利用することで、OpenGLがウィンドウに出るようにすることが出来た後でも、OpenGLでは、形状の描画を行うglBegin()を記述するまでに、事前に記述しなくてはならない七面倒くさい各種初期設定がある。もちろん初心者がそれらの意味を理解することは非常に重要だ。しかしどんなにOpenGLを使い慣れても、関数名や引数の詳細までは覚えられない。簡単な描画系を記述するたびにそれらの一つ一つを、昔のコードなどから切り出してくるのは非常にかったるいことだ。
具体的にやるべきことは以下のような内容だ。

  1. (OpenGLSimpleAdapter などを利用することで、OpenGLがウィンドウに出るようにする。)(必須でしょ
  • ビューポートの設定(必須でしょ
  • 投影マトリクス(視体積)の設定(必須でしょ
  • モデルビューマトリクスの設定(最低限カメラ)(必須でしょ
  • ライトの設定(オプショナルでしょ
  • マテリアルの設定(モデル描画時)(オプショナルでしょ
  • 画面のクリア(必須でしょ
  • モデル描画

例えばライティングの処理をしたい場合は、マテリアルの設定とライティングの設定が必要となる。それらは合わせて最低でも10数行のコードを然るべき場所に書かなくてはならない。glBegin()を記述し始められるまでの基本的な、最低限のコードをここにメモ書きとして残すことにより、そのような場合はここのコードをコピペするだけでいいようにしておこう。

	//
	// ●OpenGL初期化glBegin()までのデフォルトコード
	//
	// ビューポートと視体積( MFCとかの場合 )
	{
		float width, height;
		{
#if 01
			// MFCとかの場合
			RECT rect;
			this->GetClientRect( &rect );
			width = rect.right;
			height = rect.bottom;
#else
			// CLIとかだったら例えば
			width = panel1->Width;
			height = panel1->Height;
#endif
		}
		glViewport( 0,0, width, height );
		glMatrixMode( GL_PROJECTION );
		float a = width / height;
		float h = 1.0;
		float nc = 2.0;
		float fc = 9900;
		glLoadIdentity();
		glFrustum( -a*h, a*h, -h, h, nc, fc );
	}
	// モデルビューマトリクス
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	// カメラ描画
	glTranslatef( 0, 0, -10 );
	glRotatef( m_tht, 1,0,0 );// m_phiはマウス座標水平移動で更新
	glRotatef( m_phi, 0,1,0 );// m_thtはマウス座標垂直移動で更新
	// デプステスト有効
	glEnable( GL_DEPTH_TEST );
	glDepthFunc( GL_LEQUAL );
	//
	{
		// ライト設定
		GLfloat spc0[]	={1.0f, 1.0f, 1.0f, 1.0f};
		GLfloat diff0[]	={0.99f, 0.99f, 0.99f, 1.0f};
		GLfloat amb0[]	={0.99f, 0.99f, 0.99f, 1.0f};
		GLfloat pos0[]	={ 0,5,0, 1};// 4つ目の値は1⇒点光源
		glLightfv(GL_LIGHT0, GL_SPECULAR, spc0);
		glLightfv(GL_LIGHT0, GL_AMBIENT, amb0);
		glLightfv(GL_LIGHT0, GL_DIFFUSE, diff0);
		glLightfv(GL_LIGHT0, GL_POSITION, pos0);
		glEnable( GL_LIGHT0 );
	}
	//
	{
		// マテリアル設定
		GLfloat c[]={1, .7, .7, 1};
		GLfloat c1[]={.1, .1, .1, 1};
		glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, c );
		glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, c1 );
		glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 50.0 );
	}

	glClearColor( 0, 0, 0, 0 );
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	// ここから描画開始します
	glEnable( GL_LIGHTING );
	// グリッド
	{
		GLfloat c[]={ 0,.4,0, 1};
		glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, c );
		
		const int res =10;
		glNormal3f( 0,1,0 );
		for( int i=-res; i<res; ++i ){
			glBegin( GL_TRIANGLE_STRIP );
			for( int j=-res; j<=res; ++j ){
				glVertex3f( i, -1, j );
				glVertex3f( i+1, -1, j );
			}// j
			glEnd();	
		}// i
	}
	// 
	glBegin( GL_TRIANGLES );
	{
		GLfloat c[]={1, .7, .7, 1};
		glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, c );

		glNormal3f( 0,.7,.7 );
		glVertex3f( 0,2,0 );
		glNormal3f( 0,-.7,.7 );
		glVertex3f( -1.73,-1,0 );
		glVertex3f( 1.73,-1,0 );
	}
	glEnd();

まあしかし、欲を言えばこのくらいの基本事項は何も見ずにサラサラとある程度は記述できるようになることが望ましいという説もある。