Ну вот и свершилось наконец-то. Я родил шаг номер 13. Хммм... цифра наводит на мысли ;)
Но не будем о грустном. Как я и обещал когда-то раньше, в этом шаге объекты на экране получат текстуру.
Сначала я хотел пойти в том же ключе, что и раньше, т.е. 2 объекта, текстура на одном, текстура на другом, стереосистема справа, стереосистема слева и ... и потом решил, что все это не интересно. Решил потратить время на "прикольную" текстуру. Начал искать, полез на свою станцию и нашел забавный живой телевизор, он, оказывается, входит в комплект поставки Irix 6.2 от SGI. Но вот проблема встала - телевизор там в видео ролике. И решил я, что надо динамическую текстурку слепить, да посмотреть что из этого получится. Слепил, посмотрел, ничего, жить будет, для учебных целей пойдет.
Прежде всего бросьте читать эти буковки и посмотрите код. Мне кажется и объяснять-то там нечего, но раз уж назвался ... то я полез в печку.
И так - объяснения.
Программка практически копирует предыдущие. Т.е. берем опять скелет win32 приложения (проще всего взять от PiraCube), вырезаем оттуда все лишнее и вставляем все нужное, куда уж проще ;). Ну, а если серьезно, то изменения такие:
В глобальных переменных:
#define FRAME_RATE 7Это предельное значение счетчика LoopCount. Нужен он потому, что моя лень победила и мне не хотелось писать код, который бы менял текстуру 25 раз в секунду, т.е. как в TV. Поэтому, если у вас ролик крутится медленно или быстро, то можно поменять эту цыфирьку и станет лучше (может быть ;) )
BOOL Fm;Сие опять моя лень, т.е. просто булева переменная, по изменению которой мы переключаемся на новый элемент массива текстур
int LoopCount;Об этом "левом" счетчике я уже говорил. Поместил я его в цикл while(1)
GLint TexNum;
А это собственно и сам номер картинки.
В функциях:
Изменения претерпела функция LoadGLTexture, сейчас она выглядит так:
GLvoid LoadGLTexture(GLvoid) { int i; char buffer[30]; AUX_RGBImageRec *txtre[12]; for(i=1; i<=12; i++) { sprintf(buffer,"./Images/0%d.bmp",i); txtre[i-1] = auxDIBImageLoad(buffer); glBindTexture (GL_TEXTURE_2D, i); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, 3, txtre[i-1]->sizeX, txtre[i-1]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, txtre[i-1]->data); } }
В начале объявляется массив из 12 указателей на картинки, которые мы загрузим из bmp файлов, а далее в цикле загружаем текстуры в буфер текстур и настраиваем свойства. Я думаю, что перечислять назначение всех функций и их аргументы, это просто повторять MSDN, но в по сути происходит следующее - glBindTexture как бы индексирует текстуру в буфере текстур, glPixelStorei - устанавливает режим pixel storage, glTexParameteri и glexEnvf - устанавливают многочисленные параметры текстур, посмотрите MSDN, его (MSDN) профи пишут, не в пример мне. Ну, а glTexImage2D собственно загружает текстуру.
В Initial добавился вызов функции LoadGLTexture. Изменения в Draw:
glEnable (GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,TexNum);Соответственно включают режим текстурирования и выбирают текстуру по номеру из тех, что лежат в буфере.
glBegin(GL_QUADS); glNormal3f(0.0, 0.0, -1.0); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glNormal3f(0.0, 0.0, 1.0); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glNormal3f(1.0, 0.0, 0.0); glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); glNormal3f(-1.0, 0.0, 0.0); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glNormal3f(0.0, -1.0, 0.0); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glEnd(); glDisable(GL_TEXTURE_2D); Xrot += 0.1f; Yrot += 0.2f; Zrot += 0.25f; if(Fm) { TexNum++; if(TexNum == 13) TexNum = 1; Fm = FALSE; }
Далее мы просто рисуем куб, при этом с каждой вершиной грани связываем соответствующий угол текстуры, выключаем текстурирование, увеличиваем углы поворотов, проверяем не пора ли нам переключиться на следующую в буфере текстуру. Если да, то проверяем выход за пределы карты мира, т.е. у нас всего 12 картинок и если уже 12-я, то опять на 1-ю.
И последнее изменение касается WinMain:
LoopCount++; if(LoopCount >= FRAME_RATE) { Fm = TRUE; LoopCount = 0; } Draw(); SwapBuffers(hDC);
Просто и не затейливо увеличиваем счетчик при каждом проходе цикла, как только он больше чем задано, включаем условие переключения картинки и обнуляем счетчик.
И последнее - не забудте в настройке проекта добавить библиотеки: opengl32.lib; glu32.lib; glaux.lib;.