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 перед тем, как убить этот поток, иначе некоторые операции будут отменены.