[解決済み] glActiveTextureとglBindTextureの違いと関係
質問
私が調べたところでは
glActiveTexture
はアクティブなquot;テクスチャユニット"を設定します。各テクスチャ ユニットは、複数のテクスチャ ターゲット(通常は GL_TEXTURE_1D、2D、3D または CUBE_MAP)を持つことができます。
私が正しく理解しているならば、あなたは
glActiveTexture
を呼び出して、まずテクスチャユニットを設定します(初期化は
GL_TEXTURE0
を設定し、次にそのテクスチャユニットに(1つまたは複数の)"テクスチャターゲット"をバインドするのでしょうか?
利用可能なテクスチャユニットの数は、システム依存です。私のライブラリでは、最大 32 の列挙型があります。これは、本質的に、私の GPU の制限のうち小さい方 (私が考えるには
16
8)、および GPU メモリに一度に 32 個のテクスチャを持つことができるということでしょうか。GPU の最大メモリ (1 GB と思われる) を超えないという制限が追加されるのでしょう。
テクスチャ ターゲットとテクスチャ ユニットの関係は正しく理解されていますか。たとえば、私が 16 個のユニットと 4 個のターゲットを許可されているとすると、16*4=64 個のターゲットに余裕があるということでしょうか、それともそのように機能しないのでしょうか?
次に、一般的にテクスチャをロードしたいと思います。これは
glTexImage2D
. その最初の引数はテクスチャターゲットです。もし、この
のように動作します。
glBufferData
というように、テクスチャターゲットに "handle"/"texture name" を結合し、テクスチャデータをそのターゲットにロードして、間接的にそのハンドルと関連付けるのです。
についてはどうでしょうか。
glTexParameter
? テクスチャターゲットをバインドして、その同じターゲットを最初の引数として再び選択しなければならないのでしょうか?それとも、正しいアクティブなテクスチャユニットがある限り、テクスチャターゲットはバインドされる必要はないのでしょうか?
glGenerateMipmap
は、ターゲットも操作します。そのターゲットは、成功するためにテクスチャ名にまだバインドされている必要がありますか?
では、テクスチャを貼ったオブジェクトを描画したい場合、次のようにすればよいのでしょうか。 両方とも アクティブなテクスチャ ユニットとテクスチャ ターゲットの両方を選択する必要がありますか? それとも、テクスチャユニットを選択し、そのユニットに関連付けられた 4 つのターゲットのいずれかからデータを取得するのでしょうか。これは、私を本当に混乱させる部分です。
どのように解決するのですか?
OpenGLオブジェクトのすべて
OpenGLオブジェクトの標準的なモデルは以下の通りです。
オブジェクトは状態を持ちます。それらを
struct
. ですから、次のようなオブジェクトが定義されているかもしれません。
struct Object
{
int count;
float opacity;
char *name;
};
オブジェクトにはある値が格納されており、その値には 状態 . OpenGLオブジェクトも状態を持ちます。
状態の変更
C/C++では、もし型
Object
のインスタンスがあった場合、以下のようにその状態を変更します。
obj.count = 5;
オブジェクトのインスタンスを直接参照し、変更したい状態の特定の部分を取得し、そこに値を押し込むことになります。
OpenGLでは はしません。 を行います。
説明しない方が良いレガシーな理由のため、OpenGLオブジェクトの状態を変更するには、最初に
バインド
しなければなりません。これは
glBind*
の呼び出しで行われます。
これに相当するC/C++は次のようになります。
Object *g_objs[MAX_LOCATIONS] = {NULL};
void BindObject(int loc, Object *obj)
{
g_objs[loc] = obj;
}
テクスチャは興味深いもので、バインディングの特殊なケースを表しています。多くの場合
glBind*
の呼び出しには、"target" というパラメータがあります。これは、そのタイプのオブジェクトをバインドすることができるOpenGLコンテキストの異なる場所を表します。例えば、フレームバッファオブジェクトを読み込むためにバインドすることができます (
GL_READ_FRAMEBUFFER
) または書き込み用 (
GL_DRAW_FRAMEBUFFER
). これはOpenGLがバッファをどのように使用するかに影響します。これは
loc
パラメータが表しています。
テクスチャが特別なのは
最初に
をターゲットにバインドすると、特別な情報を取得するからです。テクスチャを最初に
GL_TEXTURE_2D
としてテクスチャを最初にバインドするとき、実際にはテクスチャに特別な状態を設定していることになります。つまり、このテクスチャは2Dテクスチャであるということです。そして、このテクスチャは
常に
であり、この状態を変更することはできません。
常に
. として最初にバインドされたテクスチャがある場合、そのテクスチャの状態を変更することはできません。
GL_TEXTURE_2D
としてバインドされたテクスチャがある場合、そのテクスチャを
常に
としてバインドします。
GL_TEXTURE_2D
として結合しようとすると
GL_TEXTURE_1D
として結合しようとすると、(実行時に)エラーが発生します。
いったんオブジェクトがバインドされると、その状態を変更することができます。これは、そのオブジェクトに特化した汎用関数によって行われます。それらもまた、どのオブジェクトを変更するかを表す場所を取ります。
C/C++では、これは次のようになります。
void ObjectParameteri(int loc, ObjectParameters eParam, int value)
{
if(g_objs[loc] == NULL)
return;
switch(eParam)
{
case OBJECT_COUNT:
g_objs[loc]->count = value;
break;
case OBJECT_OPACITY:
g_objs[loc]->opacity = (float)value;
break;
default:
//INVALID_ENUM error
break;
}
}
この関数が、現在バインドされているものをどのように設定するかに注意してください。
loc
の値を設定することに注意してください。
テクスチャオブジェクトの場合、主なテクスチャ状態変更関数は
glTexParameter
. テクスチャの状態を変更する他の関数は
glTexImage
関数とそのバリエーション (
glCompressedTexImage
,
glCopyTexImage
は、最近の
glTexStorage
). 様々な
SubImage
のバージョンはテクスチャの内容を変更しますが、技術的にはその
状態
. そのため
Image
関数はテクスチャストレージを割り当て、テクスチャのフォーマットを設定します。
SubImage
関数は単にピクセルをコピーするだけです。これはテクスチャの状態とはみなされません。
繰り返しになりますが、これらは
だけです。
関数です。
glTexEnv
は環境の状態を変更します。これはテクスチャオブジェクトに格納されているものには影響しません。
アクティブなテクスチャ
テクスチャの状況はより複雑ですが、これもレガシーな理由のため、公表されないままにしておくのが最善です。ここでは
glActiveTexture
が入ってきます。
テクスチャの場合、ターゲットだけでなく(
GL_TEXTURE_1D
,
GL_TEXTURE_CUBE_MAP
など)。また、テクスチャ
ユニット
. C/C++の例でいうと、こんな感じです。
Object *g_objs[MAX_OBJECTS][MAX_LOCATIONS] = {NULL};
int g_currObject = 0;
void BindObject(int loc, Object *obj)
{
g_objs[g_currObject][loc] = obj;
}
void ActiveObject(int currObject)
{
g_currObject = currObject;
}
今、私たちは2次元のリストである
Object
の 2 次元リストだけでなく、カレントオブジェクトの概念も持っていることに注意してください。現在のオブジェクトを設定する関数があり、現在のオブジェクトの最大数の概念があり、すべてのオブジェクト操作関数が現在のオブジェクトから選択されるように調整されています。
現在アクティブなオブジェクトを変更すると、ターゲットロケーションのセット全体が変更されます。したがって、現在のオブジェクト 0 に入る何かをバインドして、現在のオブジェクト 4 に切り替えると、まったく別のオブジェクトを変更することになります。
このテクスチャオブジェクトのアナロジーは完璧です...ほとんど。
見てください。
glActiveTexture
は整数を取りません。
列挙子
. つまり、理論的には
GL_TEXTURE0
から
GL_TEXTURE31
. しかし、ひとつだけ理解しておかなければならないことがあります。
これは嘘だ!
実際に
glActiveTexture
が取ることのできる範囲は
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
. これは、実装が許容する同時マルチテクスチャの最大数です。これらはそれぞれ、異なるシェーダステージ用に異なるグループに分割されます。たとえば、GL 3.x クラスのハードウェアでは、16 のバーテックスシェーダテキス チャ、16 のフラグメントシェーダテキスチャ、および 16 のジオメトリシェーダテキスチャが得られます。したがって
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
は 48 になります。
しかし、48人の列挙者はいない。そのため
glActiveTexture
は実際には列挙体を取らないのです。その
正しい
を呼び出す方法は
glActiveTexture
は以下のようになります。
glActiveTexture(GL_TEXTURE0 + i);
ここで
i
は0から
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
.
レンダリング
では、これらすべてがレンダリングとどのような関係があるのでしょうか。
シェーダーを使用する場合、サンプラーユニフォームをテクスチャイメージユニット(
glUniform1i(samplerLoc, i)
で、ここで
i
は画像単位)。で使用した数値を表します。
glActiveTexture
. サンプラーは、サンプラーの種類に基づいてターゲットを選びます。そのため
sampler2D
は
GL_TEXTURE_2D
のターゲットから選びます。これがサンプラーに異なるタイプがある理由の一つです。
さて、これは2つのGLSLサンプラーを持つことができるように怪しく聞こえますが、異なる タイプ で、同じテクスチャ画像ユニットを使用することができます。OpenGLはこれを禁じており、レンダリングしようとするとエラーが発生します。
関連
-
[解決済み] テスト
-
[解決済み] glBlitFramebufferを使用してテクスチャを表示する
-
[解決済み] glGetShaderiv() GL_COMPILE_STATUS GL_FALSE を返す
-
[解決済み] 最新のOpenGLで複数のテクスチャをレンダリングするには?
-
[解決済み] コンセプト:glDrawBufferとglDrawBuffersの使い分けは?
-
opengl glGetIntegerv エラーを使用します。アクセス違反 ロケーション0x0000000000000000を実行中
-
[解決済み] gl_FragColorとout vec4カラーを使用する?
-
[解決済み] gluPerspectiveパラメータ - その意味するところは?
-
[解決済み】GLSLシェーダをデバッグする方法は?
-
[解決済み] OpenGLでglLoadIdentity()は何をするのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] glEnableVertexAttribArrayは具体的に何をするのですか?
-
[解決済み] 頂点シェーダとフラグメントシェーダにおけるgl_Colorとgl_FrontColorの関係を教えてください。
-
[解決済み] OpenGL - GLenumはどのように符号なし32ビット整数ですか?
-
[解決済み] gl_FragColorとout vec4カラーを使用する?
-
[解決済み] 最新のOpenGLで複数のテクスチャをレンダリングするには?
-
[解決済み] Ken Silverman氏のVoxlapエンジンで使用されているアルゴリズムについて、どなたか教えてください。
-
[解決済み] gl_PointSizeの動作について
-
[解決済み] gluPerspectiveパラメータ - その意味するところは?
-
[解決済み】GLSLシェーダをデバッグする方法は?
-
[解決済み] GLSLシェーダーの正しいファイル拡張子は何ですか?[クローズド]。