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
28 #include "CEGuiGLFWSharedBase.h"
29 #include "SamplesFrameworkBase.h"
30 #include "CEGUI/CEGUI.h"
31
32 //----------------------------------------------------------------------------//
33 GLFWwindow* CEGuiGLFWSharedBase::d_window = 0;
34
35 //----------------------------------------------------------------------------//
run()36 void CEGuiGLFWSharedBase::run()
37 {
38 // Input callbacks of glfw for CEGUI
39 glfwSetKeyCallback(d_window, glfwKeyCallback);
40 glfwSetCharCallback(d_window, glfwCharCallback);
41 glfwSetMouseButtonCallback(d_window, glfwMouseButtonCallback);
42 glfwSetScrollCallback(d_window, glfwScrollCallback);
43 glfwSetCursorPosCallback(d_window, glfwCursorPosCallback);
44
45 //Window callbacks
46 glfwSetWindowCloseCallback(d_window, glfwWindowCloseCallback);
47 glfwSetWindowSizeCallback(d_window, glfwWindowResizeCallback);
48 d_windowSized = false; //The resize callback is being called immediately after setting it in this version of glfw
49 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
50
51 // set starting time
52 d_frameTime = glfwGetTime();
53
54 while (!d_sampleApp->isQuitting())
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 glfwPollEvents();
67 }
68
69 }
70
71 //----------------------------------------------------------------------------//
endRendering()72 void CEGuiGLFWSharedBase::endRendering()
73 {
74 glfwSwapBuffers(d_window);
75 }
76
77 //----------------------------------------------------------------------------//
createGLFWWindow()78 void CEGuiGLFWSharedBase::createGLFWWindow()
79 {
80 glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE);
81 glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE);
82 glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE);
83 glfwWindowHint(GLFW_ALPHA_BITS, 0);
84 if (!(d_window = glfwCreateWindow(s_defaultWindowWidth,
85 s_defaultWindowHeight, d_windowTitle, 0, 0)))
86 {
87 CEGUI_THROW(RendererException("Failed to open GLFW window."));
88 glfwTerminate();
89 }
90 glfwMakeContextCurrent (d_window);
91 }
92
93 //----------------------------------------------------------------------------//
setGLFWAppConfiguration()94 void CEGuiGLFWSharedBase::setGLFWAppConfiguration()
95 {
96 //Deactivate VSYNC
97 glfwSwapInterval(0);
98
99 // Disable the mouse position in Non_Debug mode
100 #ifndef DEBUG
101 glfwSetInputMode(d_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
102 #endif
103 // Clear Errors by GLFW, even if Setup is correct.
104 glGetError();
105 }
106
107 //----------------------------------------------------------------------------//
glfwWindowCloseCallback(GLFWwindow *)108 void CEGuiGLFWSharedBase::glfwWindowCloseCallback(GLFWwindow* /*window*/)
109 {
110 d_sampleApp->setQuitting(true);
111 }
112
113 //----------------------------------------------------------------------------//
glfwWindowResizeCallback(GLFWwindow *,int width,int height)114 void CEGuiGLFWSharedBase::glfwWindowResizeCallback(GLFWwindow* /*window*/, int width, int height)
115 {
116 // We cache this in order to minimise calls to notifyDisplaySizeChanged,
117 // which happens in the main loop whenever d_windowSized is set to true.
118 d_windowSized = true;
119 d_newWindowWidth = width;
120 d_newWindowHeight = height;
121 }
122
123 //----------------------------------------------------------------------------//
GlfwToCeguiKey(int glfwKey)124 CEGUI::Key::Scan CEGuiGLFWSharedBase::GlfwToCeguiKey(int glfwKey)
125 {
126 switch(glfwKey)
127 {
128 case GLFW_KEY_ESCAPE : return CEGUI::Key::Escape;
129 case GLFW_KEY_F1 : return CEGUI::Key::F1;
130 case GLFW_KEY_F2 : return CEGUI::Key::F2;
131 case GLFW_KEY_F3 : return CEGUI::Key::F3;
132 case GLFW_KEY_F4 : return CEGUI::Key::F4;
133 case GLFW_KEY_F5 : return CEGUI::Key::F5;
134 case GLFW_KEY_F6 : return CEGUI::Key::F6;
135 case GLFW_KEY_F7 : return CEGUI::Key::F7;
136 case GLFW_KEY_F8 : return CEGUI::Key::F8;
137 case GLFW_KEY_F9 : return CEGUI::Key::F9;
138 case GLFW_KEY_F10 : return CEGUI::Key::F10;
139 case GLFW_KEY_F11 : return CEGUI::Key::F11;
140 case GLFW_KEY_F12 : return CEGUI::Key::F12;
141 case GLFW_KEY_F13 : return CEGUI::Key::F13;
142 case GLFW_KEY_F14 : return CEGUI::Key::F14;
143 case GLFW_KEY_F15 : return CEGUI::Key::F15;
144 case GLFW_KEY_UP : return CEGUI::Key::ArrowUp;
145 case GLFW_KEY_DOWN : return CEGUI::Key::ArrowDown;
146 case GLFW_KEY_LEFT : return CEGUI::Key::ArrowLeft;
147 case GLFW_KEY_RIGHT : return CEGUI::Key::ArrowRight;
148 case GLFW_KEY_LEFT_SHIFT : return CEGUI::Key::LeftShift;
149 case GLFW_KEY_RIGHT_SHIFT : return CEGUI::Key::RightShift;
150 case GLFW_KEY_LEFT_CONTROL : return CEGUI::Key::LeftControl;
151 case GLFW_KEY_RIGHT_CONTROL: return CEGUI::Key::RightControl;
152 case GLFW_KEY_LEFT_ALT : return CEGUI::Key::LeftAlt;
153 case GLFW_KEY_RIGHT_ALT : return CEGUI::Key::RightAlt;
154 case GLFW_KEY_TAB : return CEGUI::Key::Tab;
155 case GLFW_KEY_ENTER : return CEGUI::Key::Return;
156 case GLFW_KEY_BACKSPACE : return CEGUI::Key::Backspace;
157 case GLFW_KEY_INSERT : return CEGUI::Key::Insert;
158 case GLFW_KEY_DELETE : return CEGUI::Key::Delete;
159 case GLFW_KEY_PAGE_UP : return CEGUI::Key::PageUp;
160 case GLFW_KEY_PAGE_DOWN : return CEGUI::Key::PageDown;
161 case GLFW_KEY_HOME : return CEGUI::Key::Home;
162 case GLFW_KEY_END : return CEGUI::Key::End;
163 case GLFW_KEY_KP_ENTER : return CEGUI::Key::NumpadEnter;
164 default : return CEGUI::Key::Unknown;
165 }
166 }
167
168 //----------------------------------------------------------------------------//
glfwKeyCallback(GLFWwindow *,int key,int,int action,int)169 void CEGuiGLFWSharedBase::glfwKeyCallback(GLFWwindow* /*window*/, int key,
170 int /*scancode*/, int action, int /*mods*/)
171 {
172 CEGUI::Key::Scan ceguiKey = GlfwToCeguiKey(key);
173
174 if(action == GLFW_PRESS)
175 d_sampleApp->injectKeyDown(ceguiKey);
176 else if (action == GLFW_RELEASE)
177 d_sampleApp->injectKeyUp(ceguiKey);
178 }
179
180 //----------------------------------------------------------------------------//
glfwCharCallback(GLFWwindow *,unsigned codepoint)181 void CEGuiGLFWSharedBase::glfwCharCallback
182 (GLFWwindow* /*window*/, unsigned codepoint)
183 {
184 d_sampleApp->injectChar(codepoint);
185 }
186
187 //----------------------------------------------------------------------------//
glfwMouseButtonCallback(GLFWwindow *,int button,int action,int)188 void CEGuiGLFWSharedBase::glfwMouseButtonCallback
189 (GLFWwindow* /*window*/, int button, int action, int /*mods*/)
190 {
191 CEGUI::MouseButton ceguiMouseButton = GlfwToCeguiMouseButton(button);
192
193 if (action == GLFW_PRESS)
194 d_sampleApp->injectMouseButtonDown(ceguiMouseButton);
195 else if (action == GLFW_RELEASE)
196 d_sampleApp->injectMouseButtonUp(ceguiMouseButton);
197 }
198
199 //----------------------------------------------------------------------------//
glfwScrollCallback(GLFWwindow *,double,double yoffset)200 void CEGuiGLFWSharedBase::glfwScrollCallback
201 (GLFWwindow* /*window*/, double /*xoffset*/, double yoffset)
202 {
203 d_sampleApp->injectMouseWheelChange(static_cast<float>(yoffset/4));
204 }
205
206 //----------------------------------------------------------------------------//
glfwCursorPosCallback(GLFWwindow *,double x,double y)207 void CEGuiGLFWSharedBase::glfwCursorPosCallback
208 (GLFWwindow* /*window*/, double x, double y)
209 {
210 if (!d_mouseDisableCalled)
211 {
212 // if cursor didn't leave the window nothing changes
213 d_sampleApp->injectMousePosition(static_cast<float>(x), static_cast<float>(y));
214 }
215 else
216 {
217 // if the cursor left the window, we need to use the saved position
218 // because glfw beams the cursor to the middle of the window if
219 // the cursor is disabled
220 d_sampleApp->injectMousePosition(static_cast<float>(d_oldMousePosX), static_cast<float>(d_oldMousePosY));
221 glfwSetCursorPos(d_window, d_oldMousePosX, d_oldMousePosY);
222 d_mouseDisableCalled = false;
223 }
224
225 #ifndef DEBUG
226 if (x < 0 || y < 0
227 || x > d_newWindowWidth
228 || y > d_newWindowHeight)
229 {
230 // show cursor
231 glfwSetInputMode(d_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
232
233 // move the cursor to the position where it left the window
234 glfwSetCursorPos(d_window, x, y);
235
236 // "note down" that the cursor left the window
237 d_mouseLeftWindow = true;
238 }
239 else
240 {
241 if (d_mouseLeftWindow)
242 {
243 // get cursor position to restore afterwards
244 glfwGetCursorPos(d_window, &d_oldMousePosX, &d_oldMousePosY);
245
246 // we need to inject the previous cursor position because
247 // glfw moves the cursor to the centre of the render
248 // window if it gets disabled. therefore notify the
249 // next MousePosCallback invocation of the "mouse disabled" event.
250 d_mouseDisableCalled = true;
251
252 // disable cursor
253 glfwSetInputMode(d_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
254
255 // "note down" that the cursor is back in the render window
256 d_mouseLeftWindow = false;
257 }
258 }
259 #endif
260 }
261