1 /*
2  -----------------------------------------------------------------------------
3  This source file is part of OGRE
4  (Object-oriented Graphics Rendering Engine)
5  For the latest info, see http://www.ogre3d.org/
6 
7  Copyright (c) 2000-2013 Torus Knot Software Ltd
8 
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25  THE SOFTWARE.
26  -----------------------------------------------------------------------------
27  */
28 
29 #ifndef __SampleBrowser_iOS_H__
30 #define __SampleBrowser_iOS_H__
31 
32 #include "OgrePlatform.h"
33 
34 #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS
35 #error This header is for use with iOS only
36 #endif
37 
38 #import <UIKit/UIKit.h>
39 #import <QuartzCore/QuartzCore.h>
40 #import "SampleBrowser.h"
41 
42 #ifdef __OBJC__
43 
44 @interface AppDelegate : NSObject <UIApplicationDelegate>
45 {
46     OgreBites::SampleBrowser sb;
47 
48     CADisplayLink *mDisplayLink;
49     NSDate* mDate;
50     NSTimeInterval mLastFrameTime;
51 }
52 
53 - (void)go;
54 - (void)renderOneFrame:(id)sender;
55 
56 @property (nonatomic) NSTimeInterval mLastFrameTime;
57 
58 @end
59 
60 @implementation AppDelegate
61 
62 @dynamic mLastFrameTime;
63 
64 - (NSTimeInterval)mLastFrameTime
65 {
66     return mLastFrameTime;
67 }
68 
69 - (void)setLastFrameTime:(NSTimeInterval)frameInterval
70 {
71     // Frame interval defines how many display frames must pass between each time the
72     // display link fires. The display link will only fire 30 times a second when the
73     // frame internal is two on a display that refreshes 60 times a second. The default
74     // frame interval setting of one will fire 60 times a second when the display refreshes
75     // at 60 times a second. A frame interval setting of less than one results in undefined
76     // behavior.
77     if (frameInterval >= 1)
78     {
79         mLastFrameTime = frameInterval;
80     }
81 }
82 
83 - (void)go {
84 
85     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
86 
87     try {
88         sb.go();
89 
90         Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets();
91 
92         // Clear event times
93 		Ogre::Root::getSingleton().clearEventTimes();
catch(Ogre::Exception & e)94     } catch( Ogre::Exception& e ) {
95         std::cerr << "An exception has occurred: " <<
96         e.getFullDescription().c_str() << std::endl;
97     }
98 
99     [pool release];
100 }
101 
102 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
103 {
104     // Defaulting to 2 means that we run at 30 frames per second. For 60 frames, use a value of 1.
105     // 30 FPS is usually sufficient and results in lower power consumption.
106     mLastFrameTime = 2;
107     mDisplayLink = nil;
108 
109     [self go];
110 
111     return YES;
112 }
113 
114 - (void)applicationWillTerminate:(UIApplication *)application
115 {
116     sb.shutdown();
117 }
118 
119 - (void)applicationDidBecomeActive:(UIApplication *)application
120 {
121     // Reset event times and reallocate the date and displaylink objects
122     Ogre::Root::getSingleton().clearEventTimes();
123     mDate = [[NSDate alloc] init];
124     mLastFrameTime = 2; // Reset the timer
125 
126     mDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(renderOneFrame:)];
127     [mDisplayLink setFrameInterval:mLastFrameTime];
128     [mDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
129 }
130 
131 - (void)applicationWillResignActive:(UIApplication *)application
132 {
133     Ogre::Root::getSingleton().saveConfig();
134 
135     [mDate release];
136     mDate = nil;
137 
138     [mDisplayLink invalidate];
139     mDisplayLink = nil;
140 }
141 
142 - (void)renderOneFrame:(id)sender
143 {
144     [sb.mGestureView becomeFirstResponder];
145 
146     // NSTimeInterval is a simple typedef for double
147     NSTimeInterval currentFrameTime = -[mDate timeIntervalSinceNow];
148     NSTimeInterval differenceInSeconds = currentFrameTime - mLastFrameTime;
149     mLastFrameTime = currentFrameTime;
150 
151     dispatch_async(dispatch_get_main_queue(), ^(void)
152     {
153         Root::getSingleton().renderOneFrame((Real)differenceInSeconds);
154     });
155 }
156 
157 @end
158 
159 #endif
160 
161 #endif
162