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-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 |
|
---|
26 | #include "OgreOSXCocoaWindow.h"
|
---|
27 | #include "OgreRoot.h"
|
---|
28 | #include "OgreRenderSystem.h"
|
---|
29 | #include "OgreImageCodec.h"
|
---|
30 | #include "OgreException.h"
|
---|
31 | #include "OgreLogManager.h"
|
---|
32 | #include "OgreStringConverter.h"
|
---|
33 |
|
---|
34 | #include "OgreGLRenderSystem.h"
|
---|
35 | #include "OgreOSXCocoaContext.h"
|
---|
36 | #include "OgreOSXCGLContext.h"
|
---|
37 |
|
---|
38 | #include <OpenGL/gl.h>
|
---|
39 | #define GL_EXT_texture_env_combine 1
|
---|
40 | #include <OpenGL/glext.h>
|
---|
41 | #include <OpenGL/glu.h>
|
---|
42 |
|
---|
43 | namespace Ogre {
|
---|
44 |
|
---|
45 | OSXCocoaWindow::OSXCocoaWindow()
|
---|
46 | {
|
---|
47 | mActive = false;
|
---|
48 | mContext = 0;
|
---|
49 | mWindow = 0;
|
---|
50 | }
|
---|
51 |
|
---|
52 | OSXCocoaWindow::~OSXCocoaWindow()
|
---|
53 | {
|
---|
54 | [glContext clearDrawable];
|
---|
55 | CGReleaseAllDisplays();
|
---|
56 | //[mWindow close];
|
---|
57 | //[mWindow release];
|
---|
58 | }
|
---|
59 |
|
---|
60 | void OSXCocoaWindow::create(const String& name, unsigned int width, unsigned int height,
|
---|
61 | bool fullScreen, const NameValuePairList *miscParams)
|
---|
62 | {
|
---|
63 | NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
|
---|
64 | NSApplicationLoad();
|
---|
65 | //OgreWindowDelegate *delegate = [[OgreWindowDelegate alloc] initWithGLOSXCocoaWindow:this];
|
---|
66 | //[window setDelegate:delegate];
|
---|
67 | /*
|
---|
68 | ***Key: "title" Description: The title of the window that will appear in the title bar Values: string Default: RenderTarget name
|
---|
69 |
|
---|
70 | Key: "colourDepth" Description: Colour depth of the resulting rendering window; only applies if fullScreen is set. Values: 16 or 32 Default: desktop depth Notes: [W32 specific]
|
---|
71 |
|
---|
72 | ***Key: "left" Description: screen x coordinate from left Values: positive integers Default: 'center window on screen' Notes: Ignored in case of full screen
|
---|
73 |
|
---|
74 | ***Key: "top" Description: screen y coordinate from top Values: positive integers Default: 'center window on screen' Notes: Ignored in case of full screen
|
---|
75 |
|
---|
76 | ***Key: "depthBuffer" [DX9 specific] Description: Use depth buffer Values: false or true Default: true
|
---|
77 |
|
---|
78 | ***Key: "externalWindowHandle" [API specific] Description: External window handle, for embedding the OGRE context Values: positive integer for W32 (HWND handle) poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*) for GLX Default: 0 (None)
|
---|
79 |
|
---|
80 | ***Key: "FSAA" Description: Full screen antialiasing factor Values: 0,2,4,6,... Default: 0
|
---|
81 |
|
---|
82 | Key: "displayFrequency" Description: Display frequency rate, for fullscreen mode Values: 60...? Default: Desktop vsync rate
|
---|
83 |
|
---|
84 | Key: "vsync" Description: Synchronize buffer swaps to vsync Values: true, false Default: 0
|
---|
85 | */
|
---|
86 |
|
---|
87 | BOOL hasDepthBuffer = YES;
|
---|
88 | int fsaa_samples = 0;
|
---|
89 | NSString *windowTitle = [NSString stringWithCString:name.c_str()];
|
---|
90 | int winx = 0, winy = 0;
|
---|
91 | int depth = 32;
|
---|
92 |
|
---|
93 | if(miscParams)
|
---|
94 | {
|
---|
95 | NameValuePairList::const_iterator opt = 0;
|
---|
96 |
|
---|
97 | opt = miscParams->find("title");
|
---|
98 | if(opt != miscParams->end())
|
---|
99 | windowTitle = [NSString stringWithCString:opt->second.c_str()];
|
---|
100 |
|
---|
101 | opt = miscParams->find("left");
|
---|
102 | if(opt != miscParams->end())
|
---|
103 | winx = StringConverter::parseUnsignedInt(opt->second);
|
---|
104 |
|
---|
105 | opt = miscParams->find("top");
|
---|
106 | if(opt != miscParams->end())
|
---|
107 | winy = NSHeight([[NSScreen mainScreen] frame]) - StringConverter::parseUnsignedInt(opt->second) - height;
|
---|
108 |
|
---|
109 |
|
---|
110 | opt = miscParams->find("depthBuffer");
|
---|
111 | if(opt != miscParams->end())
|
---|
112 | hasDepthBuffer = StringConverter::parseBool(opt->second);
|
---|
113 |
|
---|
114 | opt = miscParams->find("FSAA");
|
---|
115 | if(opt != miscParams->end())
|
---|
116 | fsaa_samples = StringConverter::parseUnsignedInt(opt->second);
|
---|
117 |
|
---|
118 | opt = miscParams->find( "colourDepth" );
|
---|
119 | if( opt != miscParams->end() )
|
---|
120 | depth = StringConverter::parseUnsignedInt( opt->second );
|
---|
121 | }
|
---|
122 |
|
---|
123 |
|
---|
124 | NSOpenGLPixelFormat* openglFormat;
|
---|
125 | {
|
---|
126 | NSOpenGLPixelFormatAttribute attribs[30];
|
---|
127 | int i=0;
|
---|
128 |
|
---|
129 | if(fullScreen)
|
---|
130 | {
|
---|
131 | GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem());
|
---|
132 | OSXContext *mainContext = (OSXContext*)rs->_getMainContext();
|
---|
133 |
|
---|
134 | CGLContextObj share = NULL;
|
---|
135 | if(mainContext == 0)
|
---|
136 | {
|
---|
137 | share = NULL;
|
---|
138 | }
|
---|
139 | else if(mainContext->getContextType() == "NSOpenGL")
|
---|
140 | {
|
---|
141 | OSXCocoaContext* cocoaContext = static_cast<OSXCocoaContext*>(mainContext);
|
---|
142 | NSOpenGLContext* nsShare = cocoaContext->getContext();
|
---|
143 | share = (CGLContextObj)[nsShare CGLContextObj];
|
---|
144 | }
|
---|
145 | else if(mainContext->getContextType() == "CGL")
|
---|
146 | {
|
---|
147 | OSXCGLContext* cglShare = static_cast<OSXCGLContext*>(mainContext);
|
---|
148 | share = cglShare->getContext();
|
---|
149 | }
|
---|
150 |
|
---|
151 | // create the context
|
---|
152 | createCGLFullscreen(width, height, depth, fsaa_samples, share);
|
---|
153 | }
|
---|
154 | else
|
---|
155 | {
|
---|
156 | // Specifying "NoRecovery" gives us a context that cannot fall back to the software renderer. This makes the View-based context a compatible with the fullscreen context, enabling us to use the "shareContext" feature to share textures, display lists, and other OpenGL objects between the two.
|
---|
157 | attribs[i++] = NSOpenGLPFANoRecovery;
|
---|
158 |
|
---|
159 | attribs[i++] = NSOpenGLPFAAccelerated;
|
---|
160 | attribs[i++] = NSOpenGLPFADoubleBuffer;
|
---|
161 |
|
---|
162 | attribs[i++] = NSOpenGLPFAAlphaSize;
|
---|
163 | attribs[i++] = (NSOpenGLPixelFormatAttribute) 0;
|
---|
164 |
|
---|
165 | attribs[i++] = NSOpenGLPFAStencilSize;
|
---|
166 | attribs[i++] = (NSOpenGLPixelFormatAttribute) 1;
|
---|
167 |
|
---|
168 | attribs[i++] = NSOpenGLPFAAccumSize;
|
---|
169 | attribs[i++] = (NSOpenGLPixelFormatAttribute) 0;
|
---|
170 |
|
---|
171 | attribs[i++] = NSOpenGLPFADepthSize;
|
---|
172 | attribs[i++] = (NSOpenGLPixelFormatAttribute) (hasDepthBuffer? 16 : 0);
|
---|
173 |
|
---|
174 | if(fsaa_samples > 0)
|
---|
175 | {
|
---|
176 | attribs[i++] = NSOpenGLPFASampleBuffers;
|
---|
177 | attribs[i++] = (NSOpenGLPixelFormatAttribute) 1;
|
---|
178 |
|
---|
179 | attribs[i++] = NSOpenGLPFASamples;
|
---|
180 | attribs[i++] = (NSOpenGLPixelFormatAttribute) fsaa_samples;
|
---|
181 | }
|
---|
182 |
|
---|
183 | attribs[i++] = (NSOpenGLPixelFormatAttribute) 0;
|
---|
184 |
|
---|
185 | openglFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: attribs] autorelease];
|
---|
186 | }
|
---|
187 |
|
---|
188 | NameValuePairList::const_iterator opt2 = 0;
|
---|
189 | if(miscParams)
|
---|
190 | {
|
---|
191 | opt2 = miscParams->find("pixelFormat");
|
---|
192 | if(opt2 != miscParams->end())
|
---|
193 | openglFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*)StringConverter::parseUnsignedLong(opt2->second)] autorelease];
|
---|
194 | }
|
---|
195 | GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem());
|
---|
196 | OSXCocoaContext *mainContext = (OSXCocoaContext*)rs->_getMainContext();
|
---|
197 | NSOpenGLContext *shareContext = mainContext == 0? nil : mainContext->getContext();
|
---|
198 |
|
---|
199 | glContext = [[NSOpenGLContext alloc] initWithFormat: openglFormat shareContext:shareContext];
|
---|
200 |
|
---|
201 | NameValuePairList::const_iterator opt = 0;
|
---|
202 | if(miscParams)
|
---|
203 | opt = miscParams->find("externalWindowHandle");
|
---|
204 | if(!miscParams || opt == miscParams->end())
|
---|
205 | {
|
---|
206 | //Not sure why this should be but it is required for the window to work at fullscreen.
|
---|
207 | int styleMask = fullScreen? NSBorderlessWindowMask : NSResizableWindowMask;
|
---|
208 |
|
---|
209 | mWindow = [[OgreWindow alloc] initWithContentRect:NSMakeRect(winx, winy, width, height) styleMask:styleMask backing:NSBackingStoreBuffered defer:NO];
|
---|
210 | [mWindow setTitle:windowTitle];
|
---|
211 |
|
---|
212 | if(winx == 0 && winy == 0) [mWindow center];
|
---|
213 |
|
---|
214 | mView = [[OgreView alloc] initWithGLOSXWindow:this];
|
---|
215 | [mWindow setContentView:mView];
|
---|
216 | }
|
---|
217 | else
|
---|
218 | {
|
---|
219 | mView = (OgreView*)StringConverter::parseUnsignedLong(opt->second);
|
---|
220 | [mView setOgreWindow:this];
|
---|
221 |
|
---|
222 | NSRect b = [mView bounds];
|
---|
223 | width = b.size.width;
|
---|
224 | height = b.size.height;
|
---|
225 | }
|
---|
226 |
|
---|
227 | [glContext setView:mView];
|
---|
228 |
|
---|
229 | mName = name;
|
---|
230 | mWidth = width;
|
---|
231 | mHeight = height;
|
---|
232 |
|
---|
233 | // Create register the context with the rendersystem and associate it with this window
|
---|
234 | mContext = new OSXCocoaContext(glContext);
|
---|
235 | /*rs->_registerContext(this, newContext);
|
---|
236 |
|
---|
237 | if (rs->_getMainContext() == 0)
|
---|
238 | [glContext makeCurrentContext];
|
---|
239 | */
|
---|
240 | //show window
|
---|
241 | if(mWindow)
|
---|
242 | [mWindow performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:NULL waitUntilDone:NO];
|
---|
243 |
|
---|
244 | [arp release];
|
---|
245 | }
|
---|
246 |
|
---|
247 | // make active
|
---|
248 | mActive = true;
|
---|
249 | }
|
---|
250 |
|
---|
251 | void OSXCocoaWindow::destroy(void)
|
---|
252 | {
|
---|
253 | if(mIsFullScreen)
|
---|
254 | destroyCGLFullscreen();
|
---|
255 |
|
---|
256 | // Unregister and destroy OGRE GLContext
|
---|
257 | delete mContext;
|
---|
258 |
|
---|
259 | if(mWindow) [mWindow close];
|
---|
260 |
|
---|
261 | mActive = false;
|
---|
262 |
|
---|
263 | Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() );
|
---|
264 | }
|
---|
265 |
|
---|
266 | /*OgreView* OSXCocoaWindow::ogreView() const
|
---|
267 | {
|
---|
268 | return [window contentView];
|
---|
269 | }*/
|
---|
270 |
|
---|
271 | bool OSXCocoaWindow::isActive() const
|
---|
272 | {
|
---|
273 | return mActive;
|
---|
274 | }
|
---|
275 |
|
---|
276 | bool OSXCocoaWindow::isClosed() const
|
---|
277 | {
|
---|
278 | return false;
|
---|
279 | }
|
---|
280 |
|
---|
281 | void OSXCocoaWindow::reposition(int left, int top)
|
---|
282 | {
|
---|
283 | if(!mWindow) return;
|
---|
284 |
|
---|
285 | NSRect frame = [mWindow frame];
|
---|
286 | frame.origin.x = left;
|
---|
287 | frame.origin.y = top-frame.size.height;
|
---|
288 | [mWindow setFrame:frame display:YES];
|
---|
289 | }
|
---|
290 |
|
---|
291 | void OSXCocoaWindow::resize(unsigned int width, unsigned int height)
|
---|
292 | {
|
---|
293 | if(!mWindow) return;
|
---|
294 |
|
---|
295 | NSRect frame = [mWindow frame];
|
---|
296 | frame.size.width = width;
|
---|
297 | frame.size.height = height;
|
---|
298 | [mWindow setFrame:frame display:YES];
|
---|
299 | /*SHOULD be called from delegate
|
---|
300 | for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it)
|
---|
301 | {
|
---|
302 | (*it).second->_updateDimensions();
|
---|
303 | }*/
|
---|
304 | }
|
---|
305 |
|
---|
306 | void OSXCocoaWindow::windowMovedOrResized()
|
---|
307 | {
|
---|
308 | [glContext update];
|
---|
309 | NSRect frame = [mView frame];
|
---|
310 | mWidth = (unsigned int)frame.size.width;
|
---|
311 | mHeight = (unsigned int)frame.size.height;
|
---|
312 | mLeft = (int)frame.origin.x;
|
---|
313 | mTop = (int)frame.origin.y+(unsigned int)frame.size.height;
|
---|
314 |
|
---|
315 | for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it)
|
---|
316 | {
|
---|
317 | (*it).second->_updateDimensions();
|
---|
318 | }
|
---|
319 | }
|
---|
320 |
|
---|
321 | void OSXCocoaWindow::swapBuffers(bool waitForVSync)
|
---|
322 | {
|
---|
323 | if(!mIsFullScreen)
|
---|
324 | [glContext flushBuffer];
|
---|
325 | else
|
---|
326 | swapCGLBuffers();
|
---|
327 |
|
---|
328 | /*if(![[[NSRunLoop currentRunLoop] currentMode] isEqualTo:NSEventTrackingRunLoopMode])
|
---|
329 | {
|
---|
330 | NSEvent *e = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
|
---|
331 | if(e)
|
---|
332 | [NSApp sendEvent:e];
|
---|
333 | }*/
|
---|
334 | }
|
---|
335 |
|
---|
336 | //-------------------------------------------------------------------------------------------------//
|
---|
337 | void OSXCocoaWindow::getCustomAttribute( const String& name, void* pData )
|
---|
338 | {
|
---|
339 | if( name == "GLCONTEXT" )
|
---|
340 | {
|
---|
341 | *static_cast<OSXContext**>(pData) = mContext;
|
---|
342 | return;
|
---|
343 | }
|
---|
344 | }
|
---|
345 | }
|
---|