Текстуры OpenGL: почему порядок имеет значение? - PullRequest
0 голосов
/ 08 марта 2012

Я пытаюсь настроить простую функцию, которая облегчит мне текстурирование геометрии карты в OpenGL, но по какой-то причине, когда я пытаюсь создать скайбокс, вместо белого появляется текстурированная геометрия. Я думаю, что проблемный код заключается в следующем:

void MapTexture (char *File, int TextNum) {
    if (!TextureImage[TextNum]){
        TextureImage[TextNum]=auxDIBImageLoad(File);
        glGenTextures(1, &texture[TextNum]);
        glBindTexture(GL_TEXTURE_2D, texture[TextNum]);
        glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[TextNum]->sizeX, TextureImage[TextNum]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[TextNum]->data);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    }
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[TextNum]);
//glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[TextNum]->sizeX, TextureImage[TextNum]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[TextNum]->data);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

}

Главное, чего я не понимаю, по какой-то причине glBindTexture() должно находиться между glGenTextures() и glTexImage2D. Если я помещу это где-нибудь еще, это все испортит. Что может быть причиной этой проблемы? Извините, если это что-то простое, я новичок в openGL.

Ниже приведен скриншот whitebox, о котором я говорю: enter image description here

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

Поработав с кодом немного больше, я понял, что если я добавлю glTexImage2D() и glTexParameteri() после последнего glBindTexture(), то все текстуры загрузятся. Почему без этих двух строк большинство текстур загружалось бы, а есть некоторые, которые не загружались бы, и почему я должен вызывать glTexImage () для каждого кадра, но только для нескольких текстур?

Ответы [ 2 ]

8 голосов
/ 08 марта 2012

Да, порядок определенно важен.

  • glGenTexture создает имя текстуры.

  • glBindTexture принимает сгенерированное имя текстурына glGenTexture, поэтому он не может быть запущен раньше glGenTexture.

  • glTexImage2D загружает данные в текущую привязанную текстуру, поэтому его нельзя запустить до glBindTexture.

Интерфейс OpenGL на стороне клиента - это Sigggly State Machine Big Giant.Существует огромное количество параметров и флагов, которые вы можете изменить, и вы должны быть скрупулезными, чтобы всегда оставлять OpenGL в правильном состоянии.Обычно это означает выталкивание нажатых матриц и восстановление измененных вами флагов (по крайней мере, в OpenGL 1.x).

4 голосов
/ 08 марта 2012

OpenGL - это конечный автомат, который означает, что вы можете тянуть его рычаги, поворачивать ручки и сохранять эти настройки, пока вы не измените их активно.

Однако он также управляет постоянными данными в объектах., Такие объекты являются чем-то абстрактным, и их не следует путать с объектами, видимыми на экране! Теперь снаружи OpenGL идентифицирует объекты по их так называемому имени , числовому идентификатору.Вы создаете (список) имя (имена) - но не объект (ы)!- с glGenTextures для объектов текстуры, которые являются такого рода объектом OpenGL.

Чтобы манипулировать таким объектом, сначала необходимо перевести OpenGL в состояние, в котором все последующие вызовы манипулируют такими объектами этого типаслучиться с одним конкретным объектом.Это сделано с glBindTexture.После вызова glBindTexture все последующие вызовы, которые манипулируют текстурами, происходят с тем одним объектом текстуры, который вы только что связали.Если объект ранее не существовал, он создается, если новое назначенное имя объекта связывается впервые.Теперь OpenGL использует этот конкретный объект.

glTexImage2D - это всего лишь одна из нескольких функций для манипулирования данными в настоящее время связанных текстур.


В противном случае ваша функция указывает в правильном направлении.OpenGL не имеет реальной фазы инициализации, вы просто делаете что-то по ходу дела.И имеет смысл отложить загрузку данных до тех пор, пока она вам не понадобится.Но также имеет смысл провести несколько итераций по спискам объектов, прежде чем вы начнете рисовать рамку.Одна из подготовительных процедур должна заключаться в том, что вы перебираете все объекты (теперь не OpenGL, а ваши), чтобы проверить, загружены ли уже данные.Если значительный объем данных все еще отсутствует, вместо этого нарисуйте экран загрузки, чтобы у пользователя не сложилось впечатление, что ваша программа зависает.Возможно, даже выполнять длительные операции загрузки в отдельном потоке, но с OpenGL это требует некоторых мер предосторожности.

...