2.7 Упражнение: "Снеговик"
Используя функцию glRotate, нарисуйте снеговика. Три сферы, шапка - конус,
нос - тоже конус, глаза - сфера, рот можно квадратным сделать - glBox.
Исходный файл смотрите здесь.
Исполняемый файл здесь.
Примечание: Имеется еще один баг в glaux.lib от Microsoft. Кажется, последний
из обнаруженных мной. Функция aux[Solid/Wire]Cylinder прежде, чем нарисовать
цилиндр, сдвигает и поворачивает координаты. Так что, если вы уже сместили
и повернули координаты, то цилиндр нарисуется совсем не там, где вы рассчитывали.
Люди из Microsoft, конечно же, будут уверять, что это особенность, и предложат
вам скачать очередной ServicePack.;-) А я ниже расскажу, как более правильно
рисовать цилиндры и конусы. Если вам некогда ждать, то далее приведен
исправленный код этих функций. Большинство из вас сейчас пропустят его
и перейдут к следующему очень интересному разделу - "Анимация". И правильно
сделаете. К исправлению ошибок вернетесь, когда немного освоитесь. Но
я все же решил привести код по исправлению ошибок Microsoft именно здесь.
Можете пересобрать glaux.lib, заменив соответсвующий код в файле shapes.c.
Где взять исходники, смотрите в приложении 'A'. По-моему, они есть в MSDN.
void auxWireCylinder (GLdouble radius, GLdouble height)
{
GLUquadricObj *quadObj;
GLdouble *sizeArray, *tmp;
GLuint displayList;
sizeArray = (GLdouble *) malloc (sizeof (GLdouble) * 2);
tmp = sizeArray;
*tmp++ = radius;
*tmp++ = height;
displayList = findList (CYLINDERWIRE, sizeArray, 2);
if (displayList == 0) {
glNewList(makeModelPtr (CYLINDERWIRE, sizeArray, 2),
GL_COMPILE_AND_EXECUTE);
quadObj = gluNewQuadric ();
gluQuadricDrawStyle (quadObj, GLU_LINE);
gluCylinder (quadObj, radius, radius, height, 12, 2);
glEndList();
}
else {
glCallList(displayList);
free (sizeArray);
}
}
void auxSolidCylinder (GLdouble radius, GLdouble height)
{
GLUquadricObj *quadObj;
GLdouble *sizeArray, *tmp;
GLuint displayList;
sizeArray = (GLdouble *) malloc (sizeof (GLdouble) * 2);
tmp = sizeArray;
*tmp++ = radius;
*tmp++ = height;
displayList = findList (CYLINDERSOLID, sizeArray, 2);
if (displayList == 0) {
glNewList(makeModelPtr (CYLINDERSOLID, sizeArray, 2),
GL_COMPILE_AND_EXECUTE);
quadObj = gluNewQuadric ();
gluQuadricDrawStyle (quadObj, GLU_FILL);
gluQuadricNormals (quadObj, GLU_SMOOTH);
gluCylinder (quadObj, radius, radius, height, 12, 2);
glEndList();
}
else {
glCallList(displayList);
free (sizeArray);
}
}
void auxSolidCone (GLdouble base, GLdouble height)
{
GLUquadricObj *quadObj;
GLdouble *sizeArray, *tmp;
GLuint displayList;
sizeArray = (GLdouble *) malloc (sizeof (GLdouble) * 2);
tmp = sizeArray;
*tmp++ = base;
*tmp++ = height;
displayList = findList (CONESOLID, sizeArray, 2);
if (displayList == 0) {
glNewList(makeModelPtr (CONESOLID, sizeArray, 2),
GL_COMPILE_AND_EXECUTE);
quadObj = gluNewQuadric ();
gluQuadricDrawStyle (quadObj, GLU_FILL);
gluQuadricNormals (quadObj, GLU_SMOOTH);
gluCylinder (quadObj, base, (GLdouble)0.0, height, 15, 10);
glEndList();
}
else {
glCallList(displayList);
free (sizeArray);
}
}
|