\n |
[ トップページ ]
[ ____CommandPrompt ]
[ ____JScript ]
[ ____MySQL ]
[ ____Cygwin ]
[ ____Java ]
[ ____Emacs ]
[ ____Make ]
[ ____Perl ]
[ ____Python ]
[ ____OpenGL ]
[ ____C# ]
[ ____StyleSheet ]
[ ____C++ ]
[ ____Winsock ]
[ ____Thread ]
[ ____VisualStudio ]
[ ____C ]
[ ____Win32API ]
[ ____Lua ]
[ ____PhotoShop ]
ヘッダ検索
■ マルチテクスチャ(MultiTexture)
SAMPLE
マルチテクスチャ
■ 全体の流れ
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は以下のもの。
現在のユニットの影響を受けるため、把握しておくこと。
ユニットをサンプラーとして考えると必要な設定が理解しやすい。
DEFAULT
GL_TEXTURE0
#include < GL/glext.h>
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つある。
次のように使い分ける.
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;
#if defined(WIN32)
glActiveTexture =
(PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
#endif
■ ProxyTexure
DESC
proxy texture は GL に texture のサポートを問い合わるもの
圧縮 texture も対応している
|
金利比較.COM
|