Jump to content

Render issuses in custom widgets


Andy90
 Share

Go to solution Solved by Josh,

Recommended Posts

 

When dynamically adding and deleting items in a GridView widget during gameplay, rendering errors occur.
After deleting and re-adding items, the GridView is not updated correctly, resulting in visual anomalies.
Additionally, @Dreikblack discovered that blocks are overlaid when they are exactly on top of each other.
He may provide further details on this.

To reproduce the error, follow these steps:

1. Add the provided C++ classes from the GitHub repository  https://github.com/Andy16823/UltraEngine-GridView-Widget/ to the project.
2. Create the GridView widget in main.cpp.
3. Add two items and observe correct rendering.
4. In the main loop, call the ClearGridItems function to delete the grid items.
5. Afterward, add new items and check for rendering errors.
6. It has been observed that the error does not occur if the initially created items are skipped.
 

Create the Widget

g_inventoryGrid = CreateGridView("Gridview", 20, 180, 6, 5, 90, 90, 2, window_2->panel, GridView_DEFAULT);
g_inventoryGrid->AddGridItem(GridItem::CreateGridItem("Wood", "Images/wood.jpg", GRID_ITEM_TEXT_NO_BG));
g_inventoryGrid->AddGridItem(GridItem::CreateGridItem("Armor", "Images/armor.jpg"));

Way to change the Items

void Inventory::UpdateGUI() 
{
	g_inventoryGrid->ClearGridItems();
	for (auto item : Items) {
		auto ivItem = InventoryGridItem::CreateInventoryGridItem(item->name, String(item->currentStackSize), item->itemIcon, STYLE_SHOW_PROGRESS_BAR);
		ivItem->SetProgress(50);
		g_inventoryGrid->AddGridItem(ivItem);
	}
}

 

Video from the bug

https://streamable.com/rb2ypw

 

Link to comment
Share on other sites

Is it possible to provide an example project that is ready to compile? There's a lot of things that could go wrong if I have to guess and recreate your project.

I also have the "Wild West" project you sent but I don't know what to do to demonstrate the error.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Made an example without extra classes that imitate first version of inventory that Andy had when i looked into this case.

2 issues:

1. After Redraw() in real time top block overlap a block under it even if top is transparent or blue border in this example.

2. Some blocks change positions and sizes after Redraw() if those blocks were drawn initially, in this example it's text and background for text.

First row is a widget with items and it looks fine until you hit space.

Second initially without items.

Space clears make two items for both widgets. After pressing Space:

Second widget looks fine beside blue borders being filled square (issue 1).

But first widget totally broken and have both issues.

image.png.7c3e0f04e075678c31ae734745ef99da.png

After redrawing with Space button:

image.png.d534ba35e5efc8c744e44596df8ed9b5.png


    itemCount - to set how many items (red squares) suppose to show
    doHideBgId - hide text background for specific item. For some reason without it second issue does not happens. Maybe i missing something in a code.

#include "UltraEngine.h"

using namespace UltraEngine;

class CustomWidget : public Panel
{

    CustomWidget::CustomWidget()
    {
        cornerradius = 8;
    }

protected:

	virtual bool Initialize(const int x, const int y, const int width, const int height, shared_ptr<Widget> parent)
	{
		return Widget::Initialize(text, x, y, width, height, parent, style);
	}

	void Draw(const int x, const int y, const int width, const int height)
	{
		blocks.clear();
		Vec4 color = Vec4(0.9, 0.9, 0.9, 0.3);
        int blockWidth = 100;

		for (int i = 0; i < 4; i++)
		{
			iVec2 pos;
			pos.x = i * blockWidth + i * 10;
			pos.y = 0;

			iVec2 blockSize(blockWidth);

			AddBlock(pos, blockSize, color);

            if (i < itemCount) {
                auto pm = CreatePixmap(50, 50);
                pm->Fill(Vec4(1, 0, 0, 1));
                int block = AddBlock(pm, pos, Vec4(1));
                blocks[block].size = blockSize;
                if (doHideBgId != i) AddBlock(iVec2(pos.x, pos.y + (blockSize.height - 18)), iVec2(blockSize.width, 18), Vec4(0.2f, 0.2f, 0.2f, 1));
                AddBlock("item", iVec2(pos.x, pos.y + (blockSize.height - 15)), iVec2(blockSize.width, 15), Vec4(1));
            }

			if (i != 0) {
			    int block = AddBlock(pos, iVec2(blockSize.x, blockSize.y), Vec4(0, 0, 0, 1), true);
			    blocks[block].wireframe = true;
			}
			else {
				int block = AddBlock(pos, iVec2(blockSize.x, blockSize.y), Vec4(0.16, 0.47, 1, 1), true);
				blocks[block].wireframe = true;
			}		
		}
	}

public:

    int itemCount = 0;
    int doHideBgId = 0;

    static shared_ptr<CustomWidget> create(const int x, const int y, const int width, const int height, shared_ptr<Widget> parent)
    {
        struct Struct : public CustomWidget {
        };
        auto instance = std::make_shared<Struct>();
        instance->Initialize(x, y, width, height, parent);
        instance->SetColor(0, 1, 0, 1, WIDGETCOLOR_BACKGROUND);
        return instance;
    }

};

shared_ptr<Window> window;
shared_ptr<Framebuffer> framebuffer;
shared_ptr<World> menuWold;
shared_ptr<Interface> ui;
shared_ptr<Camera> uiCamera;

shared_ptr<CustomWidget> customWidget;
shared_ptr<CustomWidget> customWidget2;

void initGui()
{
    auto default_font = LoadFont("Fonts\\arial.ttf");
    ui = CreateInterface(menuWold, default_font, framebuffer->GetSize());
    ui->SetRenderLayers(2);
    ui->root->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
    uiCamera = CreateCamera(menuWold, PROJECTION_ORTHOGRAPHIC);
    uiCamera->SetPosition((float)framebuffer->GetSize().x * 0.5f, (float)framebuffer->GetSize().y * 0.5f, 0);
    uiCamera->SetRenderLayers(2);
    uiCamera->SetClearMode(CLEAR_DEPTH);
    customWidget = CustomWidget::create(10, 10, 500, 120, ui->root);
    customWidget->itemCount = 2;
    customWidget2 = CustomWidget::create(10, 150, 500, 120, ui->root);
}


int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    window = CreateWindow("Ultra Engine", 0, 0, 500, 300, displays[0], WINDOW_DEFAULT);

    //Create a world
    menuWold = CreateWorld();

    //Create a framebuffer
    framebuffer = CreateFramebuffer(window);

    auto textureLoaderPlugin = LoadPlugin("Plugins/FITextureLoader");

    initGui();

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyHit(KEY_SPACE))
        {
            customWidget->itemCount = 2;
            customWidget->doHideBgId = -1;
            customWidget->Redraw();
            customWidget2->itemCount = 2;
            customWidget2->doHideBgId = -1;
            customWidget2->Redraw();
        }
        menuWold->Update();
        menuWold->Render(framebuffer);
    }
    return 0;
}

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • Solution

Okay, I was able to fix this once I saw what was going on.

Thank you @Andy90 for reporting it, and thank you @Dreikblack for making it easy to debug.

An update will be available later today.

  • Like 1
  • Thanks 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...