[SOLVED] - PNMImage.add_sub_image() issue?

Hello everyone,
Im still working on custom ui with c++ and for the window background, i wrote something like this;

PNMImage UI::CreateWindowTexture(int w, int h, bool title)
{
    PNMImage left_top_corner;
    left_top_corner.read("bin/neuera/ui/window/board_corner_lefttop.png");

    PNMImage right_top_corner;
    right_top_corner.read("bin/neuera/ui/window/board_corner_righttop.png");

    PNMImage left_bottom_corner;
    left_bottom_corner.read("bin/neuera/ui/window/board_corner_leftbottom.png");

    PNMImage right_bottom_corner;
    right_bottom_corner.read("bin/neuera/ui/window/board_corner_rightbottom.png");

    PNMImage board_line_top;
    board_line_top.read("bin/neuera/ui/window/board_line_top.png");

    PNMImage board_line_left;
    board_line_left.read("bin/neuera/ui/window/board_line_left.png");

    PNMImage board_line_right;
    board_line_right.read("bin/neuera/ui/window/board_line_right.png");

    PNMImage board_line_bottom;
    board_line_bottom.read("bin/neuera/ui/window/board_line_bottom.png");

    PNMImage board_base;
    board_base.read("bin/neuera/ui/window/board_base.png");

    PNMImage window_bg(w, h);
    window_bg.add_alpha(); //window_bg.alpha_fill(0.0f);

    //---TOP---
    window_bg.add_sub_image(left_top_corner, 0, 0);
    for (size_t i = left_top_corner.get_read_x_size(); i < w - right_top_corner.get_read_x_size(); i += board_line_top.get_read_x_size())
    {
        if (i + board_line_top.get_read_x_size() > w - right_top_corner.get_read_x_size()) {
            window_bg.add_sub_image(board_line_top, i, 0, 0, 0, w - right_top_corner.get_read_x_size() - i);
        }
        else {
            window_bg.add_sub_image(board_line_top, i, 0);
        }
    }
    window_bg.add_sub_image(right_top_corner, w - right_top_corner.get_read_x_size(), 0);

    //---BOTTOM---
    window_bg.add_sub_image(left_bottom_corner, 0, h - left_bottom_corner.get_read_y_size());
    for (size_t i = left_bottom_corner.get_read_x_size(); i < w - right_bottom_corner.get_read_x_size(); i += board_line_bottom.get_read_x_size())
    {
        if (i + board_line_bottom.get_read_x_size() > w - right_bottom_corner.get_read_x_size()) {
            window_bg.add_sub_image(board_line_bottom, i, h - board_line_bottom.get_read_y_size(), 0, 0, w - right_bottom_corner.get_read_x_size() - i);
        }
        else {
            window_bg.add_sub_image(board_line_bottom, i, h - board_line_bottom.get_read_y_size());
        }
    }
    window_bg.add_sub_image(right_bottom_corner, w - right_bottom_corner.get_read_x_size(), h - right_bottom_corner.get_read_y_size());

    //---MID---
    for (size_t i = left_top_corner.get_read_y_size(); i < h - left_bottom_corner.get_read_y_size(); i += board_line_left.get_read_y_size())
    {
        if (i + board_line_left.get_read_y_size() > h - left_bottom_corner.get_read_y_size()) {
            window_bg.add_sub_image(board_line_left, 0, i, 0, 0, -1, h - left_bottom_corner.get_read_y_size() - i);
        }
        else {
            window_bg.add_sub_image(board_line_left, 0, i);
        }
    }

    for (size_t i = right_top_corner.get_read_y_size(); i < h - right_bottom_corner.get_read_y_size(); i += board_line_right.get_read_y_size())
    {
        if (i + board_line_right.get_read_y_size() > h - right_bottom_corner.get_read_y_size()) {
            window_bg.add_sub_image(board_line_right, w - board_line_right.get_read_x_size(), i, 0, 0, -1, h - right_bottom_corner.get_read_y_size() - i);
        }
        else {
            window_bg.add_sub_image(board_line_right, w - board_line_right.get_read_x_size(), i);
        }
    }

    for (size_t x = left_top_corner.get_read_x_size(); x < w - right_top_corner.get_read_y_size(); x += board_base.get_read_x_size())
    {
        for (size_t y = left_top_corner.get_read_y_size(); y < h - right_bottom_corner.get_read_y_size(); y += board_base.get_read_y_size())
        {
            if ((x + board_base.get_read_x_size() > w - right_top_corner.get_read_x_size()) || (y + board_base.get_read_y_size() > h - right_bottom_corner.get_read_y_size())) {
                window_bg.add_sub_image(board_base, x, y, 0, 0, w - right_top_corner.get_read_x_size() - x, h - right_bottom_corner.get_read_y_size() - y);
            }
            else {
                window_bg.add_sub_image(board_base, x, y);
            }
        }
    }

    //---TITLE---
    if (title) {
        PNMImage title_left;
        title_left.read("bin/neuera/ui/window/titlebar_left.png");

        PNMImage title_right;
        title_right.read("bin/neuera/ui/window/titlebar_right.png");

        PNMImage title_mid;
        title_mid.read("bin/neuera/ui/window/titlebar_center.png");

        window_bg.add_sub_image(title_left, 0, 0);
        for (size_t i = title_left.get_read_x_size(); i < w - title_right.get_read_x_size(); i += title_mid.get_read_x_size())
        {
            if (i + title_mid.get_read_x_size() > w - title_right.get_read_x_size()) {
                window_bg.add_sub_image(title_mid, i, 0, 0, 0, w - title_right.get_read_x_size() - i);
            }
            else {
                window_bg.add_sub_image(title_mid, i, 0);
            }
        }
        window_bg.add_sub_image(title_right, w - title_right.get_read_x_size(), 0);
    }
    
    return window_bg;
}

my goal is to create a texture by combining various window parts with using PNMImage like this;

But there is something wrong (with alpha maybe im not sure) it should be like this;
expected

But result is;
test

test2

Ah, I think that the problem is likely that you’re using “add_sub_image”, rather than “blend_sub_image”.

In short:

  • The former blends the pixels in additively
    • The result is that of the source pixel + the copied pixel
  • The latter blends the pixels in via alpha-blending
    • The result is that of using the alpha-channel of the copied pixel to blend between the source pixel and the copied pixel.
2 Likes

@Thaumaturge thank you! “blend_sub_image” worked like expected…

bandicam 2023-12-26 22-20-33-916

1 Like

Excellent! I’m glad that it worked! :slight_smile:

And it looks like you have a nice UI coming along there! :slight_smile:

1 Like

thanks, this assets from another game, for testing purposes only of course.
i’m still at the beginning of the road, but I’m trying to do my best :slight_smile:

1 Like

But even so, the GUI system itself is looking like it’s coming together! Even having buttons with hover-states! :slight_smile:

1 Like