diff --git a/hilbert.c b/hilbert.c index 9947c61..b460e11 100644 --- a/hilbert.c +++ b/hilbert.c @@ -6,26 +6,36 @@ #include #include #include +#include /* constants */ #define SEGMENTS 16 #define WIDTH 800 #define HEIGHT 600 +/* macros */ +#define keepingMatrix(x) { glPushMatrix(); x; glPopMatrix(); } + /* functions */ void usage(void); void initgl(void); void display(void); void mainloop(void); -void drawHilbert(); +void initLists(void); +void tlRtDrwCyl(float x, float y, float z, float a, float u, float v, float w); +void drawHilbert(int level, float size, int cap1, int cap2); +void drawHilbert1(int cap1, int cap2); /* global variables */ -int level = 2; +int level = 1; float size = 0.4; SDL_Surface * sdlScreen; int winWidth = WIDTH; int winHeight = HEIGHT; -int displayList = -1; +int hilbertList = -1; +int sphereList = -1; +int cylList = -1; +const float diffuse[4] = {0.9f, 0.6f, 0.1f, 1.0f}; int main(int argc, char *argv[]) { @@ -68,6 +78,7 @@ int main(int argc, char *argv[]) SDL_WM_SetCaption(argv[0], argv[0]); initgl(); + initLists(); mainloop(); return 0; @@ -102,42 +113,125 @@ void initgl(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); glShadeModel(GL_SMOOTH); glViewport(0, 0, winWidth, winHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(60.0, (GLfloat)winHeight/(GLfloat)winWidth, 1.0, 30.0); + gluPerspective(60.0, 1, 0.01, 3000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glTranslatef(0.0, 0.0, -3.6); + gluLookAt(10, -10, 10, + 0, 0, 0, + 0, 0, 1); + + /* set up materials */ + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, diffuse); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (displayList >= 0) - { - glCallList(displayList); - } - else - { - displayList = glGenLists(1); - if (displayList < 0) - { - fprintf(stderr, "Error allocating display list!\n"); - exit(132); - } - glNewList(displayList, GL_COMPILE_AND_EXECUTE); - drawHilbert(); - glEndList(); - } - + glCallList(hilbertList); SDL_GL_SwapBuffers(); } -void drawHilbert() +void drawHilbert(int level, float size, int cap1, int cap2) { + if (level == 1) + { + drawHilbert1(cap1, cap2); + } +} + +void drawHilbert1(int cap1, int cap2) +{ + if (cap1) + { + keepingMatrix( + glTranslatef(-0.5f, -0.5f, -0.5f); + glCallList(sphereList); + ) + } + else + { + tlRtDrwCyl(-0.5, -1.0, -0.5, 90, 1.0, 0.0, 0.0); + tlRtDrwCyl(-0.5, -0.5, -0.5, 90, 1.0, 0.0, 0.0); + } + + if (cap2) + { + keepingMatrix( + glTranslatef(0.5f, 0.5f, 0.5f); + glCallList(sphereList); + ) + } + else + { + tlRtDrwCyl(-0.5, -1.0, 0.5, 90, 1.0, 0.0, 0.0); + tlRtDrwCyl(-0.5, -0.5, 0.5, 90, 1.0, 0.0, 0.0); + } + + glColor3f(0.2, 0.2, 1.0); + glDisable(GL_LIGHTING); + glBegin(GL_LINE_STRIP); + glVertex3f(-0.5, -0.5, -0.5); + glVertex3f(-0.5, 0.5, -0.5); + glVertex3f(0.5, 0.5, -0.5); + glVertex3f(0.5, -0.5, -0.5); + glVertex3f(0.5, -0.5, 0.5); + glVertex3f(0.5, 0.5, 0.5); + glVertex3f(-0.5, 0.5, 0.5); + glVertex3f(-0.5, -0.5, 0.5); + glEnd(); + glEnable(GL_LIGHTING); +} + +void tlRtDrwCyl(float x, float y, float z, float a, float u, float v, float w) +{ + keepingMatrix( + glTranslatef(x, y, z); + glRotatef(a, u, v, w); + glCallList(cylList); + ) +} + +void initLists(void) +{ + GLUquadric * q; + + hilbertList = glGenLists(1); + sphereList = glGenLists(1); + cylList = glGenLists(1); + + if (hilbertList < 0 || sphereList < 0 || cylList < 0) + { + fprintf(stderr, "Error allocating display list!\n"); + exit(132); + } + + /* get a quadric object to draw with */ + q = gluNewQuadric(); + + /* draw a sphere */ + glNewList(sphereList, GL_COMPILE); + gluSphere(q, size, SEGMENTS, SEGMENTS/2); + glEndList(); + + /* draw a cylinder */ + glNewList(cylList, GL_COMPILE); + gluCylinder(q, size, size, 0.25, SEGMENTS, SEGMENTS/4); + glEndList(); + + /* draw Hilbert curve */ + glNewList(hilbertList, GL_COMPILE); + drawHilbert(level, size, 1, 1); + glEndList(); + + /* free quadric memory */ + gluDeleteQuadric(q); } void usage(void)