Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageButton - white empty rectangle - why ? #521

Closed
MINIONBOTS opened this issue Feb 5, 2016 · 18 comments
Closed

ImageButton - white empty rectangle - why ? #521

MINIONBOTS opened this issue Feb 5, 2016 · 18 comments

Comments

@MINIONBOTS
Copy link

Sorry for opening another issue with the same problem, but I cannot make it work and I would appreciate it if someone could tell me why.
...
static LPDIRECT3DTEXTURE9 pTexture = NULL;
if ( D3DXCreateTextureFromFile( g_pd3dDevice, "Z:\alog\minion.jpg" , &pTexture ) != D3D_OK ){
printf("poop\n");
}
...
ImGui::ImageButton((void*)pTexture , ImVec2(236, 325), ImVec2(0,0),ImVec2(100,100),2);
...

All it draws is this, a white empty rectangle:
http://pasteboard.co/1kDzuLNa.png

I tripple checked the pTexture, it is a valid texture and also gets selected correctly (the same pointer) in the render funciton with:
g_pd3dDevice->SetTexture( 0,( LPDIRECT3DTEXTURE9)pcmd->TextureId );

I am honestly lost and need some help, what am I doing wrong ? what am I missing ?

@emoon
Copy link
Contributor

emoon commented Feb 5, 2016

Looking at the code in the header file

 IMGUI_API bool          ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0),  const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1));    // <0 frame_padding uses default frame padding settings. 0 for no padding

It looks like the UV range is [(0,0) - (1,1)] but you send in quite large values for the last UV coords. What happens if you only set the size for the button and leave the rest of the values as default?

@adam4813
Copy link

adam4813 commented Feb 5, 2016 via email

@MINIONBOTS
Copy link
Author

I tried it with the default UV values, same result, and also (without any idea what else I could do anymore) with the image size itself, like in the few lines of code I wrote above. Same white rectangle. :(
I changed to 3 different jpg, bmp, png, I tried Imgui:Image, Imgui:Imagebutton, with all kinds of different arguments I could think of. Always resulting in the white rectangle.

I can make the rectangle BLACK when I set the last arg, the "tin_col" to ImVec4(0,0,0,255)....not that it helps me in anyway, but maybe someone has an idea.

The pTexture, which I pass as (void*) to the ImageButton function is correct afaik, it uses the pointer as "ID".

If anyone has a running working texture loaded, maybe he could post a code snippet, so I know what i have to do in order to get this to work ?

@MINIONBOTS
Copy link
Author

If I use the already existing
ImTextureID tex_id = ImGui::GetIO().Fonts->TexID;
ImGui::ImageButton((void*)tex_id, ImVec2(50, 50), ImVec2(1,1),ImVec2(0,0),2);

it shows this texture.... but not the one(s) loaded from a file ...am I missing any steps in loading a texture from a file or why is it so much not showing anything -.- ?

@ocornut
Copy link
Owner

ocornut commented Feb 6, 2016

Show us your code!

On 6 Feb 2016, at 02:04, MINIONBOTS notifications@github.com wrote:

If I use the already existing
ImTextureID tex_id = ImGui::GetIO().Fonts->TexID;
ImGui::ImageButton((void*)tex_id, ImVec2(50, 50), ImVec2(1,1),ImVec2(0,0),2);

it shows this texture.... but not the one(s) loaded from a file ...am I missing any steps in loading a texture from a file or why is it so much not showing anything -.- ?


Reply to this email directly or view it on GitHub.

@MINIONBOTS
Copy link
Author

imgui.cpp:

#include "imgui_D3D9.h"

// Data
static HWND                     g_hWnd = 0;
static INT64                    g_Time = 0;
static INT64                    g_TicksPerSecond = 0;
static LPDIRECT3DDEVICE9        g_pd3dDevice = NULL;
static LPDIRECT3DVERTEXBUFFER9  g_pVB = NULL;
static LPDIRECT3DINDEXBUFFER9   g_pIB = NULL;
static LPDIRECT3DTEXTURE9       g_FontTexture = NULL;
static LPDIRECT3DTEXTURE9       pTexture = NULL;

static int                      g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
static bool                     g_Ready = false;
static Poco::FastMutex          g_Mutex;

struct CUSTOMVERTEX
{
    D3DXVECTOR3 pos;
    D3DCOLOR    col;
    D3DXVECTOR2 uv;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data)
{
    // Create and grow buffers if needed
    if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
    {
        if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
        g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
        if (g_pd3dDevice->CreateVertexBuffer(g_VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
            return;
    }
    if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
    {
        if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
        g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
        if (g_pd3dDevice->CreateIndexBuffer(g_IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &g_pIB, NULL) < 0)
            return;
    }

    // Copy and convert all vertices into a single contiguous buffer
    CUSTOMVERTEX* vtx_dst;
    ImDrawIdx* idx_dst;
    if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
        return;
    if (g_pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
        return;
    for (int n = 0; n < draw_data->CmdListsCount; n++)
    {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        const ImDrawVert* vtx_src = &cmd_list->VtxBuffer[0];
        for (int i = 0; i < cmd_list->VtxBuffer.size(); i++)
        {
            vtx_dst->pos.x = vtx_src->pos.x;
            vtx_dst->pos.y = vtx_src->pos.y;
            vtx_dst->pos.z = 0.0f;
            vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16);     // RGBA --> ARGB for DirectX9
            vtx_dst->uv.x = vtx_src->uv.x;
            vtx_dst->uv.y = vtx_src->uv.y;
            vtx_dst++;
            vtx_src++;
        }
        memcpy(idx_dst, &cmd_list->IdxBuffer[0], cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx));
        idx_dst += cmd_list->IdxBuffer.size();
    }
    g_pVB->Unlock();
    g_pIB->Unlock();
    g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
    g_pd3dDevice->SetIndices( g_pIB );
    g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );

    // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
    g_pd3dDevice->SetPixelShader( NULL );
    g_pd3dDevice->SetVertexShader( NULL );
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, false );
    g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
    g_pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
    g_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, false );
    g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
    g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
    g_pd3dDevice->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
    g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );

    // Setup orthographic projection matrix
    D3DXMATRIXA16 mat;
    D3DXMatrixIdentity(&mat);
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &mat );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &mat );
    D3DXMatrixOrthoOffCenterLH( &mat, 0.5f, ImGui::GetIO().DisplaySize.x+0.5f, ImGui::GetIO().DisplaySize.y+0.5f, 0.5f, -1.0f, +1.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &mat );

    // Render command lists
    int vtx_offset = 0;
    int idx_offset = 0;
    for (int n = 0; n < draw_data->CmdListsCount; n++)
    {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
        {
            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
            if (pcmd->UserCallback)
            {
                pcmd->UserCallback(cmd_list, pcmd);
            }
            else
            {
                const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
                //printf("R: %x \n",pcmd->TextureId);

                g_pd3dDevice->SetTexture( 0,(LPDIRECT3DTEXTURE9)pcmd->TextureId );
                g_pd3dDevice->SetScissorRect( &r );
                g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.size(), idx_offset, pcmd->ElemCount/3 );
            }
            idx_offset += pcmd->ElemCount;
        }
        vtx_offset += cmd_list->VtxBuffer.size();
    }
}

IMGUI_API LRESULT ImGui_ImplDX9_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
{
    ImGuiIO& io = ImGui::GetIO();

    switch (msg)
    {
    case WM_LBUTTONDOWN:
        io.MouseDown[0] = true;
        return io.WantCaptureMouse;
    case WM_LBUTTONUP:
        io.MouseDown[0] = false; 
        return io.WantCaptureMouse;
    case WM_LBUTTONDBLCLK:
        io.MouseDown[0] = false; 
        return io.WantCaptureMouse;
    case WM_RBUTTONDOWN:
        io.MouseDown[1] = true; 
        return io.WantCaptureMouse;
    case WM_RBUTTONUP:
        io.MouseDown[1] = false; 
        return io.WantCaptureMouse;
    case WM_RBUTTONDBLCLK:
        io.MouseDown[1] = false; 
        return io.WantCaptureMouse;
    case WM_MBUTTONDOWN:
        io.MouseDown[2] = true; 
        return io.WantCaptureMouse;
    case WM_MBUTTONUP:
        io.MouseDown[2] = false; 
        return io.WantCaptureMouse;
    case WM_MBUTTONDBLCLK:
        io.MouseDown[2] = false; 
        return io.WantCaptureMouse;
    case WM_MOUSEWHEEL:
        io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;
        return io.WantCaptureMouse;
    case WM_MOUSEMOVE:
        io.MousePos.x = (signed short)(lParam);
        io.MousePos.y = (signed short)(lParam >> 16); 
        return io.WantCaptureMouse;
    case WM_KEYDOWN:
        if (wParam < 256)
            io.KeysDown[wParam] = 1;
        return io.WantCaptureKeyboard;
    case WM_KEYUP:
        if (wParam < 256)
            io.KeysDown[wParam] = 0;
        return io.WantCaptureKeyboard;
    case WM_CHAR:
        // You can also use ToAscii()+GetKeyboardState() to retrieve characters.
        if (wParam > 0 && wParam < 0x10000)
            io.AddInputCharacter((unsigned short)wParam);
        return io.WantCaptureKeyboard || io.WantTextInput;
    }
    return 0;
}

bool    ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device)
{
    g_hWnd = (HWND)hwnd;
    g_pd3dDevice = device;

    if (!QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) 
        return false;
    if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time))
        return false;

    ImGuiIO& io = ImGui::GetIO();
    io.KeyMap[ImGuiKey_TAB] = VK_TAB;                       // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
    io.KeyMap[ImGuiKey_LEFT] = VK_LEFT;
    io.KeyMap[ImGuiKey_RIGHT] = VK_RIGHT;
    io.KeyMap[ImGuiKey_UP] = VK_UP;
    io.KeyMap[ImGuiKey_DOWN] = VK_DOWN;
    io.KeyMap[ImGuiKey_PRIOR] = VK_PRIOR;
    io.KeyMap[ImGuiKey_NEXT] = VK_NEXT;
    io.KeyMap[ImGuiKey_HOME] = VK_HOME;
    io.KeyMap[ImGuiKey_END] = VK_END;
    io.KeyMap[ImGuiKey_DELETE] = VK_DELETE;
    io.KeyMap[ImGuiKey_BACK] = VK_BACK;
    io.KeyMap[ImGuiKey_RETURN] = VK_RETURN;
    io.KeyMap[ImGuiKey_ESCAPE] = VK_ESCAPE;
    io.KeyMap[ImGuiKey_A] = K_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';

    io.RenderDrawListsFn = ImGui_ImplDX9_RenderDrawLists;   // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
    io.ImeWindowHandle = g_hWnd;

    return true;
}

void ImGui_ImplDX9_Shutdown()
{
    ImGui_ImplDX9_InvalidateDeviceObjects();
    ImGui::Shutdown();
    g_pd3dDevice = NULL;
    pTexture = NULL;
    g_hWnd = 0;
    g_Ready = false;
}

static bool ImGui_ImplDX9_CreateFontsTexture()
{
    // Build texture atlas
    ImGuiIO& io = ImGui::GetIO();
    unsigned char* pixels;
    int width, height, bytes_per_pixel;
    io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height, &bytes_per_pixel);

    // Upload texture to graphics system
    g_FontTexture = NULL;
    pTexture = NULL;
    if (D3DXCreateTexture(g_pd3dDevice, width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8, D3DPOOL_DEFAULT, &g_FontTexture) < 0)
        return false;
    D3DLOCKED_RECT tex_locked_rect;
    if (g_FontTexture->LockRect(0, &tex_locked_rect, NULL, 0) != D3D_OK) 
        return false;
    for (int y = 0; y < height; y++)
        memcpy((unsigned char *)tex_locked_rect.pBits + tex_locked_rect.Pitch * y, pixels + (width * bytes_per_pixel) * y, (width * bytes_per_pixel));
    g_FontTexture->UnlockRect(0);

    // Store our identifier
    io.Fonts->TexID = (void *)g_FontTexture;

    if ( D3DXCreateTextureFromFile( g_pd3dDevice, "Z:\\alog\\minion.bmp" , &pTexture ) != D3D_OK ){
        printf("WHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFASÖFHIAHSFPaSFHI WRONG ");
    }
    else
        printf("OOOOOOOOOOOOOOOOOKAAAAAAAAAAAAAAAAYYYYYYYYYYYYYYYYY %x",pTexture);


    return true;
}

LPDIRECT3DTEXTURE9 ImGui_ImplDX9_TEST(){
    return pTexture;
}

bool ImGui_ImplDX9_CreateDeviceObjects()
{
    if (!g_pd3dDevice)
        return false;
    if (!ImGui_ImplDX9_CreateFontsTexture())
        return false;
    g_Ready = true;
    return true;
}

void ImGui_ImplDX9_InvalidateDeviceObjects()
{
    g_Ready = false; 
    if (!g_pd3dDevice)
        return;
    if (g_pVB)
    {
        g_pVB->Release();
        g_pVB = NULL;
    }
    if (g_pIB)
    {
        g_pIB->Release();
        g_pIB = NULL;
    }
    if (LPDIRECT3DTEXTURE9 tex = (LPDIRECT3DTEXTURE9)ImGui::GetIO().Fonts->TexID)
    {
        tex->Release();
        ImGui::GetIO().Fonts->TexID = 0;
    }
    g_FontTexture = NULL;
    pTexture->Release();
    pTexture = NULL;
}

bool ImGui_ImplDX9_NewFrame( bool calledfromrenderthread )
{
    // is called from the gameloop thread, cannot have the recreation of textures in here, can we ?
    if ( !ImGui_ImplDX9_Ready() && !calledfromrenderthread)
        return false;

    if (!g_FontTexture || !pTexture)
        if (!ImGui_ImplDX9_CreateDeviceObjects())
            return false;   

    ImGuiIO& io = ImGui::GetIO();

    // Setup display size (every frame to accommodate for window resizing)
    RECT rect;
    GetClientRect(g_hWnd, &rect);
    io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));

    // Setup time step
    INT64 current_time;
    QueryPerformanceCounter((LARGE_INTEGER *)&current_time); 
    io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond;
    g_Time = current_time;

    // Read keyboard modifiers inputs
    io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
    io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
    io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
    // io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events
    // io.MousePos : filled by WM_MOUSEMOVE events
    // io.MouseDown : filled by WM_*BUTTON* events
    // io.MouseWheel : filled by WM_MOUSEWHEEL events

    // Hide OS mouse cursor if ImGui is drawing it
    //SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW));

    // Start the frame
    ImGui::NewFrame();
    return true;
}

bool ImGui_ImplDX9_Ready()
{
    return g_Ready && g_pd3dDevice && g_FontTexture;
}

void ImGui_ImplDx9_LockMutex()
{
    return g_Mutex.lock();
}

void ImGui_ImplDx9_UnlockMutex()
{
    return g_Mutex.unlock();
}

And the function where I call imgui:Image for drawing the image:

       float tex_w = (float)ImGui::GetIO().Fonts->TexWidth;
         float tex_h = (float)ImGui::GetIO().Fonts->TexHeight;
         ImTextureID tex_id = ImGui::GetIO().Fonts->TexID;

         if ( ImGui_ImplDX9_TEST() ){
             //printf("SET: %x \n",ImGui_ImplDX9_TEST());
             //ImGui::Image((void*)ImGui_ImplDX9_TEST(), ImVec2(100, 100), ImVec2(0,0),ImVec2(100,100),ImColor(0, 0, 0));

             void* qw = ImGui_ImplDX9_TEST();

             ImGui::ImageButton(qw, ImVec2(50, 50));
             ImGui::ImageButton(qw, ImVec2(50, 50), ImVec2(0,0),ImVec2(1,1),2);
             ImGui::ImageButton(qw, ImVec2(50, 50), ImVec2(0,1),ImVec2(0,1),2,ImVec4(0,0,0,0),ImVec4(0,0,0,125));
             ImGui::ImageButton(qw, ImVec2(50, 50), ImVec2(0,0),ImVec2(1,1),2,ImVec4(0,0,0,0),ImVec4(0,0,0,125));
             ImGui::ImageButton(qw, ImVec2(50, 50), ImVec2(1,0),ImVec2(0,1),2,ImVec4(0,0,0,0),ImVec4(0,0,0,125));
             ImGui::ImageButton(qw, ImVec2(50, 50), ImVec2(0,0),ImVec2(1,1),2,ImVec4(0,0,0,0),ImVec4(0,0,0,255));
             ImGui::ImageButton(qw, ImVec2(50, 50), ImVec2(0,0),ImVec2(1,1),2,ImVec4(0,0,0,255),ImVec4(0,0,0,125));
             ImGui::ImageButton(qw, ImVec2(50, 50), ImVec2(0,0),ImVec2(1,1),2,ImVec4(0,1,0,0),ImVec4(0,0,0,125));            
             ImGui::ImageButton((void*)tex_id, ImVec2(50, 50));
         }
         else
             ImGui::Image(tex_id, ImVec2(tex_w, tex_h),ImVec2(1,1),ImVec2(0,0));  <-- this gets drawn fine

This is what gets drawn, I can color the "own texture" boxes to whatever color I want by changin the tin_col argument in the ImageButton() function.
http://pasteboard.co/1lyUKj2g.png

it is like the alpha is not working and it always draws the color ontop...or maybe it is normal that the color is drawn first and the texture later ontop ? sadly I have no idea how this "usually" works.

@ocornut
Copy link
Owner

ocornut commented Feb 6, 2016

Try opening the metrics window and confirm the texture id in the different draw calls.

@MINIONBOTS
Copy link
Author

This is while hovering with the mouse over the topmost white rectangle:
http://pasteboard.co/1lCsfijb.png

This is while hovering over the first "Draw 42 ..." line:
http://pasteboard.co/1lCvAl0d.png

"HoverID" and "tex" number differ..... I assume they would have to be the same pointer/ID ?

@ocornut
Copy link
Owner

ocornut commented Feb 6, 2016

Well you can see the draw calls with 6 vtx here.
Hard to tell I don't know what you file is, I don't know what D3DXCreateTextureFromFile() does and how it may setup the alpha channel or how DX behave if the texture has 3 channels and we're using blending. Try disabling blending g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, false );. Try creating a texture the same way the font texture is created and work out the difference from there. Maybe some other code not shown here is destroying your texture. ImGui is very likely not culprit here, all it does is passing your pointer down the chain.

HoveredId is the id of widget when they interact, it has nothnig to do with texture id.
Please preferably upload pictures to github and not pasteboard where they'll disappear eventually which makes the post not as useful for people reading in a few years (also they aren't viewable in e-mail).

@MINIONBOTS
Copy link
Author

g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, false );
-> with this, the normal imgui font texture then also shows up as white rectangle...
So your idea that the texture itself needs to be loaded (or stored?) differently may be a good point to start.

My texture is a static pointer, which gets created on startup of the program and never gets touched by any other code but when the program exits. So this one should be fine.

What I'm basically asking is, if anyone else from the community uses DirectX and has a working texture code which he could share, so I get pointed with my nose what I'm missing or what special things have to be done in order to make imgui show the texture.

@MINIONBOTS
Copy link
Author

If I remove the line :
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );

I get this :
pic

If I leave it on, it just draws the alhpa channel if I see that correctly:
pic2

Someone with DX experience would probably instantly know what to do .... I assume my image needs to be in a special format / layers / ARGB something ?

@MINIONBOTS
Copy link
Author

I got it working now, so in case someone else gets the same issue, I had to do this in order to make it work:

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_ADD );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );   g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TEXTURE );   
...

Calling it with:
ImGui::ImageButton((void*)pTexture, ImVec2(50, 50), ImVec2(0,0),ImVec2(1,1),-1,ImVec4(0,0,0,0),ImVec4(0,0,0,255));

Thanks for the help :))

@Flix01
Copy link

Flix01 commented Feb 6, 2016

@MINIONBOTS
Hmm, could you please post the whole sequence of g_pd3dDevice->SetRenderState(...) and g_pd3dDevice->SetTextureStageState(...) please ?

@Flix01
Copy link

Flix01 commented Feb 6, 2016

I ask because my best solution so far is to leave all the g_pd3dDevice->SetRenderState(...) as they are and replace ALL the g_pd3dDevice->SetTextureStageState(...) with:

g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_BLENDDIFFUSEALPHA);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

This gives me this result:
selection_019

However in openGL I got the correct blending that is slightly different:
selection_020

(Tested both under Wine on Linux, so they should be correct).

P.S. on a closer look I have an additional problem: my texture colour channels are swapped!
But the alpha blending issue still remains (see the ImGui window).

ocornut added a commit that referenced this issue Feb 8, 2016
…re to make compability more evident with user's textures (#521)
@ocornut
Copy link
Owner

ocornut commented Feb 8, 2016

So there is a problem with the _dx9 sample, it was using an Alpha only texture for the font and the renderer assumed that, hence the:

    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );

It works for the font texture but would ignore color in other textures=.
The DX9 default is:

    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );   
    g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );   

I've changed it to that and changed the font texture to get RGBA instead of Alpha only, which is a waste of resource unfortunately.

In a real world scenario, you'd expect

  • either to keep it very simple and only have RGBA textures
  • have the renderer interrogate the texture format via GetLevelDesc and default on some different blending based on texture format.
  • have your texture id be a pointer to your high-level "material" structure which would carry the texture and the blending settings, and adapt the renderer accordingly.

@ocornut
Copy link
Owner

ocornut commented Feb 8, 2016

So it is a legit problem you pointed here. On one hand I think those _impl files are merely examples of how to integrate ImGui within our own engine and the user is expected to plug their own system. On another hand realistically lots of people use low-level format provided by DX/OpenGL and it is nice if those renderer can be copied and pasted without any modifications (as suggested). So right now I'll adopt the more standard color format for the font texture and assume that people who adapt the renderer to their engine may want to use a Alpha-only texture for the font to save memory.

@MINIONBOTS
Copy link
Author

Thanks again :) glad it works now

@Flix01
Copy link

Flix01 commented Feb 8, 2016

@ocornut
It works perfectly for me too. Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants