Click here to Skip to main content
15,902,445 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi guys,
I created a texture protoype for a logistic software I currently work on, to visualize free and taken storage capacities of holding areas for a company in the neighbourhood.

The prototype looks something like this: Texture Prototype
The texture is then mapped on an object and assigned to a holding area.

So far so good, now to the actual problem!

The texture has to change its appearance depending on the holding area it is assigned to.
The features that have to change according to the holding area are:
- the Text (i.e. different name for different stored materials)
- the curved yellow bar on the left and the curved red bar on the right (depending on the amount of free and taken storage capacity the bar fill up the curved bars more or less and may also change their colors)

Now I don't really know how to approach this problem. It is obvious that I can't create textures for all fillstates of all the areas in advance and then just pick the respective one at runtime.

So my idea was to somehow generate these textures on runtime somehow or create some kind of template with exchangable parts.

Do you think that would be realisable? If yesm what would be your approach? Did you guys encounter some similar problem before or do you have any tipps or tricks how to approach this task best way? Maybe you know a library that can support me on this?

Right now I'm working with VS 2012 C++, OpenSG for Scene generation and OpenGL.

Thanks Guys in advance!
Posted
Updated 8-Jan-14 3:41am
v2

1 solution

Yes, this is both possible and relatively easy. Whether or not I used GDI or GDI+ would depend on whether or not I wanted to support transparency/gradients - your image appears to show shadows generated by semi-opaque black lines, so gdi+ would be needed to duplicate it exactly.

Here's a little something to get you started. Its quite simple, just a series of circles, lines and arcs with a touch of text.

C++
HBITMAP zCreateDibSection(HDC hdc, int width, int height, int bitCount)
{
    BITMAPINFO bi;
    ZeroMemory(&bi, sizeof(bi));
    bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
    bi.bmiHeader.biWidth = width;
    bi.bmiHeader.biHeight = height;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = bitCount;
    bi.bmiHeader.biCompression = BI_RGB;
    return CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, 0,0,0);
}

// should allow for size specification
// I've hardcoded it to 256x256 pixels
HBITMAP genTexture(wchar_t *text1, wchar_t *text2, COLORREF col1, COLORREF col2, int fillPercent1, int fillPercent2)
{
    HPEN origPen, thinBlack, thickBlack;
    HBRUSH origBrush, bkgBrush, col1Brush, col2Brush;
    HDC memDC;
    HBITMAP origBmp, result;
    RECT imgRect;
    RECT outerRc, innerRc;
    HFONT origFont, font;

    memDC = CreateCompatibleDC(0);
    origBmp = (HBITMAP) GetCurrentObject(memDC, OBJ_BITMAP);
    origPen = (HPEN) GetCurrentObject(memDC, OBJ_PEN);
    origBrush = (HBRUSH) GetCurrentObject(memDC, OBJ_BRUSH);
    origFont = (HFONT) GetCurrentObject(memDC, OBJ_FONT);

    result = zCreateDibSection(memDC, 256, 256, 24);
    SelectObject(memDC, result);

    SetRect(&innerRc, 256/4,256/4,256*3/4-1,256*3/4-1);
    SetRect(&outerRc, 0,0,255,255);

    bkgBrush = CreateSolidBrush( RGB(204,204,204) );
    FillRect(memDC, &outerRc, bkgBrush);

    thickBlack = CreatePen(PS_SOLID, 2, 0);
    SelectObject(memDC, thickBlack);
    SelectObject(memDC, GetStockObject(WHITE_BRUSH));
    Ellipse(memDC, outerRc.left,outerRc.top,outerRc.right,outerRc.bottom);

    BeginPath(memDC);
        col2Brush = CreateSolidBrush(col2);
        SelectObject(memDC, col2Brush);
        MoveToEx(memDC,128,128,NULL);


        AngleArc(memDC, 127,127,126,-90.0,(fillPercent2 / 100.0)*180.0);
        LineTo(memDC,128,128);
    EndPath(memDC);
    FillPath(memDC);


    BeginPath(memDC);
        col1Brush = CreateSolidBrush(col1);
        SelectObject(memDC, col1Brush);
        MoveToEx(memDC,128,128,NULL);
        AngleArc(memDC, 127,127,126,-90.0,-(fillPercent1 / 100.0)*180.0);
        LineTo(memDC,128,128);
    EndPath(memDC);
    FillPath(memDC);


    //  inner circle
    SelectObject(memDC, GetStockObject(WHITE_BRUSH));
    Ellipse(memDC, 64,64,(256*0.75)-1,(256*0.75)-1);

    MoveToEx(memDC, 66, 128, NULL);
    LineTo(memDC, 190,128);

    RECT textRectTop, textRectBottom;
    SetRect(&textRectTop, 64,64,192,128);
    SetRect(&textRectBottom, 64,128,192,192);

    font = CreateFont(-24, 0, 0, 0, 0, FALSE, FALSE, FALSE, 1, 0, 0, 0, 0, "Verdana");// ("Ms Shell Dlg"));
    SelectObject(memDC, font);
    DrawTextW(memDC, text1, -1, &textRectTop, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    DrawTextW(memDC, text2, -1, &textRectBottom, DT_CENTER|DT_VCENTER|DT_SINGLELINE);


    // clean-up
    SelectObject(memDC, origBrush);
    SelectObject(memDC, origPen);
    SelectObject(memDC, origBmp);
    SelectObject(memDC, origFont);


    DeleteObject(col1Brush);
    DeleteObject(col2Brush);
    DeleteObject(font);
    DeleteObject(thickBlack);
    DeleteObject(bkgBrush);

    DeleteDC(memDC);
    return result;
}

void onPaint(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HBITMAP img = genTexture(L"Text 1",L"Text 2", RGB(255,192,0),RGB(192,80,77),  50,66);
    HDC hdc;
    PAINTSTRUCT ps;
    HBITMAP old;
    HDC memDC;

    memDC = CreateCompatibleDC(0);
    old = (HBITMAP)SelectObject(memDC, img);

    hdc = BeginPaint(hwnd, &ps);

    BitBlt(hdc, 0,0, 255,255, memDC, 0,0, SRCCOPY);

    EndPaint(hwnd, &ps);
    SelectObject(memDC, old);
    DeleteObject(img);
}


BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
    {
    }
    return TRUE;

    case WM_CLOSE:
    {
        EndDialog(hwndDlg, 0);
    }
    return TRUE;

    case WM_PAINT:
        onPaint(hwndDlg, wParam, lParam);
        return 0;

    case WM_COMMAND:
    {
        switch(LOWORD(wParam))
        {
        }
    }
    return TRUE;
    }
    return FALSE;
}
 
Share this answer
 
Comments
gibson86 10-Jan-14 4:03am    
Works awesome dude. Thank you so much!
enhzflep 10-Jan-14 4:15am    
No worries mate. :) There's a bazillion articles on both GDI and GDI+ here on code-project - there should be plenty to help you achieve the exact look you're after.
gibson86 10-Jan-14 5:55am    
Thanks for the advice, I will definately check that.

Just one last question: I found out about the GDI SmoothingMode. How can it be applied in this example? Or would you suggest another form of anti-aliasing?

thanks
enhzflep 10-Jan-14 6:15am    
You're welcome - it will be well worth your while..

The only uses I'm aware of for smoothing modes in GDI are for (1) StretchBlt and (2) for text rendering. I dont think either would be suitable for you here. You could always try (1) by creating the image larger than you want it, before 'stretching' it smaller. That _may_ make use of smoothing, though I'm not sure - I tend to think that it wont. GDI+ would be my first choice day-in,day-out for anything that needs to produce anti-aliased output (with the exception of a few specialized use cases)

You can use floating-point co-ordinates with GDI+, which to me, implies that sub-pixel coordinates are accepted, which then suggests anti-aliasing is available.

A quick google tells me that yes indeed, this is the case.
Perhaps these links will be of use:

Antialiasing with Lines and Curves
Custom AntiAliasing with GDI+
Antialiasing Using Windows GDI

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900