// // kGLView.m // CocoaGL // // Created by Katherine Tattersall on Thu Jul 11 2002. // Copyright (c) 2001 ZeroByZero. All rights reserved. // #import "kGLView.h" @interface kGLView (privatestuff) - (void)initGL; @end @implementation kGLView // i would like to thank the academy... um... i mean... er... // Dietmar Planitzer, whose code I shamelessly stole from in order to implement // this full screen stuff // if you try to use the NSOpenGLContext's full screen method, you lose // all the nice things about Cocoa, and have to implement your own even queue // because it seems that nothing else will pass it to you // if you try to use the OmniGroup's OpenGL Example code, you will ALSO lose // the event queue and will have to implement it yourself // THIS is much easier to code AND understand - (IBAction)toggleFullScreen:(id)sender { if( FullScreenOn == true ) // we need to go back to non-full screen { [FullScreenWindow close]; [StartingWindow setContentView: self]; [StartingWindow makeKeyAndOrderFront: self]; [StartingWindow makeFirstResponder: self]; FullScreenOn = false; } else // FullScreenOn == false { unsigned int windowStyle; NSRect contentRect; StartingWindow = [NSApp keyWindow]; windowStyle = NSBorderlessWindowMask; contentRect = [[NSScreen mainScreen] frame]; FullScreenWindow = [[NSWindow alloc] initWithContentRect:contentRect styleMask: windowStyle backing:NSBackingStoreBuffered defer: NO]; if(FullScreenWindow != nil) { NSLog(@"Window was created"); [FullScreenWindow setTitle: @"myWindow"]; [FullScreenWindow setReleasedWhenClosed: YES]; [FullScreenWindow setContentView: self]; [FullScreenWindow makeKeyAndOrderFront:self ]; [FullScreenWindow setLevel: NSScreenSaverWindowLevel - 1]; [FullScreenWindow makeFirstResponder:self]; FullScreenOn = true; } } } - (id)initWithFrame:(NSRect) frameRect { // First, we must create an NSOpenGLPixelFormatAttribute NSOpenGLPixelFormat *nsglFormat; NSOpenGLPixelFormatAttribute attr[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated, NSOpenGLPFAColorSize, BITS_PER_PIXEL, NSOpenGLPFADepthSize, DEPTH_SIZE, 0 }; [self setPostsFrameChangedNotifications: YES]; // Next, we initialize the NSOpenGLPixelFormat itself nsglFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr]; // Check for errors in the creation of the NSOpenGLPixelFormat // If we could not create one, return nil (the OpenGL is not initialized, and // we should send an error message to the user at this point) if(!nsglFormat) { NSLog(@"Invalid format... terminating."); return nil; } // Now we create the the CocoaGL instance, using our initial frame and the NSOpenGLPixelFormat self = [super initWithFrame:frameRect pixelFormat:nsglFormat]; [nsglFormat release]; // If there was an error, we again should probably send an error message to the user if(!self) { NSLog(@"Self not created... terminating."); return nil; } // Now we set this context to the current context (means that its now drawable) [[self openGLContext] makeCurrentContext]; // Finally, we call the initGL method (no need to make this method too long or complex) [self initGL]; return self; } - (void)initGL { // Set the clear color to black. This is the color that your background will be if you don't draw to it // If setting to black, we needn't specifically say this, but it's good style to mention explicitly // You can set the clear color to something else later, but it should not be between a glBegin and glEnd glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set the clear depth to 1. This is the initial (default) value. // Set the depth function. This specifies when something will be drawn. GL_LESS passes if the incoming // depth value is lESS than the current value // Turn the depth test on glClearDepth(1.0f); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); // Set the blending up glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set up a hint telling the computer to create the nicest (aka "costliest" or "most correct") // image it can // This hint is for the quality of color and texture mapping glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // This hint is for antialiasing glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); font = [[NSGLFont alloc] pixmapFont: @"CurlzMT" atSize:96]; // font = [[NSGLFont alloc] bitmapFont: @"CurlzMT" atSize:96]; // font = [[NSGLFont alloc] outlineFont: @"CurlzMT" atSize:96 extrude:0.5 stepsize:0]; // font = [[NSGLFont alloc] cheapOutlineFont: @"CurlzMT" atSize:96 extrude:0.5]; [font retain]; NSLog(@"end initGL"); } // awake from nib is called when the window opens - (void)awakeFromNib { NSLog(@"awakeFromNib"); time = [ [NSTimer scheduledTimerWithTimeInterval: DEFAULT_TIME_INTERVAL target:self selector:@selector(drawFrame) //go to this method whenever the time comes userInfo:nil repeats:YES] retain ]; // Add our timers to the EventTracking loop [[NSRunLoop currentRunLoop] addTimer: time forMode: NSEventTrackingRunLoopMode]; // Add our timers to the ModelPanel loop [[NSRunLoop currentRunLoop] addTimer: time forMode: NSModalPanelRunLoopMode]; NSLog(@"end awakeFromNib"); } // this method is called whenever the window/control is reshaped // it is also called when the control is first opened - (void) reshape { float aspect; NSSize bound = [self frame].size; aspect = bound.width / bound.height; // change the size of the viewport to the new width and height // this controls the affine transformation of x and y from normalized device // coordinates to window coordinates (from the OpenGl 1.1 reference book, 2nd ed) glViewport(0, 0, bound.width, bound.height); glMatrixMode(GL_PROJECTION); // you must reload the identity before this or you'll lose your picture glLoadIdentity(); gluPerspective(45.0f, (GLfloat)aspect, 0.1f,1000.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } - (void)drawFrame { // Clear the buffers! glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glTranslatef(0.0,0.0,-10); // this is where you would want to draw glColor4f( 1.0, 0.0, 0.0, 0.8 ); glPrint3( font, -5, -1, -10, "Tutorial 8" ); // flush the buffer! (send drawing to the screen) [[self openGLContext] flushBuffer]; } /* This is the preferred way to determine events */ // if you want to get events sent to you, you must make yourself a first responder - (BOOL)acceptsFirstResponder { return YES; } - (BOOL)becomeFirstResponder { return YES; } // handle key down events // if you don't handle this, the system beeps when you press a key (how annoying) - (void)keyDown:(NSEvent *)theEvent { NSLog( @"key down" ); } // handle mouse up events (left mouse button) - (void)mouseUp:(NSEvent *)theEvent { NSLog( @"Mouse L up"); } // handle mouse up events (right mouse button) - (void)rightMouseUp:(NSEvent *)theEvent { NSLog( @"Mouse R up"); } // handle mouse up events (other mouse button) - (void)otherMouseUp:(NSEvent *)theEvent { NSLog( @"Mouse O up"); } @end