1 // Copyright (C) 2014 Patryk Nadrowski
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in Irrlicht.h
\r
5 #include "CNSOGLManager.h"
\r
7 #ifdef _IRR_COMPILE_WITH_NSOGL_MANAGER_
\r
9 #include <mach-o/dyld.h>
\r
17 CNSOGLManager::CNSOGLManager()
\r
18 : PrimaryContext(SExposedVideoData(0)), PixelFormat(nil)
\r
21 setDebugName("CNSOGLManager");
\r
25 CNSOGLManager::~CNSOGLManager()
\r
29 bool CNSOGLManager::initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata)
\r
36 void CNSOGLManager::terminate()
\r
40 bool CNSOGLManager::generateSurface()
\r
42 if (Params.DriverType == video::EDT_OPENGL)
\r
44 int alphaSize = Params.WithAlphaChannel ? 4 : 0;
\r
45 int depthSize = Params.ZBufferBits;
\r
47 if (Params.WithAlphaChannel && Params.Bits == 32)
\r
50 NSOpenGLPixelFormatAttribute Attribs[] =
\r
52 NSOpenGLPFANoRecovery,
\r
53 NSOpenGLPFAAccelerated,
\r
54 NSOpenGLPFADoubleBuffer,
\r
55 NSOpenGLPFADepthSize, static_cast<NSOpenGLPixelFormatAttribute>(depthSize),
\r
56 NSOpenGLPFAColorSize, Params.Bits,
\r
57 NSOpenGLPFAAlphaSize, static_cast<NSOpenGLPixelFormatAttribute>(alphaSize),
\r
58 NSOpenGLPFASampleBuffers, 1,
\r
59 NSOpenGLPFASamples, Params.AntiAlias,
\r
60 NSOpenGLPFAStencilSize, static_cast<NSOpenGLPixelFormatAttribute>(Params.Stencilbuffer ? 1 : 0),
\r
61 //NSOpenGLPFAFullScreen,
\r
67 // Choose the best pixel format.
\r
72 case 6: // decrease step.
\r
76 if (Attribs[12] > 2)
\r
90 if (Params.AntiAlias)
\r
93 Attribs[12] = Params.AntiAlias;
\r
105 if (Params.AntiAlias)
\r
108 Attribs[12] = Params.AntiAlias;
\r
115 case 2: // depth size
\r
116 if (Attribs[4] > 16)
\r
118 Attribs[4] = Attribs[4] - 8;
\r
123 case 1: // buffer size
\r
124 if (Attribs[6] > 16)
\r
126 Attribs[6] = Attribs[6] - 8;
\r
132 os::Printer::log("Could not get pixel format.");
\r
136 PixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:Attribs];
\r
138 while (PixelFormat == nil);
\r
140 if (Params.AntiAlias && !Attribs[10])
\r
141 os::Printer::log("No multisampling.");
\r
143 if (Params.WithAlphaChannel && !Attribs[8])
\r
144 os::Printer::log("No alpha.");
\r
146 if (Params.Stencilbuffer && !Attribs[14])
\r
147 os::Printer::log("No stencil buffer.");
\r
149 if (Params.ZBufferBits > Attribs[4])
\r
150 os::Printer::log("No full depth buffer.");
\r
152 if (Params.Bits > Attribs[6])
\r
153 os::Printer::log("No full color buffer.");
\r
159 void CNSOGLManager::destroySurface()
\r
161 [PixelFormat release];
\r
165 bool CNSOGLManager::generateContext()
\r
167 NSOpenGLContext* Context = [[NSOpenGLContext alloc] initWithFormat:PixelFormat shareContext:nil];
\r
169 GLint Vsync = Params.Vsync ? 1 : 0;
\r
170 [Context setValues:&Vsync forParameter:NSOpenGLCPSwapInterval];
\r
172 if (Context == nil)
\r
174 os::Printer::log("Could not create OpenGL context.", ELL_ERROR);
\r
178 // set exposed data
\r
179 CurrentContext.OpenGLOSX.Context = Context;
\r
181 if (!PrimaryContext.OpenGLOSX.Context)
\r
182 PrimaryContext.OpenGLOSX.Context = CurrentContext.OpenGLOSX.Context;
\r
187 const SExposedVideoData& CNSOGLManager::getContext() const
\r
189 return CurrentContext;
\r
192 bool CNSOGLManager::activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero)
\r
194 //TODO: handle restorePrimaryOnZero
\r
195 if (videoData.OpenGLOSX.Context)
\r
197 if ((NSOpenGLContext*)videoData.OpenGLOSX.Context != [NSOpenGLContext currentContext])
\r
199 [(NSOpenGLContext*)videoData.OpenGLOSX.Context makeCurrentContext];
\r
201 CurrentContext = videoData;
\r
204 // set back to main context
\r
207 if ((NSOpenGLContext*)PrimaryContext.OpenGLOSX.Context != [NSOpenGLContext currentContext])
\r
209 [(NSOpenGLContext*)PrimaryContext.OpenGLOSX.Context makeCurrentContext];
\r
211 CurrentContext = PrimaryContext;
\r
218 void CNSOGLManager::destroyContext()
\r
220 if (CurrentContext.OpenGLOSX.Context)
\r
222 if (PrimaryContext.OpenGLOSX.Context == CurrentContext.OpenGLOSX.Context)
\r
223 PrimaryContext.OpenGLOSX.Context = nil;
\r
225 [(NSOpenGLContext*)CurrentContext.OpenGLOSX.Context makeCurrentContext];
\r
226 [(NSOpenGLContext *)CurrentContext.OpenGLOSX.Context clearDrawable];
\r
227 [(NSOpenGLContext *)CurrentContext.OpenGLOSX.Context release];
\r
228 [NSOpenGLContext clearCurrentContext];
\r
230 CurrentContext.OpenGLOSX.Context = nil;
\r
234 // It appears that there is no separate GL proc address getter on OSX.
\r
235 // https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_entrypts/opengl_entrypts.html
\r
236 void* CNSOGLManager::getProcAddress(const std::string &procName)
\r
238 NSSymbol symbol = NULL;
\r
239 // Allocate a buffer for the name, an underscore prefix, and a cstring terminator.
\r
240 std::string mangledName = "_" + procName;
\r
241 if (NSIsSymbolNameDefined(mangledName.c_str()))
\r
242 symbol = NSLookupAndBindSymbol(mangledName.c_str());
\r
243 return symbol ? NSAddressOfSymbol(symbol) : NULL;
\r
246 bool CNSOGLManager::swapBuffers()
\r
248 [(NSOpenGLContext*)CurrentContext.OpenGLOSX.Context flushBuffer];
\r