Jump to content

Window recreating causes Asset failed error


Dreikblack
 Share

Go to solution Solved by Josh,

Recommended Posts

Press Change display to recreate a window and get an error.

btw UI now seems to be working now on my 2nd screen.

#include "UltraEngine.h"

using namespace UltraEngine;

shared_ptr<Window> window;
shared_ptr<Framebuffer> framebuffer;
shared_ptr<World> menuWold;
shared_ptr<Interface> ui;
shared_ptr<Camera> uiCamera;
shared_ptr<Widget> btn;
shared_ptr<Widget> btn2;
bool fullscreen = false;
int displayId = 0;

void initGui()
{
    auto default_font = LoadFont("Fonts\\arial.ttf");
    ui = CreateInterface(menuWold, default_font, framebuffer->GetSize());
    ui->SetRenderLayers(2);
    ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.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);

    btn = CreateButton("Change display", (float)framebuffer->GetSize().x / 2, framebuffer->GetSize().y / 2, 200, 200, ui->root);
    btn->SetFontScale(2.0f);

    btn2 = CreateButton("Fullscreen", (float)framebuffer->GetSize().x / 2, framebuffer->GetSize().y / 2 - 100, 120, 30, ui->root, BUTTON_CHECKBOX);
    if (fullscreen) btn2->SetState(WIDGETSTATE_SELECTED);
}

void changeDisplay()
{
    auto displays = GetDisplays();
    displayId = ++displayId;
    if (displayId == displays.size())
    {
        displayId = 0;
    }
    if (!fullscreen)
    {
        window = CreateWindow("Ultra Engine", 0, 0, 1000, 1000, GetDisplays()[displayId], WINDOW_DEFAULT);
    }
    else
    {
        window = CreateWindow("Ultra Engine", 0, 0, displays[displayId]->GetSize().width, displays[displayId]->GetSize().height, displays[displayId], WINDOW_DEFAULT | WINDOW_FULLSCREEN);
    }
    framebuffer = CreateFramebuffer(window);
    initGui();
}

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

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

    //Create a world
    menuWold = CreateWorld();

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

    //Create light
    auto light = CreateBoxLight(menuWold);
    light->SetRange(-10, 10);
    light->SetRotation(15, 15, 0);
    light->SetColor(2);

    //Create camera
    auto camera = CreateCamera(menuWold);
    camera->SetClearColor(0.125);
    camera->SetPosition(0, 0, -3);
    camera->SetFov(70);

    //Create scenery
    auto box = CreateBox(menuWold);

    initGui();

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        while (PeekEvent())
        {
            const Event ev = WaitEvent();
            if (ev.source == btn && ev.id == EVENT_WIDGETACTION)
            {
                changeDisplay();
            }
            if (ev.source == btn2 && ev.id == EVENT_WIDGETACTION)
            {
                fullscreen = !fullscreen;
            }
            ui->ProcessEvent(ev);
        }
        menuWold->Update();
        menuWold->Render(framebuffer);
    }
    return 0;
}

 

Link to comment
Share on other sites

Fixed for build later today. If you hit an assert, just send me some code to produce it, like you did here.

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

Confirmed, although rendering is working fine for me.

I have simplified your example and am testing...

#include "UltraEngine.h"

using namespace UltraEngine;

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

    shared_ptr<Window> window;
    shared_ptr<Framebuffer> framebuffer;
    shared_ptr<World> menuWold;
   
    //Create a window
    window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0], WINDOW_TITLEBAR);

    //Create a world
    menuWold = CreateWorld();

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

    //Create light
    auto light = CreateBoxLight(menuWold);
    light->SetRange(-10, 10);
    light->SetRotation(15, 15, 0);
    light->SetColor(2);

    //Create camera
    auto camera = CreateCamera(menuWold);
    camera->SetClearColor(0.125);
    camera->SetPosition(0, 0, -3);
    camera->SetFov(70);

    //Create scenery
    auto box = CreateBox(menuWold);

    int x = 0;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyHit(KEY_SPACE))
        {
            x += 100;
            window = CreateWindow("Ultra Engine", x, x, 800, 600, displays[0], WINDOW_TITLEBAR);
            framebuffer = CreateFramebuffer(window);
        }
        menuWold->Update();
        menuWold->Render(framebuffer);
    }
    return 0;
}

 

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

Okay, this has to do with resource cleanup and I have to treat this very carefully...stay tuned.

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

Yeah, from my application, it seems that the active window isn't being reassigned. The text should be in the bottom corner of this window but it's in the position of the bottom right of my splash window.  

image.thumb.png.95c13f924402f685b977fc71a6122411.png

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

In my current build this code is working correctly. Please let me know if you have problems after today's update.

Two things to remember:

  • A window with a framebuffer will not be deleted until after two calls to World::Render with a different framebuffer, because it has to make a round-trip to the rendering thread and back to delete the window's graphics context before the window is deleted.
  • You don't have this problem in your code, but remember to clear out events to prevent windows from being stuck in memory.
     
#include "UltraEngine.h"

using namespace UltraEngine;

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

    shared_ptr<Window> window;
    shared_ptr<Framebuffer> framebuffer;
    shared_ptr<World> menuWold;

    //Create a window
    window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0], WINDOW_TITLEBAR);

    //Create a world
    menuWold = CreateWorld();

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

    //Create light
    auto light = CreateBoxLight(menuWold);
    light->SetRange(-10, 10);
    light->SetRotation(15, 15, 0);
    light->SetColor(2);

    //Create camera
    auto camera = CreateCamera(menuWold);
    camera->SetClearColor(0.125);
    camera->SetPosition(0, 0, -3);
    camera->SetFov(70);

    //Create scenery
    auto box = CreateBox(menuWold);

    int x = 0;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        while (PeekEvent()) WaitEvent();

        if (window->KeyHit(KEY_SPACE))
        {
            x += 100;
            window = CreateWindow("Ultra Engine", x, x, 800, 600, displays[0], WINDOW_TITLEBAR);
            framebuffer = CreateFramebuffer(window);
        }
        menuWold->Update();
        menuWold->Render(framebuffer);
    }
    return 0;
}

 

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

18 hours ago, Josh said:
  if (window->KeyHit(KEY_SPACE))
        {
            x += 100;
            window = CreateWindow("Ultra Engine", x, x, 800, 600, displays[0], WINDOW_TITLEBAR);
            framebuffer = CreateFramebuffer(window);
        }

Tried this example - windows stays if i hold a button for few seconds (removed offset for y - window was hiding below before reaching 2nd screen)

image.thumb.png.47fc2f9df05b5dece899d6efa12b52cc.png

Link to comment
Share on other sites

2 hours ago, Dreikblack said:

Tried this example - windows stays if i hold a button for few seconds (removed offset for y - window was hiding below before reaching 2nd screen)

image.thumb.png.47fc2f9df05b5dece899d6efa12b52cc.png

Weird.

Holding the space key will continuously generate new key hits because it's a different window each time.

I have verified that the system is working correctly and DestroyWindow(hwnd) is actually being called on the old windows.

It's indicating error ERROR_ACCESS_DENIED, but I am sure the function is being called from the main thread...

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

Maybe what is going on is wglCreateContextAttribsARB creates a child window on the rendering thread, then DestroyWindow on the main thread is unable to delete the child that was created on the rendering thread, but I need to investigate further. In the meantime I will just add a check that hides the window if DestroyWindow fails.

That doesn't actually make sense, because this only occurs if windows are created in rapid succession. Otherwise it is fine...

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...