И напоследок приведем функции для отображения ряда стандартных квадратичных поверхностей, поддерживаемых OpenGL. gluNewQuadric - создание квадратичного объекта; gluCylinder - создание цилиндра; gluDisk - создание диска; gluPartialDisk - создание части диска; gluQuadricCallback - обработка ошибки вывода объекта; gluQuadricDrawStyle - способ вывода объекта, gluQuadricNormals - способ вычисления нормалей для объекта; gluQuadricOrientation - определяет ориентацию объекта; gluQuadricTexture - управление наложением текстуры; gluSphere - создание сферы; gluDeleteQuadric - удаление квадратичного объекта.
/*
Демонстрация отображения поверхности Безье, NURBS и квадратичной поверхности.
*/
GLUquadricObj *obj=gluNewQuadric() ;
GLUnurbsObj *nurbs=gluNewNurbsRenderer() ;
// контрольные точки поверхности Безье float ctrlp[][3]=
{
{-2 0,0,40},{-2 0,40,40},{40,0,40},
{-40,0,0},{-20,40,0},{40,0,0},
{-40,0,-40},{-20,40,-4 0},{40,0,-4 0}
} ;
// контрольные точки NURBS поверхности float nurbsctrl[][3]=
{
{-60,-60,0},{-60,-20,0},{-60,20,0},{-60,60,0}, {-20,-60,0},{-20,-20,-8 0},{-20,20,-80},{-20,60,0}, {20,-60,0},{20,-20,-80},{20,20,-80},{20,60,0}, {60,-60, 0}, {60,-20, 0}, {60, 20, 0}, {60, 60, 0}
};
float knots[8]={0,0,0,0,1,1,1,1}; // узлы NURBS // внешний контур NURBS поверхности float outer[]={0,0,1,0,1,1,0,1,0,0} ;
// внутренний контур NURBS поверхности float inner[]=
{0.25,0.25,0.5,0.5,0.75,0.25f,0.25,0.25}; int fig; // тип отображаемой фигуры float k=0; // угол вращения
void example_init()
{
gl.set (1);
glPolygonMode(GL_BACK,GL_LINE);
}
void example_deinit()
{
// уничтожения NURBS объекта gluDeleteNurbsRenderer(nurbs) ;
// уничтожения квадратичного объекта gluDeleteQuadric(obj); gl.deinit() ;
}
// обработка ввода void input()
{
switch(in.vkey)
{
case VK_ADD:fig++; break; case VK_SUBTRACT: fig--; break; default:;
}
in.vkey=0; fig%=4;
fig=(fig<0)?3:fig;
}
void draw() // вывод сцены {
input();
glLoadldentity();
// очищение буфера кадра
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glRotatef(k,1,0,0); k+=0.5; switch(fig)
{
case 0:
gluCylinder(obj,30,30,50,30,10); break;
case 1: // поверхность Безье // разрешаем двухмерный вычислитель вершин glEnable(GL_MAP2_VERTEX_3);
// инициализируем двухмерный вычислитель glMap2f(GL_MAP2_VERTEX_3, 0,10,3,3,
0,10,9,3,ctrlp[0]);
// определяем способ формирования сетки glMapGrid2f(10,0.Of,10.Of,10,0.Of,10.Of);
// вывод поверхности glEvalMesh2(GL_FILL,0,10,0,10); break; case 2:
// начало описания NURBS поверхности gluBeginSurface(nurbs);
gluNurbsSurface(nurbs,8,knots,8,knots,12,3, nurbsctrl[0],4,4,GL_MAP2_VERTEX_3);
// внешний контур gluBeginTrim(nurbs);
gluPwlCurve(nurbs,5,outer,2,GLU_MAP1_TRIM_2); gluEndTrim(nurbs);
// внутренний контур gluBeginTrim(nurbs);
gluPwlCurve(nurbs,4,inner,2,GLU_MAP1_TRIM_2); gluEndTrim(nurbs);
// конец описания NURBS поверхности
gluEndSurface(nurbs);
break;
case 3:
// вывод сферы gluSphere(obj,30,30,30); break;
}
}
Списки отображения
Списком отображения называется скомпилированная группа команд вывода OpenGL. Использование списков имеет ряд преимуществ, например повышение скорости работы программы. Обычно в них сохраняют часто используемую геометрию или наборы атрибутов. Списки также удобны для разработки сложных иерархических моделей, в которых одна часть может двигаться относительно другой.