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>
33 #if defined (__APPLE__)
34 # include <OpenGL/OpenGL.h>
37 #if !defined (WIN32) && !defined(__APPLE__)
43 #include "SkyContext.hpp"
44 #include "SkyUtil.hpp"
45 #include "SkyMaterial.hpp"
46 #include "SkyTextureState.hpp"
48 //------------------------------------------------------------------------------
49 // Function : SkyContext::SkyContext
51 //------------------------------------------------------------------------------
53 * @fn SkyContext::SkyContext()
57 SkyContext::SkyContext()
59 // _iWidth = glutGet(GLUT_WINDOW_WIDTH);
60 // _iHeight = glutGet(GLUT_WINDOW_HEIGHT);
64 // materials and structure classes
65 AddCurrentGLContext();
66 // Initialize all the extensions and load the functions - JW (file is extgl.c)
69 InitializeExtension("GL_ARB_multitexture");
74 //------------------------------------------------------------------------------
75 // Function : SkyContext::~SkyContext
77 //------------------------------------------------------------------------------
79 * @fn SkyContext::~SkyContext()
82 SkyContext::~SkyContext()
84 // delete map of materials
85 for (ContextMaterialIterator cmi = _currentMaterials.begin(); cmi != _currentMaterials.end(); ++cmi)
87 SAFE_DELETE(cmi->second);
89 _currentMaterials.clear();
93 //------------------------------------------------------------------------------
94 // Function : SkyContext::ProcessReshapeEvent
96 //------------------------------------------------------------------------------
98 * @fn SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
99 * @brief Handles window resize events, and notifies all context listeners of the event.
101 SKYRESULT SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
105 return _SendMessage(SKYCONTEXT_MESSAGE_RESHAPE);
109 //------------------------------------------------------------------------------
110 // Function : SkyContext::InitializeExtensions
112 //------------------------------------------------------------------------------
114 * @fn SkyContext::InitializeExtensions(const char *pExtensionNames)
115 * @brief Initializes GL extension specified by @a pExtensionNames.
117 SKYRESULT SkyContext::InitializeExtension(const char *pExtensionName)
119 if (!QueryExtension(pExtensionName)) // see query search function defined in extgl.c
122 "ERROR: SkyContext::InitializeExtenstions: The following extensions are unsupported: %s\n",
124 return SKYRESULT_FAIL;
126 //set this false to catch all the extensions until we come up with a linux version
127 return SKYRESULT_FAIL;
131 //------------------------------------------------------------------------------
132 // Function : SkyContext::GetCurrentMaterial
134 //------------------------------------------------------------------------------
136 * @fn SkyContext::GetCurrentMaterial()
137 * @brief Returns the current cached material state that is active in this OpenGL context.
139 * @todo <WRITE EXTENDED SkyContext::GetCurrentMaterial FUNCTION DOCUMENTATION>
141 SkyMaterial* SkyContext::GetCurrentMaterial()
144 ContextMaterialIterator cmi = _currentMaterials.find(wglGetCurrentContext());
145 #elif defined(__APPLE__)
146 ContextMaterialIterator cmi = _currentMaterials.find(CGLGetCurrentContext());
148 ContextMaterialIterator cmi = _currentMaterials.find(glXGetCurrentContext());
150 if (_currentMaterials.end() != cmi)
154 SkyTrace("SkyContext::GetCurrentMaterial(): Invalid context.");
161 //------------------------------------------------------------------------------
162 // Function : SkyContext::GetCurrentTextureState
164 //------------------------------------------------------------------------------
166 * @fn SkyContext::GetCurrentTextureState()
167 * @brief Returns the current cached texture state that is active in this OpenGL context.
169 * @todo <WRITE EXTENDED SkyContext::GetCurrentTextureState FUNCTION DOCUMENTATION>
171 SkyTextureState* SkyContext::GetCurrentTextureState()
174 ContextTextureStateIterator ctsi = _currentTextureState.find(wglGetCurrentContext());
175 #elif defined(__APPLE__)
176 ContextTextureStateIterator ctsi = _currentTextureState.find(CGLGetCurrentContext());
178 ContextTextureStateIterator ctsi = _currentTextureState.find(glXGetCurrentContext());
180 if (_currentTextureState.end() != ctsi)
184 SkyTrace("SkyContext::GetCurrentTextureState(): Invalid context.");
190 //------------------------------------------------------------------------------
191 // Function : SkyContext::AddCurrentGLContext
193 //------------------------------------------------------------------------------
195 * @fn SkyContext::AddCurrentGLContext()
196 * @brief @todo <WRITE BRIEF SkyContext::AddCurrentGLContext DOCUMENTATION>
198 * @todo <WRITE EXTENDED SkyContext::AddCurrentGLContext FUNCTION DOCUMENTATION>
200 SKYRESULT SkyContext::AddCurrentGLContext()
202 SkyMaterial *pCurrentMaterial = new SkyMaterial;
204 _currentMaterials.insert(std::make_pair(wglGetCurrentContext(), pCurrentMaterial));
205 #elif defined (__APPLE__)
206 _currentMaterials.insert(std::make_pair(CGLGetCurrentContext(), pCurrentMaterial));
208 _currentMaterials.insert(std::make_pair(glXGetCurrentContext(), pCurrentMaterial));
211 SkyTextureState *pCurrentTS = new SkyTextureState;
213 _currentTextureState.insert(std::make_pair(wglGetCurrentContext() , pCurrentTS));
214 #elif defined (__APPLE__)
215 _currentTextureState.insert(std::make_pair(CGLGetCurrentContext() , pCurrentTS));
217 _currentTextureState.insert(std::make_pair(glXGetCurrentContext() , pCurrentTS));
222 //------------------------------------------------------------------------------
223 // Function : SkyContext::Register
225 //------------------------------------------------------------------------------
227 * @fn SkyContext::Register(Listener* pListener, int priority)
228 * @brief Register with the messaging system to handle notification of mode changes
230 SKYRESULT SkyContext::Register(Listener* pListener, int priority)
232 std::list<ListenerPair>::iterator iter =
233 std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
234 if (iter == _listeners.end())
236 // insert the listener, sorted by priority
237 for (iter=_listeners.begin(); iter != _listeners.end(); ++iter)
239 if (priority <= iter->first)
241 _listeners.insert(iter, ListenerPair(priority, pListener));
245 if (iter == _listeners.end())
247 _listeners.push_back(ListenerPair(priority, pListener));
249 // Send a message to the pListener if we are already active so it
250 // can intialize itself
251 //FAIL_RETURN(pListener->GraphicsReshapeEvent());
255 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is already registered");
261 //------------------------------------------------------------------------------
262 // Function : SkyContext::UnRegister
264 //------------------------------------------------------------------------------
266 * @fn SkyContext::UnRegister(Listener *pListener)
267 * @brief UnRegister with the messaging system.
269 SKYRESULT SkyContext::UnRegister(Listener *pListener)
271 std::list<ListenerPair>::iterator iter =
272 std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
273 if (iter == _listeners.end())
275 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is not registered");
279 _listeners.erase(iter);
286 * @fn SkyContext::_SendMessage(SkyMessageType msg)
287 * @brief Messaging system to handle notification of mode changes
289 SKYRESULT SkyContext::_SendMessage(SkyMessageType msg)
291 if (_listeners.size() == 0) return SKYRESULT_OK;
293 bool failure = false;
294 SKYRESULT res, failureCode = SKYRESULT_OK;
295 std::list<ListenerPair>::iterator iter;
296 SKYRESULT (Listener::*fnPtr)() = NULL;
298 // Make a pointer to the appropriate method
301 case SKYCONTEXT_MESSAGE_RESHAPE: fnPtr = &Listener::GraphicsReshapeEvent; break;
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();
309 iter = _listeners.begin();
312 if ( SKYFAILED( res = (iter->second->*fnPtr)() ) )
315 SkyTrace("SkyContext: SendMessage failed");
317 if (iter == endIter) break;
321 FAIL_RETURN(failureCode);