Sources/Classes/Application/View/Toolkit/OpenGLView.m
//--------------------------------------------------------------------------------------- |
// |
// File: OpenGLView.m |
// |
// Abstract: OpenGL view class with text labels and added utility methods |
// |
// Disclaimer: IMPORTANT: This Apple software is supplied to you by |
// Inc. ("Apple") in consideration of your agreement to the following terms, |
// and your use, installation, modification or redistribution of this Apple |
// software constitutes acceptance of these terms. If you do not agree with |
// these terms, please do not use, install, modify or redistribute this |
// Apple software. |
// |
// In consideration of your agreement to abide by the following terms, and |
// subject to these terms, Apple grants you a personal, non-exclusive |
// license, under Apple's copyrights in this original Apple software (the |
// "Apple Software"), to use, reproduce, modify and redistribute the Apple |
// Software, with or without modifications, in source and/or binary forms; |
// provided that if you redistribute the Apple Software in its entirety and |
// without modifications, you must retain this notice and the following |
// text and disclaimers in all such redistributions of the Apple Software. |
// Neither the name, trademarks, service marks or logos of Apple Inc. may |
// be used to endorse or promote products derived from the Apple Software |
// without specific prior written permission from Apple. Except as |
// expressly stated in this notice, no other rights or licenses, express |
// or implied, are granted by Apple herein, including but not limited to |
// any patent rights that may be infringed by your derivative works or by |
// other works in which the Apple Software may be incorporated. |
// |
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
// |
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
// POSSIBILITY OF SUCH DAMAGE. |
// |
// Copyright (c) 2008-2009, 2012 Apple Inc., All rights reserved. |
// |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
#import "OpenGLView.h" |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
enum OpenGLViewFlags |
{ |
kOpenGLViewResized = 0, |
kOpenGLViewStopRotation, |
kOpenGLViewDisplayCounter, |
kOpenGLViewDisplayPrefTimer, |
kOpenGLViewDisplayRenderer, |
kOpenGLViewDisplayBounds |
}; |
typedef enum OpenGLViewFlags OpenGLViewFlags; |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
//--------------------------------------------------------------------------------------- |
@implementation OpenGLView |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Post Notification |
//--------------------------------------------------------------------------------------- |
- (void) postOpenGLViewNotifications |
{ |
[[NSNotificationCenter defaultCenter] addObserver:self |
selector:@selector(viewWillTerminate:) |
name:@"NSApplicationWillTerminateNotification" |
object:NSApp]; |
} // postOpenGLViewNotifications |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Labels Initialization |
//--------------------------------------------------------------------------------------- |
- (void) initPrefTimerLabel:(const NSRect *)theBounds |
textColor:(NSColor *)theTextColor |
boxColor:(NSColor *)theBoxColor |
borderColor:(NSColor *)theBorderColor |
{ |
NSPoint prefTimerInfoCoordinates = NSMakePoint(10.0f, 32.0f); |
mpLabelPrefTimer = [[OpenGLPrefTimerLabel alloc] initLabelWithFormat:nil |
fontName:@"Helvetica" |
fontSize:20.0f |
textColor:theTextColor |
boxColor:theBoxColor |
borderColor:theBorderColor |
coordinates:&prefTimerInfoCoordinates |
bounds:theBounds]; |
} // initPrefTimerLabel |
//--------------------------------------------------------------------------------------- |
- (void) initRendererLabel:(const NSRect *)theBounds |
textColor:(NSColor *)theTextColor |
boxColor:(NSColor *)theBoxColor |
borderColor:(NSColor *)theBorderColor |
{ |
NSRect bounds = [self bounds]; |
NSPoint infoCoordinates = NSMakePoint(10.0f, bounds.size.height - 52.0f); |
mpLabelRenderer = [[OpenGLRendererLabel alloc] initLabelWithFontName:@"Helvetica" |
fontSize:12.0 |
textColor:theTextColor |
boxColor:theBoxColor |
borderColor:theBorderColor |
coordinates:&infoCoordinates |
bounds:theBounds]; |
} // initRendererLabel |
//--------------------------------------------------------------------------------------- |
- (void) initViewBoundsLabel:(const NSRect *)theBounds |
textColor:(NSColor *)theTextColor |
boxColor:(NSColor *)theBoxColor |
borderColor:(NSColor *)theBorderColor |
{ |
NSPoint infoCoordinates = NSMakePoint(10.0f, 10.0f); |
mpLabelViewBounds = [[OpenGLViewBoundsLabel alloc] initLabelWithFormat:nil |
fontName:@"Helvetica" |
fontSize:12.0 |
textColor:theTextColor |
boxColor:theBoxColor |
borderColor:theBorderColor |
coordinates:&infoCoordinates |
bounds:theBounds]; |
} // initViewBoundsLabel |
//--------------------------------------------------------------------------------------- |
- (void) initLabels:(const NSRect *)theBounds |
{ |
NSColor *textColor = [NSColor colorWithDeviceRed:1.0f |
green:1.0f |
blue:1.0f |
alpha:1.0f]; |
NSColor *boxColor = [NSColor colorWithDeviceRed:0.5f |
green:0.5f |
blue:0.5f |
alpha:0.5f]; |
NSColor *borderColor = [NSColor colorWithDeviceRed:0.8f |
green:0.8f |
blue:0.8f |
alpha:0.8f]; |
[self initPrefTimerLabel:theBounds |
textColor:textColor |
boxColor:boxColor |
borderColor:borderColor]; |
[self initRendererLabel:theBounds |
textColor:textColor |
boxColor:boxColor |
borderColor:borderColor]; |
[self initViewBoundsLabel:theBounds |
textColor:textColor |
boxColor:boxColor |
borderColor:borderColor]; |
} // initLabels |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Designated initializer |
//--------------------------------------------------------------------------------------- |
// |
// Create an OpenGL Context to use - i.e. init the animated view superclass |
// |
//--------------------------------------------------------------------------------------- |
- (id) initWithFrame:(NSRect)theFrame |
pixelFormat:(NSOpenGLPixelFormat *)thePixelFormat |
{ |
self = [super initWithFrame:theFrame |
pixelFormat:thePixelFormat]; |
if( self ) |
{ |
// Instantiate label objects for displaying |
// performance timer and view bounds |
[self initLabels:&theFrame]; |
mpSnapshot = nil; |
mpDirectory = nil; |
m_ViewFlags[kOpenGLViewResized] = NO; |
m_ViewFlags[kOpenGLViewStopRotation] = NO; |
m_ViewFlags[kOpenGLViewDisplayPrefTimer] = YES; |
m_ViewFlags[kOpenGLViewDisplayRenderer] = YES; |
m_ViewFlags[kOpenGLViewDisplayBounds] = YES; |
[self postOpenGLViewNotifications]; |
} // if |
return( self ); |
} // initWithFrame |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Deallocating Resources |
//--------------------------------------------------------------------------------------- |
- (void) releaseOpenGLViewSnapshot |
{ |
if( mpSnapshot ) |
{ |
[mpSnapshot release]; |
mpSnapshot = nil; |
} // if |
} // releaseOpenGLViewSnapshot |
//--------------------------------------------------------------------------------------- |
- (void) releaseOpenGLPrefTimerLabel |
{ |
if( mpLabelPrefTimer ) |
{ |
[mpLabelPrefTimer release]; |
mpLabelPrefTimer = nil; |
} // if |
} // releaseOpenGLPrefTimerLabel |
//--------------------------------------------------------------------------------------- |
- (void) releaseOpenGLRendererLabel |
{ |
if( mpLabelRenderer ) |
{ |
[mpLabelRenderer release]; |
mpLabelRenderer = nil; |
} // if |
} // releaseOpenGLRendererLabel |
//--------------------------------------------------------------------------------------- |
- (void) releaseOpenGLViewBoundsLabel |
{ |
if( mpLabelViewBounds ) |
{ |
[mpLabelViewBounds release]; |
mpLabelViewBounds = nil; |
} // if |
} // releaseOpenGLViewBoundsLabel |
//--------------------------------------------------------------------------------------- |
- (void) releaseMovieDirectoryPathname |
{ |
if( mpDirectory ) |
{ |
[mpDirectory release]; |
mpDirectory = nil; |
} // if |
} // releaseMovieDirectoryPathname |
//--------------------------------------------------------------------------------------- |
- (void) cleanUpOpenGLView |
{ |
// Release the renderer's label |
[self releaseOpenGLRendererLabel]; |
// Release the view bounds' label |
[self releaseOpenGLViewBoundsLabel]; |
// Release perf timer's label |
[self releaseOpenGLPrefTimerLabel]; |
// Release the view snapshot object |
[self releaseOpenGLViewSnapshot]; |
// Release the directory pathname string |
[self releaseMovieDirectoryPathname]; |
} // cleanUpOpenGLView |
//--------------------------------------------------------------------------------------- |
- (void) dealloc |
{ |
[self cleanUpOpenGLView]; |
// Dealloc the superclass |
[super dealloc]; |
} // dealloc |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Accessor |
//--------------------------------------------------------------------------------------- |
- (BOOL) viewResized |
{ |
return( m_ViewFlags[kOpenGLViewResized] ); |
} // viewResized |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Capturing from a View |
//--------------------------------------------------------------------------------------- |
- (void) viewSnapshot:(NSString *)theDocPath |
type:(NSNumber *)theDocFormat |
compression:(NSNumber *)theDocCompression |
title:(NSString *)theDocTitle |
author:(NSString *)theDocAuthor |
subject:(NSString *)theDocSubject |
creator:(NSString *)theDocCreator |
{ |
if( mpSnapshot == nil ) |
{ |
NSRect frame = [self bounds]; |
mpSnapshot = [[OpenGLViewSnapshot alloc] initViewSnapshotWithFrame:&frame |
view:self]; |
} // if |
[mpSnapshot setDocumentTitle:theDocTitle]; |
[mpSnapshot setDocumentAuthor:theDocAuthor]; |
[mpSnapshot setDocumentSubject:theDocSubject]; |
[mpSnapshot setDocumentCreator:theDocCreator]; |
if( theDocFormat ) |
{ |
[mpSnapshot setFormat:[theDocFormat unsignedIntValue]]; |
} // if |
if( theDocCompression ) |
{ |
[mpSnapshot setCompression:[theDocCompression floatValue]]; |
} // if |
[mpSnapshot saveAs:theDocPath]; |
} // viewSnapshot |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Showing/Hiding Labels |
//--------------------------------------------------------------------------------------- |
- (void) prefTimerDisplayLabel:(const BOOL)theDisplayFlag |
{ |
m_ViewFlags[kOpenGLViewDisplayPrefTimer] = theDisplayFlag; |
} // prefTimerLabelSetDisplay |
//--------------------------------------------------------------------------------------- |
- (void) rendererDisplayLabel:(const BOOL)theDisplayFlag |
{ |
m_ViewFlags[kOpenGLViewDisplayRenderer] = theDisplayFlag; |
} // rendererLabelSetDisplay |
//--------------------------------------------------------------------------------------- |
- (void) viewBoundsDisplayLabel:(const BOOL)theDisplayFlag |
{ |
m_ViewFlags[kOpenGLViewDisplayBounds] = theDisplayFlag; |
} // viewBoundsSetDisplay |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Preformance Timer Utilities |
//--------------------------------------------------------------------------------------- |
- (void) prefTimerEnable |
{ |
[mpLabelPrefTimer labelSetNeedsDisplay:YES]; |
} // prefTimerEnable |
//--------------------------------------------------------------------------------------- |
- (void) prefTimerDisable |
{ |
[mpLabelPrefTimer labelSetNeedsDisplay:NO]; |
} // prefTimerDisable |
//--------------------------------------------------------------------------------------- |
- (void) prefTimerMoveTo:(const NSPoint *)thePoint |
{ |
[mpLabelPrefTimer moveTo:thePoint]; |
} // prefTimerMoveTo |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark View Updates |
//--------------------------------------------------------------------------------------- |
// |
// Handles resizing of OpenGL view, if the window dimensions change, window dimensions |
// update, viewports reset, and projection matrix update. |
// |
//--------------------------------------------------------------------------------------- |
- (void) viewResize |
{ |
m_ViewFlags[kOpenGLViewResized] = [self viewUpdate]; |
if( m_ViewFlags[kOpenGLViewResized] ) |
{ |
// OpenGL text objects needs to know the view bounds |
// have changed as well. |
NSRect viewBounds = [self viewBounds]; |
// Get a new backing store for our view's snapshot |
[mpSnapshot setFrame:&viewBounds]; |
// Notify all labels that their bounds have changed |
[mpLabelViewBounds viewSetBounds:&viewBounds]; |
[mpLabelRenderer viewSetBounds:&viewBounds]; |
[mpLabelPrefTimer viewSetBounds:&viewBounds]; |
} // if |
} // viewResize |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Draw Utilities |
//--------------------------------------------------------------------------------------- |
- (void) drawBegin |
{ |
// Make the OpenGL context the current context |
[self contextMakeCurrent]; |
// Forces projection matrix update (does test for size changes) |
[self viewResize]; |
// Clear our drawable |
[self viewClear]; |
} // drawBegin |
//--------------------------------------------------------------------------------------- |
// |
// Display the view bounds label |
// |
//--------------------------------------------------------------------------------------- |
- (void) drawViewBoundsLabel |
{ |
if( m_ViewFlags[kOpenGLViewDisplayBounds] ) |
{ |
[mpLabelViewBounds labelDraw]; |
} // if |
} // drawViewBoundsLabel |
//--------------------------------------------------------------------------------------- |
// |
// Display the pref timer label |
// |
//--------------------------------------------------------------------------------------- |
- (void) drawPrefTimerLabel |
{ |
if( m_ViewFlags[kOpenGLViewDisplayPrefTimer] ) |
{ |
[mpLabelPrefTimer labelSetNeedsUpdate:[self rotation]]; |
[mpLabelPrefTimer labelDraw]; |
} // if |
} // drawPrefTimerLabel |
//--------------------------------------------------------------------------------------- |
// |
// Display the renderer label |
// |
//--------------------------------------------------------------------------------------- |
- (void) drawRendererLabel |
{ |
if( m_ViewFlags[kOpenGLViewDisplayRenderer] ) |
{ |
[mpLabelRenderer labelDraw]; |
} // if |
} // drawRendererLabel |
//--------------------------------------------------------------------------------------- |
- (void) drawEnd |
{ |
// Take a snapshot of the view |
[mpSnapshot snapshot]; |
// Draw the view bounds |
[self drawViewBoundsLabel]; |
// Draw the pref timer |
[self drawPrefTimerLabel]; |
// Draw the renderer's info |
[self drawRendererLabel]; |
// Flush the current context |
[self contextFlushBuffer]; |
} // drawEnd |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Notification |
//--------------------------------------------------------------------------------------- |
// |
// It's important to clean up our rendering objects before we terminate -- Cocoa will |
// not specifically release everything on application termination, so we explicitly |
// call our clean up routine ourselves. |
// |
//--------------------------------------------------------------------------------------- |
- (void) viewWillTerminate:(NSNotification *)notification |
{ |
[self cleanUpOpenGLView]; |
} // viewWillTerminate |
//--------------------------------------------------------------------------------------- |
// |
// When flushing media author queue one needs to stop object rotation. |
// |
//--------------------------------------------------------------------------------------- |
- (void) suspendObjectRotation:(NSNotification *)notification |
{ |
if( !m_ViewFlags[kOpenGLViewStopRotation] ) |
{ |
[self rotationStop]; |
m_ViewFlags[kOpenGLViewStopRotation] = YES; |
} // if |
} // suspendObjectRotation |
//--------------------------------------------------------------------------------------- |
// |
// When media sample authoring is restarted, one needs to restart object rotation. |
// |
//--------------------------------------------------------------------------------------- |
- (void) resumeObjectRotation:(NSNotification *)notification |
{ |
if( m_ViewFlags[kOpenGLViewStopRotation] ) |
{ |
[self rotationStart]; |
m_ViewFlags[kOpenGLViewStopRotation] = NO; |
} // if |
} // resumeObjectRotation |
//--------------------------------------------------------------------------------------- |
@end |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
Copyright © 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-01-02