diff options
-rw-r--r-- | common/glfw_view.cpp | 238 | ||||
-rw-r--r-- | common/glfw_view.hpp | 39 | ||||
-rw-r--r-- | common/map_view.cpp | 263 | ||||
-rw-r--r-- | linux/llmr-app.gyp | 2 | ||||
-rw-r--r-- | linux/main.cpp | 2 | ||||
-rw-r--r-- | macosx/llmr-app.gyp | 5 | ||||
-rw-r--r-- | macosx/main.mm | 2 |
7 files changed, 285 insertions, 266 deletions
diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp new file mode 100644 index 0000000000..c4fafb69ac --- /dev/null +++ b/common/glfw_view.cpp @@ -0,0 +1,238 @@ +#include "glfw_view.hpp" + +MapView::MapView(llmr::Settings &settings, bool fullscreen) + : fullscreen(fullscreen), settings(settings), map(settings) {} + +MapView::~MapView() { glfwTerminate(); } + +void MapView::init() { + if (!glfwInit()) { + fprintf(stderr, "Failed to initialize glfw\n"); + exit(1); + } + + GLFWmonitor *monitor = nullptr; + if (fullscreen) { + monitor = glfwGetPrimaryMonitor(); + } + +#ifdef GL_ES_VERSION_2_0 + glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +#endif + + glfwWindowHint(GLFW_RED_BITS, 8); + glfwWindowHint(GLFW_GREEN_BITS, 8); + glfwWindowHint(GLFW_BLUE_BITS, 8); + glfwWindowHint(GLFW_ALPHA_BITS, 8); + glfwWindowHint(GLFW_STENCIL_BITS, 8); + glfwWindowHint(GLFW_DEPTH_BITS, 16); + + window = glfwCreateWindow(1024, 768, "llmr", monitor, NULL); + if (!window) { + glfwTerminate(); + fprintf(stderr, "Failed to initialize window\n"); + exit(1); + } + + glfwSetWindowUserPointer(window, this); + glfwMakeContextCurrent(window); + + int width, height; + glfwGetWindowSize(window, &width, &height); + int fb_width, fb_height; + glfwGetFramebufferSize(window, &fb_width, &fb_height); + + settings.load(); + map.setup(); + + resize(window, 0, 0); + + glfwSwapInterval(1); + + map.loadSettings(); + + glfwSetCursorPosCallback(window, mousemove); + glfwSetMouseButtonCallback(window, mouseclick); + glfwSetWindowSizeCallback(window, resize); + glfwSetFramebufferSizeCallback(window, resize); + glfwSetScrollCallback(window, scroll); + glfwSetKeyCallback(window, key); +} + +void MapView::key(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + + if (action == GLFW_RELEASE) { + switch (key) { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(window, true); + break; + case GLFW_KEY_TAB: + mapView->map.toggleDebug(); + break; + case GLFW_KEY_X: + if (!mods) + mapView->map.resetPosition(); + break; + case GLFW_KEY_R: + if (!mods) + mapView->map.toggleRaster(); + break; + case GLFW_KEY_N: + if (!mods) + mapView->map.resetNorth(); + break; + } + } +} + +void MapView::scroll(GLFWwindow *window, double /*xoffset*/, double yoffset) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + double delta = yoffset * 40; + + bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0; + + double absdelta = delta < 0 ? -delta : delta; + double scale = 2.0 / (1.0 + exp(-absdelta / 100.0)); + + // Make the scroll wheel a bit slower. + if (!is_wheel) { + scale = (scale - 1.0) / 2.0 + 1.0; + } + + // Zooming out. + if (delta < 0 && scale != 0) { + scale = 1.0 / scale; + } + + mapView->map.startScaling(); + mapView->map.scaleBy(scale, mapView->last_x, mapView->last_y); +} + +void MapView::resize(GLFWwindow *window, int, int) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + + int width, height; + glfwGetWindowSize(window, &width, &height); + int fb_width, fb_height; + glfwGetFramebufferSize(window, &fb_width, &fb_height); + + mapView->map.resize(width, height, (float)fb_width / (float)width, fb_width, fb_height); + mapView->map.update(); +} + +void MapView::mouseclick(GLFWwindow *window, int button, int action, int modifiers) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + + if (button == GLFW_MOUSE_BUTTON_RIGHT || + (button == GLFW_MOUSE_BUTTON_LEFT && modifiers & GLFW_MOD_CONTROL)) { + mapView->rotating = action == GLFW_PRESS; + if (!mapView->rotating) { + mapView->map.stopRotating(); + } + } else if (button == GLFW_MOUSE_BUTTON_LEFT) { + mapView->tracking = action == GLFW_PRESS; + + if (action == GLFW_RELEASE) { + mapView->map.stopPanning(); + double now = glfwGetTime(); + if (now - mapView->last_click < 0.4 /* ms */) { + mapView->map.scaleBy(2.0, mapView->last_x, mapView->last_y, 0.5); + } + mapView->last_click = now; + } + } +} + +void MapView::mousemove(GLFWwindow *window, double x, double y) { + MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); + if (mapView->tracking) { + double dx = x - mapView->last_x; + double dy = y - mapView->last_y; + if (dx || dy) { + mapView->map.startPanning(); + mapView->map.moveBy(dx, dy); + } + } else if (mapView->rotating) { + mapView->map.startRotating(); + mapView->map.rotateBy(mapView->last_x, mapView->last_y, x, y); + } + mapView->last_x = x; + mapView->last_y = y; +} + +int MapView::run() { + while (!glfwWindowShouldClose(window)) { + llmr::platform::cleanup(); + + if (dirty) { + try { + dirty = map.render(); + } + catch (std::exception &ex) { + fprintf(stderr, "exception: %s\n", ex.what()); + } + glfwSwapBuffers(window); + fps(); + } + + if (dirty) { + glfwPollEvents(); + } else { + glfwWaitEvents(); + } + } + + return 0; +} + +void MapView::fps() { + static int frames = 0; + static double time_elapsed = 0; + + frames++; + double current_time = glfwGetTime(); + + if (current_time - time_elapsed >= 1) { + fprintf(stderr, "FPS: %4.2f\n", frames / (current_time - time_elapsed)); + time_elapsed = current_time; + frames = 0; + } +} + +namespace llmr { +namespace platform { + +double elapsed() { return glfwGetTime(); } + +void show_debug_image(std::string name, const char *data, size_t width, size_t height) { + static GLFWwindow *debug_window = nullptr; + if (!debug_window) { + debug_window = glfwCreateWindow(width, height, name.c_str(), nullptr, nullptr); + if (!debug_window) { + glfwTerminate(); + fprintf(stderr, "Failed to initialize window\n"); + exit(1); + } + } + + GLFWwindow *current_window = glfwGetCurrentContext(); + + glfwSetWindowSize(debug_window, width, height); + glfwMakeContextCurrent(debug_window); + + int fb_width, fb_height; + glfwGetFramebufferSize(debug_window, &fb_width, &fb_height); + float scale = (float)fb_width / (float)width; + + glPixelZoom(scale, -scale); + glRasterPos2f(-1.0f, 1.0f); + glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); + glfwSwapBuffers(debug_window); + + glfwMakeContextCurrent(current_window); +} +} +} diff --git a/common/glfw_view.hpp b/common/glfw_view.hpp new file mode 100644 index 0000000000..1d1a256699 --- /dev/null +++ b/common/glfw_view.hpp @@ -0,0 +1,39 @@ +#ifndef LLMR_COMMON_GLFW_VIEW +#define LLMR_COMMON_GLFW_VIEW + +#include <GLFW/glfw3.h> +#include <llmr/llmr.hpp> + +class MapView { +public: + MapView(llmr::Settings &settings, bool fullscreen = false); + ~MapView(); + + void init(); + + static void key(GLFWwindow *window, int key, int scancode, int action, int mods); + static void scroll(GLFWwindow *window, double xoffset, double yoffset); + static void resize(GLFWwindow *window, int, int); + static void mouseclick(GLFWwindow *window, int button, int action, int modifiers); + static void mousemove(GLFWwindow *window, double x, double y); + + int run(); + void fps(); + +public: + bool fullscreen = false; + + bool dirty = true; + double last_x = 0, last_y = 0; + bool tracking = false; + + bool rotating = false; + + double last_click = -1; + + GLFWwindow *window = nullptr; + llmr::Settings &settings; + llmr::Map map; +}; + +#endif diff --git a/common/map_view.cpp b/common/map_view.cpp deleted file mode 100644 index cf8269a44e..0000000000 --- a/common/map_view.cpp +++ /dev/null @@ -1,263 +0,0 @@ -#include <GLFW/glfw3.h> -#include <llmr/llmr.hpp> -#include <llmr/map/settings.hpp> - -class MapView { -public: - MapView(llmr::Settings& settings, bool fullscreen = false) : - fullscreen(fullscreen), - settings(settings), - map(settings) { - } - - void init() { - if (!glfwInit()) { - fprintf(stderr, "Failed to initialize glfw\n"); - exit(1); - } - - GLFWmonitor *monitor = nullptr; - if (fullscreen) { - monitor = glfwGetPrimaryMonitor(); - } - -#ifdef GL_ES_VERSION_2_0 - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); -#endif - - glfwWindowHint(GLFW_RED_BITS, 8); - glfwWindowHint(GLFW_GREEN_BITS, 8); - glfwWindowHint(GLFW_BLUE_BITS, 8); - glfwWindowHint(GLFW_ALPHA_BITS, 8); - glfwWindowHint(GLFW_STENCIL_BITS, 8); - glfwWindowHint(GLFW_DEPTH_BITS, 16); - - window = glfwCreateWindow(1024, 768, "llmr", monitor, NULL); - if (!window) { - glfwTerminate(); - fprintf(stderr, "Failed to initialize window\n"); - exit(1); - } - - glfwSetWindowUserPointer(window, this); - glfwMakeContextCurrent(window); - - - int width, height; - glfwGetWindowSize(window, &width, &height); - int fb_width, fb_height; - glfwGetFramebufferSize(window, &fb_width, &fb_height); - - settings.load(); - map.setup(); - - resize(window, 0, 0); - - glfwSwapInterval(1); - - map.loadSettings(); - - glfwSetCursorPosCallback(window, mousemove); - glfwSetMouseButtonCallback(window, mouseclick); - glfwSetWindowSizeCallback(window, resize); - glfwSetFramebufferSizeCallback(window, resize); - glfwSetScrollCallback(window, scroll); - glfwSetKeyCallback(window, key); - } - - static void key(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) { - MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); - - if (action == GLFW_RELEASE) { - switch (key) { - case GLFW_KEY_ESCAPE: - glfwSetWindowShouldClose(window, true); - break; - case GLFW_KEY_TAB: - mapView->map.toggleDebug(); - break; - case GLFW_KEY_X: - if (!mods) mapView->map.resetPosition(); - break; - case GLFW_KEY_R: - if (!mods) mapView->map.toggleRaster(); - break; - case GLFW_KEY_N: - if (!mods) mapView->map.resetNorth(); - break; - } - } - } - - static void scroll(GLFWwindow *window, double /*xoffset*/, double yoffset) { - MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); - double delta = yoffset * 40; - - bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0; - - double absdelta = delta < 0 ? -delta : delta; - double scale = 2.0 / (1.0 + exp(-absdelta / 100.0)); - - // Make the scroll wheel a bit slower. - if (!is_wheel) { - scale = (scale - 1.0) / 2.0 + 1.0; - } - - // Zooming out. - if (delta < 0 && scale != 0) { - scale = 1.0 / scale; - } - - mapView->map.startScaling(); - mapView->map.scaleBy(scale, mapView->last_x, mapView->last_y); - } - - static void resize(GLFWwindow *window, int, int) { - MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); - - int width, height; - glfwGetWindowSize(window, &width, &height); - int fb_width, fb_height; - glfwGetFramebufferSize(window, &fb_width, &fb_height); - - mapView->map.resize(width, height, (float)fb_width / (float)width, fb_width, fb_height); - mapView->map.update(); - } - - static void mouseclick(GLFWwindow *window, int button, int action, int modifiers) { - MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); - - if (button == GLFW_MOUSE_BUTTON_RIGHT || (button == GLFW_MOUSE_BUTTON_LEFT && modifiers & GLFW_MOD_CONTROL)) { - mapView->rotating = action == GLFW_PRESS; - if (!mapView->rotating) { - mapView->map.stopRotating(); - } - } else if (button == GLFW_MOUSE_BUTTON_LEFT) { - mapView->tracking = action == GLFW_PRESS; - - if (action == GLFW_RELEASE) { - mapView->map.stopPanning(); - double now = glfwGetTime(); - if (now - mapView->last_click < 0.4 /* ms */) { - mapView->map.scaleBy(2.0, mapView->last_x, mapView->last_y, 0.5); - } - mapView->last_click = now; - } - } - } - - static void mousemove(GLFWwindow *window, double x, double y) { - MapView *mapView = (MapView *)glfwGetWindowUserPointer(window); - if (mapView->tracking) { - double dx = x - mapView->last_x; - double dy = y - mapView->last_y; - if (dx || dy) { - mapView->map.startPanning(); - mapView->map.moveBy(dx, dy); - } - } else if (mapView->rotating) { - mapView->map.startRotating(); - mapView->map.rotateBy(mapView->last_x, mapView->last_y, x, y); - } - mapView->last_x = x; - mapView->last_y = y; - } - - int run() { - while (!glfwWindowShouldClose(window)) { - llmr::platform::cleanup(); - - if (dirty) { - try { - dirty = map.render(); - } catch (std::exception& ex) { - fprintf(stderr, "exception: %s\n", ex.what()); - } - glfwSwapBuffers(window); - fps(); - } - - if (dirty) { - glfwPollEvents(); - } else { - glfwWaitEvents(); - } - } - - return 0; - } - - void fps() { - static int frames = 0; - static double time_elapsed = 0; - - frames++; - double current_time = glfwGetTime(); - - if (current_time - time_elapsed >= 1) { - fprintf(stderr, "FPS: %4.2f\n", frames / (current_time - time_elapsed)); - time_elapsed = current_time; - frames = 0; - } - } - - ~MapView() { - glfwTerminate(); - } - -public: - bool fullscreen = false; - - bool dirty = true; - double last_x = 0, last_y = 0; - bool tracking = false; - - bool rotating = false; - - double last_click = -1; - - GLFWwindow *window = nullptr; - llmr::Settings& settings; - llmr::Map map; -}; - -namespace llmr { -namespace platform { - -double elapsed() { - return glfwGetTime(); -} - - -void show_debug_image(std::string name, const char *data, size_t width, size_t height) { - static GLFWwindow *debug_window = nullptr; - if (!debug_window) { - debug_window = glfwCreateWindow(width, height, name.c_str(), nullptr, nullptr); - if (!debug_window) { - glfwTerminate(); - fprintf(stderr, "Failed to initialize window\n"); - exit(1); - } - } - - GLFWwindow *current_window = glfwGetCurrentContext(); - - glfwSetWindowSize(debug_window, width, height); - glfwMakeContextCurrent(debug_window); - - int fb_width, fb_height; - glfwGetFramebufferSize(debug_window, &fb_width, &fb_height); - float scale = (float)fb_width / (float)width; - - glPixelZoom(scale, -scale); - glRasterPos2f(-1.0f, 1.0f); - glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); - glfwSwapBuffers(debug_window); - - glfwMakeContextCurrent(current_window); -} - -} -} diff --git a/linux/llmr-app.gyp b/linux/llmr-app.gyp index de455e38ae..e12737b92c 100644 --- a/linux/llmr-app.gyp +++ b/linux/llmr-app.gyp @@ -14,6 +14,8 @@ './settings.hpp', './request.cpp', './request.hpp', + '../common/glfw_view.hpp', + '../common/glfw_view.cpp', ], 'conditions': [ diff --git a/linux/main.cpp b/linux/main.cpp index bb32029bb8..42aa579b8c 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -4,8 +4,8 @@ #include <signal.h> #include <getopt.h> -#include "../common/map_view.cpp" #include "settings.hpp" +#include "../common/glfw_view.hpp" #include "request.hpp" diff --git a/macosx/llmr-app.gyp b/macosx/llmr-app.gyp index 3c1bfedf77..b6a42c91c9 100644 --- a/macosx/llmr-app.gyp +++ b/macosx/llmr-app.gyp @@ -12,7 +12,10 @@ './main.mm', './settings.mm', './settings.hpp', - '../common/foundation_request.mm' + '../common/glfw_view.hpp', + '../common/glfw_view.cpp', + '../common/foundation_request.h', + '../common/foundation_request.mm', ], 'product_extension': 'app', 'mac_bundle': 1, diff --git a/macosx/main.mm b/macosx/main.mm index 6a40f22e11..c6cc04d843 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -2,7 +2,7 @@ #import <AppKit/AppKit.h> #include "settings.hpp" -#include "../common/map_view.cpp" +#include "../common/glfw_view.hpp" #include <cstdio> |