/* Globals */
GLfloat spin = 0.0f;
GLdouble vz = -5.0;
GLfloat ambient[4] = { 0.5f, 1.0f, 1.0f, 1.0f };
GLfloat diffuse[4] = { 0.5f, 1.0f, 1.0f, 1.0f };
GLfloat specular[4] = { 0.5f, 1.0f, 1.0f, 1.0f };
int wireframe = 0; /* Wireframe mode */
static GLdouble isoVtx[12][3] = {
#define X .525731112119133606
#define Z .850650808352039932
{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
{0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
{Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};
static GLuint isoInd[20][3] = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
float mProjection[16]; /* Projection matrix to load for 'background' */
float mModelview[16]; /* Modelview matrix to load for 'background' */
float mTexture[16]; /* Texture matrix to load for 'background' */
static void
Norm(GLdouble *a)
{
GLdouble d = sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
a[0] /= d;
a[1] /= d;
a[2] /= d;
}
/* For MyDrawFunction(). */
static void
MyDrawTriangle(GLdouble *a, GLdouble *b, GLdouble *c, int div, float r)
{
if (div <= 0) {
glNormal3dv(a); glVertex3d(a[0]*r, a[1]*r, a[2]*r);
glNormal3dv(b); glVertex3d(b[0]*r, b[1]*r, b[2]*r);
glNormal3dv(c); glVertex3d(c[0]*r, c[1]*r, c[2]*r);
} else {
GLdouble ab[3], ac[3], bc[3];
int i;
for (i = 0; i < 3; i++) {
ab[i] = (a[i]+b[i])/2.0;
ac[i] = (a[i]+c[i])/2.0;
bc[i] = (b[i]+c[i])/2.0;
}
Norm(ab);
Norm(ac);
Norm(bc);
MyDrawTriangle(a, ab, ac, div-1, r);
MyDrawTriangle(b, bc, ab, div-1, r);
MyDrawTriangle(c, ac, bc, div-1, r);
MyDrawTriangle(ab, bc, ac, div-1, r);
}
}
/* React to a change in window size. */
static void
MyResizeFunction(AG_DriverEvent *ev)
{
GLdouble xMin, xMax, yMin, yMax;
glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity();
glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
/* Set a 60 degrees field of view with 1.0 aspect ratio. */
yMax = 0.01*tan(0.523598f);
yMin = -yMax;
xMin = yMin;
xMax = yMax;
glFrustum(xMin, xMax, yMin, yMax, 0.01, 100.0);
glGetFloatv(GL_PROJECTION_MATRIX, mProjection);
glGetFloatv(GL_MODELVIEW_MATRIX, mModelview);
glGetFloatv(GL_TEXTURE_MATRIX, mTexture);
glMatrixMode(GL_PROJECTION); glPopMatrix();
glMatrixMode(GL_MODELVIEW); glPopMatrix();
glMatrixMode(GL_TEXTURE); glPopMatrix();
}
/* Render our background. */
static void
MyDrawFunction()
{
int i;
GLfloat pos[4];
/* Save state */
glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadMatrixf(mTexture);
glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrixf(mProjection);
glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadMatrixf(mModelview);
glPushAttrib(GL_ALL_ATTRIB_BITS);
glEnable(GL_CULL_FACE);
glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE1);
glDisable(GL_CLIP_PLANE2);
glDisable(GL_CLIP_PLANE3);
/* Draw our background */
glLoadIdentity();
glPushAttrib(GL_POLYGON_BIT|GL_LIGHTING_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_POLYGON);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
glShadeModel(GL_SMOOTH);
pos[0] = 10.0f;
pos[1] = 10.0f;
pos[2] = 0.0f;
pos[3] = 1.0f;
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 10.0f);
glPushMatrix();
glTranslated(0.0, 0.0, vz);
glRotatef(spin,0.0f,1.0f,0.0f);
glRotatef(spin,1.0f,1.0f,1.0f);
glBegin(GL_TRIANGLES);
for (i = 0; i < 20; i++) {
MyDrawTriangle(isoVtx[isoInd[i][0]],
isoVtx[isoInd[i][1]],
isoVtx[isoInd[i][2]],
2, 1.0f);
}
glEnd();
glPopMatrix();
glPopAttrib();
if (++spin > 360.0f) { spin -= 360.0f; }
/* Restore state */
glPopAttrib();
glMatrixMode(GL_MODELVIEW); glPopMatrix();
glMatrixMode(GL_TEXTURE); glPopMatrix();
glMatrixMode(GL_PROJECTION); glPopMatrix();
}