1 /***********************************************************************
2 created:    Sep 15 2014
3 author:     Luca Ebach <bitbucket@lucebac.net>
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 /**************************************************************************
29 * The following libs (and corresponding headers) are needed to compile and to link:
30 * CEGUIBase
31 * CEGUIOpenGLRenderer
32 * CEGUICoreWindowRendererSet
33 * default CEGUI xml parser (and dependencies)
34 * GLFW3
35 * OpengGL
36 * glm headers (as part of CEGUIBase)
37 ***************************************************************************/
38 
39 #include <iostream>
40 
41 #include <CEGUI/CEGUI.h>
42 #include <CEGUI/RendererModules/OpenGL/GLRenderer.h>
43 
44 #include <GLFW/glfw3.h>
45 
46 static GLFWwindow* window;
47 
toCEGUIButton(int button)48 CEGUI::MouseButton toCEGUIButton(int button)
49 {
50     switch (button)
51     {
52     case GLFW_MOUSE_BUTTON_LEFT:
53         return CEGUI::LeftButton;
54 
55     case GLFW_MOUSE_BUTTON_MIDDLE:
56         return CEGUI::MiddleButton;
57 
58     case GLFW_MOUSE_BUTTON_RIGHT:
59         return CEGUI::RightButton;
60 
61     default:
62         return CEGUI::MouseButtonCount;
63     }
64 }
65 
toCEGUIKey(int glfwKey)66 CEGUI::Key::Scan toCEGUIKey(int glfwKey)
67 {
68     switch (glfwKey)
69     {
70     case GLFW_KEY_ESCAPE: return CEGUI::Key::Escape;
71     case GLFW_KEY_F1: return CEGUI::Key::F1;
72     case GLFW_KEY_F2: return CEGUI::Key::F2;
73     case GLFW_KEY_F3: return CEGUI::Key::F3;
74     case GLFW_KEY_F4: return CEGUI::Key::F4;
75     case GLFW_KEY_F5: return CEGUI::Key::F5;
76     case GLFW_KEY_F6: return CEGUI::Key::F6;
77     case GLFW_KEY_F7: return CEGUI::Key::F7;
78     case GLFW_KEY_F8: return CEGUI::Key::F8;
79     case GLFW_KEY_F9: return CEGUI::Key::F9;
80     case GLFW_KEY_F10: return CEGUI::Key::F10;
81     case GLFW_KEY_F11: return CEGUI::Key::F11;
82     case GLFW_KEY_F12: return CEGUI::Key::F12;
83     case GLFW_KEY_F13: return CEGUI::Key::F13;
84     case GLFW_KEY_F14: return CEGUI::Key::F14;
85     case GLFW_KEY_F15: return CEGUI::Key::F15;
86     case GLFW_KEY_UP: return CEGUI::Key::ArrowUp;
87     case GLFW_KEY_DOWN: return CEGUI::Key::ArrowDown;
88     case GLFW_KEY_LEFT: return CEGUI::Key::ArrowLeft;
89     case GLFW_KEY_RIGHT: return CEGUI::Key::ArrowRight;
90     case GLFW_KEY_LEFT_SHIFT: return CEGUI::Key::LeftShift;
91     case GLFW_KEY_RIGHT_SHIFT: return CEGUI::Key::RightShift;
92     case GLFW_KEY_LEFT_CONTROL: return CEGUI::Key::LeftControl;
93     case GLFW_KEY_RIGHT_CONTROL: return CEGUI::Key::RightControl;
94     case GLFW_KEY_LEFT_ALT: return CEGUI::Key::LeftAlt;
95     case GLFW_KEY_RIGHT_ALT: return CEGUI::Key::RightAlt;
96     case GLFW_KEY_TAB: return CEGUI::Key::Tab;
97     case GLFW_KEY_ENTER: return CEGUI::Key::Return;
98     case GLFW_KEY_BACKSPACE: return CEGUI::Key::Backspace;
99     case GLFW_KEY_INSERT: return CEGUI::Key::Insert;
100     case GLFW_KEY_DELETE: return CEGUI::Key::Delete;
101     case GLFW_KEY_PAGE_UP: return CEGUI::Key::PageUp;
102     case GLFW_KEY_PAGE_DOWN: return CEGUI::Key::PageDown;
103     case GLFW_KEY_HOME: return CEGUI::Key::Home;
104     case GLFW_KEY_END: return CEGUI::Key::End;
105     case GLFW_KEY_KP_ENTER: return CEGUI::Key::NumpadEnter;
106     case GLFW_KEY_SPACE: return CEGUI::Key::Space;
107     case 'A': return CEGUI::Key::A;
108     case 'B': return CEGUI::Key::B;
109     case 'C': return CEGUI::Key::C;
110     case 'D': return CEGUI::Key::D;
111     case 'E': return CEGUI::Key::E;
112     case 'F': return CEGUI::Key::F;
113     case 'G': return CEGUI::Key::G;
114     case 'H': return CEGUI::Key::H;
115     case 'I': return CEGUI::Key::I;
116     case 'J': return CEGUI::Key::J;
117     case 'K': return CEGUI::Key::K;
118     case 'L': return CEGUI::Key::L;
119     case 'M': return CEGUI::Key::M;
120     case 'N': return CEGUI::Key::N;
121     case 'O': return CEGUI::Key::O;
122     case 'P': return CEGUI::Key::P;
123     case 'Q': return CEGUI::Key::Q;
124     case 'R': return CEGUI::Key::R;
125     case 'S': return CEGUI::Key::S;
126     case 'T': return CEGUI::Key::T;
127     case 'U': return CEGUI::Key::U;
128     case 'V': return CEGUI::Key::V;
129     case 'W': return CEGUI::Key::W;
130     case 'X': return CEGUI::Key::X;
131     case 'Y': return CEGUI::Key::Y;
132     case 'Z': return CEGUI::Key::Z;
133     default: return CEGUI::Key::Unknown;
134     }
135 }
136 
charCallback(GLFWwindow * window,unsigned int char_pressed)137 void charCallback(GLFWwindow* window, unsigned int char_pressed)
138 {
139     CEGUI::System::getSingleton().getDefaultGUIContext().injectChar(char_pressed);
140 }
141 
cursorPosCallback(GLFWwindow * window,double x,double y)142 void cursorPosCallback(GLFWwindow* window, double x, double y)
143 {
144     CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(x, y);
145 }
146 
keyCallback(GLFWwindow * window,int key,int scan,int action,int mod)147 void keyCallback(GLFWwindow* window, int key, int scan, int action, int mod)
148 {
149     CEGUI::Key::Scan cegui_key = toCEGUIKey(key);
150     if (action == GLFW_PRESS)
151     {
152         CEGUI::System::getSingleton().getDefaultGUIContext().injectKeyDown(cegui_key);
153     }
154     else
155     {
156         CEGUI::System::getSingleton().getDefaultGUIContext().injectKeyUp(cegui_key);
157     }
158 }
159 
mouseButtonCallback(GLFWwindow * window,int button,int state,int mod)160 void mouseButtonCallback(GLFWwindow* window, int button, int state, int mod)
161 {
162     if (state == GLFW_PRESS)
163     {
164         CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseButtonDown(toCEGUIButton(button));
165     }
166     else
167     {
168         CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseButtonUp(toCEGUIButton(button));
169     }
170 }
171 
mouseWheelCallback(GLFWwindow * window,double x,double y)172 void mouseWheelCallback(GLFWwindow* window, double x, double y)
173 {
174     if (y < 0.f)
175         CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseWheelChange(-1.f);
176     else
177         CEGUI::System::getSingleton().getDefaultGUIContext().injectMouseWheelChange(+1.f);
178 }
179 
windowResizedCallback(GLFWwindow * window,int width,int height)180 void windowResizedCallback(GLFWwindow* window, int width, int height)
181 {
182     CEGUI::System::getSingleton().notifyDisplaySizeChanged(
183         CEGUI::Sizef(static_cast<float>(width), static_cast<float>(height)));
184     glViewport(0, 0, width, height);
185 }
186 
errorCallback(int error,const char * message)187 void errorCallback(int error, const char* message)
188 {
189     CEGUI::Logger::getSingleton().logEvent(message, CEGUI::Errors);
190 }
191 
setupCallbacks()192 void setupCallbacks()
193 {
194     // input callbacks
195     glfwSetCharCallback(window, charCallback);
196     glfwSetCursorPosCallback(window, cursorPosCallback);
197     glfwSetKeyCallback(window, keyCallback);
198     glfwSetMouseButtonCallback(window, mouseButtonCallback);
199     glfwSetScrollCallback(window, mouseWheelCallback);
200 
201     // window callback
202     glfwSetWindowSizeCallback(window, windowResizedCallback);
203 
204     // error callback
205     glfwSetErrorCallback(errorCallback);
206 }
207 
initGLFW()208 void initGLFW()
209 {
210     // init everything from glfw
211     if (glfwInit() != GL_TRUE)
212     {
213         std::cerr << "glfw could not be initialized!" << std::endl;
214         exit(1);
215     }
216 
217     // create glfw window with size of 800x600px
218     window = glfwCreateWindow(800, 600, "CEGUI + glfw3 window", NULL, NULL);
219     if (!window)
220     {
221         std::cerr << "Could not create glfw window!" << std::endl;
222         glfwTerminate();
223         exit(1);
224     }
225 
226     // makes this window's gl context the current one
227     glfwMakeContextCurrent(window);
228 
229     // hide native mouse cursor when it is over the window
230     glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
231 
232     // disable VSYNC
233     glfwSwapInterval(0);
234 
235     // clear error messages
236     glGetError();
237 }
238 
initCEGUI()239 void initCEGUI()
240 {
241     using namespace CEGUI;
242 
243     // create renderer and enable extra states
244     OpenGLRenderer& cegui_renderer = OpenGLRenderer::create(Sizef(800.f, 600.f));
245     cegui_renderer.enableExtraStateSettings(true);
246 
247     // create CEGUI system object
248     CEGUI::System::create(cegui_renderer);
249 
250     // setup resource directories
251     DefaultResourceProvider* rp = static_cast<DefaultResourceProvider*>(System::getSingleton().getResourceProvider());
252     rp->setResourceGroupDirectory("schemes", "datafiles/schemes/");
253     rp->setResourceGroupDirectory("imagesets", "datafiles/imagesets/");
254     rp->setResourceGroupDirectory("fonts", "datafiles/fonts/");
255     rp->setResourceGroupDirectory("layouts", "datafiles/layouts/");
256     rp->setResourceGroupDirectory("looknfeels", "datafiles/looknfeel/");
257     rp->setResourceGroupDirectory("lua_scripts", "datafiles/lua_scripts/");
258     rp->setResourceGroupDirectory("schemas", "datafiles/xml_schemas/");
259 
260     // set default resource groups
261     ImageManager::setImagesetDefaultResourceGroup("imagesets");
262     Font::setDefaultResourceGroup("fonts");
263     Scheme::setDefaultResourceGroup("schemes");
264     WidgetLookManager::setDefaultResourceGroup("looknfeels");
265     WindowManager::setDefaultResourceGroup("layouts");
266     ScriptModule::setDefaultResourceGroup("lua_scripts");
267 
268     XMLParser* parser = System::getSingleton().getXMLParser();
269     if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
270         parser->setProperty("SchemaDefaultResourceGroup", "schemas");
271 
272     // load TaharezLook scheme and DejaVuSans-10 font
273     SchemeManager::getSingleton().createFromFile("TaharezLook.scheme", "schemes");
274     FontManager::getSingleton().createFromFile("DejaVuSans-10.font");
275 
276     // set default font and cursor image and tooltip type
277     System::getSingleton().getDefaultGUIContext().setDefaultFont("DejaVuSans-10");
278     System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("TaharezLook/MouseArrow");
279     System::getSingleton().getDefaultGUIContext().setDefaultTooltipType("TaharezLook/Tooltip");
280 }
281 
initWindows()282 void initWindows()
283 {
284     using namespace CEGUI;
285 
286     /////////////////////////////////////////////////////////////
287     // Add your gui initialisation code in here.
288     // You should preferably use layout loading because you won't
289     // have to recompile everytime you change the layout. But you
290     // can also use static window creation code here, of course.
291     /////////////////////////////////////////////////////////////
292 
293     // load layout
294     Window* root = WindowManager::getSingleton().loadLayoutFromFile("application_templates.layout");
295     System::getSingleton().getDefaultGUIContext().setRootWindow(root);
296 }
297 
298 #ifdef _MSC_VER
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)299 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
300 #else
301 int main(int argc, char* argv[])
302 #endif
303 {
304     using namespace CEGUI;
305 
306     // init glfw
307     initGLFW();
308 
309     // init cegui
310     initCEGUI();
311 
312     // setup glfw callbacks
313     setupCallbacks();
314 
315     // notify system of the window size
316     System::getSingleton().notifyDisplaySizeChanged(Sizef(800.f, 600.f));
317     glViewport(0, 0, 800, 600);
318 
319     // initialise windows and setup layout
320     initWindows();
321 
322     // set gl clear color
323     glClearColor(0, 0, 0, 255);
324 
325     float time = glfwGetTime();
326 
327     OpenGLRenderer* renderer = static_cast<OpenGLRenderer*>(System::getSingleton().getRenderer());
328 
329     // repeat until a quit is requested
330     while (glfwWindowShouldClose(window) == GL_FALSE)
331     {
332         // clear screen
333         glClear(GL_COLOR_BUFFER_BIT);
334 
335         // inject time pulses
336         const float newtime = glfwGetTime();
337         const float time_elapsed = newtime - time;
338         System::getSingleton().injectTimePulse(time_elapsed);
339         System::getSingleton().getDefaultGUIContext().injectTimePulse(time_elapsed);
340         time = newtime;
341 
342         // render gui
343         renderer->beginRendering();
344         System::getSingleton().renderAllGUIContexts();
345         renderer->endRendering();
346 
347         // swap buffers
348         glfwSwapBuffers(window);
349 
350         // poll events
351         glfwPollEvents();
352     }
353 
354     // destroy system and renderer
355     System::destroy();
356     OpenGLRenderer::destroy(*renderer);
357     renderer = 0;
358 
359     // destroy glfw window
360     glfwDestroyWindow(window);
361 
362     // cleanup glfw
363     glfwTerminate();
364 
365     return 0;
366 }
367