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
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.
18 * @file SkyContext.cpp
20 * Graphics Context Interface. Initializes GL extensions, etc.
24 # include <simgear_config.h>
39 #include "SkyContext.hpp"
40 #include "SkyUtil.hpp"
41 #include "SkyMaterial.hpp"
42 #include "SkyTextureState.hpp"
44 //------------------------------------------------------------------------------
45 // Function : SkyContext::SkyContext
47 //------------------------------------------------------------------------------
49 * @fn SkyContext::SkyContext()
53 SkyContext::SkyContext()
55 _iWidth = glutGet(GLUT_WINDOW_WIDTH);
56 _iHeight = glutGet(GLUT_WINDOW_HEIGHT);
58 // materials and structure classes
59 AddCurrentGLContext();
60 // Initialize all the extensions and load the functions - JW (file is extgl.c)
63 InitializeExtension("GL_ARB_multitexture");
68 //------------------------------------------------------------------------------
69 // Function : SkyContext::~SkyContext
71 //------------------------------------------------------------------------------
73 * @fn SkyContext::~SkyContext()
76 SkyContext::~SkyContext()
78 // delete map of materials
79 for (ContextMaterialIterator cmi = _currentMaterials.begin(); cmi != _currentMaterials.end(); ++cmi)
81 SAFE_DELETE(cmi->second);
83 _currentMaterials.clear();
87 //------------------------------------------------------------------------------
88 // Function : SkyContext::ProcessReshapeEvent
90 //------------------------------------------------------------------------------
92 * @fn SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
93 * @brief Handles window resize events, and notifies all context listeners of the event.
95 SKYRESULT SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
99 return _SendMessage(SKYCONTEXT_MESSAGE_RESHAPE);
103 //------------------------------------------------------------------------------
104 // Function : SkyContext::InitializeExtensions
106 //------------------------------------------------------------------------------
108 * @fn SkyContext::InitializeExtensions(const char *pExtensionNames)
109 * @brief Initializes GL extension specified by @a pExtensionNames.
111 SKYRESULT SkyContext::InitializeExtension(const char *pExtensionName)
113 if (!QueryExtension(pExtensionName)) // see query search function defined in extgl.c
116 "ERROR: SkyContext::InitializeExtenstions: The following extensions are unsupported: %s\n",
118 return SKYRESULT_FAIL;
120 //set this false to catch all the extensions until we come up with a linux version
121 return SKYRESULT_FAIL;
125 //------------------------------------------------------------------------------
126 // Function : SkyContext::GetCurrentMaterial
128 //------------------------------------------------------------------------------
130 * @fn SkyContext::GetCurrentMaterial()
131 * @brief Returns the current cached material state that is active in this OpenGL context.
133 * @todo <WRITE EXTENDED SkyContext::GetCurrentMaterial FUNCTION DOCUMENTATION>
135 SkyMaterial* SkyContext::GetCurrentMaterial()
138 ContextMaterialIterator cmi = _currentMaterials.find(wglGetCurrentContext());
140 ContextMaterialIterator cmi = _currentMaterials.find(glXGetCurrentContext());
142 if (_currentMaterials.end() != cmi)
146 SkyTrace("SkyContext::GetCurrentMaterial(): Invalid context.");
153 //------------------------------------------------------------------------------
154 // Function : SkyContext::GetCurrentTextureState
156 //------------------------------------------------------------------------------
158 * @fn SkyContext::GetCurrentTextureState()
159 * @brief Returns the current cached texture state that is active in this OpenGL context.
161 * @todo <WRITE EXTENDED SkyContext::GetCurrentTextureState FUNCTION DOCUMENTATION>
163 SkyTextureState* SkyContext::GetCurrentTextureState()
166 ContextTextureStateIterator ctsi = _currentTextureState.find(wglGetCurrentContext());
168 ContextTextureStateIterator ctsi = _currentTextureState.find(glXGetCurrentContext());
170 if (_currentTextureState.end() != ctsi)
174 SkyTrace("SkyContext::GetCurrentTextureState(): Invalid context.");
180 //------------------------------------------------------------------------------
181 // Function : SkyContext::AddCurrentGLContext
183 //------------------------------------------------------------------------------
185 * @fn SkyContext::AddCurrentGLContext()
186 * @brief @todo <WRITE BRIEF SkyContext::AddCurrentGLContext DOCUMENTATION>
188 * @todo <WRITE EXTENDED SkyContext::AddCurrentGLContext FUNCTION DOCUMENTATION>
190 SKYRESULT SkyContext::AddCurrentGLContext()
192 SkyMaterial *pCurrentMaterial = new SkyMaterial;
194 _currentMaterials.insert(std::make_pair(wglGetCurrentContext(), pCurrentMaterial));
196 _currentMaterials.insert(std::make_pair(glXGetCurrentContext(), pCurrentMaterial));
199 SkyTextureState *pCurrentTS = new SkyTextureState;
201 _currentTextureState.insert(std::make_pair(wglGetCurrentContext() , pCurrentTS));
203 _currentTextureState.insert(std::make_pair(glXGetCurrentContext() , pCurrentTS));
208 //------------------------------------------------------------------------------
209 // Function : SkyContext::Register
211 //------------------------------------------------------------------------------
213 * @fn SkyContext::Register(Listener* pListener, int priority)
214 * @brief Register with the messaging system to handle notification of mode changes
216 SKYRESULT SkyContext::Register(Listener* pListener, int priority)
218 std::list<ListenerPair>::iterator iter =
219 std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
220 if (iter == _listeners.end())
222 // insert the listener, sorted by priority
223 for (iter=_listeners.begin(); iter != _listeners.end(); ++iter)
225 if (priority <= iter->first)
227 _listeners.insert(iter, ListenerPair(priority, pListener));
231 if (iter == _listeners.end())
233 _listeners.push_back(ListenerPair(priority, pListener));
235 // Send a message to the pListener if we are already active so it
236 // can intialize itself
237 //FAIL_RETURN(pListener->GraphicsReshapeEvent());
241 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is already registered");
247 //------------------------------------------------------------------------------
248 // Function : SkyContext::UnRegister
250 //------------------------------------------------------------------------------
252 * @fn SkyContext::UnRegister(Listener *pListener)
253 * @brief UnRegister with the messaging system.
255 SKYRESULT SkyContext::UnRegister(Listener *pListener)
257 std::list<ListenerPair>::iterator iter =
258 std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
259 if (iter == _listeners.end())
261 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is not registered");
265 _listeners.erase(iter);
272 * @fn SkyContext::_SendMessage(SkyMessageType msg)
273 * @brief Messaging system to handle notification of mode changes
275 SKYRESULT SkyContext::_SendMessage(SkyMessageType msg)
277 if (_listeners.size() == 0) return SKYRESULT_OK;
279 bool failure = false;
280 SKYRESULT res, failureCode = SKYRESULT_OK;
281 std::list<ListenerPair>::iterator iter;
282 SKYRESULT (Listener::*fnPtr)() = NULL;
284 // Make a pointer to the appropriate method
287 case SKYCONTEXT_MESSAGE_RESHAPE: fnPtr = &Listener::GraphicsReshapeEvent; break;
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();
295 iter = _listeners.begin();
298 if ( SKYFAILED( res = (iter->second->*fnPtr)() ) )
301 SkyTrace("SkyContext: SendMessage failed");
303 if (iter == endIter) break;
307 FAIL_RETURN(failureCode);