Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
remove code duplication between osx/glfw and linux/glfw programs
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaefer committed Mar 14, 2014
1 parent 4f03b43 commit bdfa761
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 519 deletions.
236 changes: 236 additions & 0 deletions common/map_view.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
#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((double)fb_width / width);

resize(window, 0, 0);

glfwSwapInterval(1);

map.loadSettings();

glfwSetCursorPosCallback(window, mousemove);
glfwSetMouseButtonCallback(window, mouseclick);
glfwSetWindowSizeCallback(window, resize);
glfwSetFramebufferSizeCallback(window, resize);
glfwSetScrollCallback(window, scroll);
glfwSetCharCallback(window, character);
glfwSetKeyCallback(window, key);
}


static void character(GLFWwindow *window, unsigned int codepoint) {

}


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_R:
if (!mods) mapView->map.resetPosition();
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, fb_width, fb_height);
}

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->start_x = mapView->last_x;
mapView->start_y = mapView->last_y;
} else {
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) {
mapView->map.scaleBy(2.0, mapView->last_x, mapView->last_y);
}
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->start_x, mapView->start_y, 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 = render();
} catch (std::exception& ex) {
fprintf(stderr, "exception: %s\n", ex.what());
}
glfwSwapBuffers(window);
fps();
}

if (dirty) {
glfwPollEvents();
} else {
glfwWaitEvents();
}
}

return 0;
}

bool render() {
return map.render();
}

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;

double start_x = 0, start_y = 0;
bool rotating = false;

double last_click = -1;

GLFWwindow *window = nullptr;
llmr::Settings& settings;
llmr::Map map;
};
3 changes: 3 additions & 0 deletions include/llmr/platform/platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ void cancel_request_http(Request *request);
// Returns a relative timestamp in seconds. This value must be monotonic.
double time();

// Performs routine cleanup operation and is called on every loop iteration.
void cleanup();

}

}
Expand Down
Loading

0 comments on commit bdfa761

Please sign in to comment.