const GLint pickBuffSize = 32;
/* Исходный размер окна на экране. */
GLsizei winWidth = 400, winHeight = 400; void init (void) {
/* Цвет окна дисплея - белый. */ glClearColor (1.0, 1.0, 1.0, 1.0);
}
/* Определяются 3 прямоугольника и связанные с ними
* идентификаторы.
*/
void rects (GLenurti mode) { if (mode == GL_SELECT)
glPushName (30); // Красный прямоугольник.
glColor3f (1.0, 0.0, 0.0); glRecti (40, 130, 150, 260); if (mode == GL_SELECT)
glPushName (10); // Синий прямоугольник.
glColor3f (0.0, 0.0, 1.0);
glRecti (Ц50, 130, 260, 260); if (mode == GL_SELECT)
glPushName (20); // Зеленый прямоугольник.
glColor3f (0.0, 1.0, 0.0); glRecti (40, 40, 260, 130);
}
/* Печать содержимого буфера выбора для каждого
* щелчка мьшыо.
*/
void processPicks (GLint nPicks, GLuint pickBuffer [ ])
{
GLint j, k;
GLuint objID, *ptr;
printf (" Число выбранных объектов = %d\n", nPicks); printf ("\n"); ptr = pickBuffer;
/* Вывод всех элементов в каждой записи выбора. */ for (j = 0; j < nPicks; j++) { objID = *ptr;
printf ("Положение в стеке = %d\n", objID); ptr++;
printf ("Минимальная глубина = %g,",
float (*ptr/0x7fffffff));
ptr++;
printf ("Максимальная глубина = %g\n",
float (*ptr/0x7 fffffff));
ptr++;
printf ("Идентификаторы в стеке: \n"); for (k = 0; k < objID; k++) { printf (" %d ",*ptr); ptr++;
}
printf ("\n\n");
}
}
void pickRects (GLint button, GLint action, GLint xMouse,
GLint yMouse)
{
GLuint pickBuffer [pickBuffSize];
GLint nPicks, vpArray [4];
if (button != GLUT_LEFT_BUTTON || action != GLUT_DOWN) return;
glSelectBuffer (pickBuffSize, pickBuffer);
/* Обозначить буфер выбора. */ glRenderMode (GL_SELECT) ;
/* Активизировать операции выбора. */ gllnitNames ( );
/* Инициализировать стек идентификаторов объектов. */
/* Запись текущей матрицы наблюдения. */ glMatrixMode (GL_PROJECTION);
glPushMatrix ( ); glLoadldentity ( );
/* Получить параметры текущего окна просмотра. Задать
* окно 5 на 5 и инвертировать входное значение yMouse,
* используя высоту окна просмотра (четвертый элемент
* массива vpArray).
*/
glGetlntegerv (GL_VIEWPORT, vpArray);
gluPickMatrix (GLdouble (xMouse), GLdouble (vpArray [3]
- yMouse), 5.0, 5.0, vpArray) gluOrtho2D (0.0, 300.0, 0.0, 300.0); rects (GL_SELECT) ;
/* Обработать прямоугольник в режиме выбора. */
/* Восстановить исходную матрицу наблюдения. */ glMatrixMode (GL_PROJECTION); glPopMatrix ( ); glFlush ( );
/* Определить число выделенных объектов и вернуться
* в обычный режим визуализации.
*/
nPicks = glRenderMode (GL_RENDER); processPicks (nPicks, pickBuffer);
/* Обработать выбранные объекты. */ glutPostRedisplay ( );
}
void displayFcn (void)
{
glClear (GL_COLOR_BUFFER_BIT);
rects (GL_RENDER); // Отобразить прямоугольники.
glFlush ( );
}
void winReshapeFcn (GLint newWidth, GLint newHeight)
{
/* Обновить окно просмотра и проекционные параметры. */