マルチテクスチャ(MultiTexture)
	SAMPLE
		http://ooo.iiyudana.net/bin/gl/multi_texture.exe( マルチテクスチャ )		
 全体の流れ
  DEP
		glext.h
  VER
		 1.3
  DESC
	  ひとつの物( Primitive )に絵( Texture )をたくさん貼り付ける
	  [0][1][2][3][4][5][6][7]
		テクスチャユニット( サンプラー )は8つあり、テクスチャオブジェクトを設定することで
		一度の描画で複数のテクスチャを参照できる。
		ペイントソフトのレイヤーと同じ概念。
	POINT
    TextureObject を 各 Unit に bind する
    OpenGL は GL_TEXTURE0 から順にフラグメントに適用する
    
		テクスチャマトリックスは ユニットごとに持つ
	POINT
		テクスチャユニットの設定に関連したAPIは以下のもの。
		現在のユニットの影響を受けるため、把握しておくこと。
		ユニットをサンプラーとして考えると必要な設定が理解しやすい。
		
    [.] glTexGen();                     // tc 自動生成 Param
    [.] glEnable( GEN_S );              // UV 自動生成の各成分ごとの ON/OFF
    [.] glEnable( GL_TEXTURE_2D );      // サンプリング処理の ON/OFF
		[.] Texture Enviroment ( glTexEnv )
		[.] TextureMatrix
		[.] バインドするテクスチャオブジェクトの指定
  DEFAULT
    GL_TEXTURE0
		void App::init() {
		  PFNGLACTIVETEXTUREPROC glActiveTexture =
				(PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
			// 操作するテクスチャユニットを指定する			
			//		一枚のみを利用しているときはこれが暗黙の指定になっている。
			glActiveTexture( GL_TEXTURE0 );
			// UNIT0 にテクスチャオブジェクトをセットする
			glBindTexture( GL_TEXTURE_2D, id );
			// ブレンド方法の指定
			// 次の設定が最も simple blend 方法 ( 各 unit にすること )
			glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			// 2D Texure をサンプリング処理を有効化する。
			glEnable( GL_TEXTURE_2D );
			// 2 番目のユニットを指定
			glActiveTexture( GL_TEXTURE1 );
			//  上と同じように設定するだけ
			glBindTexture( GL_TEXTURE_2D, id2 );
			glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		}
		
		// 描画時は各UNITごとに Texture座標を指定する
		App::draw() {
		}
    glClientActiveTexture(); で texture 座標を割り当てる texture unit を選択
    glTexCoordPointer(); で texture 座標配列を ( 明示的 | buffer object ) から指定
    glEnableClientState( GL_TEXTURE_COORD_ARRAY );
  WARNING
    描画毎に Unit は使い回すので state の管理は必要
    glTexEnv(); の計算は texture object の intenral format にも依存
	  && alpha 成分も計算の対象
    ( glTexImage(), TexParamter(), TexEnv(), BindTexture() )
	    はカレントに対して有効
    // 単一の tex unit に戻す
    glActiveTexture( GL_TEXTURE1 );
    glDisable( GL_TEXTURE_2D );
    glActiveTexture( GL_TEXTURE0 );
  MultiTexture 用に複数の TextureCoord を指定する方法は3つある。
    [.] glMultiTexCoord();
    [.] glTexCoordPointer();    // 頂点配列を指定する
    [.] glTexGen();
      次のように使い分ける.
    MultiTex && VertexArray
	    -> glTexCoordPointer();
    MultiTex && Scratch
	    -> glMultiTexCoord();
    MultiTex && 自動生成.
	    -> glTexGen();	  // ( Shader 利用するなら不要 )
    / / Multi tc の指定方法.
    // Server 側の Unit ( State ) を選択する
    glActiveTexture();
    // 複数の tc を VertexArray に指定する.
    // VertexArray の tc を割り当てる [ U.n.i.t ] を指定する.
    glClientActiveTexture();
    // Client 側の UnitTex を指定する.
    glEnableClientState( );
    // TexCoord を指定
    glTexCoordPointer( 2, GL_FLOAT, 0, buf );
    複数の TexCoord を指定する
    glClientActiveTexture( GL_TEXTUREn );
    glTexCoordPointer():
    glClientActiveTexture() が指す TexUnit に TexCoord を割り当てる.
	 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
   も指定している, TexUnit が利用される.
  WARNING
    glBegin() - glEnd() では指定できない
	POINT
		[.] Texcoord.w の成分により w 除算される
		[.] glTexCoord2f( 1, 0 );  == glTexCoord4f( 1, 0, 0, 1 );
		[.] glTexGen  をした時も, Texture Matrix の影響をうける
	WARNING
		[.] 部分的に glTexGen はできない ?
		[.] GL_TEXTURE_2D && glTexGen は併用できない ? -> それはないはず
void drawCube()
{
	float s = 30;
	// 8 頂点
	static float v[] = {
		-s, -s, s,		s, -s, s,		s, s, s,		-s, s, s,
		-s, -s, -s,		s, -s, -s,		s, s, -s,		-s, s, -s,
	};
	// 6 QUADS の index
	static unsigned short idx[] = {
		0, 1, 2, 3,		4, 5, 6, 7,
		1, 5, 6, 2,		4, 0, 3, 7,
		4, 5, 1, 0,		3, 2, 6, 7,
	};
	// 各面の Normal
	static float n[] = {
		0, 0, 1,		0, 0, -1,
		1, 0, 0,		-1, 0, 0,
		0, -1, 0,		0, 1, 0,
	};
	// 各面の Texcoord
	static float t[] = {
		0, 0,		1, 0,		1, 1,		0, 1,
	};
	glBegin( GL_QUADS );
	for( int i=0; i<6; i++ ){
		// 法線を設定
		// ここの影響をうける
		glNormal3fv( n + (3*i) );
		//		world となるように normal を指定する ?
		//		先ほどの見え方から推測すると,
		//		ここで指定した normal が , 視線空間上で mapping される
		//glNormal3fv( n );
		for( int j=0; j<4; j++ ){
			// 現在の idx
			int p = idx[ 4*i + j ];
			glMultiTexCoord2f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1] );
			// z も指定してみる
			//glMultiTexCoord3f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], t[2*j + 1] );
			// w も指定してみる
			//glMultiTexCoord4f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], t[2*j + 1], 1 );
			// 前言撤回 -> ここも影響をうける
			glMultiTexCoord4f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], -1, -1 );
			glMultiTexCoord4f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], -1, -100 );
			// w 除算される -> 頂点処理 と同じ流れ
			//glMultiTexCoord4f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], -1, 0.5f );
			glMultiTexCoord4f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], -1, 2 );
			//glMultiTexCoord4f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], -1, 1 );
			// Z 値はなんでもいい
			glMultiTexCoord4f( GL_TEXTURE1, t[2*j + 0], t[2*j + 1], 10000, 1 );
			glVertex3fv( v + 3*p );
		}
	}
	glEnd();
}
 glMultiTexCoord
  SYNTAX
		void glMultiTexCoord( GLenum unitTex, TYPE tc );
  DESC
    指定したテクスチャユニットに Texcoord をセットする
  POINT
    glTexCoord(); は実は. glMultiTexCoord( GL_TEXTURE0, ); と同じ.
	// ユニット1 に UV を指定する
	float t = { 0, 0, 1 };
	glMultiTexCoord3fv( GL_TEXTURE0, t );
	float t = { 0, 0, 1 };
	glMultiTexCoord3fv( GL_TEXTURE1, t );
	glBegin( GL_QUADS );
	for( int i=0; i<4; i++ ){
		glVertex3fv( vtx );
	}
	glEnd();
		拡張機能のため 関数ポインタを取得しておく
	PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv;
	PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv;
  glMultiTexCoord2dv =
    (PFNGLMULTITEXCOORD2DVPROC)wglGetProcAddress("glMultiTexCoord2dv");
  glMultiTexCoord3fv =
    (PFNGLMULTITEXCOORD3FVPROC)wglGetProcAddress("glMultiTexCoord3fv");
		より複雑に指定するには GL_COMBINE mode を使う
		( Shader を使った方が簡単だけど )
				{
					// Preset の補間( GL_ADD, GL_MODULATE )ではなく, CUSTOM の補間を使う
					glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
					// 線形補間 を指定
					//		ここも複数指定できる
					//		{ GL_COMBINE_RGB }
					//		{ GL_COMBINE_A }
					//
					//		GL_REPLACE     a0
					//		GL_MODULATE    a0a1
					//		GL_ADD		    a0 + a1
					//		GL_ADD_SIGNED  a0 + a1 - 0.5f
					//		GL_SUBSTRACT   a0 - a1
					//		GL_INTERPOLATE a1 * ( 1 - a2 ) + a0 * a2;
					//
					glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE );
					///glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE );
					glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED );
					// 補間する 係数 を指定する ( Alpha 成分のみが使われる )
					static const float c[] = { 1, 1, 1, 0.5f };
					//glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, c );
					// 次のような計算をすることになる
					// GL_INTERPOLATE
					//	V1 * ( 1 - V2 ) + V0 * V2;
					// POINT
					//	V2 も Vector 扱い
					//	rgb, a を別途指定できる
					// f.r = ( 1 - a2.r ) + a0.r * a2.r;
					// f.g = ( 1 - a2.g ) + a0.g * a2.g;
					// f.b = ( 1 - a2.b ) + a0.b * a2.b;
					// f.a = ( 1 - a2.a ) + a0.a * a2.a;
					// Document からの仮定( この順番 )
					//
					//	 a0 : 今 処理中の UNIT がサンプルする Texture 色
					//	 a1 : 前の Texture UNIT の結果
					//
					// 今 Alpha にしているのは UNIT1 の結果の RGB の値
					// CubeMap が明るい -> a0 が優先
					// 変数 a2 に何を使うか 決める
					// GL_PREVIOUS == 前の UNIT の結果
					glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS );
					//glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE );
					//glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA );
					// a2.rgb にどの値を使うか決める
					//
					// a2.r = TexUnit1.r
					// a2.g = TexUnit1.g
					// a2.b = TexUnit1.b
					//
					// WARNING
					//		GL_SRC_RGB という 定数 はなし
					// a2.rgb に 前の Unit の結果のどの成分を使うか ?
					//	GL_SRC_COLOR なので
					//		a2.rgb = UnitPrev.rgb
					//
					glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR );
					//glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_RGB );
					//glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_ALPHA );
					//glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_CONSTANT );
					// Primary Color( 頂点色 )を指定すれば Texture の色は無視される
					//
					glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR );
					glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR );
					glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
					glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
				}
 glActiveTexture
	SYNTAX
		PFNGLACTIVETEXTUREPROC glActiveTexture;
  glActiveTexture =
    (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
 ProxyTexure
  DESC
    proxy texture は GL に texture のサポートを問い合わるもの
    圧縮 texture も対応している