Файл: Opengl игорь Тарасов Часть i основы OpenGL.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 12.01.2024

Просмотров: 190

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Если там указать не те числа, то изображение наклонится.


Исходный файл смотрите здесь. Исполняемый файл здесь.
5.6  Упражнение: "Вращаем текстуру"

Завращайте плоскость с фотографией вокруг оси X и Y. Также пусть она равномерно колеблется вдоль оси Z от 3 до 7.


Исходный файл смотрите здесь. Исполняемый файл здесь.


5.7  Текстура на сфере

Здесь я покажу, как работать с одной единственной текстурой и накладывать текстуры на сферы. Создайте новый проект с именем sphere. Добавьте глобальную переменную.
AUX_RGBImageRec* photo_image;
В функции main загрузите изображение и создайте текстуру. Поскольку текстура у нас в этом приложении всего одна, то создавать идентификатор для нее не надо.
void main()

{

auxInitPosition( 50, 10, 400, 400);

auxInitDisplayMode( AUX_RGB | AUX_DEPTH | AUX_DOUBLE );

auxInitWindow( "Shapes" );

auxIdleFunc(display);

auxReshapeFunc(resize);

glEnable(GL_DEPTH_TEST);

glEnable(GL_TEXTURE_2D);
photo_image = auxDIBImageLoad("photo.bmp");
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, 3,

photo_image->sizeX,

photo_image->sizeY,

0, GL_RGB, GL_UNSIGNED_BYTE,

photo_image->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
auxMainLoop(display);

}
Отредактируйте функцию display. Здесь все вам знакомо см. 4.1, кроме gluQuadricTexture. Эта функция разрешает или запрещает наложение текстуры на трехмерный объект. Второй параметр GL_TRUE или GL_FALSE. По умолчанию наложение текстуры запрещено.
void CALLBACK display(void)

{

GLUquadricObj *quadObj;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
quadObj = gluNewQuadric();

gluQuadricTexture(quadObj, GL_TRUE);

gluQuadricDrawStyle(quadObj, GLU_FILL);

glColor3d(1,1,1);
glRotated(5, 0,1,0);
glPushMatrix();

glRotated(-90, 1,0,0);

gluSphere(quadObj, 3, 16, 16);

glPopMatrix();
gluDeleteQuadric(quadObj);

auxSwapBuffers();

}



Исходный файл смотрите здесь. Исполняемый файл здесь.
5.8  Упражнение

Наложите текстуру на цилиндр, конус, диски и частичный диск.
5.9  Текстура на чайнике

Текстуру можно наложить на объект любой сложности. Для этого надо разрешить автоматически генерировать координаты текстуры - glEnable(GL_TEXTURE_GEN_S) и glEnable(GL_TEXTURE_GEN_T). Далее, вы должны установить один из трех алгоритмов генерации координат текстур.
GL_OBJECT_LINEAR

GL_EYE_LINEAR

GL_SPHERE_MAP
Алгоритм генерации координат устанавливается с помощью функции glTexGeni. Первый параметр функции указывает тип координаты, для которой будет установлен алгоритм. GL_S -горизонтальная координата, GL_T - вертикальная. Второй параметр этой функции должен быть GL_TEXTURE_GEN_MODE. И третий параметр - один из перечисленных выше алгоритмов. Создайте очередной проект с именем teapot. Отредактируйте функцию main, как в предыдущей программе, где мы накладывали изображение на сферу. Только добавьте там строчку glEnable(GL_AUTO_NORMAL), чтобы чайник лучше выглядел. Этот режим разрешает расчет векторов нормалей, что позволяет получать улучшенные изображения, однако занимает некоторое время. А функцию display отредактируйте, как показано ниже.


void CALLBACK display(void)

{

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_TEXTURE_2D);

glEnable(GL_TEXTURE_GEN_S);

glEnable(GL_TEXTURE_GEN_T);
glColor3d(1,1,1);

glRotated(5,0,1,0);
glPushMatrix();

glTranslated(0,3,0);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

auxSolidTeapot(2);
glTranslated(0,-3,0);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

auxSolidTeapot(2);
glTranslated(0,-3,0);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);

auxSolidTeapot(2);

glPopMatrix();
glDisable(GL_TEXTURE_GEN_S);

glDisable(GL_TEXTURE_GEN_T);

glDisable(GL_TEXTURE_2D);
auxSwapBuffers();

}



Исходный файл смотрите здесь. Исполняемый файл здесь.

Конечно, фотография накладывается не самым лучшим образом. А что вы хотели? Машина сама сгенерировать правильно координаты на кривой поверхности не может. Тем не менее, если в качестве текстуры взять изображение в горошек, то оно довольно неплохо ляжет на чайник.




Chapter 6

Освещение и все что с ним связано

6.1  Общие понятия

Создавать объекты и накладывать на них текcтуры вы научились. Осталась последняя из основных тем - это освещение объектов. Освоив освещение, вы сможете создавать полноценные трехмерные сцены. Освещение любого объекта зависит от двух факторов. Первый - это материал, из которого сделан объект. Второй - это свет, которым он освещен. В этой главе мы подробно рассмотрим все особенности OpenGL, касающиеся освещения объектов.
6.2  Модель освещения

По умолчанию освещение отключено. Включается оно командой glEnable(GL_LIGHTING). В базовом шаблоне освещение я включил, потому что без освещения работать практически невозможно. Сфера всегда будет показываться как круг, а конус - как круг или треугольник. Если монотонное тело у вас равномерно освещено, то вы не можете увидеть его рельеф. Поэтому нам нужно использовать источники света. Сначала рассмотрим функцию, которая устанавливает базовые настройки. Когда вы разрешили освещение, то вы можете уже устанавливать фоновую освещенность. По умолчанию, значение фоновой освещенности равно (0.2, 0.2, 0.2, 1). Создайте новый проект, скопируйте туда шаблонный файл и отключите освещение. Вы с трудом сможете различить сферу на экране. С помощью функции glLightModel вы можете установить фоновое освещение. Если вы повысите его до (1,1,1,1), т.е. до максимума, то включать источники света вам не понадобится. Вы их действия просто не заметите, т.к. объект уже максимально освещен. И получится, что вы как бы отключили освещение. В общем, добавьте в main вызов следующей функции:

float ambient[4] = {0.5, 0.5, 0.5, 1};

...

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
Попробуйте изменить параметры и посмотрите на результат. Нулевую лампу (glEnable(GL_LIGHT0)) лучше отключить.


Исходный файл смотрите здесь. Исполняемый файл здесь.
6.3 Материал
Материал может рассеивать, отражать и излучать свет. Свойства материала устанавливаются при помощи функции
glMaterialfv(GLenum face, GLenum pname, GLtype* params)
Первый параметр определяет грань, для которой устанавливаются свойства. Он может принимать одно из следующих значений:

GL_BACK задняя грань

GL_FONT передняя грань

GL_FRONT_AND_BACK обе грани
Второй парметр функции glMaterialfv определяет свойство материала, которое будет установлено, и может принимать следующие значения.
GL_AMBIENT рассеянный свет

GL_DIFFUSE тоже рассеянный свет, пояснения смотри ниже

GL_SPECULAR отраженный свет

GL_EMISSION излучаемый свет

GL_SHININESS степень отраженного света

GL_AMBIENT_AND_DIFFUSE оба рассеянных света
Ambient и diffuse переводятся на русский как "рассеянный". Разница между ними не очень понятна. Я использую только GL_DIFFUSE. Третий параметр определяет цвет соответствующего света, кроме случая GL_SHININESS.

Цвет задается в виде массива из четырех элементов - RGBA. В случае GL_SHININESS params указывает на число типа float, которое должно быть в диапазоне от 0 до 128. Я написал простенький пример с цилиндром и раскрасил его грани в разные цвета. Вам надо всего лишь модифицировать функцию display.
void CALLBACK display(void)

{

GLUquadricObj *quadObj;

GLfloat front_color[] = {0,1,0,1};

GLfloat back_color[] = {0,0,1,1};
quadObj = gluNewQuadric();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMaterialfv(GL_FRONT, GL_DIFFUSE, front_color);

glMaterialfv(GL_BACK, GL_DIFFUSE, back_color);
glPushMatrix();

glRotated(110, -1,1,0);

gluCylinder(quadObj, 1, 0.5, 2, 10, 10);

glPopMatrix();
gluDeleteQuadric(quadObj);

auxSwapBuffers();

}
И вы должны разрешить режим освещенности для двух граней. По умолчанию он запрещен. Добавьте в функцию main следующую строчку.
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

Исходный файл смотрите здесь. Исполняемый файл здесь.



  1. Лампы и их свойства


6.5  Тени
Chapter 7
Инициализация или как написать приложение с нуля


7.1  Общие положения

В этой главе вы познакомитесь с самой главной частью приложения - начальной инициализацией. На мой взгляд, это очень сложная тема. Я решил оставить ее на конец книги, когда вы уже будете знакомы с OpenGL. В противном случае, если бы я поместил эту главу в самом начале, я боюсь вы многого не поняли бы. Да и вообще, может не стали бы читать эту книжку.


Сначала, я расскажу в общих чертах, что нужно для инициализации OpenGL. Далее мы рассмотрим несколько частных реализаций в среде Windows, Linux и межплатформенный вариант для Java.

Для программирования графики в OpenGL вы должны иметь контекст воспроизведения. Это что-то типа контекста устройства в Windows или же магического адреса 0xA000 для графического или же 0xB800 для текстого режима MSDOS. Первое, что вы должны сделать, это подобрать и установить нужные вам параметры контекста воспроизведения. Потом создать сам контекст воспроизведения. И последнее, вы должны сделать его активным. Вообще говоря, вы можете иметь несколько контекстов воспроизведения, но активным может быть только один. Теперь вы можете уже что-нибудь рисовать. Но, возможно, вам не подходят настройки по умолчанию, которые предлагает OpenGL. Так что, придется еще немного потрудиться. Нужно сделать две вещи. Первое - это разрешить нужные вам опции с помощью glEnable и, здесь же, настроить параметры ламп, если вы используете освещение. Второе - надо обрабатывать сообщение об изменениях размера вашего окна. Тут вы указываете ту часть окна, где у вас будет располагаться контекст OpenGL. До этой главы у нас во всех примерах размер нашего окна и окна OpenGL совпадали, но, вообще говоря, это необязательно. Вывод OpenGL может занимать только часть окна, а в остальной части вы можете разместить свои компоненты: кнопки, поля ввода и т.п. Далее, вы должны указать тип проекции: перпективная или параллельная. В перспективной проекции две параллельных прямых будут сходиться вдалеке. В параллельной же проекции они всегда будут оставаться параллельными. И последнее, вы устанавливаете точку, где находится ваш глаз; точку, куда вы смотрите, и вектор, который принимается за направление вверх. У меня этот вектор во всех примерах - (0,1,0), т.е. ось Y направлена вверх.
7.2  Консольное приложение - Win32 Console Application

Достоинством приложений данного типа является переносимость на другие платформы при условии, что вы не пользовались другими платформенно зависимыми библиотеками. Реализация OpenGL Auxilary Library существует для большинства платформ. Также здесь значительно упрощена начальная инициализация, т.е. вы быстро можете начать программировать. Идеально подходит для начинающих. Именно поэтому, все примеры в этой книге я привязал к этому варианту приложения OpenGL. Хотя, как я уже говорил, вы можете вставлять приводимый код в WinAPI-приложение и MFC-приложение, и все будет работать точно так же. Для Java-приложения вам придется добавить префиксы к функциям. Недостатком является урезанная функциональность. Вы не можете обрабатывать все сообщения, которые приходят вашему окну. Такой тип приложения идеально подходит для написания небольших портабельных утилит, размером до 25Kb.