Файл: графическая библиотека opengl.pdf

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

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

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

Добавлен: 09.06.2020

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

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

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

 111

        line[1] = rgb[numb++]; 
        line[0]= rgb[numb++]; 
        line += 3; 
      } 
    } 
    fclose(f); 
    free(rgb); 
  } 
  else 
    return 0; 
 
  return 1; 

D.4. 

Пример

 3: 

Текстурирование

 

 

Результатом

 

выполнения

 

этой

 

программы

 

является

 

построение

 

тетраэдра

 

с

 

вращающимися

 

вокруг

 

него

 

кольцами

на

 

которые

 

нанесена

 

текстура

.  

  

При

 

компиляции

 

программы

 

в

 MS Visual C++ 

файл

 ‘texture.bmp’ 

надо

 

поместить

 

в

 

каталог

 

проекта

 

или

 

указать

 

полный

 

путь

 

к

 

нему

используя

 

символ

 ‘/’. 

Если

 

путь

 

не

 

указан

то

 

при

 

запуске

 

исполняемого

 

файла

 

из

 

операционной

 

системы

файл

 

с

 

текстурой

 

должен

 

находиться

 

в

 

том

 

же

 

каталоге

Для

 

загрузки

 

изображения

 

текстуры

 

программа

 

использует

 

функцию

 LoadBMP, 

приведенную

 

в

 

предыдущем

 

пункте

 

#include <GL\glut.h> 
#include <gl\glaux.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, 
float CurAng=0, RingRad=1, RingHeight=0.1; 
GLUquadricObj* QuadrObj; 
GLuint TexId; 

GLfloat TetrVertex[4][3], TetrNormal[4][3]; 
 


background image

 112

/* 

Вычисление

 

нормали

 

к

 

плоскости

 * 

задаваемой

 

точками

 a,b,c 

 */ 
void getnorm (float a[3],float b[3],float c[3],float *n) 

 float mult=0,sqr; 
 int i,j; 
 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 (i=0;i<3;i++)  mult+=a[i]*n[i]; 
 if (mult<0) for (j=0;j<3;j++) n[j]=-n[j]; 

 
/* 

Вычисление

 

координат

 

вершин

 

тетраэдра

 */ 

void InitVertexTetr() 

 float alpha=0; 
 int i; 
 TetrVertex[0][0]=0; 
 TetrVertex[0][1]=1.3; 
 TetrVertex[0][2]=0; 
 /* 

Вычисление

 

координат

 

основания

 

тетраэдра

 */ 

 for (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]); 

 


background image

 113

/* 

Создание

 

списка

 

построения

 

тетраэдра

 */ 

void MakeTetrList() 

 int 

i; 

  glNewList(TETR_LIST,GL_COMPILE); 
  /* 

Задание

 

сторон

 

тетраэдра

 */ 

  glBegin(GL_TRIANGLES); 
  for (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"; 
 IMAGE img; 
 
 /* 

Выравнивание

 

в

 *.bmp 

по

 

байту

 */ 

 glPixelStorei(GL_UNPACK_ALIGNMENT,1); 
 /* 

Создание

 

идентификатора

 

для

 

текстуры

 */ 

 glGenTextures(1,&TexId); 
 /* 

Загрузка

 

изображения

 

в

 

память

 */ 

 if (!LoadBMP(strFile, &img)) 


background image

 114

   return; 
 
 /* 

Начало

 

описания

 

свойств

 

текстуры

 */ 

 glBindTexture (GL_TEXTURE_2D,TexId); 
 /* 

Создание

 

уровней

 

детализации

 

и

 

инициализация

 

текстуры

 

  */ 
  gluBuild2DMipmaps(GL_TEXTURE_2D,3,img.width, 
img.height,GL_RGB,GL_UNSIGNED_BYTE,img.data); 
 
 /* 

Разрешение

 

наложения

 

этой

 

текстуры

 

на

 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); 
 /* 

Проводить

 

нормирование

 

нормалей

 */ 


background image

 115

 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); 
  /* 

Для

 

рисования

 

колец

 

каждое

 

из

 

них

 

надо

 

   * 

преобразовать

 

отдельно

поэтому

 

сначала

 

сохраняем

 

видовую

 

матрицу

затем

 

восстанавливаем