Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 16
Текст из файла (страница 16)
GLint slices , GLint stacks)
Эти команды строят конус или его каркас высотой height и радиусом основания base, расположенный вдоль оси z. Основание находится в плоскости z = 0.
void glutSolidTorus (GLdouble innerRadius ,
GLdouble outerRadius ,
GLint nsides ,
GLint rings ) void glutWireTorus (GLdouble innerRadius ,
GLdouble outerRadius ,
GLint nsides ,
GLint rings )
Эти команды строят тор или его каркас в плоскости z = 0. Внутренний и внешний радиусы контролируются параметрами
168 Приложение А. Примитивы библиотек GLU и GLUT
inner Radius и outer Radius. Параметр nsides задает число сторон в кольцах, составляющих ортогональное сечение тора, a rings — число радиальных разбиений тора.
void glutSolidTetrahedron (void) void glutWireTetrahedron (void)
Эти команды строят тетраэдр (правильную треугольную пирамиду) или его каркас, при этом радиус описанной сферы вокруг него равен 1.
void glutSolidOctahedron (void) void glutWireOctahedron (void)
Эти команды строят октаэдр или его каркас, радиус описанной вокруг него сферы равен 1.
void glutSolidDodecahedron (void) void glutWireDodecahedron (void)
Эти команды строят додекаэдр или его каркас, радиус описанной вокруг него сферы равен квадратному корню из трех.
void glutSolidlcosahedron (void) void glutWirelcosahedron (void)
Эти команды строят икосаэдр или его каркас, радиус описанной вокруг него сферы равен 1.
Правильное построение перечисленных примитивов возможно при удалении невидимых линии и поверхностей, для чего надо включить соответствующий режим вызовом команды glEnable(GL_DEPTH_TEST).
Приложение Б.
Демонстрационные программы
Б.1. Пример 1: Простое GLUT-приложение
Этот простой пример предназначен для демонстрации структуры GLUT-приложения и простейших основ OpenGL. Результатом работы программы является случайный набор цветных прямоугольников, который меняется при нажатии левой кнопки мыши. С помощью правой кнопки мыши можно менять режим заливки прямоугольников.
Программа Б.1. Простой пример OpenGL.
^include <stdlib.h> ^include <gl\glut.h>
#ifdef random #undef random #endif
#define random (m) ( float) rand () *m/RAND_MAX
169
170
Приложение Б. Демонстрационные программы
// ширина и высота окна
GLint Width = 512, Height = 512;
// число прямоугольников в окне
int Times = 100;
// с заполнением ?
int FillFlag = 1;
long Seed = 0;
// функция отображает прямоугольник void DrawRect ( float xl , float yl ,
float x2 , float y2 ,
int FillFlag )
{
glBegin( FillFlag ? GL_QUADS : GL_UNE_LOOP);
glVertex2f (xl , yl) ; glVertex2f(x2, yl) ; glVertex2f(x2, y2 ) ; glVertex2f (xl , y2 ) ; glEnd(); }
// управляет всем выводом на экран void Display (void)
{ _
int i ;
float xl , yl , x2 , y2 ;
float r , g, b;
srand(Seed);
glClearColor(0, 0, 0, I);
g 1С1 e ar (GL_COIX)R_BUFFER_Brr);
for( i = 0; i < Times; i++ ) { r = random (1); g = random (1);
Б.1. Пример 1: Простое GLUT-приложение
171
b = random (1); glColor3f( r, g, b );
xl = random (1) * Width; yl = random (1) * Height; x2 = random (1) * Width; y2 = random (1) * Height; DrawRect( xl , yl , x2 , y2 , FillFlag ); }
glFinish () ; }
// Вызывается при изменении размеров окна void Reshape (GLint w, GLint h)
{
Width = w;
Height = h;
glViewport (0 , 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadldentity () ;
glOrtho(0, w, 0, h, -1.0, 1.0);
glMatrixMode (GL_MODELVIEW); glLoadldentity () ; }
// Обрабатывает сообщения от мыши void Mouse (int button, int state , int x, int y)
{
if( state = GLUT_DOWN ) { switch( button ) {
case GLUTLEFTBUTTON:
Seed = random (RAND_MAX);
172 Приложение Б. Демонстрационные программы
break; case GLUT_raGHT_BlJTTC)N:
FillFlag = ! FillFlag ; break;
}
glutPostRedisplay ();
} }
// Обрабатывает сообщения от клавиатуры
void Keyboard ( unsigned char key, int x, int у )
{ const char ESCAPE = '\033';
if ( key = ESCAPE ) exit(0); }
void main(int argc , char *argv[])
{
glut Init (&argc , argv ); glutlnitDisplayMode (GLUT_RGB) ; glutlnitWindowSize (Width , Height ); glutCreateWindow (" Rect„drawwexample„ (RGB) " );
glutDisplayFunc( Display ) ; gl ut Re shape Fun с (Reshape ); glutKeyboardFunc (Keyboard); glutMouseFunc (Mouse);
glutMainLoop () ; }
Б. 2. Пример 2: Модель освещения OPENGL 173

Рис. Б.1. Результат работы программы Б.1. Слева — режим заполнения, справа — режим контуров.
Б.2. Пример 2: Модель освещения OpenGL
Программа предназначена для демонстрации модели освещения OpenGL на примере простой сцены, состоящей из тора, конуса и шара. Объектам назначаются разные материалы. В сцене присутствует точечный источник света.
Программа Б.2. Модель освещения OpenGL.
^include <stdlib.h> #include <GL/glut.h>
// параметры материала тора float matl_dif[] = {0.8f ,0.8f,0.0f}; float matl_amb[]= {0.2 f ,0 . 2 i ,0 . 2 i } ; float matl_spec[] = {0.6f ,0.6f,0.6f}; float mat l_shininess=0.5 f *128;
// параметры материала конуса float mat2_dif[] = {0.0i ,0.0f,0.8f}; float mat2_amb[]= {0.2 f ,0 . 2 f ,0 . 2 f } ; float mat2_spec[] = {0.6f ,0.6f,0.6f};
174
Приложение Б. Демонстрационные программы
float mat2_shininess =0.7f *128;
// параметры материала шара float mat3_dif[] = {0.9f ,0.2 f ,0.0 f}; float mat3_amb[]= {0.2f,0.2f,0.2f}; float mat3_spec[] = {0.6f ,0.6f ,0.6f}; float mat3_shininess =0.1 f *128;
// Инициализируем параметры материалов и // источника света void init (void)
{
GLfloat light_ambient [] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse [] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular [] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position [] = { 1.0, 1.0, 1.0, 0.0 };
/* устанавливаем параметры источника света */ glLightfv (GL_LIGHT0, GL_AMBIENT,
light_ambient ); glLightfv (GL_LIGHT0, GL_DIFFUSE,
light _diffuse ); glLightfv (GL_LIGHT0, GL_SPECULAR,
light_specular ); glLightfv (GL_LIGHT0, GL_POSITION,
light _position );
/* включаем освещение и источник света */ glEnable (GL_LIGHTLNG); glEnable (GL_LIGHT0); /* включаем z—буфер */ glEnable (GL_DEPTH_TEST);
}
// Функция вызывается при необходимости // перерисовки изображения.
Б. 2. Пример 2: Модель освещения OPENGL 175
// В ней осуществляется весь вывод геометрии. void display (void)
{
/* очищаем буфер кадра и буфер глубины */ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BrT) ;
glPushMatrix ();
glRotatef (20.0, 1.0, 0.0, 0.0);
/* отображаем тор */
glMaterialfv (GL_FRONT,GL_ AMBIENT,
matl_amb); glMaterialfv (GL_FRONT,GL_DIFFUSE,
matl_dif); glMaterialfv (GL_FRONT,GL_SPECULAR,
matl_spec) ; g 1M a t e r i a 1 f (GL_FRONT, GL_SHININESS,
matl_shininess );
glPushMatrix (); glTranslatef (-0.75, 0.5, 0.0); glRotatef (90.0, 1.0, 0.0, 0.0); glutSolidTorus (0.275, 0.85, 15, 15); glPopMatrix ();
/* отображаем конус. */ glMaterialfv (GL_FRONT,GL_ AMBIENT,
mat2_amb); glMaterialfv (GL_FRONT,GL_DIFFUSE,
mat2_dif); glMaterialfv (GL_FRONT,GL_SPECULAR,
mat2_spec) ; g 1M a t e r i a 1 f (GL_FRONT, GL_SHININESS,
mat2_shininess );
glPushMatrix ();
176
Приложение Б. Демонстрационные программы
glTranslatef (-0.75, -0.5, 0.0); glRotatef (270.0, 1.0, 0.0, 0.0); glutSolidCone (1.0, 2.0, 15, 15); glPopMatrix () ;
/* отображаем шар */
glMaterialfv (GL_FRONT,GL_ AMBIENT,
mat3_amb) ; glMaterialfv (GL_FRONT, GL_DIFFUSE,
mat3_dif) ; glMaterialfv (GL_FRONT, GL_SPECULAR,
mat3_spec) ; g 1M a t e r i a 1 f (GL_FRONT, GL_SHININESS,
mat3_shininess ) ;
glPushMatrix (); glTranslatef (0.75, 0.0, -1.0); glutSolidSphere (1.0, 15, 15); glPopMatrix () ;
glPopMatrix () ;
/* выводим сцену на экран */
glFlush ();
}
// Вызывается при изменении пользователем
// размеров окна
void reshape(int w, int h)
{
// устанавливаем размер области вывода
// равным размеру окна
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
// задаем матрицу проекции с учетом // размеров окна glMatrixMode (GL_PROJECTION) ; glLoadldentity () ;
Б. 2. Пример 2: Модель освещения OPENGL
177
gluPerspective (
// угол зрения в градусах
40.0 ,
// коэффициент сжатия окна
(GLfloat)w/h,
// расстояние до плоскостей отсечения
1,100.0); glMatrixMode (GL_MODELVIEW);
glLoadldentity () ; gluLookAt (
// положение камеры
O.Of,0.0 f ,8.Of ,
// центр сцены
O.Of ,0.0f ,0.0f ,
// положительное направление, оси у
O.Of ,1.0f ,0.0f);
}
// Вызывается при нажатии клавиши на клавиатуре. void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: /* escape */ exit(0); break;
} }
// Главный цикл приложения
// Создается окно, устанавливается режим
// экрана с буфером глубины
int main (int argc , char** argv)
{
glutlnit (&argc , argv);
178
Приложение Б. Демонстрационные программы
glutlnitDisplayMode ( GLUT_SINGLE | GLUT_RGB | GLUT_DEFTH);
glutlnitWindowSize (500, 500); glutCreateWindow (argv[0]); init ();
glutReshapeFunc (reshape); glutDisplayFunc( display ) ; glutKeyboardFunc (keyboard); glutMainLoop () ; return 0;
}
Рис. Б.2. Результат работы программы Б.2.
Б.З. Загрузка BMP файла
В этом пункте приводится исходный текст функции LoadBMP(), которая позволяет загружать файлы полноцветных изображений (24 бита на точку) в формате Windows Bitmap (BMP).
Синтаксис вызова функции:
Б. 3. Загрузка BMP файла
179
int LoadBMP(const char* filename , IMAGE* out_img)
Параметр filename определяет имя файла. Результат выполнения функции записывается в структуру out_img, которая определена следующим образом:
typedef struct _MAGE
{ _
int width;
int height;
unsigned char* data; } IMAGE;
Поля width и height хранят, соответственно, высоту и ширину изображения. В поле data построчно хранится само изображение, в виде последовательности RGB-компонент цветов пикселей.
Программа Б.З. Загрузка BMP. Файл loadbmp.h.
#ifndef JjOADBMP_H #define JjOADBMP_H
typedef struct _MAGE
{ _
int width;
int height;
unsigned char* data;
} IMAGE;
int LoadBMP(const char* file , IMAGE* out_img);
#endif
Программа Б.4. Загрузка BMP. Файл loadbmp.cpp. ^include "loadbmp.h"
^include <stdio.h>
180 Приложение Б. Демонстрационные программы
^include <stdlib.h> T^include <memory. h>
// размер заголовка BMP—файла
#define BMP_SIZE_FILEHEADER 14
// размер информационного заголовка BMP—файла
#define BMP_SIZEJNFOHEADER 40
#define BMP_COLOR_BITS_24 24
// вспомогательные функции
static unsigned int uIntl6Number (unsigned char buf[2])
{
return (buf[l] « 8) | buf[0];
}
static unsigned int uInt32Number (unsigned char buf[4])