0

I'm trying to create an immutable texture with glTexImage2D() that I can then bind using glBindImageTexture()

Here's my C++ code :

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);
}

As I don't need Mipmap levels I set GL_TEXTURE_MAX_LEVEL to 0.
Then I call glTexImage2D() to set up all texture's levels (only one here) and I have no errors raised.

Unfortunately the result of
glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_IMMUTABLE_FORMAT,&status) is 0 which means that the texture is not immutable.

Now, when I try to call glBindImageTexture(), error 1282 is raised because as it is written in the khronos documentation, this opengl function needs an immutable texture.

Any ideas on what I'm doing wrong ?

Thanks in advance ;)

EDIT :

Thank you to both of you for your time and for all the information provided but There are things I don't understand.

This paragraph of the glTexStorage2D() man (khronos documentation) confuses me:

The behavior of glTexStorage2D depends on the target parameter. When target is GL_TEXTURE_2D, calling glTexStorage2D is equivalent, assuming no errors are generated, to executing the following pseudo-code:

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));
}

Since no texture data is actually provided, the values used in the pseudo-code for format and type are irrelevant and may be considered to be any values that are legal for the chosen internalformat enumerant. internalformat must be one of the sized internal formats given in Table 1, or one of the compressed internal formats given in Table 2 below. Upon success, the value of GL_TEXTURE_IMMUTABLE_FORMAT becomes GL_TRUE. The value of GL_TEXTURE_IMMUTABLE_FORMAT may be discovered by calling glGetTexParameter with pname set to GL_TEXTURE_IMMUTABLE_FORMAT. No further changes to the dimensions or format of the texture object may be made. Using any command that might alter the dimensions or format of the texture object (such as glTexImage2D or another call to glTexStorage2D) will result in the generation of a GL_INVALID_OPERATION error, even if it would not, in fact, alter the dimensions or format of the object.

It remains unclear for me wether the paragraph above is about glTexImage2D() or glTexStorage2D().

Moreover, my underlying question is: Can we bind a texture created with glTexImage2D() using glBindImageTexture() ? (I saw code samples where these two functions were actually used together, here for instance)

4

1 回答 1

1

要分配不可变纹理存储,请使用glTexStorage2D()而不是glTexImage2D(). 因此,您分配纹理内存的调用变为:

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

在这种情况下,您通过这个单一调用分配所有 mipmap 级别,因此您不需要当前拥有的循环。

另外,我不确定您对此有何期望:

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

在您的代码中,您只是在进行此调用时创建了纹理。所以查询层数是没有意义的。如果您想要一个 mipmap 纹理,则必须根据大小计算所需的 mipmap 数量。如果您不需要 mipmapping,您只需将1第二个参数传递给glTexStorage2D().


由于有一些关于是否有其他方法可以创建不可变纹理的后续问题,例如 with glTexImage2D(),答案是否定的。ES 3.1 规范的第 8.17 节标题为“不可变格式纹理图像”,从第 190 页开始,解释了如何创建不可变纹理。该部分中列出的唯一调用是glTexStorage2D()glTexStorage3D()。它还特别提到这些调用将GL_TEXTURE_IMMUTABLE_FORMAT属性设置为 true。

唯一提到它创建不可变纹理的另一个调用glTexStorage2DMultisample()来自第 171 页的第 8.8 节。

这意味着glTexImage2D()创建的纹理不是不可变的。确认这是第 194 页上标题为“纹理状态”的第 8.18 节,其中列出了各种纹理属性的默认值:

在初始状态下,[..] TEXTURE_IMMUTABLE_FORMAT 的值为 FALSE。

由于 的规范glTexImage2D()没有提到更改值,因此它将保持为假。

于 2016-06-30T15:06:00.723 回答