/ examples / NSOpenGLView / MyOpenGLView.m
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