Flix01 / imgui

Dear ImGui Addons Branch = plain unmodified dear imgui plus some extra addon.
https://github.com/Flix01/imgui/wiki/ImGui-Addons-Branch-Home
MIT License
395 stars 34 forks source link

How to use Icons for toolbar? #4

Closed zhouxs1023 closed 8 years ago

zhouxs1023 commented 8 years ago

How to load Icon for toolbar?such as : myImageTextureId2

 static ImGui::Toolbar toolbar("myFirstToolbar##foo");
        if (toolbar.getNumButtons()==0)  {
            char tmp[1024];ImVec2 uv0(0,0),uv1(0,0);
            for (int i=0;i<9;i++) {
                strcpy(tmp,"toolbutton ");
                sprintf(&tmp[strlen(tmp)],"%d",i+1);
                uv0 = ImVec2((float)(i%3)/3.f,(float)(i/3)/3.f);
                uv1 = ImVec2(uv0.x+1.f/3.f,uv0.y+1.f/3.f);

                toolbar.addButton(ImGui::Toolbutton(tmp,(void*)myImageTextureId2,uv0,uv1));
            }
Flix01 commented 8 years ago

myImageTextureId2 is not a texture for ImGui::Toolbar only, it's a texture for ImGui in general, of type ImTextureID, defined in imgui.h as:

typedef void* ImTextureID;          // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp)

So it depends of the imgui port you use. For example in imgui/examples/opengl_example/imgui_impl_glfw.cpp:

// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp.

So basically you need code to load images into GLuint if you use openGL.

P.S. You can use stb_image.h to turn images into byte arrays and openGL methods to turn byte arrays into GLuint textures for example.

zhouxs1023 commented 8 years ago

Can help provide some simple codes for me?I will be very grateful.!

Flix01 commented 8 years ago

In my fork, they are in imgui/addons/bindings/imguibindings.cpp. Basically the code that works for any imgui port and that uses stb_image.h is something like:

ImTextureID ImImpl_LoadTexture(const char* filename, int req_comp, bool useMipmapsIfPossible, bool wraps, bool wrapt)  {
    int w,h,n;
    unsigned char* pixels = stbi_load(filename,&w,&h,&n,req_comp);
    if (!pixels) {
        fprintf(stderr,"Error: can't load texture: \"%s\".\n",filename);
        return 0;
    }
    if (req_comp>0 && req_comp<=4) n = req_comp;

    ImTextureID texId = NULL;
    ImImpl_GenerateOrUpdateTexture(texId,w,h,n,pixels,useMipmapsIfPossible,wraps,wrapt);

    stbi_image_free(pixels);

    return texId;
}

ImTextureID ImImpl_LoadTextureFromMemory(const unsigned char* filenameInMemory,int filenameInMemorySize,int req_comp,bool useMipmapsIfPossible,bool wraps,bool wrapt)  {
    int w,h,n;
    unsigned char* pixels = stbi_load_from_memory(filenameInMemory,filenameInMemorySize,&w,&h,&n,req_comp);
    if (!pixels) {
        fprintf(stderr,"Error: can't load texture from memory\n");
        return 0;
    }
    if (req_comp>0 && req_comp<=4) n = req_comp;

    ImTextureID texId = NULL;
    ImImpl_GenerateOrUpdateTexture(texId,w,h,n,pixels,useMipmapsIfPossible,wraps,wrapt);

    stbi_image_free(pixels);

    return texId;
}

But then you must implement ImImpl_GenerateOrUpdateTexture(...) and ImImpl_FreeTexture(...) according to your imgui port. For OpenGL I use:

void ImImpl_FreeTexture(ImTextureID& imtexid) {
    GLuint& texid = reinterpret_cast<GLuint&>(imtexid);
    if (texid) {glDeleteTextures(1,&texid);texid=0;}
}
void ImImpl_GenerateOrUpdateTexture(ImTextureID& imtexid,int width,int height,int channels,const unsigned char* pixels,bool useMipmapsIfPossible,bool wraps,bool wrapt) {
    IM_ASSERT(pixels);
    IM_ASSERT(channels>0 && channels<=4);
    GLuint& texid = reinterpret_cast<GLuint&>(imtexid);
    if (texid==0) glGenTextures(1, &texid);

    glBindTexture(GL_TEXTURE_2D, texid);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,wraps ? GL_REPEAT : GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,wrapt ? GL_REPEAT : GL_CLAMP);
    //const GLfloat borderColor[]={0.f,0.f,0.f,1.f};glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,borderColor);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    if (useMipmapsIfPossible)   {
#       ifdef NO_IMGUI_OPENGL_GLGENERATEMIPMAP
#           ifndef GL_GENERATE_MIPMAP
#               define GL_GENERATE_MIPMAP 0x8191
#           endif //GL_GENERATE_MIPMAP
        // I guess this is compilable, even if it's not supported:
        glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);    // This call must be done before glTexImage2D(...) // GL_GENERATE_MIPMAP can't be used with NPOT if there are not supported by the hardware of GL_ARB_texture_non_power_of_two.
#       endif //NO_IMGUI_OPENGL_GLGENERATEMIPMAP
    }
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, useMipmapsIfPossible ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    const GLenum ifmt = channels==1 ? GL_ALPHA : channels==2 ? GL_LUMINANCE_ALPHA : channels==3 ? GL_RGB : GL_RGBA;  // channels == 1 could be GL_LUMINANCE, GL_ALPHA, GL_RED ...
    const GLenum fmt = ifmt;
    glTexImage2D(GL_TEXTURE_2D, 0, ifmt, width, height, 0, fmt, GL_UNSIGNED_BYTE, pixels);

#       ifndef NO_IMGUI_OPENGL_GLGENERATEMIPMAP
    if (useMipmapsIfPossible) glGenerateMipmap(GL_TEXTURE_2D);
#       endif //NO_IMGUI_OPENGL_GLGENERATEMIPMAP
}

Then you should be able to load and free textures using the same code I used in my imgui/examples/addons_examples/main.cpp file. If you need further details you can check the imgui/addons/bindings/imguibindings.cpp file.

P.S. in the last two days I've posted many fixes for the Visual Studio compiler and some command lines to compile all the addons using the Visual Studio Command Prompt. See imgui/examples/addons_examples/README_FIRST.txt.

zhouxs1023 commented 8 years ago

How to setup imguibindings for my projects? I setup steps for opengl as below: ===>1. add "#define IMGUI_USE_GLUT_BINDING" in main.cpp file; ===>2. add demo code as below: ImTextureID myImageTextureId2 = 0; if (!myImageTextureId2) myImageTextureId2 = ImImpl_LoadTexture("./myNumbersTexture.png"); then add toolbar but compile can not success qq 20160710134216 Pls help me provide GL include head files(such as glext.h glut.h and so on)

===>Then setup DX9(#define IMGUI_USE_DIRECT3D9_BINDING) ,compile turn on : qq 20160710135135

Flix01 commented 8 years ago

Nope: it would be easier for me to give you a full working project, but I'm on Linux... and that wouldn't work that easily.

I suggest you: 1) Update your fork of imgui_addons. Use git pull or delete your fork and clone it again. 2) Read imgui/examples/addons_examples/README_FIRST.txt 3) Open a Visual Studio Command Prompt. 4) Type: cd imgui/examples/addons_examples (well, replace it with the correct path...). 5) Now copy and paste one of the command-lines suggested in README_FIRST.txt (the Direct3D9 one does not have any dependencies, the others need at least glew32s.lib). These command-lines are intended to be used on 32bit systems, because I don't know if the names of the libraries are the same on 64bit systems, but they could work. 6) Report compiler errors here.

This way it's easier for me to provide meaningful feed-back; although it's still hard to do it for me, since I'm on Linux...

P.S. However all the definitions should be added at the project level, not simply in main.cpp, as you seem to be doing.