1 /***********************************************************************
2 created: 21/7/2015
3 author: Yaron Cohen-Tal
4 *************************************************************************/
5 /***************************************************************************
6 * Copyright (C) 2004 - 2015 Paul D Turner & The CEGUI Development Team
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 ***************************************************************************/
27 #include "CEGuiGLFWSharedBase.h"
28 #include "SamplesFrameworkBase.h"
29 #include "CEGUI/CEGUI.h"
30
31 #include <stdexcept>
32 #include <sstream>
33
34 //----------------------------------------------------------------------------//
run()35 void CEGuiGLFWSharedBase::run()
36 {
37 // Input callbacks of glfw for CEGUI
38 glfwSetKeyCallback(glfwKeyCallback);
39 glfwSetCharCallback(glfwCharCallback);
40 glfwSetMouseButtonCallback(glfwMouseButtonCallback);
41 glfwSetMouseWheelCallback(glfwMouseWheelCallback);
42 glfwSetMousePosCallback(glfwMousePosCallback);
43
44 //Window callbacks
45 glfwSetWindowCloseCallback(glfwWindowCloseCallback);
46 glfwSetWindowSizeCallback(glfwWindowResizeCallback);
47 d_windowSized = false; //The resize callback is being called immediately after setting it in this version of glfw
48 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
49
50 // set starting time
51 d_frameTime = glfwGetTime();
52
53 while (!d_sampleApp->isQuitting() &&
54 glfwGetWindowParam(GLFW_OPENED))
55 {
56 if (d_windowSized)
57 {
58 d_windowSized = false;
59 CEGUI::System::getSingleton().
60 notifyDisplaySizeChanged(
61 CEGUI::Sizef(static_cast<float>(d_newWindowWidth),
62 static_cast<float>(d_newWindowHeight)));
63 }
64
65 drawFrame();
66 }
67 }
68
69 //----------------------------------------------------------------------------//
endRendering()70 void CEGuiGLFWSharedBase::endRendering()
71 {
72 glfwSwapBuffers();
73 }
74
75 //----------------------------------------------------------------------------//
createGLFWWindow()76 void CEGuiGLFWSharedBase::createGLFWWindow()
77 {
78 if (glfwOpenWindow(s_defaultWindowWidth, s_defaultWindowHeight, 0, 0, 0, 0,
79 24, 8, GLFW_WINDOW) != GL_TRUE)
80 {
81 CEGUI_THROW(RendererException("Failed to open GLFW window."));
82 glfwTerminate();
83 }
84 glfwEnable (GLFW_KEY_REPEAT);
85 }
86
87 //----------------------------------------------------------------------------//
setGLFWAppConfiguration()88 void CEGuiGLFWSharedBase::setGLFWAppConfiguration()
89 {
90 glfwSetWindowTitle(d_windowTitle);
91
92 //Deactivate VSYNC
93 glfwSwapInterval(0);
94
95 // Disable the mouse position in Non_Debug mode
96 #ifndef DEBUG
97 glfwDisable(GLFW_MOUSE_CURSOR);
98 #endif
99 // Clear Errors by GLFW, even if Setup is correct.
100 glGetError();
101 }
102
103 //----------------------------------------------------------------------------//
glfwWindowCloseCallback(void)104 int CEGuiGLFWSharedBase::glfwWindowCloseCallback(void)
105 {
106 d_sampleApp->setQuitting(true);
107 return GL_TRUE;
108 }
109
110 //----------------------------------------------------------------------------//
glfwWindowResizeCallback(int w,int h)111 void CEGuiGLFWSharedBase::glfwWindowResizeCallback(int w, int h)
112 {
113 // We cache this in order to minimise calls to notifyDisplaySizeChanged,
114 // which happens in the main loop whenever d_windowSized is set to true.
115 d_windowSized = true;
116 d_newWindowWidth = w;
117 d_newWindowHeight = h;
118 }
119
120 //----------------------------------------------------------------------------//
GlfwToCeguiKey(int glfwKey)121 CEGUI::Key::Scan CEGuiGLFWSharedBase::GlfwToCeguiKey(int glfwKey)
122 {
123 switch(glfwKey)
124 {
125 case GLFW_KEY_ESC : return CEGUI::Key::Escape;
126 case GLFW_KEY_F1 : return CEGUI::Key::F1;
127 case GLFW_KEY_F2 : return CEGUI::Key::F2;
128 case GLFW_KEY_F3 : return CEGUI::Key::F3;
129 case GLFW_KEY_F4 : return CEGUI::Key::F4;
130 case GLFW_KEY_F5 : return CEGUI::Key::F5;
131 case GLFW_KEY_F6 : return CEGUI::Key::F6;
132 case GLFW_KEY_F7 : return CEGUI::Key::F7;
133 case GLFW_KEY_F8 : return CEGUI::Key::F8;
134 case GLFW_KEY_F9 : return CEGUI::Key::F9;
135 case GLFW_KEY_F10 : return CEGUI::Key::F10;
136 case GLFW_KEY_F11 : return CEGUI::Key::F11;
137 case GLFW_KEY_F12 : return CEGUI::Key::F12;
138 case GLFW_KEY_F13 : return CEGUI::Key::F13;
139 case GLFW_KEY_F14 : return CEGUI::Key::F14;
140 case GLFW_KEY_F15 : return CEGUI::Key::F15;
141 case GLFW_KEY_UP : return CEGUI::Key::ArrowUp;
142 case GLFW_KEY_DOWN : return CEGUI::Key::ArrowDown;
143 case GLFW_KEY_LEFT : return CEGUI::Key::ArrowLeft;
144 case GLFW_KEY_RIGHT : return CEGUI::Key::ArrowRight;
145 case GLFW_KEY_LSHIFT : return CEGUI::Key::LeftShift;
146 case GLFW_KEY_RSHIFT : return CEGUI::Key::RightShift;
147 case GLFW_KEY_LCTRL : return CEGUI::Key::LeftControl;
148 case GLFW_KEY_RCTRL : return CEGUI::Key::RightControl;
149 case GLFW_KEY_LALT : return CEGUI::Key::LeftAlt;
150 case GLFW_KEY_RALT : return CEGUI::Key::RightAlt;
151 case GLFW_KEY_TAB : return CEGUI::Key::Tab;
152 case GLFW_KEY_ENTER : return CEGUI::Key::Return;
153 case GLFW_KEY_BACKSPACE : return CEGUI::Key::Backspace;
154 case GLFW_KEY_INSERT : return CEGUI::Key::Insert;
155 case GLFW_KEY_DEL : return CEGUI::Key::Delete;
156 case GLFW_KEY_PAGEUP : return CEGUI::Key::PageUp;
157 case GLFW_KEY_PAGEDOWN : return CEGUI::Key::PageDown;
158 case GLFW_KEY_HOME : return CEGUI::Key::Home;
159 case GLFW_KEY_END : return CEGUI::Key::End;
160 case GLFW_KEY_KP_ENTER : return CEGUI::Key::NumpadEnter;
161 default : return CEGUI::Key::Unknown;
162 }
163 }
164
165 //----------------------------------------------------------------------------//
glfwKeyCallback(int key,int action)166 void GLFWCALL CEGuiGLFWSharedBase::glfwKeyCallback(int key, int action)
167 {
168 CEGUI::Key::Scan ceguiKey = GlfwToCeguiKey(key);
169
170 if(action == GLFW_PRESS)
171 d_sampleApp->injectKeyDown(ceguiKey);
172 else if (action == GLFW_RELEASE)
173 d_sampleApp->injectKeyUp(ceguiKey);
174 }
175
176 //----------------------------------------------------------------------------//
glfwCharCallback(int character,int action)177 void GLFWCALL CEGuiGLFWSharedBase::glfwCharCallback(int character, int action)
178 {
179 if(action == GLFW_PRESS)
180 d_sampleApp->injectChar(character);
181 }
182
183 //----------------------------------------------------------------------------//
glfwMouseButtonCallback(int key,int action)184 void GLFWCALL CEGuiGLFWSharedBase::glfwMouseButtonCallback(int key, int action)
185 {
186 CEGUI::MouseButton ceguiMouseButton = GlfwToCeguiMouseButton(key);
187
188 if(action == GLFW_PRESS)
189 d_sampleApp->injectMouseButtonDown(ceguiMouseButton);
190 else if (action == GLFW_RELEASE)
191 d_sampleApp->injectMouseButtonUp(ceguiMouseButton);
192 }
193
194 //----------------------------------------------------------------------------//
glfwMouseWheelCallback(int position)195 void GLFWCALL CEGuiGLFWSharedBase::glfwMouseWheelCallback(int position)
196 {
197 static int lastPosition = 0;
198 d_sampleApp->injectMouseWheelChange(static_cast<float>(position - lastPosition));
199 lastPosition = position;
200 }
201
202 //----------------------------------------------------------------------------//
glfwMousePosCallback(int x,int y)203 void GLFWCALL CEGuiGLFWSharedBase::glfwMousePosCallback(int x, int y)
204 {
205 if (!d_mouseDisableCalled)
206 {
207 // if cursor didn't leave the window nothing changes
208 d_sampleApp->injectMousePosition(static_cast<float>(x), static_cast<float>(y));
209 }
210 else
211 {
212 // if the cursor left the window, we need to use the saved position
213 // because glfw beams the cursor to the middle of the window if
214 // the cursor is disabled
215 d_sampleApp->injectMousePosition(static_cast<float>(d_oldMousePosX), static_cast<float>(d_oldMousePosY));
216 glfwSetMousePos(static_cast<int>(d_oldMousePosX), static_cast<int>(d_oldMousePosY));
217 d_mouseDisableCalled = false;
218 }
219
220 #ifndef DEBUG
221 if (x < 0 || y < 0
222 || x > d_newWindowWidth
223 || y > d_newWindowHeight)
224 {
225 // show cursor
226 glfwEnable(GLFW_MOUSE_CURSOR);
227
228 // move the cursor to the position where it left the window
229 glfwSetMousePos(x, y);
230
231 // "note down" that the cursor left the window
232 d_mouseLeftWindow = true;
233 }
234 else
235 {
236 if (d_mouseLeftWindow)
237 {
238 // get cursor position to restore afterwards
239 int mouse_x_int(0);
240 int mouse_y_int(0);
241 glfwGetMousePos(&mouse_x_int, &mouse_y_int);
242 d_oldMousePosX = mouse_x_int;
243 d_oldMousePosY = mouse_y_int;
244
245 // we need to inject the previous cursor position because
246 // glfw moves the cursor to the centre of the render
247 // window if it gets disabled. therefore notify the
248 // next MousePosCallback invocation of the "mouse disabled" event.
249 d_mouseDisableCalled = true;
250
251 // disable cursor
252 glfwDisable(GLFW_MOUSE_CURSOR);
253
254 // "note down" that the cursor is back in the render window
255 d_mouseLeftWindow = false;
256 }
257 }
258 #endif
259 }
260
261 //----------------------------------------------------------------------------//
262
263