Реферат по предмету "Разное"


Opengl игорь Тарасов Часть I основы OpenGL

OpenGL Игорь ТарасовЧасть IОсновы OpenGL Глава 1. Введение. Глава 2. Быстрый старт Глава 3. Рисуем простые объекты Глава 4. Полезные мелочи Глава 5. Работа с картинками Глава 6. Освещение и все, что с ним связано Глава 7. Инициализация или как написать приложение с нуля Глава 8. Примеры интересных программ Приложение A. Где взять OpenGL и другое ПО Библиография Загрузка исходных файлов и поддержка книги Chapter 1 Введение.1.1  Что это такое и кому это нужно? OpenGL - Open Graphics Languge, открытый графический язык. Термин "открытый" - значит независимый от производителей. Имеется спецификация OpenGL, где все четко задокументировано и описано. Библиотеку OpenGL может производить кто-угодно. Главное, чтобы библиотека удовлетворяла спецификации OpenGL и ряду тестов. Как следствие, в библиотеке нет никаких темных мест, секретов, недокументированных возможностей и т.п. Библиотеку выпускают такие корпорации, как Microsoft, Silicon Graphics, а также просто группы программистов. Одним из таких примеров служит реализация Mesa. Эту библиотеку написали целый ряд программистов, главным автором является Brian Paul. Библиотека Mesa распространяется в исходных текстах на языке Си и собирается почти для любой операционной системы. Стандарт OpenGL развивается с 1992 года. Он разрабатывается фирмой Silicon Graphics. С тех пор библиотека завоевала огромную популярность и была интегрирована со множеством языков и систем разработки приложений. Вы можете писать программу на Си,С++,Pascal,Java и многих других языках. Существуют также объектно-ориентированные библиотеки OpenGL. Библиотека OpenGL представляет из себя интерфейс программирования трехмерной графики. Единицей информации является вершина, из них состоят более сложные объекты. Программист создает вершины, указывает как их соединять(линиями или многоугольниками), устанавливает координаты и параметры камеры и ламп, а библиотека OpenGL берет на себя работу создания изображения на экране. OpenGL идеально подходит для программистов, которым необходимо создать небольшую трехмерную сцену и не задумываться о деталях реализации алгоритмов трехмерной графики. Для профессионалов, занимающихся программированием трехмерной графики, библиотека тоже будет полезной, т.к. она представляет основные механизмы и выполняет определенную автоматизацию.^ 1.2  О книге Эта книга является самоучителем по популярной библиотеке OpenGL. Изначально задумывалась некая брошюра, что-то типа небольшого самоучителя. Потом проект сильно разросся, и я подумал: "А почему бы не написать книгу?". Я рассчитываю, что вы уже неплохо знакомы с программированием, в частности, с языком Си. Здесь, в основном, будет рассматриваться написание программ в среде Windows. Рассмотрю, конечно же, и особенности использования OpenGL в операционной системе Unix. Я опишу несколько различных типов приложений. Первый тип - это консольное приложение win32 с использованием библиотеки glaux.lib. Второе - обычное оконное приложение(Win32 Application). Третье - это приложение на базе MFC с архитектурой документ/вид. Четвертое - я покажу, как писать Java-апплеты с использованием библиотеки Magician. Magician - это библиотека java-классов с функциями, идентичными OpenGL. И пятое - Unix-приложение. Различия в написании этих приложений проявляются в начальной инициализации, префиксах и суффиксах названий функций. В остальном, на 90% все везде одинаково. Книга состоит из двух частей - "Основы OpenGL" и "OpenGL для профессионалов". Первая часть является скорее учебником, вторая - справочником по малоизвестным функциональным возможностям OpenGL. Я хотел сделать каждую главу книги самодостаточной. Насколько мне это удалось, судить вам. Но я бы рекомендовал читать книгу последовательно. Главное, на что я делал упор, так это на простоту и понятность. Все примеры очень простые, и их размер не превышает нескольких килобайт. Все написано на чистом Си. В основу книги положен реальный опыт работы. И последнее, что надо сказать здесь, я не претендую на полноту и детальную точность изложения материала. Книга ставит задачей научить читателя элементарным вещам, и поэтому здесь все объясняется простым и понятным языком на конкретных примерах с точки зрения практика, а не теоретика.Более точную информацию вы сможете найти в спецификации по OpenGL и на сайте Silicon Graphics http://www.sgi.com/software/opengl. Книга написана при помощи пакета LATEX2e в ОС Linux.1.3  Об авторе Со мной можно связаться по электронной почте: * FidoNet: 2:5020/370.2 620.20 1103.5 * Inet: itarasov@rtuis.miem.edu.ruЕсли у вас имеются дополнения или какие-то материалы, которые, по вашему мнению, желательно включить в книгу, то мы с удовольствием обсудим эту тему. Особенно я занят поиском материалов для второй части книги.1.4  Благодарности Хочется поблагодарить огромную массу людей, без которых эта книга вряд ли бы состоялась. Прежде всего, хочу выразить благодарность тем, кто непосредственно помогал мне при написании книги.Chapter 2 Быстрый старт^ 2.1  Устанавливаем OpenGL Начнем с самого главного, установим необходимое программное обеспечение. Я предполагаю, что Windows у Вас уже установлен. Во-первых, установите MSVisualC++6.0 и jdk113 или выше. Во-вторых, нам понадобится реализация библиотеки OpenGL. Она входит в поставку Windows95/NT - это билиотеки opengl32.dll & glu32.dll. Вы также можете взять библиотеки OpenGL от Silicon Graphics. Инструкция по установке там прилагается. Вам придется скопировать opengl.dll и glu.dll в windows\system и положить opengl.lib, glu.lib в подкатолог Lib, где установлено MSVisualC++. В-третьих, вам понадобятся четыре моих программы-шаблона, которые представляют собой начальный скелет, который мы потом будем наполнять функциональностью. Где взять OpenGL от Silicon Graphics, Magician, jdk и мои программы-шаблоны, смотри в приложение 'А'.^ 2.2  Давайте что-нибудь изобразим Самым простым объектом, с помощью которого можно увидеть всю мощь OpenGL, является сфера. Давайте попытаемся ее изобразить. Выполните следующее: Запустите MSVisualC++6.0 Щелкните меню File->New->Win32 Console Application. Выберете каталог и имя проекта, впишите - sphere, щелкните OK. Я все свои проекты держу на диске D в каталоге Projects. Projects ветвится дальше на подкатологи с базами данных, утилитами, графикой и Java-приложениями. В общем, старайтесь присваивать разумные имена и вести разумную структуру каталогов. Это очень серьезная проблема. У меня некоторые ребята не учли моих советов, и через две недели у них в домашних директориях образовался такой беспорядок, что они сами перестали понимать, что и где у них лежит. Выберете An Empty Project, щелкните Finish. Cкопируйте в каталог вашего проекта мой шаблон console.c и переименуйте его в sphere.c Присоедините его к проекту. Project->Add To Project->Files Щелкните Build->Set Active Configuration и установите тип проекта sphere - Win32 Release Далее, щелкайте Project->Settings->Link->Object/library modules и добавьте туда opengl32.lib, glu32.lib и glaux.lib Вставьте в функцию display следующий код: glColor3d(1,0,0); auxSolidSphere(1);Теперь откомпилируйте и запустите Вашу программу. Меню Build->Execute Sphere.exe Исходный файл смотрите здесь. Исполняемый файл здесь. glColor3d устанавливает текущий цвет, которым будут рисоваться фигуры. Тут нужно пояснить, как устанавливается цвет и общюю философию в названии функций OpenGL. Цвет устанавливается четырьмя параметрами: красный, синий, зеленый и прозрачность. Эти параметры вариируются в диапозоне от нуля до единицы. Четвертый параметр нам пока не нужен, поэтому мы вызвали glColor с тремя параметрами. В этом случае, значение четвертого параметра, прозрачности, по умолчанию считается равным единице, т.е. абсолютно непрозрачным, ноль - будет абсолютно прозрачным. Так как в языке Си нет перегрузки функций, то применяется следующий синтаксис вызова функций - FuncionName[n=число параметров][тип параметров]. Доступны следующие типы: b - GLbyte байт s - GLshort короткое целое i - GLint целое f - GLfloat дробное d - GLdouble дробное с двойной точностью ub - GLubyte беззнаковый байт us - GLushortбеззнаковое короткое целое ui - GLuint беззнаковое целое v - массив из n параметров указанного типа В нашем случае - glColor3d - означает, что в функцию передается три параметра типа GLdouble. Также можно было вызвать glColor3i, т.е. три параметра типа GLint. Если тип параметров короткое целое, целое или байт, то компонента цвета приводится к диапазону [0,1]. Или же glColor3dv означает, что в качестве параметров передается массив из трех элементов типа GLdouble. Например: double array[] = {0.5, 0.75, 0.3, 0.7}; ... glColor3dv(array); glColor3ub(200,100,0);// приводится к 200/256, 100/256, 0,256 auxSolidSphere - рисует сферу в начале координат и единичным радиусом.^ 2.3  Упражнение: "Трехмерные фигуры" Замените функцию auxSolidSphere на функцию, из указанных ниже с соответсвующими параметрами. Значения параметров устанавливайте порядка единицы - 0.5-1.7. Если вы укажете слишком маленький размер, фигуру будет плохо видно; если слишком большой, то она получится урезанной. Это связано с тем, что ее край, как бы вылезет из монитора. auxSolidCube(width) // куб auxSolidBox(width, height, depth) // коробка auxSolidTorus(r,R) // тор auxSolidCylinder(r,height) // цилиндер auxSolidCone(r,height) // конус auxSolidIcosahedron(width) // многогранники auxSolidOctahedron(width) auxSolidTetrahedron(width) auxSolidDodecahedron(width) auxSolidTeapot(width) // рисует чайник С помошью выше указанных функций вы можете рисовать сплошные фигуры. Если вам надо нарисовать проволочную, то вместо Solid пишите Wire. Пример: auxWireCube(1) // рисует проволочный куб.^ 2.4  Переход к новым координатам Продолжим рисовать трехмерные фигуры. В предыдущем параграфе вы научились рисовать примитивные трехмерные объекты. Но проблема в том, что они рисуются только в начале координат, т.е. в точке (0,0,0). Для того чтобы изобразить сферу в точке ( x0,y0,z0 ), надо переместить начало координат в эту точку, т.е. надо перейти к новым координатам. Эта процедура довольно распространенная при программировании графики и анимации. Часто, бывает очень удобно, сместить координаты в новую точку и повернуть их на требуемый угол, и ваши расчеты резко упростятся. Конктреный пример мы рассмотрим ниже, когда научимся программировать анимацию. А пока вы узнаете, как переходить к новым координатам. Для перехода к новым координатам в OpenGL есть две функции: glTranslated( Dx,Dy,Dz ) glRotated(j,x0,y0,z0 ) Первая функция сдвигает начало системы координат на ( Dx,Dy,Dz ). Вторая - поворачивает на угол j против часовой стрелки вокруг вектора (x0,y0,z0) Теперь, стоит сказать еще о двух очень важных функциях: glPushMatrix() glPopMatrix() Они предназначены для сохранения и восстановления текущих координат. Я не стал здесь приводить пример на то, как неудобно переходить от одной системы координат к другой и помнить все ваши переходы. Гораздо удобнее с помощью glPushMatrix() сохранить текущие координаты, потом сдвигаться, вертеться, как вам угодно, а после, вызывом glPopMatrix вернуться к старым координатам. Итак, настало время поэкспериментировать. Создайте новый проект, повторив пункты из раздела 2.2. Только назовите его sphere2. Вставьте в функцию display следующий код: glPushMatrix(); // сохраняем текущие координатыglTranslated(1.4,0,0); // сдвигаемся по оси Х на 1.4 glColor3d(0,1,0); auxSolidSphere(0.5); // рисуем сферу в (1.4,0,0) в абсолютных координатахglTranslated(1,0,0); // еще раз сдвигаемся glColor3d(0,0,1); auxSolidSphere(0.3);glPopMatrix(); // возвращаемся к старой системе координатglColor3d(1,0,0); auxSolidSphere(0.75); // рисуем сферу в точке (0,0,0) в абсолютных координатахТеперь, откомпилируйте и запустите вашу программу. Меню Build->Execute Sphere.exe Исходный файл смотрите здесь. Исполняемый файл здесь. В общем-то, из комментариев многое понятно. Обращаю ваше внимание только на два последних вызова auxSolidSphere. Перед вызовом glPopMatrix сфера рисуется в точке (2,0,0), а после, в точке (0,0,0).^ 2.5  Упражнение: "Cписок трехмерных фигур" Используя список функций из предыдущего упражнения, нарисуйте эти фигуры в два столбца. Слева проволочные. Справа сплошные. Примечание: тут хочу заметить, что в версии glaux.lib от фирмы Microsoft имеется следующий баг: цилиндр и конус рисуются всегда либо проволочными, либо сплошными. Если вы первый цилиндр/конус в программе нарисовали проволочным, то далее все цилиндры/конусы будут проволочными. Соответсвенно, если первой была сплошная фигура, то далее все будут сплошные. Поэтому, не стоит паниковать. Это ошибка Microsoft. Могу также вас порадовать, что ниже я расскажу, как обойти эту проблему. Исходный файл смотрите здесь. Исполняемый файл здесь. ^ 2.6  Поворот координат Создайте новый проект с именем Rotate. Переименуйте glaux.c в rotate.c В функцию display вставьте следующий код: glColor3d(1,0,0); auxSolidCone(1, 2); // рисуем конус в центре координатglPushMatrix(); // сохраняем текущие координаты glTranslated(1,0,0); // сдвигаемся в точку (1,0,0) glRotated(75, 1,0,0); // поворачиваем систему координат на 75 градусов glColor3d(0,1,0); auxSolidCone(1, 2); // рисуем конус glPopMatrix(); // возвращаемся к старым координатамКак видите, конус повернулся в абсолютных координатах. Так что, для того, чтобы нарисовать фигуру не в начале координат, надо: сохранить текущие координаты сдвинуть(glTranslated), повернуть(glRotated) нарисовать то, что хотели вернуться к старым координатам Вызовы glPushMatrixglPopMatrix могут быть вложенными, т.е.: glPushMatrix(); ... glPushMatrix(); glPopMatrix(); ... glPopMatrix();Естественно число вызовов glPopMatrix должно соответствовать числу вызовов glPushMatrix.^ 2.7  Упражнение: "Снеговик" Используя функцию glRotate, нарисуйте снеговика. Три сферы, шапка - конус, нос - тоже конус, глаза - сфера, рот можно квадратным сделать - glBox. Исходный файл смотрите здесь. Исполняемый файл здесь. Примечание: Имеется еще один баг в glaux.lib от Microsoft. Кажется, последний из известных мне. Функция aux[Solid/Wire]Cylinder прежде, чем нарисовать цилиндр, сдвигает и поворачивает координаты. Так что, если вы уже сместили и повернули координаты, то цилиндр нарисуется совсем не там, где вы рассчитывали. Люди из Microsoft, конечно же, будут уверять, что это особенность, и предложат вам скачать очередной ServicePack.;-) А я ниже расскажу, как более правильно рисовать цилиндры и конусы. Если вам некогда ждать, то далее приведен исправленный код этих функций. Большинство из вас сейчас пропустят его и перейдут к следующему очень интересному разделу - "Анимация". И правильно сделаете. К исправлению ошибок вернетесь, когда немного освоитесь. Но я все же решил привести код по исправлению ошибок Microsoft именно здесь. Можете пересобрать glaux.lib, заменив соответсвующий код в файле shapes.c. Где взять исходники, смотрите в приложение 'A'. По-моему, они есть в MSDN. void auxWireCylinder (GLdouble radius, GLdouble height) { GLUquadricObj *quadObj; GLdouble *sizeArray, *tmp; GLuint displayList;sizeArray = (GLdouble *) malloc (sizeof (GLdouble) * 2); tmp = sizeArray; *tmp++ = radius; *tmp++ = height; displayList = findList (CYLINDERWIRE, sizeArray, 2);if (displayList == 0) { glNewList(makeModelPtr (CYLINDERWIRE, sizeArray, 2), GL_COMPILE_AND_EXECUTE); quadObj = gluNewQuadric (); gluQuadricDrawStyle (quadObj, GLU_LINE); gluCylinder (quadObj, radius, radius, height, 12, 2); glEndList(); } else { glCallList(displayList); free (sizeArray); } }void auxSolidCylinder (GLdouble radius, GLdouble height) { GLUquadricObj *quadObj; GLdouble *sizeArray, *tmp; GLuint displayList;sizeArray = (GLdouble *) malloc (sizeof (GLdouble) * 2); tmp = sizeArray; *tmp++ = radius; *tmp++ = height; displayList = findList (CYLINDERSOLID, sizeArray, 2);if (displayList == 0) { glNewList(makeModelPtr (CYLINDERSOLID, sizeArray, 2), GL_COMPILE_AND_EXECUTE); quadObj = gluNewQuadric (); gluQuadricDrawStyle (quadObj, GLU_FILL); gluQuadricNormals (quadObj, GLU_SMOOTH); gluCylinder (quadObj, radius, radius, height, 12, 2); glEndList(); } else { glCallList(displayList); free (sizeArray); } }void auxSolidCone (GLdouble base, GLdouble height) { GLUquadricObj *quadObj; GLdouble *sizeArray, *tmp; GLuint displayList;sizeArray = (GLdouble *) malloc (sizeof (GLdouble) * 2); tmp = sizeArray; *tmp++ = base; *tmp++ = height; displayList = findList (CONESOLID, sizeArray, 2);if (displayList == 0) { glNewList(makeModelPtr (CONESOLID, sizeArray, 2), GL_COMPILE_AND_EXECUTE); quadObj = gluNewQuadric (); gluQuadricDrawStyle (quadObj, GLU_FILL); gluQuadricNormals (quadObj, GLU_SMOOTH); gluCylinder (quadObj, base, (GLdouble)0.0, height, 15, 10); glEndList(); } else { glCallList(displayList); free (sizeArray); } }2.8  Анимация Давайте оживим нашего снеговика и добавим интерактивность. Для этого надо отрисовывать кадры и реагировать на внешние события от клавиатуры или мыши. Для отрисовки кадров их надо как-то различать. Для этого мы в функции display вводим переменную time типа int с модификатором static. Создайте новый проект и в функцию display введите следующее: Яtatic int time=0;". Модификатор static означает, что значение переменной будет сохраняться при выходе из функции. Начальное значение мы устанавливаем в ноль. Если функция display не зависит от времени, то счетчик кадров можно и не вести. Теперь добавьте следующие строчки: glPushMatrix(); glTranslated( ((double)time)/100.0 ,0,0); ... // здесь код из предыдущего упражнения "Cнеговик" glPopMatrix();Запустив приложение, вы увидите, что снеговик пополз вдоль оси Х. Вот так вы можете делать анимацию. Т.е. теперь координаты объектов вычисляются в зависимости от времени. Я привел простой пример. Вообще говоря, для программирования сложной графики вам понадобится вычислять координаты каждого отдельного объекта в зависимости от времени. Далее мы рассмотрим пример с более сложной анимацией. Здесь вращается тор и его ось вращения. Я приведу исходный текст с подробными комментариями. Пример программы "Гироскоп": Исходный файл смотрите здесь. Исполняемый файл здесь. glPushMatrix(); // сохраняем текущие координаты, т.к. при выходе // из функции нам нужно вернуться к абсолютным координатам // попробуйте закомментировать вызов glPushMatrix // здесь и glPopMatrix в конце и вы увидите, что из этого получитсяglRotated(time/2, 0.0, 1.0, 0.0); // поворачиваем координаты glLineWidth(5); // устанавливаем толщину линии - пять glColor3f(1,0,0); // устанавливаем текущий цвет - красныйglBegin(GL_LINES); // рисуем красную ось glVertex3d(-0.3,0,0); // т.к. мы повернули координаты, glVertex3d(1.5,0,0); // ось будет повернута в абсолютных glEnd(); // координатах, и т.к. функция display вызывается в цикле, и переменная // time увеличивается на единицу // при каждом вызове display, мы // получаем анимацию - вращающуюся ось glPushMatrix(); // теперь относительно повернутых координат // мы переходим к новым координатамglRotated(2*time, 1,0,0); // поворачиваем их на угол 2*time вокруг красной оси glTranslated(-0.3,0,0); // и сдвигаем на край осиglColor3f(0,0,1); // устанавливаем синий цвет glPushMatrix(); // теперь еще раз переходим к новым координатам, glRotated(90,0,1,0); // чтобы развернуть тор на 90 градусов // у вас крыша еще не поехала? // немного? // то-то же, тут не так все просто, но если понять что и как, то // очень удобно программировать графику glLineWidth(1); auxWireTorus(0.2, 0.7); glPopMatrix(); // нарисовав тор, мы возвращаемся к предыдущим // координатам, если забыли, начало этих координат // лежит на конце красной оси glLineWidth(7); glColor3f(0,1,0); glBegin(GL_LINES); // теперь рисуем три зеленых линиии glVertex3d(0,0,0); // что тут и как рисуется, я поясню в glVertex3d(0,1,0); // следующей glVertex3d(0,0,0); // главе, сейчас это не так важно glVertex3d(0,-0.5,1); glVertex3d(0,0,0); glVertex3d(0,-0.5,-1); glEnd(); glPopMatrix(); // теперь возвращаемся к повернутым координатам на угол time/2 glPopMatrix(); // ну и переходим к абсолютным координатамtime++; // увеличиваем счетчик кадров или вермя, называйте как хотите, на единицуКак вы, наверное, догадались, надо создать очередной проект, скопировать туда мой шаблон, добавить его в проект, указать библиотеки opengl32.lib glu32.lib glaux.lib в Project->Setting->Link->Settings->Link->Object/library modules:, вставить этот код в функцию display. Еще вам нужно в начале функции display вставить строку static int time=0; и закомментировать строчку glEnable(GL_LIGHTING) в функции main. Запустив это приложение, вы увидите, как оно работает. Теперь закомментируйте соответсвующие друг другу вызовы glPushMatrix и glPopMatrix и посмотрите на результат. Я бы рекомендовал такой способ для изучения и понимания работы программы: вы комментируете куски кода и смотрите, что получается. Для того, чтобы реагировать на клавиатуру или мышь, вы должны определить функцию, которая будет вызываться при поступление событий от клавиатуры или мыши. Для кнопки клавиатуры вы определяете функцию со следующим прототипом void CALLBACK FunctionName(void) и устанавливаете ее как обработчик определенной кнопки - auxKeyFunc(key_code, FunctionName); key_code смотри в glaux.h. Пример: auxKeyFunc(AUX_LEFT, FunctionName) Здесь вы устанавливаете FunctionName как функцию, которая будет вызываться при нажатии на клавиатуре клавиши "стрелка влево". Для мыши вы устанавливаете свою функцию обработки событий мыши вызовом функции auxMouseFunc(int button,int action,AUXMOUSEPROC). Переменная button может принимать значения - AUX_LEFTBUTTON, AUX_MIDDLEBUTTON, AUX_RIGHTBUTTON. Переменная action принимает следующие значения - AUX_MOUSEDOWN, AUX_MOUSEUP, AUX_MOUSELOC. Функция AUXMOUSEPROC должна иметь прототип - void CALLBACK FunctionName(AUX_EVENTREC *event), где AUX_EVENTREC определено как typedef struct _AUX_EVENTREC { GLint event; GLint data[4]; }AUX_EVENTREC;Для более детальной информации смотрите справочные руководства и исходные тексты библиотеки OpenGL Auxiliary library. Эта книга об OpenGL, а не о программировании интерфейсов пользователя. Поэтому, за подобной информацией вам придется лезть в соответсвующие справочные руководства по Win API, MFC, Java и т.п. В FunctionName вы можете изменить какую-нибудь глобальную переменную, и, соответсвенно, функция display будет рисовать кадры в зависимости от этой переменной.^ 2.9  Упражнение:" Игра Арканоид" Напишите игру "Arconoid" - летающий шарик, снизу подставка, пользователь стрелками или мышкой управляет подставкой и отбивает шарик. Исходный файл смотрите здесь. Исполняемый файл здесь. 2.10  Резюме На этом эта глава книги закончена. Вы научились рисовать трехмерные объекты и делать интерактивную анимацию, используя эти объекты. Этого, в общем-то, достаточно для написания примитивных программ.Chapter 3 Рисуем простые объекты^ 3.1  Общие положения Точки, линии, треугольники,четырехугольники, многоугольники - простые объекты, из которых состоят любые сложные фигуры. Все они рисуются следующим образом: glBegin(GLenum type); // указываем, что будем рисовать glVertex[2 3 4][s i f d](...); // первая вершина ……….. // тут остальные вершины glVertex[2 3 4][s i f d](...); // последняя вершина glEnd(); // закончили рисовать примитивСначала вы говорите, что будете рисовать - glBegin с соответсвующим параметром. Возможные значения type см. ниже. Далее вы указываете вершины, определяющие объкты указанного типа. И наконец, вы вызваете glEnd, чтобы указать, что вы закончили рисовать объекты типа, указанного в glBegin.3.2  Точки \\ // рисуем точки glPointSize(2); glBegin(GL_POINTS); glColor3d(1,0,0); glVertex3d(-4.5,4,0); // первая точкаglColor3d(0,1,0); glVertex3d(-4,4,0); // вторая точкаglColor3d(0,0,1); // третья glVertex3d(-3.5,4,0); glEnd();glPointSize(5); glBegin(GL_POINTS); glColor3d(1,0,0); glVertex3d(-2,4,0); // первая точкаglColor3d(0,1,0); glVertex3d(-1,4,0); // вторая точка glColor3d(0,0,1); // третье glVertex3d(0,4,0); glEnd();glPointSize(10); glEnable(GL_POINT_SMOOTH); glBegin(GL_POINTS); glColor3d(1,0,0); glVertex3d(2,4,0); // первая точкаglColor3d(0,1,0); glVertex3d(3,4,0); // вторая точкаglColor3d(0,0,1); // третья glVertex3d(4,4,0); glEnd(); glDisable(GL_POINT_SMOOTH); Вы можете нарисовать столько точек, сколько вам нужно. Вызывая glVertex3d, вы устанавливает новую точку. Так же вы можете вызывать glColor3d внутри glBegin/glEnd. Размер точки устанавливается с помощью функции void glPointSize(GLfloat size). Режим сглаживания устанавливается вызовом функции glEnable() с параметром GL_POINT_SMOOTH. \\\\Отключается соответственно вызовом glDisable() c этим параметром. Последние функции - glPointSize и glEnable/glDisable надо вызывать вне glBegin/glEnd, иначе они будут проигнорированы. Функции glEnable/glDisable включают/выключают множество опций, но вы должны учитывать, что некоторые опции влекут за собой большие вычисления и, следовательно, изрядно затормаживают ваше приложение, поэтому без надобности не стоит их включать.3.3  Линии \\\\\\\\\\\\\\ glLineWidth(1); // ширину линии устанавливаем 1 glBegin(GL_LINES);glColor3d(1,0,0); // красный цвет glVertex3d(-4.5,3,0); // первая линия glVertex3d(-3,3,0); glColor3d(0,1,0); // зеленый glVertex3d(-3,3.3,0); // вторая линия glVertex3d(-4,3.4,0); glEnd();glLineWidth(3); // ширина 3 glBegin(GL_LINE_STRIP); // см. нижеglColor3d(1,0,0); glVertex3d(-2.7,3,0); glVertex3d(-1,3,0);glColor3d(0,1,0); glVertex3d(-1.5,3.3,0); glColor3d(0,0,1); glVertex3d(-1,3.5,0); glEnd();glLineWidth(5); glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_STIPPLE); // разрешаем рисовать прерывистую линию glLineStipple(2,58360); // устанавливаем маску пояснения см. нижеglBegin(GL_LINE_LOOP);glColor3d(1,0,0); glVertex3d(1,3,0); glVertex3d(4,3,0);glColor3d(0,1,0); glVertex3d(3,2.7,0); glColor3d(0,0,1); glVertex3d(2.5,3.7,0); glEnd();glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_STIPPLE);glLineStipple устанавливает маску, при помощи которой будут рисоваться штриховые линии. Второй параметр задает саму маску. В двоичном виде это число выглядит так: 0000000011111111, т.е. всего 16 бит, старшие восемь установлены в ноль, значит тут линии не будет. Младшие установлены в единицу, тут будет рисоваться линия. Первый параметр определяет, сколько раз повторяется каждый бит. Скажем, если его установить равным 2, то накладываемая маска будет выглядить так: 00000000000000001111111111111111. Чтобы высчитать маску, я воспользовался калькулятором.Набрал в нем число в двоичной форме и перевел его в десятичную систему. Также линии можно рисовать, передавая в glBegin GL_LINE_STRIP и GL_LINE_LOOP. В первом случае будет рисоваться ломаная, т.е. первая вершина соединяется со второй, вторая с третьей и так далее. GL_LINE_LOOP идентичен GL_LINE_STRIP, только последняя вершина будет соединена с первой.3.4  ТреугольникиglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // см. ниже glBegin(GL_TRIANGLES); glColor3d(1,0,0); // рисуем треугольник glVertex3d(-4,2,0); glVertex3d(-3,2.9,0); glVertex3d(-2,2,0); glEnd();glLineWidth(2); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //рисуем проволочные треугольникиglBegin(GL_TRIANGLE_STRIP); // обратите внимание на порядок вершин glColor3d(0,1,0); glVertex3d(1,2,0); glVertex3d(0,2.9,0); glVertex3d(-1,2,0); glVertex3d(0,1.1,0); glEnd();glEnable(GL_LINE_STIPPLE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_TRIANGLE_FAN); glColor3d(0,0,1); glVertex3d(4,2,0); glVertex3d(2.6,2.8,0); glVertex3d(2,2,0); glVertex3d(3,1.1,0); glEnd();glDisable(GL_LINE_STIPPLE); glPolygonMode устанавливает опции для отрисовки многоугольника. Первый параметр может принимать значения - GL_FRONT, GL_BACK и GL_FRONT_AND_BACK. Второй параметр указывает, как будет рисоваться многоугольник. Он примает значения - GL_POINT(рисуются только точки), GL_LINE(рисуем линии) и GL_FILL(рисуем заполненный многоугольник). Первый параметр указывает: к лицевой, тыльной или же к обеим сторонам применяется опция, заданная вторым параметром. Треугольники можно рисовать, передав GL_TRIANGLES_STRIP или GL_TRIANGLES_FAN в glBegin. В первом случае первая, вторая и третья вершины задают первый треугольник. Вторая, третья и четвертая вершина - второй треугольник. Третья, четвертая и пятая вершина - третий треугольник и т.д. Вершины n, n+1 и n+2 определят n-ый треугольник. Во втором случае первая, вторая и третья вершина задают первый треугольник. Первая, третья и четвертая вершины задают второй треугольник и т.д. Вершины 1, n+1, n+2 определяют n-ый треугольник.^ 3.5  Четырехугольники и многоугольники Четырехугольники рисуются вызовом функции glBegin с параметром GL_QUADS или GL_QUAD_STRIP. Для первого случая каждые четыре вершины определяют свой четырехугольник. Во втором случае рисуются связанные четырехугольники. Первая, вторая, третья и четвертая вершина определяют первый четырехугольник. Третья, четвертая, пятая и шестая вершина - второй четырехугольник и т.д. (2n-1), 2n, (2n+1) и (2n+2) вершины задают n-ый четырехугольник. Многоугольники задаются вызывом glBegin с параметром GL_POLYGON. Все вершины определяют один многоугольник. Для многоугольников можно задавать стили при помощи выше описанной функции glPolygonMode, толщину линии, толщину точек и цвет.3.6  Уражнение:"Многогранники" Изобразите точки, линии, треугольники, многоугольники в одном окне, как показано ниже.Исходный файл смотрите здесь. Исполняемый файл здесь. 3.7 Уражнение:"Многогранники"Реализуйте проволочные многогранники с помощью проволочных треугольников, многоугольников и линий. 3.8 РезюмеНу вот, вы еще на один шаг продвинулись в изучение библиотеки OpenGL. Теперь вы имеете представление о том, как рисовать элементарные фигуры. Из примитивов вы можете составить фигуры любой сложности.Chapter 4 Полезные мелочи^ 4.1  Построение поверхностей Существует набор функций для посторения сфер, цилиндров и дисков. Эти функции представляют очень мощный контроль за построением трехмерных объектов. Непосредственно рисовать вы будете, используя следующие функции: gluSphere, gluCylinder, gluDisk и gluPartialDisk. В начале книги вы научились строить трехмерные объекты с помощью функций из библиотеки Auxilary Library. Функции aux[Solid/Wire]Sphere, aux[Solid/Wire]Cylinder и aux[Solid/Wire]Cone просто вызывают gluSphere и gluCylinder. Как я уже ранее говорил, в aux[Solid/Wire]Cylinder и aux[Solid/Wire]Cone фирмы Microsoft имеются баги. Здесь будет подробно рассмотрено построение сфер и цилиндров, так что потребность в aux[Solid/Wire]Cylinder и aux[Solid/Wire]Cone отпадет. Первым параметром для gluSphere, gluCylinder, gluDisk является указатель на объект типа GLUquadricObj. Далее следуют параметры непосредственно создаваемой фигуры. Для сферы - это радиус; для цилиндра - радиус нижнего основания, радиус верхнего основания и высота; для диска - внутренний радиус, внешний радиус и для частичного диска - внутренний радиус, внешний радиус, угол, с которого начинать рисовать, длина дуги в градусах, которую рисовать. Последние два параметра у всех этих функций одинаковы. Это число разбиений вокруг оси Z и число разбиений вдоль оси Z. Как я уже говорил, все сложные объекты состоят из простых: точек, линий и многоугольников. Вы понимаете, что нарисовать/создать идеально гладкую сферу или цилиндр невозможно. Поэтому строится приближение из плоскостей. Для этого и нужно указать количество разбиений. Чем больше разбиение, тем лучше будет выглядеть ваша сфера. Однако, задавать здесть число с шестью нулями не стоит. Это лишено всякого смысла. Оптимальным, на мой взгляд, является число от 10 до 20. Чем больше объект, тем больше нужно разбиений. Число разбиений вдоль и поперек я выставляю одинаковыми. Сначала вы должны создать объект типа GLUquadricObj с помощью функции gluNewQuadric. Теперь устанавливаете свойства с помощью функции gluQuadricDrawStyle. Доступны стили: GLU_FILL - рисуется сплошной объект, \\\\GLU_LINE - проволочный объект, \\GLU_POINT - рисуются только точки. Рисуете то, что хотите. И не забудьте удалить созданный объект, воспользовавшись gluDeleteQuadric. Настало время поэкспериментировать. Создайте очередное консольное приложение и отредактируйте функцию display следующим образом. void CALLBACK display(void) { GLUquadricObj *quadObj; quadObj = gluNewQuadric(); // создаем новый объект для создания сфер и цилиндровglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );glPushMatrix(); glColor3d(1,0,0); gluQuadricDrawStyle(quadObj, GLU_FILL); // устанавливаем стиль: сплошнойgluSphere(quadObj, 0.5, 10, 10); // рисуем сферу радиусом 0.5 glTranslated(-2,0,0); // сдвигаемся влево glRotated(45, 1,0,0); // поворачиваем glColor3d(0,1,0); gluQuadricDrawStyle(quadObj, GLU_LINE); // устанавливаем // стиль: проволочныйgluCylinder(quadObj, 0.5, 0.75, 1, 15, 15); glPopMatrix();gluDeleteQuadric(quadObj); auxSwapBuffers(); }^ 4.2  Упражнение: "Сфера, цилиндр и диски". Доработайте код, приведенный выше, чтобы в первой строке показывались три сферы. Цвет и стили(GLU_POINT, GLU_LINE и GLU_FILL) должны быть разными. В следующих трех строках должны быть цилиндры, диски и частичные диски. Исходный файл смотрите здесь. Исполняемый файл здесь. ^ 4.3  Интерполяция цветов Когда вы создаете многоугольник, вы можете задать цвет для каждой его вершины. Если разрешено сглаживание цветов, то многоугольник будет переливаться. Поясню на примере. Режим сглаживания по умолчанию разрешен. Он переключается функцией glShadeModel с аргументами \\\\GL_FLAT и GL_SMOOTH. GL_FLAT запрещает сглаживание. На мой взгляд, сглаживание редко нужно. Вещь красивая, но бесполезная. Я в своих неучебных программах этот режим никогда не использовал. Поэтому советую его отключать, особенно, при программировании анимации,чтобы не затормаживать приложение. Создайте очередной проект. В функцию main добавьте glShadeModel(GL\_SMOOTH);Функцию display отредактируйте следующим образом: void CALLBACK display(void) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );glBegin(GL_TRIANGLES);glColor3d(1,0,0); glVertex2d(0,0);glColor3d(0,1,0); glVertex2d(0,3);glColor3d(0,0,1); glVertex2d(3,0);glEnd();auxSwapBuffers(); } Исходный файл смотрите здесь. Исполняемый файл здесь4.4  Прозрачность С помощью четвертого компонента цвета можно получать различные эффекты наложения объктов друг на друга, наложения цветов и т.п. Здесь я расскажу о наиболее нужном и распрострененном эффекте - прозрачности объектов. Для того, чтобы разрешить обрабатывать четвертый компонент цвета вы должны вызвать функцию glEnable с аргументом \\\\GL_ALPHA_TEST. Для получения требуемого эффекта прозрачности нужно разрешить наложение цветов - glEnable(GL_BLEND). \\И установить алгоритм, по которуму будут смешиваться два цвета - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). Учтите, что эти режимы очень затормаживают вывод изображения, поэтому я не рекомендую устанавливать эти режимы глобально, для воспроизведения всех объектов. Выделите из ваших объектов те, которым требуется этот режим, включайте и отключайте его своевременно. Именно поэтому, эти тесты я разместил в функции display. Создайте новый проект с именем transperence и отредактируйте функцию display, как показано ниже. void CALLBACK display(void) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glColor4d(1,0,0, 1); auxSolidSphere( 1 );glColor4d(0,1,0, 0.6); auxSolidCylinder(2,3);glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST);auxSwapBuffers(); } В заключение, добавлю, что если вы поменяете местами создание цилиндра и сферы, то никакого эффекта прозрачности не увидите. Это не баг, а фича - так задумано. Секрет прост: вы должны сначала рисовать дальние объекты, а потом ближние. Связано это с тем, что выполняется тест глубины. Теперь смотрите, что получается. Если вы сначала рисуете сферу(она удалена), а потом цилиндр, то выполняется это следующим образом. Создаем сферу. Выполняется тест глубины успешно, т.к. цилиндра пока нет. В буфере рисуется сфера. Создаем цилиндр. Выполняется тест глубины успешно, т.к. стенка цилиндра ближе, чем сфера. В буфере рисуется цилиндр, он закрывает сферу с учетом прозрачности. Теперь смотрим, что происходит, если сначала нарисовать цилиндр, потом сферу. Создаем цилиндр. Выполняется тест глубины успешно. В буфере рисуется цилиндр. Создаем сферу. Вполняется тест глубины аварийно, т.к. сфера создается за цилиндром. В буфере ничего не рисуется. В последнем случае вы увидите один цилиндр. Исходный файл смотрите здесь. Исполняемый файл здесь. ^ 4.5  Упражнение: "Снег" Ранее рассматривалось приложение "Снеговик". Анимацию создавать вы тоже уже научились. Добавьте косой снег, только сделайте снеговика прозрачным, чтобы снежинки как бы пролетали сквозь него.^ 4.6  Плоскости отсечения Если вам требуется нарисовать сферу или любой другой объект урезанным, то плоскости отсечения это то, что вам надо. Плоскостей отсечения может быть шесть штук. По умолчанию они все запрещены. Разрешается плоскость отсечения командой glEnable(GL_CLIP_PLANE0). \\\\Ноль на конце GL_CLIP_PLANE означает нулевую плоскость; можно указать оди


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.