]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CNSOGLManager.mm
Unify & improve log messages
[irrlicht.git] / source / Irrlicht / CNSOGLManager.mm
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
4 \r
5 #include "CNSOGLManager.h"\r
6 \r
7 #ifdef _IRR_COMPILE_WITH_NSOGL_MANAGER_\r
8 \r
9 #include <mach-o/dyld.h>\r
10 #include "os.h"\r
11 \r
12 namespace irr\r
13 {\r
14 namespace video\r
15 {\r
16 \r
17 CNSOGLManager::CNSOGLManager()\r
18         : PrimaryContext(SExposedVideoData(0)), PixelFormat(nil)\r
19 {\r
20 #ifdef _DEBUG\r
21         setDebugName("CNSOGLManager");\r
22 #endif\r
23 }\r
24 \r
25 CNSOGLManager::~CNSOGLManager()\r
26 {\r
27 }\r
28 \r
29 bool CNSOGLManager::initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& videodata)\r
30 {\r
31         Params = params;\r
32 \r
33     return true;\r
34 }\r
35 \r
36 void CNSOGLManager::terminate()\r
37 {\r
38 }\r
39 \r
40 bool CNSOGLManager::generateSurface()\r
41 {\r
42         if (Params.DriverType == video::EDT_OPENGL)\r
43         {\r
44         int alphaSize = Params.WithAlphaChannel ? 4 : 0;\r
45         int depthSize = Params.ZBufferBits;\r
46 \r
47         if (Params.WithAlphaChannel && Params.Bits == 32)\r
48             alphaSize = 8;\r
49 \r
50         NSOpenGLPixelFormatAttribute Attribs[] =\r
51         {\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
62             0\r
63         };\r
64 \r
65         u32 Steps = 6;\r
66 \r
67         // Choose the best pixel format.\r
68         do\r
69         {\r
70             switch (Steps)\r
71             {\r
72             case 6: // decrease step.\r
73                 --Steps;\r
74                 break;\r
75             case 5: // samples\r
76                 if (Attribs[12] > 2)\r
77                     --Attribs[12];\r
78                 else\r
79                 {\r
80                     Attribs[10] = 0;\r
81                     Attribs[12] = 0;\r
82                     --Steps;\r
83                 }\r
84                 break;\r
85             case 4: // alpha\r
86                 if (Attribs[8])\r
87                 {\r
88                     Attribs[8] = 0;\r
89 \r
90                     if (Params.AntiAlias)\r
91                     {\r
92                         Attribs[10] = 1;\r
93                         Attribs[12] = Params.AntiAlias;\r
94                         Steps = 5;\r
95                     }\r
96                 }\r
97                 else\r
98                     --Steps;\r
99                 break;\r
100             case 3: // stencil\r
101                 if (Attribs[14])\r
102                 {\r
103                     Attribs[14] = 0;\r
104 \r
105                     if (Params.AntiAlias)\r
106                     {\r
107                         Attribs[10] = 1;\r
108                         Attribs[12] = Params.AntiAlias;\r
109                         Steps = 5;\r
110                     }\r
111                 }\r
112                 else\r
113                     --Steps;\r
114                 break;\r
115             case 2: // depth size\r
116                 if (Attribs[4] > 16)\r
117                 {\r
118                     Attribs[4] = Attribs[4] - 8;\r
119                 }\r
120                 else\r
121                     --Steps;\r
122                 break;\r
123             case 1: // buffer size\r
124                 if (Attribs[6] > 16)\r
125                 {\r
126                     Attribs[6] = Attribs[6] - 8;\r
127                 }\r
128                 else\r
129                     --Steps;\r
130                 break;\r
131             default:\r
132                 os::Printer::log("Could not get pixel format.");\r
133                 return false;\r
134             }\r
135 \r
136             PixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:Attribs];\r
137         }\r
138         while (PixelFormat == nil);\r
139 \r
140         if (Params.AntiAlias && !Attribs[10])\r
141             os::Printer::log("No multisampling.");\r
142 \r
143         if (Params.WithAlphaChannel && !Attribs[8])\r
144             os::Printer::log("No alpha.");\r
145 \r
146         if (Params.Stencilbuffer && !Attribs[14])\r
147             os::Printer::log("No stencil buffer.");\r
148 \r
149         if (Params.ZBufferBits > Attribs[4])\r
150             os::Printer::log("No full depth buffer.");\r
151 \r
152         if (Params.Bits > Attribs[6])\r
153             os::Printer::log("No full color buffer.");\r
154         }\r
155 \r
156     return true;\r
157 }\r
158 \r
159 void CNSOGLManager::destroySurface()\r
160 {\r
161     [PixelFormat release];\r
162     PixelFormat = nil;\r
163 }\r
164 \r
165 bool CNSOGLManager::generateContext()\r
166 {\r
167     NSOpenGLContext* Context = [[NSOpenGLContext alloc] initWithFormat:PixelFormat shareContext:nil];\r
168 \r
169     GLint Vsync = Params.Vsync ? 1 : 0;\r
170     [Context setValues:&Vsync forParameter:NSOpenGLCPSwapInterval];\r
171 \r
172         if (Context == nil)\r
173         {\r
174                 os::Printer::log("Could not create OpenGL context.", ELL_ERROR);\r
175                 return false;\r
176         }\r
177 \r
178         // set exposed data\r
179         CurrentContext.OpenGLOSX.Context = Context;\r
180 \r
181         if (!PrimaryContext.OpenGLOSX.Context)\r
182                 PrimaryContext.OpenGLOSX.Context = CurrentContext.OpenGLOSX.Context;\r
183 \r
184         return true;\r
185 }\r
186 \r
187 const SExposedVideoData& CNSOGLManager::getContext() const\r
188 {\r
189         return CurrentContext;\r
190 }\r
191 \r
192 bool CNSOGLManager::activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero)\r
193 {\r
194         //TODO: handle restorePrimaryOnZero\r
195     if (videoData.OpenGLOSX.Context)\r
196     {\r
197         if ((NSOpenGLContext*)videoData.OpenGLOSX.Context != [NSOpenGLContext currentContext])\r
198         {\r
199             [(NSOpenGLContext*)videoData.OpenGLOSX.Context makeCurrentContext];\r
200 \r
201             CurrentContext = videoData;\r
202         }\r
203     }\r
204     // set back to main context\r
205     else\r
206     {\r
207         if ((NSOpenGLContext*)PrimaryContext.OpenGLOSX.Context != [NSOpenGLContext currentContext])\r
208         {\r
209             [(NSOpenGLContext*)PrimaryContext.OpenGLOSX.Context makeCurrentContext];\r
210 \r
211             CurrentContext = PrimaryContext;\r
212         }\r
213     }\r
214 \r
215         return true;\r
216 }\r
217 \r
218 void CNSOGLManager::destroyContext()\r
219 {\r
220         if (CurrentContext.OpenGLOSX.Context)\r
221         {\r
222         if (PrimaryContext.OpenGLOSX.Context == CurrentContext.OpenGLOSX.Context)\r
223             PrimaryContext.OpenGLOSX.Context = nil;\r
224 \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
229 \r
230                 CurrentContext.OpenGLOSX.Context = nil;\r
231         }\r
232 }\r
233 \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
237 {\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
244 }\r
245 \r
246 bool CNSOGLManager::swapBuffers()\r
247 {\r
248     [(NSOpenGLContext*)CurrentContext.OpenGLOSX.Context flushBuffer];\r
249 \r
250         return true;\r
251 }\r
252 \r
253 }\r
254 }\r
255 \r
256 #endif\r