ice1000 / jimgui

:sparkling_heart: Pure Java binding for dear-imgui
Apache License 2.0
185 stars 13 forks source link

[Question] Allow user to implement custom draw routine for the binding? #19

Open WeAthFoLD opened 5 years ago

WeAthFoLD commented 5 years ago

Currently, this binding is tightly coupled with a window creation/rendering implementation for each OS, which is different to the library's original design:

It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).

So this would make it really inflexible to use the binding.

For example, I have a very specific usage for IMGUI: To create some in-game editor tools for Minecraft modding. Minecraft uses LWJGL2, so all rendering calls must be delegated to LWJGL's gl bindings, but with this binding implementation it's impossible.

ice1000 commented 5 years ago

This Java binding's purpose is to hide the drawing implementation.

However, it's possible to provide bindings for imgui's init/deinit APIs like ImGui::CreateContext, ImGui::DestroyContext, etc. making the usage of this Java binding closer to the C++ implementation. I'll do that if I have time.

ice1000 commented 5 years ago

I may break existing API and redesign the library.

Mr00Anderson commented 5 years ago

I was thinking about this too. I wanted to be able to dynamically resize the application window. Then I realized I also wanted to use OpenGL or DirectX. Primarily OpenGL because my editor will be supporting libgdx and its primary popular extensions. I am fine using directx for a while longer, since my editor is independent of a game library and I am not writing the editor plugins to support libgdx yet. I keep all my libraries pure Java, to much technical debt for some to learn anything else and their ongoing projects.

I dedicate some time each day to trying to understand the internals of this library and review the source code. I will be looking to help maintain it in the future. I have I know c/c++ in practice but not a lot of use. Same with Kotlin.

ice1000 commented 5 years ago

No need to know kotlin actually

ice1000 commented 5 years ago

The APIs are easy adding. I have another private project that did all of these. I'll post them here as some notes, contributions are welcomed.

For Windows, the window resizing is irrelevant to dx9, but win32 API:


auto huge::life_cycle::getWindowSize(PlatformObject object) -> ImVec2 {
    auto &&rect = getWindowBounds(object);
    return { rect.z, rect.w };
}

auto huge::life_cycle::getWindowPos(PlatformObject object) -> ImVec2 {
    auto &&rect = getWindowBounds(object);
    return { rect.x, rect.y };
}

auto huge::life_cycle::getWindowBounds(PlatformObject object) -> ImVec4 {
    auto wc = reinterpret_cast<Ptr<WindowsClassEx>> (object);
    RECT rect{};
    GetWindowRect(wc->hwnd, &rect);
    return {
            static_cast<float>(rect.left),
            static_cast<float>(rect.top),
            static_cast<float>(rect.right - rect.left),
            static_cast<float>(rect.bottom - rect.top),
    };
}

auto huge::life_cycle::setWindowSize(PlatformObject object, ComVec2 size) -> void {
    auto wc = reinterpret_cast<Ptr<WindowsClassEx>> (object);

    SetWindowPos(wc->hwnd, nullptr, 0, 0,
                 static_cast<int>(size.x),
                 static_cast<int>(size.y),
                 SWP_NOMOVE);
}

auto huge::life_cycle::setWindowPos(PlatformObject object, ComVec2 size) -> void {
    auto wc = reinterpret_cast<Ptr<WindowsClassEx>> (object);

    SetWindowPos(wc->hwnd, nullptr,
                 static_cast<int>(size.x),
                 static_cast<int>(size.y), 0, 0, SWP_NOSIZE);
}

auto huge::life_cycle::setWindowBounds(PlatformObject object, ComVec4 bounds) -> void {
    auto wc = reinterpret_cast<Ptr<WindowsClassEx>> (object);

    SetWindowPos(wc->hwnd, nullptr,
                 static_cast<int>(bounds.x),
                 static_cast<int>(bounds.y),
                 static_cast<int>(bounds.z),
                 static_cast<int>(bounds.w),
                 0);
}

*nix-wise it's related to GLFW:


auto huge::life_cycle::getWindowSize(PlatformObject object) -> ImVec2 {
    auto *window = reinterpret_cast<Ptr<GLFWwindow>> (object);
    int w, h;
    glfwGetWindowSize(window, &w, &h);
    return {static_cast<float>(w), static_cast<float>(h)};
}

auto huge::life_cycle::getWindowPos(PlatformObject object) -> ImVec2 {
    auto *window = reinterpret_cast<Ptr<GLFWwindow>> (object);
    int x, y;
    glfwGetWindowPos(window, &x, &y);
    return {static_cast<float>(x), static_cast<float>(y)};
}

auto huge::life_cycle::getWindowBounds(PlatformObject object) -> ImVec4 {
    auto *window = reinterpret_cast<Ptr<GLFWwindow>> (object);
    int x, y, xPlusW, yPlusH;
    glfwGetWindowFrameSize(window, &x, &y, &xPlusW, &yPlusH);
    return {
            static_cast<float>(x), static_cast<float>(y),
            static_cast<float>(xPlusW - x), static_cast<float>(yPlusH - y)
    };
}

auto huge::life_cycle::setWindowSize(PlatformObject object, ComVec2 size) -> void {
    auto *window = reinterpret_cast<Ptr<GLFWwindow>> (object);
    glfwSetWindowSize(window, static_cast<int>(size.x), static_cast<int>(size.y));
}

auto huge::life_cycle::setWindowPos(PlatformObject object, ComVec2 size) -> void {
    auto *window = reinterpret_cast<Ptr<GLFWwindow>> (object);
    glfwSetWindowPos(window, static_cast<int>(size.x), static_cast<int>(size.y));
}

auto huge::life_cycle::setWindowBounds(PlatformObject object, ComVec4 bounds) -> void {
    auto *window = reinterpret_cast<Ptr<GLFWwindow>> (object);
    glfwSetWindowPos(window, static_cast<int>(bounds.x), static_cast<int>(bounds.y));
    glfwSetWindowSize(window, static_cast<int>(bounds.z), static_cast<int>(bounds.w));
}

Not very sure about how the JVM API wrapper of these shits should be.

ice1000 commented 3 years ago

I was thinking about this too. I wanted to be able to dynamically resize the application window. Then I realized I also wanted to use OpenGL or DirectX. Primarily OpenGL because my editor will be supporting libgdx and its primary popular extensions. I am fine using directx for a while longer, since my editor is independent of a game library and I am not writing the editor plugins to support libgdx yet. I keep all my libraries pure Java, to much technical debt for some to learn anything else and their ongoing projects.

I dedicate some time each day to trying to understand the internals of this library and review the source code. I will be looking to help maintain it in the future. I have I know c/c++ in practice but not a lot of use. Same with Kotlin.

Note that you can actually do this now, you'll have setPlatformWindow[Pos|Size]