Chapter 2
Быстрый старт

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);
    }
}