From ecc2d3ce359bf507b299cb3f52a44fcc1ae51260 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 1 Jul 2016 19:21:02 -0400 Subject: [PATCH] add initial Window class --- src/gui/Window.cc | 166 ++++++++++++++++++++++++++++++++++++++++++++++ src/gui/Window.h | 21 ++++++ 2 files changed, 187 insertions(+) create mode 100644 src/gui/Window.cc create mode 100644 src/gui/Window.h diff --git a/src/gui/Window.cc b/src/gui/Window.cc new file mode 100644 index 0000000..eba7454 --- /dev/null +++ b/src/gui/Window.cc @@ -0,0 +1,166 @@ +#include "gl3w.h" +#include "Window.h" + +#define INITIAL_WIDTH 500 +#define INITIAL_HEIGHT 500 + +/** + * Initialize SDL. + * + * @retval true SDL was loaded successfully. + * @retval false Loading SDL failed. + */ +static bool Initialize_SDL() +{ + static bool initialized = false; + + if (initialized) + { + return true; + } + + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + return false; + } + + atexit(SDL_Quit); + + initialized = true; + return true; +} + +/** + * Initialize OpenGL. + * + * @retval true OpenGL was loaded successfully. + * @retval false Loading OpenGL failed. + */ +static bool Initialize_OpenGL() +{ + if (gl3wInit() != 0) + { + /* Failed to gl3wInit() */ + return false; + } + + if (!gl3wIsSupported(3, 0)) + { + /* OpenGL 3.0 is not supported */ + return false; + } + + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + return true; +} + +/** + * Create a Window. + * + * @retval true The Window was created successfully. + * @retval false There was an error while creating the Window. + */ +bool Window::create() +{ + if (!Initialize_SDL()) + { + return false; + } + + m_window = SDL_CreateWindow( + "jes", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + INITIAL_WIDTH, + INITIAL_HEIGHT, + SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + if (m_window == NULL) + { + return false; + } + + (void)SDL_GL_CreateContext(m_window); + + if (!Initialize_OpenGL()) + { + return false; + } + + m_exit_requested = false; + + resize(); + + return true; +} + +/** + * Run the Window event loop. + * + * TODO: make this a static method to support multiple GUI windows. + */ +void Window::run_event_loop() +{ + SDL_Event event; + + while ((!m_exit_requested) && SDL_WaitEvent(&event)) + { + handle_event(event); + } +} + +/** + * Handle a SDL event. + * + * @retval true E + */ +void Window::handle_event(SDL_Event & event) +{ + switch (event.type) + { + case SDL_QUIT: + m_exit_requested = true; + break; + + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_ESCAPE: + m_exit_requested = true; + break; + } + break; + + case SDL_WINDOWEVENT: + switch (event.window.event) + { + case SDL_WINDOWEVENT_EXPOSED: + redraw(); + break; + case SDL_WINDOWEVENT_RESIZED: + resize(); + redraw(); + break; + } + break; + } +} + +void Window::resize() +{ + int width; + int height; + SDL_GetWindowSize(m_window, &width, &height); + glViewport(0, 0, width, height); +} + +void Window::redraw() +{ + glClearColor (0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + SDL_GL_SwapWindow(m_window); +} diff --git a/src/gui/Window.h b/src/gui/Window.h new file mode 100644 index 0000000..d79605b --- /dev/null +++ b/src/gui/Window.h @@ -0,0 +1,21 @@ +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class Window +{ +public: + bool create(); + void run_event_loop(); + +protected: + void resize(); + void redraw(); + void handle_event(SDL_Event & event); + + SDL_Window * m_window; + bool m_exit_requested; +}; + +#endif