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 }