]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/clouds3d/SkyContext.cpp
Clouds3D crashes because there is no Light
[simgear.git] / simgear / scene / sky / clouds3d / SkyContext.cpp
1 //------------------------------------------------------------------------------
2 // File : SkyContext.cpp
3 //------------------------------------------------------------------------------
4 // SkyWorks : Copyright 2002 Mark J. Harris and
5 //                                              The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its 
8 // documentation for any purpose is hereby granted without fee, provided that 
9 // the above copyright notice appear in all copies and that both that copyright 
10 // notice and this permission notice appear in supporting documentation. 
11 // Binaries may be compiled with this software without any royalties or 
12 // restrictions. 
13 //
14 // The author(s) and The University of North Carolina at Chapel Hill make no 
15 // representations about the suitability of this software for any purpose. 
16 // It is provided "as is" without express or implied warranty.
17 /**
18  * @file SkyContext.cpp
19  * 
20  * Graphics Context Interface.  Initializes GL extensions, etc.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #  include <simgear_config.h>
25 #endif
26
27 #ifdef HAVE_WINDOWS_H
28 #  include <windows.h>
29 #endif
30
31 // #include GLUT_H
32
33 #if defined (__APPLE__)
34 #  include <OpenGL/OpenGL.h>
35 #endif
36
37 #if !defined (WIN32) && !defined(__APPLE__)
38 #include <GL/glx.h>
39 #endif
40
41 //#include "extgl.h"
42
43 #include "SkyContext.hpp"
44 #include "SkyUtil.hpp"
45 #include "SkyMaterial.hpp"
46 #include "SkyTextureState.hpp"
47
48 //------------------------------------------------------------------------------
49 // Function               : SkyContext::SkyContext
50 // Description      : 
51 //------------------------------------------------------------------------------
52 /**
53  * @fn SkyContext::SkyContext()
54  * @brief Constructor.
55  *
56  */ 
57 SkyContext::SkyContext()
58 {
59   // _iWidth  = glutGet(GLUT_WINDOW_WIDTH);
60   // _iHeight = glutGet(GLUT_WINDOW_HEIGHT);
61   _iWidth  = 640;
62   _iHeight = 480;
63   
64   // materials and structure classes
65   AddCurrentGLContext();
66   // Initialize all the extensions and load the functions - JW (file is extgl.c)
67   #ifdef WIN32
68   glInitialize();
69   InitializeExtension("GL_ARB_multitexture");
70   #endif
71 }
72
73
74 //------------------------------------------------------------------------------
75 // Function               : SkyContext::~SkyContext
76 // Description      : 
77 //------------------------------------------------------------------------------
78 /**
79  * @fn SkyContext::~SkyContext()
80  * @brief Destructor.
81  */ 
82 SkyContext::~SkyContext()
83 {
84   // delete map of materials
85   for (ContextMaterialIterator cmi = _currentMaterials.begin(); cmi != _currentMaterials.end(); ++cmi)
86   {
87     SAFE_DELETE(cmi->second);
88   }
89   _currentMaterials.clear();
90 }
91
92
93 //------------------------------------------------------------------------------
94 // Function               : SkyContext::ProcessReshapeEvent
95 // Description      : 
96 //------------------------------------------------------------------------------
97 /**
98  * @fn SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
99  * @brief Handles window resize events, and notifies all context listeners of the event.
100  */ 
101 SKYRESULT SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
102
103   _iWidth = iWidth; 
104   _iHeight = iHeight; 
105   return _SendMessage(SKYCONTEXT_MESSAGE_RESHAPE);
106 }
107
108
109 //------------------------------------------------------------------------------
110 // Function               : SkyContext::InitializeExtensions
111 // Description      : 
112 //------------------------------------------------------------------------------
113 /**
114 * @fn SkyContext::InitializeExtensions(const char *pExtensionNames)
115 * @brief Initializes GL extension specified by @a pExtensionNames.      
116 */ 
117 SKYRESULT SkyContext::InitializeExtension(const char *pExtensionName)
118 { /***
119   if (!QueryExtension(pExtensionName)) // see query search function defined in extgl.c
120   {
121     SkyTrace(
122       "ERROR: SkyContext::InitializeExtenstions: The following extensions are unsupported: %s\n", 
123       pExtensionName);
124     return SKYRESULT_FAIL;
125   }  **/
126   //set this false to catch all the extensions until we come up with a linux version
127   return SKYRESULT_FAIL;
128 }
129
130
131 //------------------------------------------------------------------------------
132 // Function               : SkyContext::GetCurrentMaterial
133 // Description      : 
134 //------------------------------------------------------------------------------
135 /**
136 * @fn SkyContext::GetCurrentMaterial()
137 * @brief Returns the current cached material state that is active in this OpenGL context.
138
139 * @todo <WRITE EXTENDED SkyContext::GetCurrentMaterial FUNCTION DOCUMENTATION>
140 */ 
141 SkyMaterial* SkyContext::GetCurrentMaterial()
142 {
143 #ifdef WIN32
144     ContextMaterialIterator cmi = _currentMaterials.find(wglGetCurrentContext());
145 #elif defined(__APPLE__)
146     ContextMaterialIterator cmi = _currentMaterials.find(CGLGetCurrentContext());
147 #else
148     ContextMaterialIterator cmi = _currentMaterials.find(glXGetCurrentContext());
149 #endif
150   if (_currentMaterials.end() != cmi)
151     return cmi->second;
152   else
153   {
154     SkyTrace("SkyContext::GetCurrentMaterial(): Invalid context.");
155     return NULL;
156   }
157   
158 }
159
160
161 //------------------------------------------------------------------------------
162 // Function               : SkyContext::GetCurrentTextureState
163 // Description      : 
164 //------------------------------------------------------------------------------
165 /**
166  * @fn SkyContext::GetCurrentTextureState()
167  * @brief Returns the current cached texture state that is active in this OpenGL context.
168  * 
169  * @todo <WRITE EXTENDED SkyContext::GetCurrentTextureState FUNCTION DOCUMENTATION>
170  */ 
171 SkyTextureState* SkyContext::GetCurrentTextureState()
172 {
173 #ifdef WIN32
174     ContextTextureStateIterator ctsi = _currentTextureState.find(wglGetCurrentContext());
175 #elif defined(__APPLE__)
176     ContextTextureStateIterator ctsi = _currentTextureState.find(CGLGetCurrentContext());
177 #else
178     ContextTextureStateIterator ctsi = _currentTextureState.find(glXGetCurrentContext());
179 #endif
180   if (_currentTextureState.end() != ctsi)
181     return ctsi->second;
182   else
183   {
184     SkyTrace("SkyContext::GetCurrentTextureState(): Invalid context.");
185     return NULL;
186   }
187 }
188
189
190 //------------------------------------------------------------------------------
191 // Function               : SkyContext::AddCurrentGLContext
192 // Description      : 
193 //------------------------------------------------------------------------------
194 /**
195  * @fn SkyContext::AddCurrentGLContext()
196  * @brief @todo <WRITE BRIEF SkyContext::AddCurrentGLContext DOCUMENTATION>
197  * 
198  * @todo <WRITE EXTENDED SkyContext::AddCurrentGLContext FUNCTION DOCUMENTATION>
199  */ 
200 SKYRESULT SkyContext::AddCurrentGLContext()
201 {
202     SkyMaterial *pCurrentMaterial = new SkyMaterial;
203 #ifdef WIN32
204     _currentMaterials.insert(std::make_pair(wglGetCurrentContext(), pCurrentMaterial));
205 #elif defined (__APPLE__)
206     _currentMaterials.insert(std::make_pair(CGLGetCurrentContext(), pCurrentMaterial));
207 #else
208     _currentMaterials.insert(std::make_pair(glXGetCurrentContext(), pCurrentMaterial));
209 #endif
210
211     SkyTextureState *pCurrentTS = new SkyTextureState;
212 #ifdef WIN32
213     _currentTextureState.insert(std::make_pair(wglGetCurrentContext() , pCurrentTS));
214 #elif defined (__APPLE__)
215     _currentTextureState.insert(std::make_pair(CGLGetCurrentContext() , pCurrentTS));
216 #else
217     _currentTextureState.insert(std::make_pair(glXGetCurrentContext() , pCurrentTS));
218 #endif
219     return SKYRESULT_OK;
220 }
221
222 //------------------------------------------------------------------------------
223 // Function               : SkyContext::Register
224 // Description      : 
225 //------------------------------------------------------------------------------
226 /**
227  * @fn SkyContext::Register(Listener* pListener, int priority)
228  * @brief Register with the messaging system to handle notification of mode changes
229  */ 
230 SKYRESULT SkyContext::Register(Listener* pListener, int priority)
231 {
232         std::list<ListenerPair>::iterator iter = 
233     std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
234         if (iter == _listeners.end())
235         {
236                 // insert the listener, sorted by priority
237                 for (iter=_listeners.begin(); iter != _listeners.end(); ++iter)
238                 {
239                         if (priority <= iter->first)
240                         {
241                                 _listeners.insert(iter, ListenerPair(priority, pListener));
242                                 break;
243                         }
244                 }
245                 if (iter == _listeners.end())
246                 {
247                                 _listeners.push_back(ListenerPair(priority, pListener));
248                 }
249                 // Send a message to the pListener if we are already active so it
250                 // can intialize itself
251                 //FAIL_RETURN(pListener->GraphicsReshapeEvent());
252         } 
253   else
254         {
255                 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is already registered");
256         }
257         return SKYRESULT_OK;
258 }
259
260
261 //------------------------------------------------------------------------------
262 // Function               : SkyContext::UnRegister
263 // Description      : 
264 //------------------------------------------------------------------------------
265 /**
266  * @fn SkyContext::UnRegister(Listener *pListener)
267  * @brief UnRegister with the messaging system.
268  */ 
269 SKYRESULT SkyContext::UnRegister(Listener *pListener)
270 {
271         std::list<ListenerPair>::iterator iter = 
272     std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
273         if (iter == _listeners.end())
274         {
275                 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is not registered");
276         } 
277   else
278         {
279                 _listeners.erase(iter);
280         }
281         return SKYRESULT_OK;
282 }
283
284
285 /**
286  * @fn SkyContext::_SendMessage(SkyMessageType msg)
287  * @brief Messaging system to handle notification of mode changes
288  */ 
289 SKYRESULT SkyContext::_SendMessage(SkyMessageType msg)
290 {
291         if (_listeners.size() == 0) return SKYRESULT_OK;
292
293         bool failure = false;
294         SKYRESULT res, failureCode = SKYRESULT_OK;
295         std::list<ListenerPair>::iterator iter;
296         SKYRESULT (Listener::*fnPtr)() = NULL;
297
298         // Make a pointer to the appropriate method
299         switch (msg)
300         {
301         case SKYCONTEXT_MESSAGE_RESHAPE: fnPtr = &Listener::GraphicsReshapeEvent; break;
302         }
303
304         // Notify all listeners of the messag. catch failures, but still call everyone else.
305         // !!! WRH HORRIBLE HACK must cache the current "end" because these functions could register new listeners
306         std::list<ListenerPair>::iterator endIter = _listeners.end();
307         endIter--;
308
309         iter = _listeners.begin();
310         do
311         {
312                 if ( SKYFAILED( res = (iter->second->*fnPtr)() ) )
313                 {
314                         failureCode = res;
315                         SkyTrace("SkyContext: SendMessage failed");
316                 }
317                 if (iter == endIter) break;
318                 iter++;
319         } while (true);
320
321         FAIL_RETURN(failureCode);
322
323         return SKYRESULT_OK;
324 }