MyOpenGLView.m
1 #import "MyOpenGLView.h" 2 #import <ApplicationServices/ApplicationServices.h> 3 #import <OpenGL/gl.h> 4 #import <OpenGL/glu.h> 5 6 @implementation MyOpenGLView 7 8 - (void) awakeFromNib { 9 _angleX = 360; 10 _timer = [[NSTimer scheduledTimerWithTimeInterval: 0.01 11 target: self 12 selector: @selector(timer:) 13 userInfo: nil 14 repeats: YES] retain]; 15 [[self window] setTitle: NSLocalizedString(@"WindowTitle", @"")]; 16 } 17 18 static void drawArcWithDepth(float beginAngle, float endAngle, 19 float innerRadius, float outerRadius, float z) 20 { 21 for (; beginAngle <= endAngle; beginAngle += 1) { 22 CGAffineTransform matrix = 23 CGAffineTransformMakeRotation(M_PI * beginAngle / 180.0); 24 CGPoint innerPoint = CGPointMake(innerRadius, 0); 25 CGPoint outerPoint = CGPointMake(outerRadius, 0); 26 27 innerPoint = CGPointApplyAffineTransform(innerPoint, matrix); 28 outerPoint = CGPointApplyAffineTransform(outerPoint, matrix); 29 30 glVertex3f(innerPoint.x, innerPoint.y, z); 31 glVertex3f(outerPoint.x, outerPoint.y, z); 32 } 33 } 34 35 static void drawEdge(float beginAngle, float endAngle, float radius, 36 float zclose, float zfar) 37 { 38 for (; beginAngle <= endAngle; beginAngle += 1) { 39 CGAffineTransform matrix = 40 CGAffineTransformMakeRotation(M_PI * beginAngle / 180.0); 41 CGPoint point = CGPointMake(radius, 0); 42 CGPoint normal = CGPointMake(1, 0); 43 44 point = CGPointApplyAffineTransform(point, matrix); 45 normal = CGPointApplyAffineTransform(normal, matrix); 46 47 glNormal3f(normal.x, normal.y, 0); 48 glVertex3f(point.x, point.y, zclose); 49 glVertex3f(point.x, point.y, zfar); 50 } 51 } 52 53 static void capAtAngle(float angle, float innerRadius, float outerRadius, 54 float depth) 55 { 56 CGAffineTransform matrix = 57 CGAffineTransformMakeRotation(M_PI * angle / 180.0); 58 CGPoint innerPoint = CGPointMake(innerRadius, 0); 59 CGPoint outerPoint = CGPointMake(outerRadius, 0); 60 CGPoint normal = CGPointMake(1, 0); 61 62 innerPoint = CGPointApplyAffineTransform(innerPoint, matrix); 63 outerPoint = CGPointApplyAffineTransform(outerPoint, matrix); 64 normal = CGPointApplyAffineTransform(normal, matrix); 65 66 glNormal3f(normal.x, normal.y, 0); 67 68 glVertex3f(innerPoint.x, innerPoint.y, depth / 2); 69 glVertex3f(outerPoint.x, outerPoint.y, depth / 2); 70 glVertex3f(outerPoint.x, outerPoint.y, -depth / 2); 71 glVertex3f(innerPoint.x, innerPoint.y, -depth / 2); 72 } 73 74 static void drawArc(float beginAngle, float endAngle, float innerRadius, 75 float outerRadius, float depth) 76 { 77 glNormal3f(1, 0, 0); 78 glBegin(GL_QUAD_STRIP); 79 drawArcWithDepth(beginAngle, endAngle, innerRadius, outerRadius, depth / 2); 80 glEnd(); 81 82 glNormal3f(-1, 0, 0); 83 glBegin(GL_QUAD_STRIP); 84 drawArcWithDepth(beginAngle, endAngle, innerRadius, outerRadius, 85 -depth / 2); 86 glEnd(); 87 88 glColor3f(.2, .2, .2); 89 90 glBegin(GL_QUAD_STRIP); 91 drawEdge(beginAngle, endAngle, outerRadius, depth / 2, -depth / 2); 92 glEnd(); 93 94 glBegin(GL_QUAD_STRIP); 95 drawEdge(beginAngle, endAngle, innerRadius, depth / 2, -depth / 2); 96 glEnd(); 97 98 glBegin(GL_QUADS); 99 capAtAngle(beginAngle, innerRadius, outerRadius, depth); 100 capAtAngle(endAngle, innerRadius, outerRadius, depth); 101 glEnd(); 102 } 103 104 static void drawCocotron() { 105 glColor3f(0, 0, 0); 106 drawArc(0, 60, .5, 1, .3); 107 108 glColor3f(0, 0, 0); 109 drawArc(120, 180, .5, 1, .3); 110 111 glColor3f(0, 0, 0); 112 drawArc(240, 300, .5, 1, .3); 113 114 glColor3f(.5, .5, 0); 115 drawArc(30, 330, .2, .4, .3); 116 } 117 118 - (void) drawRect: (NSRect) bounds { 119 glClearColor(.3, 0, .3, 1); 120 glLoadIdentity(); 121 glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT + GL_STENCIL_BUFFER_BIT); 122 glRotatef(_angleX, 0, 1, 0); 123 drawCocotron(); 124 glFlush(); 125 [[self openGLContext] flushBuffer]; 126 } 127 128 - (void) prepareOpenGL { 129 glEnable(GL_DEPTH_TEST); 130 glShadeModel(GL_SMOOTH); 131 } 132 133 - (void) reshape { 134 glViewport(0, 0, [self bounds].size.width, [self bounds].size.height); 135 } 136 137 - (void) timer: (NSTimer *) timer { 138 _angleX -= 1; 139 140 if (_angleX < 0) { 141 _angleX = 360; 142 } 143 144 [self setNeedsDisplay: YES]; 145 } 146 147 @end