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.
27 #include "SkyContext.hpp"
28 #include "SkyUtil.hpp"
29 #include "SkyMaterial.hpp"
30 #include "SkyTextureState.hpp"
32 //------------------------------------------------------------------------------
33 // Function : SkyContext::SkyContext
35 //------------------------------------------------------------------------------
37 * @fn SkyContext::SkyContext()
41 SkyContext::SkyContext()
43 _iWidth = glutGet(GLUT_WINDOW_WIDTH);
44 _iHeight = glutGet(GLUT_WINDOW_HEIGHT);
46 // materials and structure classes
47 AddCurrentGLContext();
48 // Initialize all the extensions and load the functions - JW (file is extgl.c)
51 InitializeExtension("GL_ARB_multitexture");
56 //------------------------------------------------------------------------------
57 // Function : SkyContext::~SkyContext
59 //------------------------------------------------------------------------------
61 * @fn SkyContext::~SkyContext()
64 SkyContext::~SkyContext()
66 // delete map of materials
67 for (ContextMaterialIterator cmi = _currentMaterials.begin(); cmi != _currentMaterials.end(); ++cmi)
69 SAFE_DELETE(cmi->second);
71 _currentMaterials.clear();
75 //------------------------------------------------------------------------------
76 // Function : SkyContext::ProcessReshapeEvent
78 //------------------------------------------------------------------------------
80 * @fn SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
81 * @brief Handles window resize events, and notifies all context listeners of the event.
83 SKYRESULT SkyContext::ProcessReshapeEvent(int iWidth, int iHeight)
87 return _SendMessage(SKYCONTEXT_MESSAGE_RESHAPE);
91 //------------------------------------------------------------------------------
92 // Function : SkyContext::InitializeExtensions
94 //------------------------------------------------------------------------------
96 * @fn SkyContext::InitializeExtensions(const char *pExtensionNames)
97 * @brief Initializes GL extension specified by @a pExtensionNames.
99 SKYRESULT SkyContext::InitializeExtension(const char *pExtensionName)
101 if (!QueryExtension(pExtensionName)) // see query search function defined in extgl.c
104 "ERROR: SkyContext::InitializeExtenstions: The following extensions are unsupported: %s\n",
106 return SKYRESULT_FAIL;
108 //set this false to catch all the extensions until we come up with a linux version
109 return SKYRESULT_FAIL;
113 //------------------------------------------------------------------------------
114 // Function : SkyContext::GetCurrentMaterial
116 //------------------------------------------------------------------------------
118 * @fn SkyContext::GetCurrentMaterial()
119 * @brief Returns the current cached material state that is active in this OpenGL context.
121 * @todo <WRITE EXTENDED SkyContext::GetCurrentMaterial FUNCTION DOCUMENTATION>
123 SkyMaterial* SkyContext::GetCurrentMaterial()
125 ContextMaterialIterator cmi = _currentMaterials.find(glXGetCurrentContext());
126 if (_currentMaterials.end() != cmi)
130 SkyTrace("SkyContext::GetCurrentMaterial(): Invalid context.");
137 //------------------------------------------------------------------------------
138 // Function : SkyContext::GetCurrentTextureState
140 //------------------------------------------------------------------------------
142 * @fn SkyContext::GetCurrentTextureState()
143 * @brief Returns the current cached texture state that is active in this OpenGL context.
145 * @todo <WRITE EXTENDED SkyContext::GetCurrentTextureState FUNCTION DOCUMENTATION>
147 SkyTextureState* SkyContext::GetCurrentTextureState()
149 ContextTextureStateIterator ctsi = _currentTextureState.find(glXGetCurrentContext());
150 if (_currentTextureState.end() != ctsi)
154 SkyTrace("SkyContext::GetCurrentTextureState(): Invalid context.");
160 //------------------------------------------------------------------------------
161 // Function : SkyContext::AddCurrentGLContext
163 //------------------------------------------------------------------------------
165 * @fn SkyContext::AddCurrentGLContext()
166 * @brief @todo <WRITE BRIEF SkyContext::AddCurrentGLContext DOCUMENTATION>
168 * @todo <WRITE EXTENDED SkyContext::AddCurrentGLContext FUNCTION DOCUMENTATION>
170 SKYRESULT SkyContext::AddCurrentGLContext()
172 SkyMaterial *pCurrentMaterial = new SkyMaterial;
173 _currentMaterials.insert(std::make_pair(glXGetCurrentContext(), pCurrentMaterial));
175 SkyTextureState *pCurrentTS = new SkyTextureState;
176 _currentTextureState.insert(std::make_pair(glXGetCurrentContext() , pCurrentTS));
181 //------------------------------------------------------------------------------
182 // Function : SkyContext::Register
184 //------------------------------------------------------------------------------
186 * @fn SkyContext::Register(Listener* pListener, int priority)
187 * @brief Register with the messaging system to handle notification of mode changes
189 SKYRESULT SkyContext::Register(Listener* pListener, int priority)
191 std::list<ListenerPair>::iterator iter =
192 std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
193 if (iter == _listeners.end())
195 // insert the listener, sorted by priority
196 for (iter=_listeners.begin(); iter != _listeners.end(); ++iter)
198 if (priority <= iter->first)
200 _listeners.insert(iter, ListenerPair(priority, pListener));
204 if (iter == _listeners.end())
206 _listeners.push_back(ListenerPair(priority, pListener));
208 // Send a message to the pListener if we are already active so it
209 // can intialize itself
210 //FAIL_RETURN(pListener->GraphicsReshapeEvent());
214 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is already registered");
220 //------------------------------------------------------------------------------
221 // Function : SkyContext::UnRegister
223 //------------------------------------------------------------------------------
225 * @fn SkyContext::UnRegister(Listener *pListener)
226 * @brief UnRegister with the messaging system.
228 SKYRESULT SkyContext::UnRegister(Listener *pListener)
230 std::list<ListenerPair>::iterator iter =
231 std::find_if(_listeners.begin(), _listeners.end(), _ListenerPred(pListener));
232 if (iter == _listeners.end())
234 FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyContext: Listener is not registered");
238 _listeners.erase(iter);
245 * @fn SkyContext::_SendMessage(SkyMessageType msg)
246 * @brief Messaging system to handle notification of mode changes
248 SKYRESULT SkyContext::_SendMessage(SkyMessageType msg)
250 if (_listeners.size() == 0) return SKYRESULT_OK;
252 bool failure = false;
253 SKYRESULT res, failureCode = SKYRESULT_OK;
254 std::list<ListenerPair>::iterator iter;
255 SKYRESULT (Listener::*fnPtr)() = NULL;
257 // Make a pointer to the appropriate method
260 case SKYCONTEXT_MESSAGE_RESHAPE: fnPtr = &Listener::GraphicsReshapeEvent; break;
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();
268 iter = _listeners.begin();
271 if ( SKYFAILED( res = (iter->second->*fnPtr)() ) )
274 SkyTrace("SkyContext: SendMessage failed");
276 if (iter == endIter) break;
280 FAIL_RETURN(failureCode);