Пример программы
Пример программы
Результатом выполнения этой программы является построение тетраэдра с вращающимися вокруг него кольцами, на которые нанесена текстура. В среде MS Visual C++ программа может компилироваться без изменений, а при компиляции в Borland C++ придется закомментировать вызов и описание функции TextureInit(), после чего не будет проводиться наложение текстур. Как было сказано выше, попытка использовать функции из библиотеки GLAUX приводит к сообщению об ошибке при компиляции программы.
При компиляции программы в MS Visual C++ файл ‘texture.bmp’ надо поместить в каталог проекта или указать полный путь к нему, используя символ ‘/’. Если путь не указан, то при запуске исполняемого файла из операционной системы, файл с текстурой должен находиться в том же каталоге.
#include <GLglut.h>
#include <GLglaux.h>
#include <math.h>
#define TETR_LIST 1
GLfloat light_col[] = {1,1,1};
float mat_diff1[]={0.8,0.8,0.8};
float mat_diff2[]={0.0,0.0,0.9};
float mat_amb[]= {0.2,0.2,0.2};
float mat_spec[]={0.6,0.6,0.6};
float shininess=0.7*128, CurAng=0, RingRad=1, RingHeight=0.1;
GLUquadricObj* QuadrObj;
GLuint TexId;
GLfloat TetrVertex[4][3], TetrNormal[4][3];
//--Вычисление нормали к плоскости, задаваемой точками a,b,c----------//
void getnorm (float a[3],float b[3],float c[3],float *n) {
float mult=0;
n[0]=(b[1]-a[1])*(c[2]-a[2])-(b[2]-a[2])*(c[1]-a[1]);
n[1]=(c[0]-a[0])*(b[2]-a[2])-(b[0]-a[0])*(c[2]-a[2]);
n[2]=(b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1]);
//--Определение нужного направления нормали: от точки (0,0,0)---------//
for (int i=0;i<3;i++) mult+=a[i]*n[i];
if (mult<0) for (int j=0;j<3;j++) n[j]=-n[j];
}
//--Вычисление координат вершин тетраэдра-----------------------------//
void InitVertexTetr() {
float alpha=0;
TetrVertex[0][0]=0;TetrVertex[0][1]=1.3;TetrVertex[0][2]=0;
//--Вычисление координат основания тетраэдра--------------------------//
for (int i=1;i<4;i++) {
TetrVertex[i][0]=0.94*cos(alpha);
TetrVertex[i][1]=0;
TetrVertex[i][2]=0.94*sin(alpha);
alpha+=120.0*3.14/180.0;
}
}
//--Вычисление нормалей сторон тетраэдра------------------------------//
void InitNormsTetr() {
getnorm(TetrVertex[0],TetrVertex[1],TetrVertex[2],TetrNormal[0]);
getnorm(TetrVertex[0],TetrVertex[2],TetrVertex[3],TetrNormal[1]);
getnorm(TetrVertex[0],TetrVertex[3],TetrVertex[1],TetrNormal[2]);
getnorm(TetrVertex[1],TetrVertex[2],TetrVertex[3],TetrNormal[3]);
}
//--Создание списка построения тетраэдра------------------------------//
void MakeTetrList() {
glNewList (TETR_LIST,GL_COMPILE);
//--Задание сторон тетраэдра------------------------------------------//
glBegin(GL_TRIANGLES);
for (int i=1;i<4;i++) {
glNormal3fv(TetrNormal[i-1]);
glVertex3fv(TetrVertex[0]);
glVertex3fv(TetrVertex[i]);
if (i!=3) glVertex3fv(TetrVertex[i+1]);
else glVertex3fv(TetrVertex[1]);
}
glNormal3fv(TetrNormal[3]);
glVertex3fv(TetrVertex[1]);
glVertex3fv(TetrVertex[2]);
glVertex3fv(TetrVertex[3]);
glEnd();
glEndList();
}
void DrawRing() {
//--Построение цилиндра (кольца), расположенного параллельно оси z----//
//--Второй и третий параметры задают радиусы оснований, четвертый-----//
//--высоту,последние два-число разбиений вокруг и вдоль оси z---------//
//--При этом дальнее основание цилиндра находится в плоскости z=0-----//
gluCylinder(QuadrObj,RingRad,RingRad,RingHeight,30,2);
}
void TextureInit() {
char strFile[]="texture.bmp";
//--Выравнивание в *.bmp по байту-------------------------------------//
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
//--Создание идентификатора для текстуры- ----------------------------//
glGenTextures(1,&TexId);
//--Загрузка изображения в память-------------------------------------//
AUX_RGBImageRec *pImage = auxDIBImageLoad(strFile);
int BmpWidth= pImage->sizeX;
int BmpHeight = pImage->sizeY;
void* BmpBits = pImage->data;
//--Начало описания свойств текстуры----------------------------------//
glBindTexture (GL_TEXTURE_2D,TexId);
//--Создание уровней детализации и инициализация текстуры ------------//
gluBuild2DMipmaps(GL_TEXTURE_2D,3,BmpWidth, BmpHeight,GL_RGB,GL_UNSIGNED_BYTE,BmpBits);
//--Разрешение наложения этой текстуры на quadric-объекты-------------//
gluQuadricTexture(QuadrObj, GL_TRUE);
//--Задание параметров текстуры---------------------------------------//
//--Повтор изображения по параметрическим осям s и t------------------//
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_MIN_FILTER,GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
//--Совмещать текстуру и материал объекта-----------------------------//
glTexEnvi (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
}
void Init(void) {
InitVertexTetr();
InitNormsTetr();
MakeTetrList();
//--Определение свойств материала-------------------------------------//
glMaterialfv (GL_FRONT_AND_BACK,GL_AMBIENT,mat_amb);
glMaterialfv (GL_FRONT_AND_BACK,GL_SPECULAR,mat_spec);
glMaterialf(GL_FRONT,GL_SHININESS,shininess);
//--Определение свойств освещения-------------------------------------//
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_col);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//--Проводить удаление невидимых линий и поверхностей-----------------//
glEnable(GL_DEPTH_TEST);
//--Проводить нормирование нормалей-----------------------------------//
glEnable(GL_NORMALIZE);
//--Материалы объектов отличаются только цветом диффузного отражения--//
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
//--Создания указателя на quadric-объект для построения колец---------//
QuadrObj=gluNewQuadric();
//--Определение свойств текстуры--------------------------------------//
TextureInit();
//--Задание перспективной проекции------------------------------------//
glMatrixMode(GL_PROJECTION);
gluPerspective(89.0,1.0,0.5,100.0);
//--Далее будет проводиться только преобразование объектов сцены------//
glMatrixMode(GL_MODELVIEW);
}
void DrawFigures(void) {
//--Включение режима нанесения текстуры-------------------------------//
glEnable(GL_TEXTURE_2D);
//--Задаем цвет диффузного отражения для колец------------------------//
glColor3fv(mat_diff1);
//--Чтобы не проводить перемножение с предыдущей матрицей загружаем единичную матрицу//
glLoadIdentity();
//--Определяем точку наблюдения---------------------------------------//
gluLookAt(0.0, 0.0, 2.5,0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
//--Сохраняем видовую матрицу, так как дальше будет проводиться поворот колец//
glPushMatrix();
//--Производим несколько поворотов на новый угол (это быстрее,--------//
//--чем умножать предыдущую видовую матрицу на матрицу поворота с-----//
//--фиксированным углом поворота)-------------------------------------//
glRotatef (-CurAng,1,1,0);
glRotatef (CurAng,1,0,0);
//--Для рисования колец каждое из них надо преобразовать отдельно,----//
//--поэтому сначала сохраняем видовую матрицу, затем восстанавливаем--//
glPushMatrix();
glTranslatef (0,0,-RingHeight/2);
DrawRing();
glPopMatrix();
glPushMatrix();
glTranslatef (0,RingHeight/2,0);
glRotatef (90,1,0,0);
DrawRing();
glPopMatrix();
glPushMatrix();
glTranslatef (-RingHeight/2,0,0);
glRotatef (90,0,1,0);
DrawRing();
glPopMatrix();
//--Восстанавливаем матрицу для поворотов тетраэдра--------------------//
glPopMatrix();
//--Выключаем режим наложения текстуры--------------------------------//
glDisable(GL_TEXTURE_2D);
//--Проводим повороты-------------------------------------------------//
glRotatef(CurAng,1,0,0);
glRotatef(CurAng/2,1,0,1);
//--Чтобы тетраэдр вращался вокруг центра, его надо сдвинуть вниз по оси oz//
glTranslatef(0,-0.33,0);
//--Задаем цвет диффузного отражения для тетраэдра--------------------//
glColor3fv(mat_diff2);
//--Проводим построение тетраэдра-------------------------------------//
glCallList(TETR_LIST);
}
void Display(void) {
//--Инициализация (очистка) текущего буфера кадра и глубины-----------//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//--Построение объектов-----------------------------------------------//
DrawFigures();
//--Перестановка буферов кадра----------------------------------------//
glutSwapBuffers();
}
void Redraw(void) {
//--Увеличение текущего угла поворота---------------------------------//
CurAng+=1;
//--Сигнал для вызова процедуры создания изображения (для обновления)-//
glutPostRedisplay();
}
int main(int argc, char **argv) {
//--Инициализация функций библиотеки GLUT-----------------------------//
glutInit(&argc, argv);
//--Задание режима с двойной буферизацией, представление цвета в формате RGB,--//
//--использование буфера глубины --//
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
//--Создание окна приложения-----------------------------------------//
glutCreateWindow("Example of using OpenGL");
//--Регистрация функции построения изображения-----------------------//
glutDisplayFunc(Display);
//--Регистрация функции обновления изображения-----------------------//
glutIdleFunc(Redraw);
//--Инициализация функций OpenGL-------------------------------------//
Init();
//--Цикл обработки событий-------------------------------------------//
glutMainLoop();
return 0;
}
Результат работы программы:
В программе используется только файл glut.h, который содержит обращения к файлам gl.h и glu.h, поэтому отдельно подключать их не нужно.
Большим достоинством OpenGL является независимость большинства команд. Например, чтобы отключить наложение текстуры, достаточно закомментировать вызов функции TextureInit(), а чтобы получить статичное изображение достаточно не регистрировать функцию обновления изображения вызовом функции glutIdleFunc(). В этом случае можно использовать режим с одним буфером, заменив GL_DOUBLE на GL_SINGLE в команде glutInitDisplayMode() и добавив команду glFlush() в конце процедуры Display() для очистки этого буфера.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Пример: перенос программы sortMM (программа 5.5)
Пример: перенос программы sortMM (программа 5.5) В программе sortMM (программа 5.5) интенсивно используются указатели, и в частности, арифметика указателей. Подготовка этой программы к переносу, в результате чего ее можно будет компоновать и выполнять под управлением как Win32, так и
21.4. Пример программы на С
21.4. Пример программы на С В п. 9.2.3 я сказал о состояниях процесса и перечислил среди них состояние «зомби». Зомби — это процесс, который уже завершился, но его родитель еще не получил сигнала о его завершении и не удалил его структуру из таблицы процессов. Такое может
22.3. Пример отладки программы
22.3. Пример отладки программы Давайте напишем программу, которая обнуляет элементы массива a[]. Да, программа ничего полезного не делает, но на ее примере можно продемонстрировать работу с отладчиком gdb.Вот листинг программы:Листинг 22.1. Демонстрационная программа,
Пример программы
Пример программы Результатом выполнения этой программы является построение тетраэдра с вращающимися вокруг него кольцами, на которые нанесена текстура. В среде MS Visual C++ программа может компилироваться без изменений, а при компиляции в Borland C++ придется закомментировать
6.7. Пример программы клиент-сервер
6.7. Пример программы клиент-сервер Перепишем наш пример программы типа клиент-сервер из раздела 4.2 с использованием двух очередей сообщений. Одна из очередей предназначена для передачи сообщений от клиента серверу, а другая — в обратную сторону.Заголовочный файл svmsg.h
Пример программы
Пример программы Чтобы сделать обсуждение иерархии VBA-элементов немного менее абстрактным, давайте рассмотрим приведенный ниже программный код модуля. Этот модуль содержит все упомянутые выше элементы (за исключением проекта, поскольку модули содержатся в проектах, а
6.1.2. Учебный пример: параметр -v программы fetchmail
6.1.2. Учебный пример: параметр -v программы fetchmail fetchmail — программа-шлюз. Ее главной задачей является преобразование между протоколами удаленной загрузки почты РОРЗ или IMAP и собственным протоколом Internet SMTP для обмена почтой. Он чрезвычайно широко распространен на
6.1.2. Учебный пример: параметр -v программы fetchmail
6.1.2. Учебный пример: параметр -v программы fetchmail fetchmail — программа-шлюз. Ее главной задачей является преобразование между протоколами удаленной загрузки почты POP3 или IMAP и собственным протоколом Internet SMTP для обмена почтой. Он чрезвычайно широко распространен на Unix-машинах,
ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ Давайте рассмотрим простую программу на языке Си. Следует сразу сказать, что такой пример нужен нам лишь для выявления некоторых основных черт любой программы, написанной на языке Си. Далее мы дадим пояснения к каждой строке, но, перед
ПРИМЕР ПРОГРАММЫ
ПРИМЕР ПРОГРАММЫ На рис. 5.8 приведена программа, которая может оказаться полезной тем, кто занимается бегом, и которая иллюстрирует некоторые положения данной главы. Она выглядит довольно длинной, но все вычисления в ней выполняются шестью операторами, помещенными
5.1.6. Пример программы
5.1.6. Пример программы Программа, приведенная в листинге 5.1, иллюстрирует методику совместного использования памяти.Листинг 5.1. (shm.c) Пример совместного использования памяти#include <stdio.h>#include <sys/shm.h>#include <sys/stat.h>int main() { int segment_id; char* shared_memory; struct shmid_ds shmbuffer; int segment_size; const
1.1. Пример программы: родственные отношения
1.1. Пример программы: родственные отношения Пролог — это язык программирования, предназначенный для обработки символьной нечисловой информации. Особенно хорошо он приспособлен для решения задач, в которых фигурируют объекты и отношения между ними. На рис. 1.1
16.1.3. Пример составления программы
16.1.3. Пример составления программы С системами, управляемыми образцами, связан свой особый стиль программирования, требующий специфического программистского мышления. Мы говорим в этом случае о программировании в терминах образцов.В качестве иллюстрации, рассмотрим
Пример программы, уязвимой к переполнению буфера
Пример программы, уязвимой к переполнению буфера После изучения основ переполнения буфера пришло время рассмотреть пример программы, извлекающей из него пользу, – программы переполнения буфера. В интересах простоты изучения программа должна быть понятной, а каждый
Пример уязвимой программы
Пример уязвимой программы На примере уязвимой программы рассмотрим, каким образом злоумышленник может использовать уязвимости форматирующей строки для достижения своих целей. Наибольший интерес представляют способы удаленного использования уязвимостей