Урок 6 - Наложение текстур
Текстура в OpenGL – это простой графический файл, который отображается на полигоне.
В этом уроке мы рассмотрим 2 вида текстур: простые и с альфа-каналом (прозрачностью).
Перед тем, как начать работу, вам необходимо скачать файл Textures.pas (ссылка в конце урока).
Он осуществляет загрузку текстуры в оперативную память, для последующего отображения на полигоне.
Текстуру мы будем накладывать на куб.
Его надо нарисовать вручную, чтобы не загромождать код, создайте новый юнит и процедуру RenderBox:
Procedure RenderBox(); begin glBegin(GL_QUADS); glNormal3f( 0.0, 0.0, 1.0); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glEnd; glBegin(GL_QUADS); glNormal3f( 0.0, 0.0,-1.0); glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); glEnd; glBegin(GL_QUADS); glNormal3f( 0.0, 1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0); glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); glEnd(); glBegin(GL_QUADS); glNormal3f( 0.0,-1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0); glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); glEnd(); glBegin(GL_QUADS); glNormal3f( 1.0, 0.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0); glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0); glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0); glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0); glEnd(); glBegin(GL_QUADS); glNormal3f(-1.0, 0.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0); glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0); glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); glEnd(); end;Эту процедуру мы будем использовать 2 раза.
Позиции для текстуры задаются функцией glTexCoord2f(s,t : single). Она задаёт позицию X, Y координаты на полигоне. Вызывать её следует перед заданием позиции каждой точки полигона.
Для правильного отображения текстуры, надо задать параметры отображения, при помощи функции glTexParameter(тип текстуры, тип фильтра, тип фильтрации) в FormCreate:
glTexParameter (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameter (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);Ну и разрешить режим наложения текстуры в FormCreate:
glEnable(GL_TEXTURE_2D);После ключевого слова implementation необходимо записать процедуру самого наложения, потому что её нет в стандартной библиотеке OpenGL.pas поставляемой с Delphi 7.
procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;В OpenGL есть специальный тип данных «Uint». Он хранит индекс загруженной текстуры в памяти.
Теперь нужно загрузить нашу текстуру при старте программы. Для этого создайте глобальную переменную Tex типа Uint и запишите следующий код в FormCreate:
Loadtexture('Tex.tga',Tex,false);Файлы текстур уже готовы и находится в папке с исходником.
Здесь мы загружаем текстуру в память и присваиваем индекс этой текстуры переменной Tex.
Подготовка закончена.
Нарисуем наш кубик:
procedure TForm1.FormPaint(Sender: TObject); begin … RenderBox(); //рисуем куб … End;
И наложим текстуру:
procedure TForm1.FormPaint(Sender: TObject); begin … glBindTexture(GL_TEXTURE_2D, Tex); // накладываем текстуру RenderBox(); //рисуем куб … End;
Вызвав один раз glBindTexture, текстура будет накладываться на все полигоны, нарисованные после вызова. Для того, чтобы текстура не накладывалась можно запретить режим наложения glDisable(GL_TEXTURE_2D), а потом разрешить или наложить нулевую текстуру, то есть ничего glBindTexture(GL_TEXTURE_2D, 0).
Готово!!!
Перейдём к текстуре с прозрачностью.
Для того, чтобы текстура имела прозрачные места, необходимо разрешить альфа-тест и задать его параметры в FormCreate:
glEnable(GL_ALPHA_TEST); //разрешаем альфа-тест glAlphaFunc(GL_GREATER,0.0); // устанавливаем параметры для того чтоб не было резких границ между прозрачным местом и текстурой: glEnable (GL_BLEND); //Включаем режим смешивания цветов glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; //параметры смешиванияЗагрузим текстуру в созданную переменную Glass в FormCreate:
Loadtexture('Tex.tga',Glass,false);Теперь наложим заранее созданную текстуру с альфа каналом:
procedure TForm1.FormPaint(Sender: TObject); begin … glBindTexture(GL_TEXTURE_2D, Glass); // накладываем текстуру RenderBox(); //рисуем куб … End;
Ну и наконец, отобразим два куба с разными текстурами.
procedure TForm1.FormPaint(Sender: TObject); begin … glBindTexture(GL_TEXTURE_2D, Glass); glPushMatrix(); glTranslatef(0,1.5,0); glRotatef(angle,0,0,1); glRotatef(angle1,0,1,0); RenderBox(); glPopMatrix; glBindTexture(GL_TEXTURE_2D, Tex); glPushMatrix(); glTranslatef(0,-1.5,0); glRotatef(angle,0,0,1); glRotatef(angle1,0,1,0); RenderBox(); glPopMatrix; … End;
В следующем уроке мы узнаем, как сделать туман (дым) в OpenGL.
Добавил(а): катари | Дата: 2012-12-18 | |
а можно сделать так чтобы пользователь мог менять цвет текстуры? хотя бы, чтобы мог менять цвет от светлого к темному
подскажите пожалуйста как это реализовать
|
Добавил(а): Admin | Дата: 2012-12-19 | |
Я не уверен, но думаю, что скорее всего цвет нужно менять через пиксельный шейдер. Автор уроков подробнее ответить тебе в течении дня.
|
Добавил(а): Klesh | Дата: 2012-12-19 | |
Никаких шейдеров тут не надо. Всё можно сделать ,вписав одну строку перед отрисовкой, glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, @dif); где dif - массив с 4 значениями типа GLFloat (R,G,B,A). Если задать значения к примеру (1,1,1,1) то будет максимальная яркость, а если (0.2,0.2,0.2,1) то будет темный цвет.
|
Добавил(а): HALF-LIFE | Дата: 2013-03-06 | |
Как нанести одно и тоже изображение несколько раз не растягивая её на поверхность?
|
Добавил(а): juzhnij | Дата: 2013-05-29 | |
Ставлю любую свою текстуру без фона и куб уже не прозрачный, таким образом урок ничего не обьясняет, а просто кывидывает информацию как кость собаке.
|
Добавил(а): Klesh | Дата: 2013-05-29 | |
В каком редакторе вы работаете? Я работал в фотошопе и сохранял текстуру с включенной маской, все что было под маской становилось прозрачным. Это уже вопрос редактора и устройства формата TGA, выходящий за рамки этого урока.
|
Добавил(а): dmch_d | Дата: 2014-05-25 | |
В примере добавлен DGLUT. Разве он используется?
|
Добавил(а): Den1k | Дата: 2017-12-25 | |
Скажите пожалуйста, почему, когда вместо куба из примера я рисую сферу с помощью glutSolidSphere, то текстура на нее не накладывается?
|
Добавил(а): ufo26 | Дата: 2018-06-25 | |
подскажите, как использовать файл "textures.pas"? Куда его сохранять и как прописывать вызов в коде?
|
Добавил(а): ufo26 | Дата: 2018-06-25 | |
разобрался. нужно сохранить файл к себе в проект, а в разделе Uses указать имя файла без расширения.
|
-
выбивает ошибку что file tex.tga найдено.
-
* не найдено. кто знает что делать?