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