mirror of https://github.com/inolen/redream.git
added imgui implementation
This commit is contained in:
parent
d0a6283b7e
commit
b1375e8807
|
@ -116,6 +116,17 @@ list(APPEND REDREAM_INCLUDE_DIRS deps/glew-1.13.0/include)
|
|||
list(APPEND REDREAM_LIBS glew_s)
|
||||
list(APPEND REDREAM_DEFS GLEW_STATIC)
|
||||
|
||||
# imgui
|
||||
add_library(imgui STATIC
|
||||
deps/cimgui/imgui/imgui.cpp
|
||||
deps/cimgui/imgui/imgui_draw.cpp
|
||||
deps/cimgui/cimgui/cimgui.cpp
|
||||
deps/cimgui/cimgui/drawList.cpp
|
||||
deps/cimgui/cimgui/fontAtlas.cpp
|
||||
deps/cimgui/cimgui/listClipper.cpp)
|
||||
list(APPEND REDREAM_INCLUDE_DIRS deps/cimgui)
|
||||
list(APPEND REDREAM_LIBS imgui)
|
||||
|
||||
# inih
|
||||
add_library(inih STATIC deps/inih/ini.c)
|
||||
list(APPEND REDREAM_INCLUDE_DIRS deps/inih)
|
||||
|
@ -208,6 +219,7 @@ set(REDREAM_SOURCES
|
|||
src/jit/jit.c
|
||||
src/jit/pass_stats.c
|
||||
src/render/gl_backend.c
|
||||
src/render/imgui.cc
|
||||
src/render/microprofile.cc
|
||||
src/render/nuklear.c
|
||||
src/sys/exception_handler.c
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "hw/pvr/trace.h"
|
||||
#include "hw/scheduler.h"
|
||||
#include "hw/sh4/sh4.h"
|
||||
#include "render/imgui.h"
|
||||
#include "render/microprofile.h"
|
||||
#include "render/nuklear.h"
|
||||
#include "render/render_backend.h"
|
||||
|
@ -58,6 +59,7 @@ struct emu {
|
|||
volatile int video_resized;
|
||||
|
||||
struct render_backend *r, *r2;
|
||||
struct imgui *imgui;
|
||||
struct microprofile *mp;
|
||||
struct nuklear *nk;
|
||||
struct trace_writer *trace_writer;
|
||||
|
@ -406,6 +408,7 @@ static void emu_paint(struct emu *emu) {
|
|||
float fwidth = (float)emu->video_width;
|
||||
float fheight = (float)emu->video_height;
|
||||
|
||||
imgui_update_input(emu->imgui);
|
||||
nk_update_input(emu->nk);
|
||||
|
||||
r_viewport(emu->r, emu->video_width, emu->video_height);
|
||||
|
@ -517,6 +520,7 @@ static void emu_paint(struct emu *emu) {
|
|||
nk_end(ctx);
|
||||
}
|
||||
|
||||
imgui_render(emu->imgui);
|
||||
mp_render(emu->mp);
|
||||
nk_render(emu->nk);
|
||||
|
||||
|
@ -604,6 +608,7 @@ static void emu_guest_push_audio(void *userdata, const int16_t *data,
|
|||
static void emu_host_mousemove(void *userdata, int port, int x, int y) {
|
||||
struct emu *emu = userdata;
|
||||
|
||||
imgui_mousemove(emu->imgui, x, y);
|
||||
mp_mousemove(emu->mp, x, y);
|
||||
nk_mousemove(emu->nk, x, y);
|
||||
}
|
||||
|
@ -615,6 +620,7 @@ static void emu_host_keydown(void *userdata, int port, enum keycode key,
|
|||
if (key == K_F1 && value > 0) {
|
||||
emu->debug_menu = emu->debug_menu ? 0 : 1;
|
||||
} else {
|
||||
imgui_keydown(emu->imgui, key, value);
|
||||
mp_keydown(emu->mp, key, value);
|
||||
nk_keydown(emu->nk, key, value);
|
||||
}
|
||||
|
@ -668,6 +674,7 @@ static void emu_host_context_destroyed(void *userdata) {
|
|||
|
||||
nk_destroy(emu->nk);
|
||||
mp_destroy(emu->mp);
|
||||
imgui_destroy(emu->imgui);
|
||||
r_destroy(emu->r);
|
||||
}
|
||||
|
||||
|
@ -680,6 +687,7 @@ static void emu_host_context_reset(void *userdata) {
|
|||
|
||||
/* create primary renderer */
|
||||
emu->r = r_create(emu->host);
|
||||
emu->imgui = imgui_create(emu->r);
|
||||
emu->mp = mp_create(emu->r);
|
||||
emu->nk = nk_create(emu->r);
|
||||
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
#include <imgui/imgui.h>
|
||||
|
||||
extern "C" {
|
||||
#include "core/assert.h"
|
||||
#include "render/imgui.h"
|
||||
#include "render/render_backend.h"
|
||||
}
|
||||
|
||||
struct imgui {
|
||||
struct render_backend *r;
|
||||
bool alt[2];
|
||||
bool ctrl[2];
|
||||
bool shift[2];
|
||||
};
|
||||
|
||||
void imgui_render(struct imgui *imgui) {
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
/* update draw batches. note, this doesn't _actually_ render anything because
|
||||
io.RenderDrawListsFn is null */
|
||||
ImGui::Render();
|
||||
|
||||
/* get the latest draw batches, and pass them off out the render backend */
|
||||
ImDrawData *draw_data = ImGui::GetDrawData();
|
||||
|
||||
for (int i = 0; i < draw_data->CmdListsCount; ++i) {
|
||||
const auto cmd_list = draw_data->CmdLists[i];
|
||||
|
||||
struct ui_vertex *verts =
|
||||
reinterpret_cast<struct ui_vertex *>(cmd_list->VtxBuffer.Data);
|
||||
int num_verts = cmd_list->VtxBuffer.size();
|
||||
|
||||
uint16_t *indices = cmd_list->IdxBuffer.Data;
|
||||
int num_indices = cmd_list->IdxBuffer.size();
|
||||
|
||||
r_begin_ui_surfaces(imgui->r, verts, num_verts, indices, num_indices);
|
||||
|
||||
int index_offset = 0;
|
||||
|
||||
for (int j = 0; j < cmd_list->CmdBuffer.size(); ++j) {
|
||||
const auto &cmd = cmd_list->CmdBuffer[j];
|
||||
|
||||
struct ui_surface surf;
|
||||
surf.prim_type = PRIM_TRIANGLES;
|
||||
surf.texture = static_cast<texture_handle_t>(
|
||||
reinterpret_cast<intptr_t>(cmd.TextureId));
|
||||
surf.src_blend = BLEND_SRC_ALPHA;
|
||||
surf.dst_blend = BLEND_ONE_MINUS_SRC_ALPHA;
|
||||
surf.scissor = true;
|
||||
surf.scissor_rect[0] = cmd.ClipRect.x;
|
||||
surf.scissor_rect[1] = io.DisplaySize.y - cmd.ClipRect.w;
|
||||
surf.scissor_rect[2] = cmd.ClipRect.z - cmd.ClipRect.x;
|
||||
surf.scissor_rect[3] = cmd.ClipRect.w - cmd.ClipRect.y;
|
||||
surf.first_vert = index_offset;
|
||||
surf.num_verts = cmd.ElemCount;
|
||||
|
||||
r_draw_ui_surface(imgui->r, &surf);
|
||||
|
||||
index_offset += cmd.ElemCount;
|
||||
}
|
||||
|
||||
r_end_ui_surfaces(imgui->r);
|
||||
}
|
||||
}
|
||||
|
||||
void imgui_update_input(struct imgui *imgui) {
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
int width = r_viewport_width(imgui->r);
|
||||
int height = r_viewport_height(imgui->r);
|
||||
io.DisplaySize =
|
||||
ImVec2(static_cast<float>(width), static_cast<float>(height));
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
/* reset mouse scroll state */
|
||||
io.MouseWheel = 0.0;
|
||||
}
|
||||
|
||||
void imgui_keydown(struct imgui *imgui, enum keycode code, int16_t value) {
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
if (code == K_MWHEELUP) {
|
||||
io.MouseWheel = 1.0f;
|
||||
} else if (code == K_MWHEELDOWN) {
|
||||
io.MouseWheel = -1.0f;
|
||||
} else if (code == K_MOUSE1) {
|
||||
io.MouseDown[0] = value > 0;
|
||||
} else if (code == K_MOUSE2) {
|
||||
io.MouseDown[1] = value > 0;
|
||||
} else if (code == K_MOUSE3) {
|
||||
io.MouseDown[2] = value > 0;
|
||||
;
|
||||
} else if (code == K_LALT || code == K_RALT) {
|
||||
imgui->alt[code == K_LALT ? 0 : 1] = !!value;
|
||||
io.KeyAlt = imgui->alt[0] || imgui->alt[1];
|
||||
} else if (code == K_LCTRL || code == K_RCTRL) {
|
||||
imgui->ctrl[code == K_LCTRL ? 0 : 1] = !!value;
|
||||
io.KeyCtrl = imgui->ctrl[0] || imgui->ctrl[1];
|
||||
} else if (code == K_LSHIFT || code == K_RSHIFT) {
|
||||
imgui->shift[code == K_LSHIFT ? 0 : 1] = !!value;
|
||||
io.KeyShift = imgui->shift[0] || imgui->shift[1];
|
||||
} else {
|
||||
io.KeysDown[code] = value > 0;
|
||||
}
|
||||
}
|
||||
|
||||
void imgui_mousemove(struct imgui *imgui, int x, int y) {
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
io.MousePos = ImVec2((float)x, (float)y);
|
||||
}
|
||||
|
||||
void imgui_destroy(struct imgui *imgui) {
|
||||
ImGui::Shutdown();
|
||||
|
||||
free(imgui);
|
||||
}
|
||||
|
||||
struct imgui *imgui_create(struct render_backend *r) {
|
||||
struct imgui *imgui =
|
||||
reinterpret_cast<struct imgui *>(calloc(1, sizeof(struct imgui)));
|
||||
|
||||
imgui->r = r;
|
||||
|
||||
/* initialize imgui */
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
/* don't really care if this is accurate */
|
||||
io.DeltaTime = 1.0f / 60.0f;
|
||||
|
||||
/* don't save settings */
|
||||
io.IniSavingRate = 0.0f;
|
||||
|
||||
/* setup key mapping */
|
||||
io.KeyMap[ImGuiKey_Tab] = K_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = K_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = K_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = K_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = K_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = K_PAGEUP;
|
||||
io.KeyMap[ImGuiKey_PageDown] = K_PAGEDOWN;
|
||||
io.KeyMap[ImGuiKey_Delete] = K_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = K_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = K_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = K_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = 'a';
|
||||
io.KeyMap[ImGuiKey_C] = 'c';
|
||||
io.KeyMap[ImGuiKey_V] = 'v';
|
||||
io.KeyMap[ImGuiKey_X] = 'x';
|
||||
io.KeyMap[ImGuiKey_Y] = 'y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'z';
|
||||
|
||||
/* setup misc callbacks ImGui relies on */
|
||||
io.RenderDrawListsFn = nullptr;
|
||||
io.SetClipboardTextFn = nullptr;
|
||||
io.GetClipboardTextFn = nullptr;
|
||||
|
||||
/* register font in backend */
|
||||
uint8_t *pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
texture_handle_t handle =
|
||||
r_create_texture(imgui->r, PXL_RGBA, FILTER_BILINEAR, WRAP_REPEAT,
|
||||
WRAP_REPEAT, 0, width, height, pixels);
|
||||
io.Fonts->TexID = reinterpret_cast<void *>(static_cast<intptr_t>(handle));
|
||||
|
||||
return imgui;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef IMGUI_H
|
||||
#define IMGUI_H
|
||||
|
||||
#include "keycode.h"
|
||||
|
||||
struct imgui;
|
||||
struct render_backend;
|
||||
|
||||
struct imgui *imgui_create(struct render_backend *r);
|
||||
void imgui_destroy(struct imgui *imgui);
|
||||
|
||||
void imgui_mousemove(struct imgui *imgui, int x, int y);
|
||||
void imgui_keydown(struct imgui *imgui, enum keycode key, int16_t value);
|
||||
|
||||
void imgui_update_input(struct imgui *imgui);
|
||||
void imgui_render(struct imgui *imgui);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue