0

glTexImage2D()私はそれを使用してバインドできる不変のテクスチャを作成しようとしていますglBindImageTexture()

ここに私のC++コードがあります:

GLuint id;
glGenTextures(1, &id);

glBindTexture(GL_TEXTURE_2D, id);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);


GLint width = 2046;
GLint height = 1086;

// Not sure what to put here 1, 2, 4 or 8 ?
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

GLint levels;
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, &levels);

for (int i = 0; i < levels + 1; i++)
{

    glTexImage2D(GL_TEXTURE_2D, i, GL_R32UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
    width = glm::max(1, (width / 2));
    height = glm::max(1, (height / 2));

    // check OpenGL error
    GLenum err;
    while ((err = glGetError()) != GL_NO_ERROR) {
        ALOGE("ERROR_GL_TEXTURE_INIT: %i", err);
    }
}

GLint status;
glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_IMMUTABLE_FORMAT,&status);
ALOGE("IMMUTABLE_TEXTURE: %i", status);

glBindTexture(GL_TEXTURE_2D, 0);

glBindImageTexture(0, id, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);

// check OpenGL error
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR) {
    ALOGE("ERROR_GL_TEXTURE_IMG-USE: %i", err);
}

Mipmap レベルは必要ないので、 に設定GL_TEXTURE_MAX_LEVEL0ます。次に、すべてのテクスチャのレベル (ここでは 1 つだけ) をセットアップするため
に呼び出しますが、エラーは発生しません。glTexImage2D()

残念ながら、の結果は
glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_IMMUTABLE_FORMAT,&status)0テクスチャがimmutableではないことを意味します。

を呼び出そうとするとglBindImageTexture()、エラー1282が発生します。これは、クロノスのドキュメントに書かれているように、この opengl 関数には不変のテクスチャが必要なためです。

私が間違っていることについてのアイデアはありますか?

前もって感謝します ;)

編集 :

お二人ともお時間を割いて情報を提供していただきありがとうございますが、わからないことがあります。

男性のこの段落glTexStorage2D()khronos documentation)は私を混乱させます:

glTexStorage2D の動作は、ターゲット パラメータによって異なります。ターゲットが GL_TEXTURE_2D の場合、glTexStorage2D を呼び出すことは、エラーが生成されないと仮定すると、次の疑似コードを実行することと同じです。

for (i = 0; i < levels; i++)
{
    glTexImage2D(target, i, internalformat, width, height, 0, format, type, NULL);
    width = max(1, (width / 2));
    height = max(1, (height / 2));
}

実際にはテクスチャ データが提供されないため、pseudo-codefor のフォーマットとタイプで使用される値は無関係であり、選択された internalformat 列挙子に有効な任意の値と見なされる場合があります。internalformat は、表 1 に示されているサイズの内部形式のいずれか、または以下の表 2 に示されている圧縮された内部形式のいずれかでなければなりません。成功すると、 の値は次のようにGL_TEXTURE_IMMUTABLE_FORMATなります。GL_TRUE. GL_TEXTURE_IMMUTABLE_FORMAT の値は、pname を GL_TEXTURE_IMMUTABLE_FORMAT に設定して glGetTexParameter を呼び出すことによって検出できます。テクスチャ オブジェクトの寸法や形式をこれ以上変更することはできません。テクスチャ オブジェクトの寸法やフォーマットを変更する可能性のあるコマンド (glTexImage2D や glTexStorage2D への別の呼び出しなど) を使用すると、実際には寸法やフォーマットを変更しない場合でも、GL_INVALID_OPERATION エラーが生成されます。物体。

上記の段落が についてなのglTexImage2D()glTexStorage2D()

さらに、私の根底にある質問は次のとおりです。使用して作成されたテクスチャをバインドできますか? glTexImage2D()glBindImageTexture()(たとえば 、これら 2 つの関数が実際に一緒に使用されているコード サンプルを見ました)

4

1 に答える 1

1

不変のテクスチャ ストレージを割り当てるには、glTexStorage2D()代わりにを使用しますglTexImage2D()。したがって、テクスチャ メモリを割り当てる呼び出しは次のようになります。

glTexStorage2D(GL_TEXTURE_2D, levels, GL_R32UI, width, height);

この場合、この 1 回の呼び出しですべてのミップマップ レベルを割り当てるので、現在持っているループは必要ありません。

また、これに対するあなたの期待が何であるかわかりません:

GLint levels;
glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, &levels);

コードでは、この呼び出しを行ったときにテクスチャを作成しました。したがって、レベル数を照会しても意味がありません。ミップマップ テクスチャが必要な場合は、サイズに基づいて、必要なミップマップの数を計算する必要があります。ミップマッピングが必要ない場合は1、2 番目の引数を に渡すだけglTexStorage2D()です。


不変のテクスチャを作成する他の方法があるかどうかについていくつかのフォローアップの質問があったため、たとえば を使用してglTexImage2D()、答えはノーです。190 ページから始まる ES 3.1 仕様の「不変フォーマット テクスチャ イメージ」というタイトルのセクション 8.17 では、不変テクスチャの作成方法について説明しています。そのセクションにリストされている呼び出しはglTexStorage2D()とだけglTexStorage3D()です。GL_TEXTURE_IMMUTABLE_FORMATまた、これらの呼び出しがプロパティを true に設定することも具体的に述べられています。

不変のテクスチャを作成することを言及している他の唯一の呼び出しは、glTexStorage2DMultisample()171 ページのセクション 8.8 からのものです。

これは、不変ではないglTexImage2D()テクスチャを作成することを意味します。これを確認するのは、194 ページの「テクスチャの状態」というタイトルのセクション 8.18 で、さまざまなテクスチャ プロパティのデフォルト値がリストされています。

初期状態では [..] TEXTURE_IMMUTABLE_FORMAT の値は FALSE です。

の仕様でglTexImage2D()は値の変更について言及されていないため、false のままになります。

于 2016-06-30T15:06:00.723 に答える