OpenGL ES 3.1 - Невозможно создать IMMUTABLE текстуры с glTexImage2D

Я пытаюсь создать неизменную текстуру с 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_LEVEL в 0,
Тогда я звоню glTexImage2D() установить все уровни текстуры (только один здесь), и у меня нет ошибок.

К сожалению, результат
glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_IMMUTABLE_FORMAT,&status) является 0 Это означает, что текстура не является неизменной.

Теперь, когда я пытаюсь позвонить glBindImageTexture() возникает ошибка 1282, потому что, как написано в документации по khronos, этой функции opengl требуется неизменная текстура.

Есть идеи, что я делаю не так?

Заранее спасибо;)

РЕДАКТИРОВАТЬ:

Спасибо вам обоим за ваше время и за всю предоставленную информацию, но есть вещи, которые я не понимаю.

Этот абзац glTexStorage2D() man ( хронос документация) смущает меня:

Поведение 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-code для формата и типа не имеют значения и могут рассматриваться как любые значения, которые являются законными для выбранного перечислителя внутреннего формата. Внутренний формат должен быть одним из внутренних форматов, указанных в Таблице 1, или одним из сжатых внутренних форматов, указанных в Таблице 2 ниже. В случае успеха значение GL_TEXTURE_IMMUTABLE_FORMAT становится GL_TRUE, Значение GL_TEXTURE_IMMUTABLE_FORMAT может быть обнаружено путем вызова glGetTexParameter с pname, установленным в GL_TEXTURE_IMMUTABLE_FORMAT. Никаких дальнейших изменений в размерах или формате объекта текстуры не может быть сделано. Использование любой команды, которая может изменить размеры или формат объекта текстуры (например, glTexImage2D или другой вызов glTexStorage2D), приведет к генерации ошибки GL_INVALID_OPERATION, даже если это фактически не изменит размеры или формат объекта. объект.

Для меня остается неясным, о чем идет речь выше? glTexImage2D() или же glTexStorage2D(),

Более того, мой основной вопрос: можем ли мы связать текстуру, созданную с glTexImage2D() с помощью glBindImageTexture() ? (Я видел примеры кода, где эти две функции фактически использовались вместе, например, здесь)

1 ответ

Решение

Чтобы выделить неизменяемое хранилище текстур, вы используете glTexStorage2D() вместо glTexImage2D(), Таким образом, ваш вызов выделить текстуру памяти становится:

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

В этом случае вы выделяете все уровни mipmap одним вызовом, поэтому вам не понадобится цикл, который у вас есть в данный момент.

Кроме того, я не уверен, что вы ожидаете от этого:

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

В своем коде вы только что создали текстуру, когда делаете этот вызов. Поэтому запрашивать количество уровней бессмысленно. Если вам нужна текстура с мип-картой, вам нужно будет рассчитать количество мип-карт, которые вам нужны, исходя из размера. Если вам не нужно mipmapping, вы просто передаете 1 для второго аргумента glTexStorage2D(),


Поскольку возникли дополнительные вопросы о том, существуют ли другие способы создания неизменяемой текстуры, например, с помощью glTexImage2D(), ответ - нет. Раздел 8.17, озаглавленный "Текстурные изображения в неизменяемом формате" спецификации ES 3.1, начиная со страницы 190, объясняет, как создавать неизменяемые текстуры. В этом разделе перечислены только glTexStorage2D() а также glTexStorage3D(), Также особо отмечалось, что эти звонки устанавливают GL_TEXTURE_IMMUTABLE_FORMAT свойство к истине.

Единственный другой вызов, упоминающий, что он создает неизменную текстуру, glTexStorage2DMultisample() из раздела 8.8 на стр. 171.

Это означает, что glTexImage2D() создает текстуры, которые не являются неизменными. Это подтверждается разделом 8.18 "Состояние текстуры" на странице 194, где перечислены значения по умолчанию для различных свойств текстуры:

В исходном состоянии [..] значение TEXTURE_IMMUTABLE_FORMAT равно FALSE.

Поскольку спецификация glTexImage2D() не упоминает об изменении значения, оно останется ложным.

Другие вопросы по тегам