HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- OpenGL (https://hlfx.ru/forum/forumdisplay.php?forumid=7)
-- VBO и glGenTextures() (https://hlfx.ru/forum/showthread.php?threadid=1847)
Отправлено axer 03-06-2009 в 14:05:
VBO и glGenTextures()
Добрый день.
У меня возникла проблема с текстурами при использовании VBO. Я загружаю текстуру:
C++ Source Code:
1 | glGenTextures(1, &texObj); |
3 | glBindTexture(GL_TEXTURE_2D, texObj); |
5 | int iWidth, iHeight, iComponents; |
8 | GLbyte *pBytes = gltLoadTGA("stone.tga", &iWidth, &iHeight, &iComponents, &eFormat); |
9 | gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes); |
Потом создаю буферы:
C++ Source Code:
1 | glGenBuffers(3, VBOpoints); |
3 | glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[2]); |
4 | glBufferData(GL_ARRAY_BUFFER_ARB, sizeof(gleVector2f) * 216000, t_objects, GL_STATIC_DRAW_ARB); |
5 | glTexCoordPointer(2, GL_FLOAT, 0, NULL); |
7 | glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[1]); |
8 | glBufferData(GL_ARRAY_BUFFER_ARB, sizeof(gleVector3f) * 216000, n_objects, GL_STATIC_DRAW_ARB); |
9 | glNormalPointer(GL_FLOAT, 0, NULL); |
11 | glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[0]); |
12 | glBufferData(GL_ARRAY_BUFFER_ARB, sizeof(gleVector3f) * 216000, v_objects, GL_STATIC_DRAW_ARB); |
13 | glVertexPointer(3, GL_FLOAT, 0, NULL); |
Дальше рендеринг:
C++ Source Code:
1 | glBindTexture(GL_TEXTURE_2D, texObj); |
3 | glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[2]); |
4 | glTexCoordPointer(2, GL_FLOAT, 0, NULL); |
6 | glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[1]); |
7 | glNormalPointer(GL_FLOAT, 0, NULL); |
9 | glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[0]); |
10 | glVertexPointer(3, GL_FLOAT, 0, NULL); |
12 | glDrawArrays(GL_QUADS, 0, 216000); |
Результат - вместо текстур белые полигоны.
Пробовал менять местами загрузку текстур и создание вершинных буферов, тогда текстуры работают, но отображаются неправильно:

Если убрать вызов glBindTexture в функции рендеринга, то всё работает нормально. Только как тогда использовать в программе несколько текстур?
Если VBO отключить - закомментировать создание вершинных буферов и переделать функцию рендеринга следующим образом:
C++ Source Code:
1 | glBindTexture(GL_TEXTURE_2D, texObj); |
3 | //glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[2]); |
4 | glTexCoordPointer(2, GL_FLOAT, 0, t_objects); |
6 | //glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[1]); |
7 | glNormalPointer(GL_FLOAT, 0, n_objects); |
9 | //glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[0]); |
10 | glVertexPointer(3, GL_FLOAT, 0, v_objects); |
12 | glDrawArrays(GL_QUADS, 0, 216000); |
(массивы t_objects, n_objects и v_objects соответственно не удалять), то всё работает правильно:

Экспериментальным путём установил, что проблемы возникают при вызове glGenBuffers. Если эту функцию вызвать после загрузки текстур, то glBindTexture(GL_TEXTURE_2D, texObj); в функции рендеринга перестаёт работать (белые полигоны). Вот теперь не знаю, что делать. В чём может быть ошибка?
Отправлено XaeroX 03-06-2009 в 14:21:
Ситуация напоминает такой вариант, что текстура и буфер (текстурные координаты) имеют одинаковый идентификатор.
Для начала проверь значения texObj и VBOpoints, чему они равны?
Отправлено axer 03-06-2009 в 14:31:
VBOpoints = {1, 2, 3}, texObj = 1
Добавил ещё 3 вызова glGenTextures, теперь
VBOpoints = {1, 2, 3}, texObj = 4
но ничего не изменилось.
Отправлено XaeroX 03-06-2009 в 14:54:
Закомментируй вызовы glGen*
Пропиши вручную
texObj = 1;
VBOpoints[0] = 2;
ну и т.п.
И скажи, что получается.
Добавлено 03-06-2009 в 21:54:
Я вообще не пользуюсь функциями вида glGen*, у меня свой менеджер идентификаторов. Советую и тебе так сделать.
А вот glDelete* - использовать обязательно (т.к. она еще и память освобождает).
Отправлено axer 03-06-2009 в 15:13:
Спасибо, я нашёл ошибку. У меня VBOpoints был объявлен как
C++ Source Code:
Видимо, я забыл поменять это число с тех пор, когда текстур ещё не было (и соответственно буфера для текстурных координат). Только неясно, почему программа не вылетала при вызове
C++ Source Code:
glBindBuffer(GL_ARRAY_BUFFER_ARB, VBOpoints[2]); |
Спасибо за помощь. Вы указали в какую сторону копать
Отправлено XaeroX 03-06-2009 в 15:52:
Цитата:
axer писал:
Только неясно, почему программа не вылетала при вызове
Потому что это С++, в нем нет контроля выхода за границы массива.
Цитата:
axer писал:
Спасибо за помощь. Вы указали в какую сторону копать
Всегда пожалуйста.