1 /** 2 Copyright: Copyright (c) 2015-2016 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module voxelman.gui.plugin; 8 9 import std.experimental.logger; 10 import std.string : format; 11 import voxelman.math; 12 import derelict.imgui.imgui; 13 14 import anchovy.glfwwindow; 15 import anchovy.input; 16 import anchovy.irenderer; 17 import anchovy.iwindow; 18 import anchovy.oglrenderer; 19 20 import pluginlib; 21 import voxelman.imgui_glfw; 22 23 import voxelman.core.config; 24 import voxelman.core.events; 25 import voxelman.world.storage.chunk; 26 import voxelman.world.storage.coordinates; 27 import voxelman.world.storage.utils; 28 29 import voxelman.eventdispatcher.plugin; 30 import voxelman.config.configmanager; 31 32 33 struct ClosePressedEvent {} 34 35 shared static this() 36 { 37 pluginRegistry.regClientPlugin(new GuiPlugin); 38 } 39 40 final class GuiPlugin : IPlugin 41 { 42 private: 43 EventDispatcherPlugin evDispatcher; 44 ConfigOption resolution; 45 46 public: 47 IWindow window; 48 IRenderer renderer; 49 ImguiState igState; 50 51 mixin IdAndSemverFrom!(voxelman.gui.plugininfo); 52 53 override void registerResources(IResourceManagerRegistry resmanRegistry) 54 { 55 auto config = resmanRegistry.getResourceManager!ConfigManager; 56 resolution = config.registerOption!(int[])("resolution", [1280, 720]); 57 } 58 59 override void preInit() 60 { 61 initLibs(); 62 63 window = new GlfwWindow(); 64 window.init(uvec2(resolution.get!(int[])), "Voxelman client"); 65 renderer = new OglRenderer(window); 66 igState.init((cast(GlfwWindow)window).handle); 67 68 // Bind events 69 window.windowResized.connect(&windowResized); 70 window.closePressed.connect(&closePressed); 71 72 window.keyPressed.connect(&igState.onKeyPressed); 73 window.keyReleased.connect(&igState.onKeyReleased); 74 window.charEntered.connect(&igState.charCallback); 75 window.mousePressed.connect(&igState.onMousePressed); 76 window.mouseReleased.connect(&igState.onMouseReleased); 77 window.wheelScrolled.connect((dvec2 s) => igState.scrollCallback(s.y)); 78 } 79 80 void initLibs() 81 { 82 import derelict.glfw3.glfw3; 83 import derelict.opengl3.gl3; 84 import derelict.imgui.imgui; 85 import voxelman.utils.libloader; 86 87 DerelictGL3.load(); 88 DerelictGLFW3.load([getLibName(BUILD_TO_ROOT_PATH, "glfw3")]); 89 DerelictImgui.load(getLibName(BUILD_TO_ROOT_PATH, "cimgui")); 90 } 91 92 override void init(IPluginManager pluginman) 93 { 94 evDispatcher = pluginman.getPlugin!EventDispatcherPlugin; 95 evDispatcher.subscribeToEvent(&onPreUpdateEvent); 96 evDispatcher.subscribeToEvent(&onRender3Event); 97 evDispatcher.subscribeToEvent(&onGameStopEvent); 98 } 99 100 override void postInit() 101 { 102 igState.newFrame(); 103 // set debug window size 104 igSetNextWindowSize(ImVec2(270, 500), ImGuiSetCond_FirstUseEver); 105 igSetNextWindowPos(ImVec2(0, 0), ImGuiSetCond_FirstUseEver); 106 igBegin("Debug"); 107 igSameLine(); 108 igEnd(); 109 igState.render(); 110 } 111 112 void onPreUpdateEvent(ref PreUpdateEvent event) 113 { 114 window.processEvents(); 115 igState.newFrame(); 116 } 117 118 void onRender3Event(ref Render3Event event) 119 { 120 igState.render(); 121 } 122 123 void onGameStopEvent(ref GameStopEvent stopEvent) 124 { 125 window.releaseWindow; 126 igState.shutdown(); 127 } 128 129 private void windowResized(uvec2 newSize) 130 { 131 evDispatcher.postEvent(WindowResizedEvent(newSize)); 132 } 133 134 private void closePressed() 135 { 136 evDispatcher.postEvent(ClosePressedEvent()); 137 } 138 }