//*** Robot arm program -- illustrates GLUT hierarchies and interaction ***
// w32ogl Project / Properties: // Must add Linker / Input / Additional Dependencies: opengl32.lib glu32.lib glut32.lib // Must set Linker / Advanced / Entry Point to: mainCRTStartup /* Robot program. Cylinder for base, scaled cube for arms */ /* Shows use of instance transformation to define parts (symbols) */ /* The cylinder is a quadric object from the GLU library */ /* The cube is also obtained from GLU */ #include <GL/glut.h> /* Let's start using #defines so we can better interpret the constants (and change them) */ #define BASE_HEIGHT 2.0 #define BASE_RADIUS 1.0 #define LOWER_ARM_HEIGHT 5.0 #define LOWER_ARM_WIDTH 0.5 #define UPPER_ARM_HEIGHT 5.0 #define UPPER_ARM_WIDTH 0.5 typedef float point[3]; static GLfloat theta[] = {0.0,0.0,0.0}; static GLint axis = 0; GLUquadricObj *p; /* pointer to quadric object */ /* Define the three parts */ /* Note use of push/pop to return modelview matrix to its state before functions were entered and use rotation, translation, and scaling to create instances of symbols (cube and cylinder */ void base() { glPushMatrix(); /* rotate cylinder to align with y axis */ glRotatef(-90.0, 1.0, 0.0, 0.0); /* cyliner aligned with z axis, render with 5 slices for base and 5 along length */ gluCylinder(p, BASE_RADIUS, BASE_RADIUS, BASE_HEIGHT, 5, 5); glPopMatrix(); } void upper_arm() { glPushMatrix(); glTranslatef(0.0, 0.5*UPPER_ARM_HEIGHT, 0.0); glScalef(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH); glutWireCube(1.0); glPopMatrix(); } void lower_arm() { glPushMatrix(); glTranslatef(0.0, 0.5*LOWER_ARM_HEIGHT, 0.0); glScalef(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH); glutWireCube(1.0); glPopMatrix(); } void display(void) { /* Accumulate ModelView Matrix as we traverse tree */ glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glColor3f(1.0, 0.0, 0.0); glRotatef(30.0,1.0,0.0,0.0); glRotatef(theta[0], 0.0, 1.0, 0.0); base(); glTranslatef(0.0, BASE_HEIGHT, 0.0); glRotatef(theta[1], 0.0, 0.0, 1.0); lower_arm(); glTranslatef(0.0, LOWER_ARM_HEIGHT, 0.0); glRotatef(theta[2], 0.0, 0.0, 1.0); upper_arm(); glFlush(); } void mykey(GLubyte key, GLint x, GLint y) { if (key=='l') { theta[axis] += 5.0; if( theta[axis] > 360.0 ) theta[axis] -= 360.0; } if (key=='r') { theta[axis] -= 5.0; if( theta[axis] > 360.0 ) theta[axis] += 360.0; } display(); } void menu(int id) { /* menu selects which angle to change or whether to quit */ if(id == 1 ) axis=0; if(id == 2) axis=1; if(id == 3 ) axis=2; if(id ==4 ) exit(0); } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-5.0, 5.0, -5.0, 15.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void myinit() { glClearColor(1.0, 1.0, 1.0, 1.0); glColor3f(1.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-5.0, 5.0, -5.0, 15.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //added p=gluNewQuadric(); /* allocate quadric object */ gluQuadricDrawStyle(p, GLU_LINE); /* render it as wireframe */ } void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow("robot"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutKeyboardFunc(mykey); glutCreateMenu(menu); glutAddMenuEntry("base", 1); glutAddMenuEntry("lower arm", 2); glutAddMenuEntry("upper arm", 3); glutAddMenuEntry("quit", 4); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); }