Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [GUI] SFML backend for ImGui  (Read 20353 times)

0 Members and 1 Guest are viewing this topic.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
[GUI] SFML backend for ImGui
« on: January 05, 2015, 07:51:23 pm »
Hello.

I've written an SFML backend for ImGui: https://github.com/Mischa-Alff/imgui-backends

Quote
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies. It is based on an "immediate" graphical user interface paradigm which allows you to build user interfaces with ease.

ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.

ImGui is particularly suited to integration in 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.

The backend uses SFML's vertex arrays (and GL_TRIANGLES) for rendering, so this should work on every platform SFML supports.

Usage is explained in the repository's SFML/README.md, or here: https://github.com/Mischa-Alff/imgui-backends/blob/master/SFML/README.md

What isn't implemented:
  • Stencils. If the horizontal ImGui window size is too small, you'll still see transparent rectangles, as SFML does not provide support for clipping, and I haven't gotten around to working on a solution.

Cheers
« Last Edit: June 28, 2015, 09:45:25 am by Aster »

Ricky

  • Jr. Member
  • **
  • Posts: 99
    • View Profile
    • Tejada
    • Email
Re: [GUI] SFML backend for ImGui
« Reply #1 on: January 06, 2015, 06:43:46 am »
Dude this is flippin' awesome!
Wilt thou yet say before him that slayeth thee, I am God? but thou shalt be a man, and no God, in the hand of him that slayeth thee.

caxco93

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #2 on: January 07, 2015, 04:53:35 pm »
very cool but check out what i get as text and console output. any ideas why?



#include "stdafx.h"
#include <stdio.h>
#include <SFML/Graphics.hpp>
#include "imgui.h"
#include "imgui-SFML.h"

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600), "ImGui test!");
        ImGui::SFML::SetWindow(window);
        ImGui::SFML::InitImGui();
        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        ImGui::SFML::ProcessEvent(event);
                        if (event.type == sf::Event::Closed) window.close();
                }
                ImGui::SFML::UpdateImGui();
                static bool ui = true;
                if (ImGui::Begin("Test!", &ui, ImVec2(10, 10)))
                {
                        ImGui::Text("Hello, world!");
                }
                ImGui::End();
                ImGui::Render();
                window.display();
        }
        return 0;
}
 
« Last Edit: January 07, 2015, 06:38:27 pm by caxco93 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [GUI] SFML backend for ImGui
« Reply #3 on: January 07, 2015, 04:59:53 pm »
If you don't understand "PNG not supported: 8-bit only", I don't know what else can be said... :P
« Last Edit: January 07, 2015, 05:04:34 pm by Laurent »
Laurent Gomila - SFML developer

caxco93

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #4 on: January 07, 2015, 05:02:40 pm »
its not like im the one setting the path to a .png file . theres not even such string in the entire project.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [GUI] SFML backend for ImGui
« Reply #5 on: January 07, 2015, 05:05:10 pm »
Yes, sorry, I didn't notice that your own code doesn't load any image (it was initially not displayed completely).

Well then I guess internal images should be converted to a supported format inside the SFML backend.
Laurent Gomila - SFML developer

caxco93

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #6 on: January 07, 2015, 05:22:09 pm »
ok so its because of this method inside the imgui thingy 
Code: [Select]
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);

that calls this
Code: [Select]
void ImGui::GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size)
{
    if (fnt_data) *fnt_data = (const void*)proggy_clean_13_fnt_data;
    if (fnt_size) *fnt_size = proggy_clean_13_fnt_size;
    if (png_data) *png_data = (const void*)proggy_clean_13_png_data;
    if (png_size) *png_size = proggy_clean_13_png_size;
}

which reads this.
Code: [Select]
static const unsigned int proggy_clean_13_png_size = 1271;
static const unsigned int proggy_clean_13_png_data[1272/4] =
{
    0x474e5089, 0x0a1a0a0d, 0x0d000000, 0x52444849, 0x00010000, 0x40000000, 0x00000301, 0x3b93cf00, 0x000000fd, 0x544c5006, 0xffffff45, 0x55ffffff,
    0x006cf57c, 0x74010000, 0x00534e52, 0x66d8e640, 0x9f040000, 0x54414449, 0xd2ed5e78, 0x57136f4d, 0xebe00518, 0x0c4c98c9, 0xdf1def0d, 0x52b2b494,
    0xe18a99db, 0x5d412243, 0x66adc8d8, 0x831a772e, 0x8c1c74aa, 0x534a9540, 0x2c162568, 0x50e1650a, 0x4e27b2a7, 0x8e289b19, 0x08555047, 0x5572c4a1,
    0x45d465e4, 0x23e2a2c5, 0x410d3602, 0x484a82ea, 0x48a58921, 0xa80d306c, 0xf5ea0150, 0x0aa91518, 0x59ed03fd, 0xa3c5de8c, 0x1dd2bef3, 0xdc02ad54,
    0xc786adbd, 0xa46249ef, 0x45672e07, 0x5368275f, 0xba00af1e, 0x50802410, 0x44584212, 0x0cc02d22, 0x54c385db, 0xa4304a20, 0x4ab0be59, 0x5581c073,
    0x3223c105, 0x3cca900e, 0x2f434141, 0xc31f00a2, 0x8381436e, 0x7582e1c3, 0xc61bd538, 0xd9d639b6, 0xac8f0873, 0x7cdf5051, 0x7068dc3a, 0x0f41ca81,
    0xb8e545db, 0xc77128e9, 0xc2357961, 0x0d9bd340, 0xb0385a6b, 0x378d1cd9, 0xf51d14c0, 0x7deed071, 0x378041c8, 0xb763cf3c, 0xca685541, 0xc170dff1,
    0x1c45eb9e, 0xca9f3beb, 0xec1a344c, 0x01c63105, 0x69b9a56c, 0xa920baa2, 0x2be30e9a, 0xa437e038, 0x68545174, 0x47a40e01, 0xbdd5104f, 0xacd51de1,
    0xb323a070, 0x00bd20d1, 0x6b8a332c, 0x3aeb8b1b, 0xf0720e7b, 0x7e6fac43, 0x20de0398, 0xaf476e65, 0xaf43df8c, 0x68be1248, 0xeb4b2d0e, 0x6009c5f5,
    0x1373d446, 0x5923eb42, 0x83bbfc11, 0x6b40b78d, 0x2c9c1e40, 0x1d25646d, 0x6dd95620, 0x2d121d08, 0xe153ea31, 0x569e2034, 0x89399009, 0x7d09e35a,
    0x6a299cc3, 0x1081d0ba, 0x93f350d6, 0x24e5f36d, 0x83939908, 0x2189e357, 0xbfa41382, 0x644cf977, 0x8d2da4a9, 0x2207ea47, 0x6f9db2c8, 0x852b401a,
    0xc88309e2, 0x926fa251, 0xcf81135f, 0x8b7fc309, 0x92d4baa1, 0xda9f9d6b, 0x285b71ff, 0x7cb1a1fe, 0xf37fc3ba, 0x5b1bd90d, 0x63fd19b9, 0x4e861b9e,
    0x5b98ba9d, 0xada921a0, 0x0d65816d, 0x0901d031, 0x8835ecaf, 0x4170458e, 0x67ae4dbe, 0xe1f03847, 0xca21ba9d, 0x09bcbc43, 0xa209a248, 0x1bccbc10,
    0xba6b0724, 0x560b7ad1, 0xbe45d18a, 0x8fc83662, 0x7845295c, 0xb4b30403, 0x083a5dab, 0xe03cd568, 0xad1cd320, 0xb16596e7, 0xf07a74ae, 0x3fdee918,
    0x9dff59d6, 0x59459b6c, 0xdf0bc40e, 0x622d7232, 0x4c58e581, 0x0289acb5, 0x9d39df61, 0x52091f79, 0x27ea7234, 0x2f862fd4, 0x018c6b90, 0xcf531873,
    0x9204974e, 0x79294e4f, 0xc42cd641, 0xe120a953, 0xb3d5d7c2, 0xcaaab02a, 0x3f57283e, 0xc6d4796f, 0x67057d81, 0xa9150405, 0xda65fc5d, 0x81abf954,
    0x52cf855a, 0x3b33e9e5, 0xa606f836, 0xd8edf562, 0x42885012, 0x4439866d, 0x5069aa75, 0xf647c08f, 0x5e5f2ad9, 0x13a29818, 0x8809993e, 0x6ce63187,
    0x039cea7e, 0x6d9a0600, 0xb23f3659, 0x54ee50e4, 0x51bd1d01, 0x69698176, 0xa78cc82e, 0x918fc7d3, 0xe68c782d, 0xddb6d41e, 0x05d50541, 0x6862b4cc,
    0x9fa0b8b5, 0x93d18d39, 0x61fb26d3, 0xc3d37c71, 0x60199ee8, 0xafd5f3d8, 0x8176ddbf, 0xc3f0d086, 0x5a4508ae, 0xb017a94b, 0x7bb4c447, 0xb47b0661,
    0x034adbe4, 0x5162d0d4, 0x145b3117, 0x265bb553, 0x13ada3d1, 0xfcf77203, 0x14cf0730, 0x79faf474, 0xc0e00514, 0x3a3397d8, 0xbef282f6, 0x9cfb06b7,
    0xbd868d8d, 0xbcf10521, 0x4313fcc5, 0xa9506c35, 0x231e9801, 0x80b83798, 0x2ffba8af, 0xea629967, 0x14bbd762, 0x404f5e86, 0x741c674e, 0xe1e4bddf,
    0xc8289e2b, 0x22161ede, 0x08ba737d, 0xfdd624de, 0x0c262c25, 0xf033fd82, 0x2d7df0c9, 0x01edfbc9, 0x1c063022, 0x5ab3cb48, 0x65787dad, 0xd174b636,
    0xcf3c6e44, 0xcec7a29e, 0xcd131c86, 0x1eb9d6e1, 0xf18cbd0d, 0xc7e3b3c4, 0x51a3855a, 0xb3b63099, 0x73791a88, 0x28bdd4b3, 0x0877396d, 0xdcb4af9f,
    0xda2678bf, 0x3f8388f1, 0xe1c23c49, 0x4bb1c0c9, 0x60811a9f, 0x32526321, 0x0de7bf4d, 0x272bb715, 0x36b4712b, 0xbecbb290, 0xf3f58cde, 0x4def93e3,
    0x68771d8e, 0x8f65effc, 0xc23357fd, 0x38a672d6, 0x6cd75a99, 0x4ba70848, 0xecfe3fd6, 0x0ed07878, 0x86fc3dda, 0xb96d25a0, 0xbd0465f3, 0xcb17658c,
    0xbb061db6, 0x5684b85c, 0x1a67638b, 0xe072ed60, 0xe41d5a04, 0x078f9275, 0xa955e8ea, 0x042929e6, 0xa473abd1, 0xfa3648a0, 0xdb13b097, 0xc91ff46c,
    0x250bf9ff, 0x6a079cd4, 0x004ebcd0, 0x49000000, 0xae444e45, 0x00826042,
};

apparently those are the bytes of a .png file that is not 8-bit.

so i assume i would have to change the size and bytes for those of an 8bit one?

now how can one get that string of bytes from a binary file?

SLC

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #7 on: January 07, 2015, 07:13:26 pm »
now how can one get that string of bytes from a binary file?

I'm not sure it even works (correctly) but... uhm... you get the idea:
#include <iostream>
#include <iterator>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>

int main(int argc, char** argv)
{
    std::cout << "Enter the number of bytes to add a new line or use 0 for continuous." << std::endl;
    std::cout << "Row length: ";

    unsigned int row_len = 0;

    std::cin >> row_len;

    std::cout << "Enter 1 if you want spacing between array elements or 0 if you don't." << std::endl;
    std::cout << "Element space: ";

    bool elem_space = false;

    std::cin >> elem_space;

    std::cout << "Enter the path of the input file that should be converted." << std::endl;
    std::cout << "File path: ";

    std::string src_path;

    std::cin >> src_path;

    if (src_path.empty()) {
        std::cout << "No path to the source file was specified. Aborting..." << std::endl;
        return 1;
    }

    std::ifstream src_file(src_path, std::ifstream::binary);

    if (!src_file.is_open()) {
        std::cout << "Unable to open source file: " << src_path << std::endl;
        return 1;
    }

    std::streampos src_size = 0;

    src_size = src_file.tellg();
    src_file.seekg(0, std::ios::end);
    src_size = src_file.tellg() - src_size;
    src_file.seekg(0, std::ios::beg);

    std::string dest_path(src_path);
    dest_path.append(".cpp");

    std::cout << "Note: Output data will be saved into " << dest_path << std::endl;

    std::ofstream dest_file(dest_path);
    if (!dest_file.is_open()) {
        std::cout << "Unable to open destination file: " << src_path << std::endl;
        src_file.close();
        return 1;
    }

    std::cout << "transferring from " << src_path << " to " << dest_path << \
                " with a row length of " << row_len << std::endl;


    std::vector<unsigned char> src_data;
    src_data.reserve(src_size);

    src_data.insert(src_data.begin(), \
                    std::istream_iterator<unsigned char>(src_file), \
                    std::istream_iterator<unsigned char>());

    dest_file << "static const unsigned char file_data[] = {\n";

    unsigned int byte_count = 0;
    for (std::vector<unsigned char>::iterator itr = src_data.begin(); itr != src_data.end(); ++itr)
    {
        if (itr + 1 != src_data.end()) {
            dest_file << "0x" << std::hex << std::setfill('0') << std::setw(2) \
                        << int(*itr) << (elem_space ? ", " : ",");
        } else {
            dest_file << "0x" << std::hex << std::setfill('0') << std::setw(2) \
                        << int(*itr) << "\n};";
            break;
        }

        ++byte_count;
        if(row_len > 0 && byte_count % row_len == 0) dest_file << "\n";
    }

    src_file.close();
    dest_file.close();

    return 0;
}
 

bock

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #8 on: January 07, 2015, 08:04:08 pm »
There was a recent optimisation to compress the PNG to lower bit-per-pixel which although correct, meant the PNG didn't load on some incomplete PNG loader. The optimisation has been reverted now:
https://github.com/ocornut/imgui/issues/109

caxco93: The answer to your question "now how can one get that string of bytes from a binary file? " was a few lines above the one you looked at, there is a program in the comments that does exactly this.


Cpt. Bread

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #9 on: March 04, 2015, 01:50:11 pm »
Good work. Unfortunately for me the clipping problem really made it a no go in its current state...
So to solve that I replaced the ImImpl_RenderDrawLists with the one you get from ImGuis example OpenGl implementation but modified to work with SFML textures... If someone else wants to use it remember you need to link opengl32.lib(or whatever is the equivalent if you aren't using VS)...

#include <SFML/OpenGL.hpp>
[...]
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
        if (cmd_lists_count == 0)
                return;

        ImImpl_window->pushGLStates();

        // We are using the OpenGL fixed pipeline to make the example code simpler to read!
        // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer.
        // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
        glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glDisable(GL_CULL_FACE);
        glDisable(GL_DEPTH_TEST);
        glEnable(GL_SCISSOR_TEST);
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        glEnable(GL_TEXTURE_2D);

        // Setup orthographic projection matrix
        const float width = ImGui::GetIO().DisplaySize.x;
        const float height = ImGui::GetIO().DisplaySize.y;
        glMatrixMode(GL_PROJECTION);
        glPushMatrix();
        glLoadIdentity();
        glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity();

        // Render command lists
        for (int n = 0; n < cmd_lists_count; n++)
        {
                const ImDrawList* cmd_list = cmd_lists[n];
                const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front();
                glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos)));
                glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv)));
                glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col)));

                int vtx_offset = 0;
                for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
                {
                        const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
                        sf::Texture::bind((sf::Texture*)pcmd->texture_id);
                        glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
                        glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
                        vtx_offset += pcmd->vtx_count;
                }
        }

        // Restore modified state
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glPopAttrib();

        ImImpl_window->popGLStates();
}
There is probably a way so that you don't need to call push/popGLStates but I don't know OpenGL so I can't fix that...

bock

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #10 on: March 09, 2015, 10:00:55 am »
Would be nice to have that pushed into the main repo.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #11 on: March 16, 2015, 11:47:27 am »
Would be nice to have that pushed into the main repo.

Sorry for my lack of response. I've been extremely busy lately, but I should have the repo updated with much more than this by Sunday (March 22nd). Rendering and event backends will be completely separate, allowing them to be used interchangeably with different libraries.

Not sure if I'll have time, but GLFW and SDL support should also be there soon enough, and I'll try to come up with a clever method for replacing glScissor without using OpenGL directly in the SFML rendering backend.
« Last Edit: March 16, 2015, 11:56:28 am by Aster »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [GUI] SFML backend for ImGui
« Reply #12 on: March 16, 2015, 04:37:15 pm »
Quote
I'll try to come up with a clever method for replacing glScissor without using OpenGL directly in the SFML rendering backend.
The usual workaround is to use a sf::View that has both the rectangle and viewport set to the clipped area.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: [GUI] SFML backend for ImGui
« Reply #13 on: April 23, 2015, 04:46:15 pm »
You should really post more than just an imagine. Describe your problem properly.

I've no idea how ImGui does it, but for SFML you'll always have to load a font.

Edit: Don't delete posts, otherwise conversations don't make sense anymore...
« Last Edit: April 23, 2015, 08:05:41 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Memorix101

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: [GUI] SFML backend for ImGui
« Reply #14 on: April 23, 2015, 05:46:23 pm »
It's alright now. ^-^
It's working, now.
I should learn to read .... :P
I forgot to paste the imconfig-SFML stuff in to my imconfig.h