glGenerateMipmap завершается ошибкой, если за ним не следует glGetError... подождите, что?

У меня была очень странная проблема с генерацией текстур моего проекта. Первая mipmapped текстура работает безупречно, но следующие только рисуют первый уровень. Во время отладки я неожиданно пришел к хаку, который это исправляет:

glGenTextures(1, &texture->textureID);
glBindTexture(GL_TEXTURE_2D, texture->textureID);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexStorage2D(GL_TEXTURE_2D, 10, GL_RGBA8, width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glGenerateMipmap(GL_TEXTURE_2D);
assert(glGetError() == GL_NO_ERROR);    // Mipmapping fails if glGetError is not here

glBindTexture(GL_TEXTURE_2D, 0);

С какой стати это работает, только когда функция glGetError (которая, как вы можете видеть из этого утверждения, ВСЕГДА возвращает GL_NO_ERROR) вызывается после glGenerateMimap? Почему это как-то связано с этим?

В настоящее время я использую GeForce GTX 670 с последним драйвером GeForce 340.52

Изменить: пара изображений может помочь

С glGetError():

Без glGetError():

1 ответ

Решение

Ссылка на iOS является glGenerateMipmap синхронным или, возможно, асинхронным? Вроде бы glGenerateMipmap s работает асинхронно. Мой проект использует общие контексты для создания шейдеров, текстур и сеток (извините, если я не упомянул об этом, я не думал, что это будет иметь значение).

Дело в том, что всякий раз, когда генерация текстур завершалась, флаг "сгенерированные текстуры" поднимался, а общий контекст разрушался, поэтому, похоже, последний glGenerateMipmap не очищался через конвейер. Вызов glGetError должен очистить операции от конвейера, чтобы увидеть, есть ли какая-либо ошибка, чтобы сообщить, и именно поэтому он заставлял все работать без нареканий.

Другими словами, если вы делаете что-то в отдельном общем контексте, вам нужно явно вызвать glFinish перед тем, как убить этот поток, иначе некоторые операции будут отменены.

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