Слайд 2Понятие текстуры
Текстура – одномерное, двумерное или трехмерное изображение, которое имеет
множество ассоциированных с ним параметров, определяющих, каким образом осуществляется наложение
изображения на поверхность.
Существует множество источников текстур. Чаще всего используются растровые изображения и вычисляемые функции.
Слайд 3Задание текстуры
Текстура задается функцией texture(s) для одномерной (1D) текстуры, texture(s,
t) – двумерной (2D), texture(s, t, r) – трехмерной (3D)
в так называемом текстурном пространстве, которое принято обозначать параметрами s, t и r.
Функция texture генерирует значение цвета или яркости для каждого значения s, t и r в диапазоне от 0 до 1.
Слайд 4Преобразование координат текстуры
Образец текстуры отображается на ближнюю грань куба. Для
грани куба имеется преобразование текстуры в мировые координаты , которое
переводит значения текстуры (s, t) в точки (x, y, z) на поверхность грани. Затем осуществляется преобразование точек трехмерного пространства в точки экрана, поэтому точка (x, y, z) поверхности «видна» на месте пикселя с координатами (sx, sy) = Tws(x, y, z).
Слайд 5Наложение текстуры на грань
Привязывание Pi к каждой Vi эквивалентно описанию
в текстурном пространстве треугольника P с тем же числом вершин,
что имеет F. Если треугольник P имеет ту же форму, что и F,то часть текстуры, лежащая внутри треугольника P, без искажений накладывается на весь треугольник F. В тех случаях, когда треугольники P и F имеют одну и ту же форму, преобразование является аффинным – это масштабирование, сопровождающееся, возможно, поворотом и смещением.
Слайд 6Текстурная мозаика
Текстурная мозаика строится путем повторения текстуры. Для этого используются
текстурные координаты, лежащие вне интервала [0,1]. Когда в подпрограмме визуализации
встречаются значения s и t, лежащие вне единичного квадрата, например s = 2.5, то подпрограмма игнорирует целую часть и использует только дробную часть – 0.5.
Слайд 7Визуализация текстура
Визуализация текстуры на грани F осуществляется пиксель за пикселем
по всей грани. Для каждого пикселя нужно определить соответствующие текстурные
координаты (s, t), получить значение текстуры и придать пикселю нужный цвет, заданный этой текстурой.
В случае выхода текстурных координат за пределы интервала (0.0, 1.0) возможны два варианта: либо повторять текстуру за пределами интервала, либо использовать предельные значения: 1.0 – если значение координаты превышает 1.0, или 0.0 – если значение координаты оказывается меньше 0.0.
Слайд 8Влияние проецирование на наложение текстуры
Эффект от наложения текстуры зависит, кроме
прочего, от того, какой тип проецирования используется при формировании изображения.
Например, по умолчанию OpenGL использует для формирования интенсивности накладываемой текстуры линейную интерполяцию в пропространстве координат экрана. При ортогональном проецировании такое линейное отражение пространства текстуры на поверхность объекта является корректным, но при перспективном проецировании следует учитывать нелинейные эффекты по глубине.
Слайд 9Подготовка текстуры в OpenGL
Для использование текстуры необходимо сначала загрузить в
память нужное изображение и передать его OpenGL.
Для этого можно воспользоваться
следующей функцией, входящей в состав библиотеки GLAUX (glaux.lib):
AUX_RGBImageRec* auxDIBImageLoad (const char * file);
Функция возвращает указатель на область памяти, где хранятся преобразованные данные.
Слайд 10Подготовка текстуры в OpenGL
Размеры текстуры должны быть кратны 2. Изменение
размеров можно провести с помощью функции
void gluScaleImage (
GLenum format,
// GL_RGB или GL_RGBA
GLint widthin, // ширина входного изображения
GLint heightin, // высота входного изображения
GLenum typein, // тип элементов входного массива, например:
// GL_UNSIGNED_BYTE , GL_SHORT , GL_INT
const void *datain, // входной массив
GLint widthout, // ширина выходного изображения
GLint heightout, // высота выходного изображения
GLenum typeout, // тип элементов выходного массива, например:
// GL_UNSIGNED_BYTE , GL_SHORT , GL_INT
void *dataout // выходной массив
);
Слайд 11Подготовка текстуры в OpenGL
На случай, когда объект после растеризации оказывается
меньше наносимой на него текстуры, необходимо создать ее уменьшенные копии:
void
gluBuild2DMipmaps (
GLenum target, // GL_TEXTURE_2D
GLint components, // GL_LUMINANCE, GL_RGB или GL_RGBA
GLint width, // ширина текстуры
GLint height, // высота текстуры
GLenum format, // GL_RGB или GL_RGBA
GLenum type, // тип элементов входного массива, например:
// GL_UNSIGNED_BYTE , GL_SHORT , GL_INT
const void *data // расположение текстуры
);
После вызова этой функции текстура копируется во внутреннюю память OpenGL и память с исходным изображением можно освободить.
Слайд 12Подготовка текстуры в OpenGL
Определить двумерную текстуру можно с помощью функции
void
glTexImage2D(
GLenum target, // текстура, например
GL_TEXTURE_2D
Glint level, // число уровней детализации, 0 - единственный уровень
GLint internalFormat, // компоненты (RGBА, глубина, яркость или интенсивность),
// задается номером от 1 до 4 (GL_LUMINANCE,
// GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA)
// либо специальными константами
GLsizei width, // ширина изображения текстуры
GLsizei height, // высота изображения текстуры
GLint border, // толщина границы
GLenum format, // формат изображения текстурв
GLenum type, // тип элементов массива текстуры
const GLvoid *texels // массив данных текстуры (тексели)
);
Слайд 13Подготовка текстуры в OpenGL
При использовании нескольких текстур необходимо:
создать текстурные объекты:
void
glGenTextures (GLsizei n, GLuint* textures);
n – число текстур, textures –
массив идентификаторов текстурных объектов;
сделать один из текстурных объектов текущим:
void glBindTexture (GLenum target , GLuint texture);
target – GL_TEXTURE_1D или GL_TEXTURE_2D, texture – идентификатор текстурного объекта.
Слайд 14Изменение параметров текстуры в OpenGL
void glTexParameter [ i f ]
(GLenum target, GLenum pname, GLenum param);
void glTexParameter [ i f
]v (GLenum target , GLenum pname, Glenum* params);
target – GL_TEXTURE_1D или GL_TEXTURE_2D,
pname:
GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER – элементы текстуры, если размеры поверхности объекта меньше/больше размеров текстуры :
param: GL_NEAREST – ближайший, GL_LINEAR – четыре ближайших,
GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T – режим выхода координат s, t за пределы интервала (0, 1) :
param: GL_REPEAT – отбрасывание целой части, GL_CLAMP – фиксация краевых значений.
Слайд 15Взаимодействие текстуры с материалом объекта в OpenGL
void glEnvParameter [ i
f ] (GLenum target, GLenum pname, GLenum param);
void glEnvParameter [
i f ]v (GLenum target , GLenum pname, Glenum* params);
target – GL_TEXTURE_ENV,
pname – GL_TEXTURE_ENV_MODE,
param:
GL_MODULATE – конечный цвет находится как произведение цвета точки на поверхности и цвета соответствующей точки текстуры,
GL_REPLACE – цвет точки текстуры выбирается в качестве конечного цвета.
Слайд 16Текстурные координаты в OpenGL
void glTexCoord [1 2 3 4][ s
i f d] (type coord);
void glTexCoord [1 2 3 4][
s i f d]v (type *coord);
Слайд 17Наложение текстуры в OpenGL
void gluQuadricTexture (GLUquadricObj* quadObject, GLboolean textureCoords);
Функция автоматического
наложения текстуры (параметр textureCoords должен быть равен GL_TRUE ) на
такие примитивы, как сфера, цилиндр и диск, для построения которых предусмотрены команды в GLU.
Слайд 18Наложение текстуры в OpenGL
void glTexGen [ i f d] (GLenum
coord, GLenum pname, GLtype param);
void glTexGen [ i f d]v
(GLenum coord , GLenum pname, const GLtype *params);
coord – GL_S , GL_T,
pname:
GL_TEXTURE_GEN_MODE – функция наложения текстуры:
param:
GL_OBJECT_LINEAR, GL_EYE_LINEAR – значение текстурной координаты определяется расстоянием до плоскости, задаваемой с помощью значения pname GL_OBJECT_PLANE либо GL_EYE_PLANE, и координатами объекта либо видовыми координатами,
GL_SPHERE_MAP – эмуляция отражения от объекта,
GL_OBJECT_PLANE, GL_EYE_PLANE – задание плоскости.
Слайд 19Наложение текстуры в OpenGL
void glEnable(GLenum cap);
cap - GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_P.
Установка автоматического
режима задания текстурных координат.
Слайд 20Пример 1
/*
texture.c
Nate Robins, 1997
A simple program to show how to do texture mapping.
*/
#include
#include
#include
GLubyte texture[] = {
0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80,
};
Слайд 21Пример 1
void reshape(int width, int height)
{
glViewport(0, 0, width,
height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1.0, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
Слайд 22Пример 1
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3ub(255, 255, 255);
glBegin(GL_TRIANGLES);
glNormal3f(0.0, 0.0, 1.0);
glColor3ub(255, 0, 0);
glTexCoord2f(0.5, 1.0);
glVertex2f(0.0, 2.0);
glColor3ub(0, 255, 0);
glTexCoord2f(0.0, 0.0);
glVertex2f(-2.0, -2.0);
glColor3ub(0, 0, 255);
glTexCoord2f(1.0, 0.0);
glVertex2f(2.0, -2.0);
glEnd();
glFlush();
}
Слайд 23Пример 1
void keyboard(unsigned char key, int x, int y)
{
if (key == 27) exit(0);
}
int main(int argc, char** argv)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 50);
glutInitWindowSize(320, 320);
glutInit(&argc, argv);
glutCreateWindow("texture");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Слайд 25Пример 2
#include
#include
#include
#include
char fileName[81];
GLuint texture[2];
struct Image {
unsigned
long sizeX;
unsigned long sizeY;
char *data;
};
typedef struct Image Image;
#define checkImageWidth 64
#define
checkImageHeight 64
GLubyte checkImage[checkImageWidth][checkImageHeight][3];
Слайд 26Пример 2
void makeCheckImage(void){
int i, j, c;
for
(i = 0; i < checkImageWidth; i++) {
for (j = 0; j < checkImageHeight; j++) {
c = ((((i&0x8)==0)^((j&0x8)==0)))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
}
}
}
Слайд 27Пример 2
int ImageLoad(char *filename, Image *image) {
FILE *file;
unsigned long size;
unsigned long i;
unsigned
short int planes;
unsigned short int bpp;
char temp;
if ((file = fopen(filename, "rb"))==NULL){
printf("File Not Found : %s\n",filename);
return 0;
}
fseek(file, 18, SEEK_CUR);
if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
printf("Error reading width from %s.\n", filename);
return 0;
}
if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
printf("Error reading height from %s.\n", filename);
return 0;
}
Слайд 28Пример 2
size = image->sizeX * image->sizeY * 3;
if ((fread(&planes, 2, 1, file)) != 1) {
printf("Error reading planes from %s.\n", filename);
return 0;
}
if (planes != 1) {
printf("Planes from %s is not 1: %u\n", filename, planes);
return 0;
}
if ((i = fread(&bpp, 2, 1, file)) != 1) {
printf("Error reading bpp from %s.\n", filename);
return 0;
}
if (bpp != 24) {
printf("Bpp from %s is not 24: %u\n", filename, bpp);
return 0;
}
Слайд 29Пример 2
fseek(file, 24, SEEK_CUR);
image->data = (char
*) malloc(size);
if (image->data == NULL) {
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf("Error reading image data from %s.\n", filename);
return 0;
}
for (i=0;i temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
return 1;
}
Слайд 30Пример 2
Image * loadTexture(){
Image *image1;
image1 =
(Image *) malloc(sizeof(Image));
if (image1 == NULL) {
printf("Error allocating space for image");
exit(0);
}
if (!ImageLoad(fileName, image1)) {
exit(1);
}
return image1;
}
Слайд 31Пример 2
void myinit(void)
{
glClearColor (0.5, 0.5, 0.5, 0.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
Image *image1 = loadTexture();
if(image1
== NULL){
printf("Image was not returned from loadTexture\n");
exit(0);
}
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(2, texture);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Слайд 32Пример 2
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,&checkImage[0][0][0]);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_FLAT);
}
Слайд 33Пример 2
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glutSolidTeapot(1.0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(0.0, 1.0);
glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
glutSwapBuffers();
}
Слайд 34Пример 2
void myReshape(int w, int h){
glViewport(0, 0, w,
h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}
void keyboard (unsigned char key, int x, int y){
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}
Слайд 35Пример 2
int main(int argc, char** argv)
{
if(argc > 1){
strcpy(fileName, argv[1]);
}
else
{
printf("Error format programm.\n");
return 0;
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Texture Mapping - Programming Techniques");
myinit();
glutReshapeFunc (myReshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}