dots.c |
| /* This is a block comment! */ /* ** Parts of the lab are freely adapted from: ** ** Computer Graphics using OpenGL (Second Edition) ** F.S. Hill, Jr. ** Prentice Hall (2001) ** ** -Raymond */ /* ** the OpenGL include files ** ** these are system libraries we need. */ #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> /* ** some other include files */ #include <stdio.h> // include for console and file IO (not used) /*#include <stdlib.h>*/ // include for standard things (not needed here) /* an example #define, ** ** this is an instruction to the compiler to replace every instance of ** 'gasketSize' by '10000' *before* doing the compilation. ** It can be used to create a number of 'interesting' effects - but we ** will usually only use it to define constants. */ #define gasketSize 10000 #define screenHeight 480 /* ** TYPE DECLARATIONS */ /* ** this a record structure that contains two GL integers (x, and y). */ typedef struct { GLint x, y; } GLintPoint; /* ** ... and this is a record of three GL floats (reals) for colour. ** r, g, and b can have the real values between 0 and 1. */ typedef struct { GLfloat r, g, b; } GLfloatRGBColour; /* ** GLOBAL VARIABLES */ /* ** create an array[0..7] of colours; and initialising their values! */ GLfloatRGBColour colour[8] = { {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f}}; // a global variable to keep track of which of the palate colours we're using. int penColour = 0; /* ** FUNCTION HEADERS - a list of the functions */ int my_random(int m); void clearScreen(void); void showScreen(void); void setPenSize(GLfloat size); void setPenColour(GLfloatRGBColour newColour); void drawPoint(GLint x, GLint y); void drawSierpinski(GLintPoint T[3]); void myDisplay(void); void myMouse(int button, int state, int x, int y); void myKeyboard(unsigned char theKey, int mouseX, int mouseY); void myInit(void); int main (int argc, char** argv); /* ** UTILITY FUNCTIONS */ /* returns an integer in the range 0..(m-1) */ int my_random(int m) { return rand()%m; } void clearScreen(void) { glClear(GL_COLOR_BUFFER_BIT); } void showScreen(void) { glFlush(); } void setPenSize(GLfloat size) { glPointSize(size); } void setPenColour(GLfloatRGBColour newColour) { glColor3f(newColour.r, newColour.g, newColour.b); } void drawPoint(GLint x, GLint y) { glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); } /* ** DRAWING ROUTINES */ /* ** Sierpinski Drawing Routine */ void drawSierpinski(GLintPoint corner[3]) { int i, index, tcolour=0; GLintPoint point; clearScreen(); setPenSize(2); point = corner[my_random(3)]; drawPoint(point.x, point.y); for (i = 0; i < gasketSize; i++) { index = my_random(3); point.x = (point.x + corner[index].x)/2; point.y = (point.y + corner[index].y)/2; tcolour = (++tcolour)%7; // col = (col + 1) mod 7; setPenColour(colour[tcolour]); drawPoint(point.x, point.y); } showScreen(); } /* ** The main display function */ void myDisplay(void) { //glClear(GL_COLOR_BUFFER_BIT); clearScreen(); // glBegin(GL_POINTS); //glVertex2i(100, 50); drawPoint(100, 50); //glVertex2i drawPoint(100, 130); //glVertex2i drawPoint(150, 130); // glEnd(); //glFlush(); showScreen(); } /* ** EVENT LISTENERS */ /* ** Mouse Listener */ void myMouse(int button, int state, int x, int y) { static GLintPoint corners[3]; static int numCorners; if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { corners[numCorners].x = x; corners[numCorners].y = screenHeight - y - 1; if (++numCorners == 3) { drawSierpinski(corners); numCorners = 0; } } } /* ** Key Listener */ void myKeyboard(unsigned char theKey, int mouseX, int mouseY) { // correct (flip) the y coordinate mouseY = screenHeight - mouseY - 1; switch (theKey) { // if we type a 'p' - draw a point where the mouse is. case 'p': case 'P': drawPoint(mouseX, mouseY); showScreen(); break; // if we type a 'c' - cycle through the 7 visible colours case 'c': case 'C': penColour = (++penColour)%7; // col = (col + 1) mod 7; setPenColour(colour[penColour]); break; // if we type an 'r' - redraw the screen case 'r': case 'R': myDisplay(); break; // if we type an 'w' - redraw the screen case 'w': case 'W': clearScreen(); break; // if we type a 'q' - quit the program normally case 'q': case 'Q': exit(0); // otherwise - we don't have anything to do. default: break; } } /* ** INITIALISERS */ /* ** My Init */ void myInit(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glColor3f(0.0f, 0.0f, 0.0f); glPointSize(4.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 640.0, 0.0, 480.0); } /* ** Main */ int main (int argc, char** argv) { /* GL initialisers */ glutInit(&argc, argv); //initialise the toolkit glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //set the display mode /* GL initialising the window */ glutInitWindowSize(640, 480); glutInitWindowPosition(100, 150); glutCreateWindow("Dots and the Sierpinski Gasket"); /* ** GL register the callback functions to deal with ** display, mouse, & keyboard */ glutDisplayFunc(myDisplay); glutKeyboardFunc(myKeyboard); glutMouseFunc(myMouse); // (initially we've no mouse listener) /* GL now lets us do our own initialisations */ myInit(); /* ** Now we enter a special loop, which listens for events to ** be processed. ** It calls the Display function, and waits. */ glutMainLoop(); return 0; // the main function need to return something } |
James Little |