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