2018-06-22 23:54:39 +01:00
|
|
|
module imgui;
|
|
|
|
|
|
|
|
import glad.gl.all;
|
|
|
|
import derelict.sdl2.sdl;
|
|
|
|
import derelict.imgui.imgui;
|
|
|
|
|
|
|
|
import window;
|
|
|
|
|
|
|
|
import std.traits : isDelegate, ReturnType, ParameterTypeTuple;
|
|
|
|
auto bindDelegate(T, string file = __FILE__, size_t line = __LINE__)(T t) if(isDelegate!T) {
|
|
|
|
|
|
|
|
static T dg;
|
|
|
|
dg = t;
|
|
|
|
|
|
|
|
extern(C) static ReturnType!T func(ParameterTypeTuple!T args) {
|
|
|
|
return dg(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
return &func;
|
|
|
|
|
|
|
|
} // bindDelegate (thanks Destructionator)
|
|
|
|
|
|
|
|
struct Imgui {
|
|
|
|
|
|
|
|
// OpenGL data, cleanup soon
|
2018-10-03 23:36:40 +01:00
|
|
|
GLuint font_texture_ = 0;
|
|
|
|
int shander_handle_ = 0, vs_handle_ = 0, fs_handle_ = 0;
|
|
|
|
int shader_attrib_loc_tex_ = 0, shader_attrib_loc_projmtx_ = 0;
|
|
|
|
int shader_attrib_loc_pos_ = 0, shader_attrib_loc_uv_ = 0, shader_attrib_loc_color_ = 0;
|
|
|
|
uint vao_ = 0, vbo_ = 0, ebo_ = 0;
|
2018-06-22 23:54:39 +01:00
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
// imgui input related state
|
|
|
|
bool[3] mouse_buttons_pressed;
|
|
|
|
float scroll_wheel = 0.0f;
|
|
|
|
|
2018-06-22 23:54:39 +01:00
|
|
|
void initialize() {
|
|
|
|
|
|
|
|
auto io = igGetIO();
|
|
|
|
io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
|
|
|
|
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
|
|
|
|
io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
|
|
|
|
io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
|
|
|
|
io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
|
|
|
|
io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
|
|
|
|
io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
|
|
|
|
io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
|
|
|
|
io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
|
|
|
|
io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
|
|
|
|
io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
|
|
|
|
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
|
|
|
|
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
|
|
|
|
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
|
|
|
|
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
|
|
|
|
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
|
|
|
|
io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
|
|
|
|
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
|
|
|
|
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
|
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
io.RenderDrawListsFn = bindDelegate(&renderDrawLists);
|
|
|
|
io.SetClipboardTextFn = bindDelegate(&setClipboardText);
|
|
|
|
io.GetClipboardTextFn = bindDelegate(&getClipboardText);
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
void createFontTexture() {
|
|
|
|
|
|
|
|
// build texture atlas
|
|
|
|
auto io = igGetIO();
|
|
|
|
|
|
|
|
ubyte* pixels;
|
|
|
|
int width, height;
|
|
|
|
ImFontAtlas_GetTexDataAsRGBA32(io.Fonts, &pixels, &width, &height, null);
|
|
|
|
|
|
|
|
// upload texture to graphics system
|
|
|
|
GLint last_texture;
|
|
|
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
2018-10-03 23:36:40 +01:00
|
|
|
glGenTextures(1, &font_texture_);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, font_texture_);
|
2018-06-23 01:02:07 +01:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
|
|
|
|
|
|
// store our identifier
|
2018-10-03 23:36:40 +01:00
|
|
|
ImFontAtlas_SetTexID(io.Fonts, cast(void*)font_texture_);
|
2018-06-23 01:02:07 +01:00
|
|
|
|
|
|
|
// restore state
|
|
|
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
void createDeviceObjects() {
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
// backup GL state
|
|
|
|
GLint last_texture, last_array_buffer, last_vertex_array;
|
2018-06-23 01:02:07 +01:00
|
|
|
if (last_texture != 0) glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
|
|
if (last_array_buffer != 0) glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
|
|
|
if (last_vertex_array != 0) glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
const GLchar *vertex_shader = q{
|
|
|
|
#version 330
|
|
|
|
uniform mat4 ProjMtx;
|
|
|
|
in vec2 Position;
|
|
|
|
in vec2 UV;
|
|
|
|
in vec4 Color;
|
|
|
|
out vec2 Frag_UV;
|
|
|
|
out vec4 Frag_Color;
|
|
|
|
void main() {
|
|
|
|
Frag_UV = UV;
|
|
|
|
Frag_Color = Color;
|
|
|
|
gl_Position = ProjMtx * vec4(Position.xy,0,1);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const GLchar* fragment_shader = q{
|
|
|
|
#version 330
|
|
|
|
uniform sampler2D Texture;
|
|
|
|
in vec2 Frag_UV;
|
|
|
|
in vec4 Frag_Color;
|
|
|
|
out vec4 Out_Color;
|
|
|
|
void main() {
|
|
|
|
Out_Color = Frag_Color * texture( Texture, Frag_UV.st);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-10-03 23:36:40 +01:00
|
|
|
shander_handle_ = glCreateProgram();
|
|
|
|
vs_handle_ = glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
fs_handle_ = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
glShaderSource(vs_handle_, 1, &vertex_shader, null);
|
|
|
|
glShaderSource(fs_handle_, 1, &fragment_shader, null);
|
|
|
|
glCompileShader(vs_handle_);
|
|
|
|
glCompileShader(fs_handle_);
|
|
|
|
glAttachShader(shander_handle_, vs_handle_);
|
|
|
|
glAttachShader(shander_handle_, fs_handle_);
|
|
|
|
glLinkProgram(shander_handle_);
|
|
|
|
|
|
|
|
shader_attrib_loc_tex_ = glGetUniformLocation(shander_handle_, "Texture");
|
|
|
|
shader_attrib_loc_projmtx_ = glGetUniformLocation(shander_handle_, "ProjMtx");
|
|
|
|
shader_attrib_loc_pos_ = glGetAttribLocation(shander_handle_, "Position");
|
|
|
|
shader_attrib_loc_uv_ = glGetAttribLocation(shander_handle_, "UV");
|
|
|
|
shader_attrib_loc_color_ = glGetAttribLocation(shander_handle_, "Color");
|
|
|
|
|
|
|
|
glGenBuffers(1, &vbo_);
|
|
|
|
glGenBuffers(1, &ebo_);
|
|
|
|
|
|
|
|
glGenVertexArrays(1, &vao_);
|
|
|
|
glBindVertexArray(vao_);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_);
|
|
|
|
glEnableVertexAttribArray(shader_attrib_loc_pos_);
|
|
|
|
glEnableVertexAttribArray(shader_attrib_loc_uv_);
|
|
|
|
glEnableVertexAttribArray(shader_attrib_loc_color_);
|
|
|
|
|
|
|
|
glVertexAttribPointer(shader_attrib_loc_pos_, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(void*)ImDrawVert.pos.offsetof);
|
|
|
|
glVertexAttribPointer(shader_attrib_loc_uv_, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(void*)ImDrawVert.uv.offsetof);
|
|
|
|
glVertexAttribPointer(shader_attrib_loc_color_, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.sizeof, cast(void*)ImDrawVert.col.offsetof);
|
2018-06-22 23:54:39 +01:00
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
createFontTexture();
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
// restore modified GL state
|
|
|
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
|
|
|
glBindVertexArray(last_vertex_array);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-10-03 23:36:40 +01:00
|
|
|
struct GLState {
|
|
|
|
GLenum last_active_texture;
|
|
|
|
GLint last_program;
|
|
|
|
GLint last_texture;
|
|
|
|
GLint last_array_buffer;
|
|
|
|
GLint last_element_array_buffer;
|
|
|
|
GLint last_vertex_array;
|
|
|
|
GLint[4] last_viewport;
|
|
|
|
GLint[4] last_scissor_box;
|
|
|
|
GLenum last_blend_src_rgb;
|
|
|
|
GLenum last_blend_dst_rgb;
|
|
|
|
GLenum last_blend_src_alpha;
|
|
|
|
GLenum last_blend_dst_alpha;
|
|
|
|
GLenum last_blend_equation_rgb;
|
|
|
|
GLenum last_blend_equation_alpha;
|
|
|
|
GLboolean last_enable_blend;
|
|
|
|
GLboolean last_enable_cull_face;
|
|
|
|
GLboolean last_enable_depth_test;
|
|
|
|
GLboolean last_enable_scissor_test;
|
|
|
|
}
|
|
|
|
|
|
|
|
nothrow @nogc
|
|
|
|
GLState backupGLState() {
|
|
|
|
|
|
|
|
GLState gl_state;
|
|
|
|
|
|
|
|
// backup GL state
|
|
|
|
with (gl_state) {
|
|
|
|
glGetIntegerv(GL_ACTIVE_TEXTURE, cast(GLint*)&last_active_texture);
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
|
|
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
|
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
|
|
|
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
|
|
|
|
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
|
|
|
glGetIntegerv(GL_VIEWPORT, last_viewport.ptr);
|
|
|
|
glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box.ptr);
|
|
|
|
glGetIntegerv(GL_BLEND_SRC_RGB, cast(GLint*)&last_blend_src_rgb);
|
|
|
|
glGetIntegerv(GL_BLEND_DST_RGB, cast(GLint*)&last_blend_dst_rgb);
|
|
|
|
glGetIntegerv(GL_BLEND_SRC_ALPHA, cast(GLint*)&last_blend_src_alpha);
|
|
|
|
glGetIntegerv(GL_BLEND_DST_ALPHA, cast(GLint*)&last_blend_dst_alpha);
|
|
|
|
glGetIntegerv(GL_BLEND_EQUATION_RGB, cast(GLint*)&last_blend_equation_rgb);
|
|
|
|
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, cast(GLint*)&last_blend_equation_alpha);
|
|
|
|
last_enable_blend = glIsEnabled(GL_BLEND);
|
|
|
|
last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
|
|
|
|
last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
|
|
|
last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
return gl_state;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
nothrow @nogc
|
|
|
|
void restoreGLState(GLState state) {
|
|
|
|
|
|
|
|
// restore modified GL state
|
|
|
|
with (state) {
|
|
|
|
glUseProgram(last_program);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
|
|
glActiveTexture(last_active_texture);
|
|
|
|
glBindVertexArray(last_vertex_array);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
|
|
|
|
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
|
|
|
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
|
|
|
|
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
|
|
|
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
|
|
|
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
|
|
|
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
|
|
|
glViewport(last_viewport[0], last_viewport[1], cast(GLsizei)last_viewport[2], cast(GLsizei)last_viewport[3]);
|
|
|
|
glScissor(last_scissor_box[0], last_scissor_box[1], cast(GLsizei)last_scissor_box[2], cast(GLsizei)last_scissor_box[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-06-22 23:54:39 +01:00
|
|
|
extern(C) nothrow
|
2018-06-23 01:02:07 +01:00
|
|
|
void renderDrawLists(ImDrawData* draw_data) {
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
// avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
|
|
|
auto io = igGetIO();
|
|
|
|
int fb_width = cast(int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
|
|
|
|
int fb_height = cast(int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
|
|
|
|
if (fb_width == 0 || fb_height == 0) { return; }
|
|
|
|
draw_data.ScaleClipRects(io.DisplayFramebufferScale);
|
|
|
|
|
|
|
|
// backup GL state
|
2018-10-03 23:36:40 +01:00
|
|
|
GLState last_state = backupGLState();
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendEquation(GL_FUNC_ADD);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
|
|
|
|
// Setup viewport, orthographic projection matrix
|
|
|
|
glViewport(0, 0, cast(GLsizei)fb_width, cast(GLsizei)fb_height);
|
|
|
|
const float[4][4] ortho_projection = [
|
|
|
|
[ 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f ],
|
|
|
|
[ 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f ],
|
|
|
|
[ 0.0f, 0.0f, -1.0f, 0.0f ],
|
|
|
|
[-1.0f, 1.0f, 0.0f, 1.0f ],
|
|
|
|
];
|
2018-06-23 01:02:07 +01:00
|
|
|
|
2018-10-03 23:36:40 +01:00
|
|
|
glUseProgram(shander_handle_);
|
|
|
|
glUniform1i(shader_attrib_loc_tex_, 0);
|
|
|
|
glUniformMatrix4fv(shader_attrib_loc_projmtx_, 1, GL_FALSE, &ortho_projection[0][0]);
|
|
|
|
glBindVertexArray(vao_);
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
foreach (int n; 0 .. draw_data.CmdListsCount) {
|
|
|
|
ImDrawList* cmd_list = draw_data.CmdLists[n];
|
|
|
|
ImDrawIdx* idx_buffer_offset;
|
|
|
|
|
|
|
|
auto countVertices = ImDrawList_GetVertexBufferSize(cmd_list);
|
|
|
|
auto countIndices = ImDrawList_GetIndexBufferSize(cmd_list);
|
|
|
|
|
2018-10-03 23:36:40 +01:00
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_);
|
2018-06-22 23:54:39 +01:00
|
|
|
glBufferData(GL_ARRAY_BUFFER, countVertices * ImDrawVert.sizeof, cast(GLvoid*)ImDrawList_GetVertexPtr(cmd_list,0), GL_STREAM_DRAW);
|
|
|
|
|
2018-10-03 23:36:40 +01:00
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_);
|
2018-06-22 23:54:39 +01:00
|
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, countIndices * ImDrawIdx.sizeof, cast(GLvoid*)ImDrawList_GetIndexPtr(cmd_list,0), GL_STREAM_DRAW);
|
|
|
|
|
|
|
|
auto cmdCnt = ImDrawList_GetCmdSize(cmd_list);
|
|
|
|
|
|
|
|
foreach(int cmd_i; 0 .. cmdCnt) {
|
|
|
|
auto pcmd = ImDrawList_GetCmdPtr(cmd_list, cmd_i);
|
|
|
|
|
|
|
|
if (pcmd.UserCallback) {
|
|
|
|
pcmd.UserCallback(cmd_list, pcmd);
|
|
|
|
} else {
|
|
|
|
glBindTexture(GL_TEXTURE_2D, cast(GLuint)pcmd.TextureId);
|
|
|
|
glScissor(cast(int)pcmd.ClipRect.x, cast(int)(fb_height - pcmd.ClipRect.w), cast(int)(pcmd.ClipRect.z - pcmd.ClipRect.x), cast(int)(pcmd.ClipRect.w - pcmd.ClipRect.y));
|
|
|
|
glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
|
|
|
}
|
|
|
|
idx_buffer_offset += pcmd.ElemCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 23:36:40 +01:00
|
|
|
// restore old state
|
|
|
|
restoreGLState(last_state);
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
extern(C) nothrow
|
2018-06-23 01:02:07 +01:00
|
|
|
const(char)* getClipboardText(void* user_data) {
|
2018-06-22 23:54:39 +01:00
|
|
|
return SDL_GetClipboardText();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern(C) nothrow
|
2018-06-23 01:02:07 +01:00
|
|
|
void setClipboardText(void* user_data, const (char)* text) {
|
2018-06-22 23:54:39 +01:00
|
|
|
SDL_SetClipboardText(text);
|
|
|
|
}
|
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
void newFrame(ref Window win) {
|
|
|
|
|
|
|
|
auto io = igGetIO();
|
|
|
|
|
|
|
|
int win_w, win_h;
|
2018-09-30 17:22:59 +01:00
|
|
|
win.windowSize(win_w, win_h);
|
2018-06-23 01:02:07 +01:00
|
|
|
|
|
|
|
int fbo_w, fbo_h;
|
2018-09-30 17:22:59 +01:00
|
|
|
win.framebufferSize(fbo_w, fbo_h);
|
2018-06-23 01:02:07 +01:00
|
|
|
|
|
|
|
io.DisplaySize = ImVec2(win_w, win_h);
|
|
|
|
io.DisplayFramebufferScale = ImVec2(cast(float)fbo_w / win_w, cast(float)fbo_h / win_h);
|
|
|
|
|
|
|
|
int m_x, m_y;
|
2018-09-30 17:22:59 +01:00
|
|
|
win.mousePos(m_x, m_y);
|
2018-06-23 01:02:07 +01:00
|
|
|
io.MousePos = ImVec2(cast(float)m_x, cast(float)m_y);
|
|
|
|
|
|
|
|
io.MouseDown[0] = mouse_buttons_pressed[0] || (SDL_GetMouseState(null, null) & SDL_BUTTON_LEFT) != 0;
|
|
|
|
mouse_buttons_pressed[0] = false;
|
|
|
|
|
|
|
|
io.MouseDown[1] = mouse_buttons_pressed[0] || (SDL_GetMouseState(null, null) & SDL_BUTTON_MIDDLE) != 0;
|
|
|
|
mouse_buttons_pressed[1] = false;
|
|
|
|
|
|
|
|
io.MouseDown[2] = mouse_buttons_pressed[2] || (SDL_GetMouseState(null, null) & SDL_BUTTON_RIGHT) != 0;
|
|
|
|
mouse_buttons_pressed[2] = false;
|
|
|
|
|
|
|
|
io.MouseWheel = scroll_wheel;
|
|
|
|
scroll_wheel = 0.0f;
|
|
|
|
|
|
|
|
igNewFrame();
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
void endFrame() {
|
|
|
|
|
|
|
|
igRender();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void handleEvent(ref SDL_Event ev) {
|
|
|
|
|
|
|
|
auto io = igGetIO();
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
switch (ev.type) with (SDL_EventType) {
|
|
|
|
|
|
|
|
case SDL_TEXTINPUT:
|
2018-06-23 01:02:07 +01:00
|
|
|
ImGuiIO_AddInputCharacter(cast(ushort)ev.text.text[0]);
|
|
|
|
|
2018-06-22 23:54:39 +01:00
|
|
|
break;
|
|
|
|
|
2018-06-23 01:02:07 +01:00
|
|
|
case SDL_KEYDOWN, SDL_KEYUP:
|
|
|
|
|
|
|
|
auto mods = ev.key.keysym.mod;
|
|
|
|
io.KeyCtrl = (mods & KMOD_CTRL) != 0;
|
|
|
|
io.KeyShift = (mods & KMOD_SHIFT) != 0;
|
|
|
|
io.KeyAlt = (mods & KMOD_ALT) != 0;
|
|
|
|
|
2018-06-22 23:54:39 +01:00
|
|
|
break;
|
2018-06-23 01:02:07 +01:00
|
|
|
|
|
|
|
case SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP:
|
|
|
|
auto btn = ev.button.button;
|
|
|
|
|
|
|
|
if (btn < 4) {
|
|
|
|
mouse_buttons_pressed[btn - 1] = (ev.type == SDL_MOUSEBUTTONDOWN);
|
|
|
|
}
|
|
|
|
|
2018-06-22 23:54:39 +01:00
|
|
|
break;
|
2018-06-23 01:02:07 +01:00
|
|
|
|
2018-06-22 23:54:39 +01:00
|
|
|
case SDL_MOUSEWHEEL:
|
2018-06-23 01:02:07 +01:00
|
|
|
scroll_wheel += ev.wheel.y;
|
2018-06-22 23:54:39 +01:00
|
|
|
|
|
|
|
break;
|
2018-06-23 01:02:07 +01:00
|
|
|
|
2018-06-22 23:54:39 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|