Jump to content

Vulkan crash after changing window resolution


Dreikblack
 Share

Go to solution Solved by Josh,

Recommended Posts

idk if there is another proper way to change a resolution of window. This way works in 2D UI.

image.png.489c5a8605fb2365b4301224a67cd9f8.png

#include "UltraEngine.h"

using namespace UltraEngine;

bool EventCallback(const Event& ev, shared_ptr<Object> extra)
{
    auto window = extra->As<Window>();
    window->SetSize(1024, 768);
    return true;
}

int main(int argc, const char* argv[])
{
    auto displays = GetDisplays();
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);
    auto world = CreateWorld();
    auto framebuffer = CreateFramebuffer(window);

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

    auto default_font = LoadFont("Fonts\\arial.ttf");
    auto ui = CreateInterface(world, default_font, framebuffer->GetSize());
    ui->SetRenderLayers(2);
    ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f);

    auto ui_camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    ui_camera->SetPosition((float)framebuffer->GetSize().x * 0.5f, (float)framebuffer->GetSize().y * 0.5f, 0);
    ui_camera->SetRenderLayers(2);
    ui_camera->SetClearMode(CLEAR_DEPTH);

    auto btn = CreateButton("change res", 0, 0, 100, 30, ui->root);
    ListenEvent(EVENT_WIDGETACTION, btn, EventCallback, window);

    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        while (PeekEvent()) {
            auto ev = WaitEvent();
            ui->ProcessEvent(ev);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

  • Thanks 1
Link to comment
Share on other sites

Assert failed with this code (in Release mode too):

#include "UltraEngine.h"

using namespace UltraEngine;

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

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

    //Create a world
    auto world = CreateWorld();

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

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

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

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

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyHit(KEY_SPACE))
        {
            window = CreateWindow("Ultra Engine", 0, 0, 1920, 1080, displays[0], WINDOW_DEFAULT);
            framebuffer = CreateFramebuffer(window);
        }

        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

Link to comment
Share on other sites

Hold on there...Window::SetSize is not supposed to exist. There’s only SetShape, and it won’t work unless asynchronous rendering is disabled. So there are several different things going on 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

I found anassert is being triggered and it’s a good thing because it caught a strange situation we don’t want to occur.,,fixing now...

  • 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

Update is available. I was never able to produce the Vulkan error, but it might not be relevant now.

Note that your code will not release the original window unless you do something like this in the main loop:

        while (PeekEvent())
        {
            WaitEvent();
        }

 

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

There is no way to transfer an interface from one framebuffer to another. Is it hard to just re-create it? You can put it all in one function and just call that function when the new window is created.

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

8 minutes ago, Josh said:

Is it hard to just re-create it? You can put it all in one function and just call that function when the new window is created.

Depends on case. I can workaround it. I just thought i was missing something. What about passing or calling framebuffer in another class though? I can make listener for settings widget in a class where framebuffer was created but maybe there is a proper way to get it for window recreate?

Link to comment
Share on other sites

#include "UltraEngine.h"

using namespace UltraEngine;

void changeRes(shared_ptr<Window>& window, shared_ptr<Framebuffer>& framebuffer)
{
    shared_ptr<Framebuffer> newFramebuffer = framebuffer;
    window = CreateWindow("Ultra Engine", 0, 0, 1920, 1080, window->display, WINDOW_DEFAULT);
    //this works
    //framebuffer = CreateFramebuffer(window);
    //this one does not
    newFramebuffer = CreateFramebuffer(window);
}

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

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

    //Create a world
    auto world = CreateWorld();

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

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

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

    auto default_font = LoadFont("Fonts\\arial.ttf");
    auto ui = CreateInterface(world, default_font, framebuffer->GetSize());
    ui->SetRenderLayers(2);
    ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f);

    auto ui_camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    ui_camera->SetPosition((float)framebuffer->GetSize().x * 0.5f, (float)framebuffer->GetSize().y * 0.5f, 0);
    ui_camera->SetRenderLayers(2);
    ui_camera->SetClearMode(CLEAR_DEPTH);

    auto btn = CreateButton("change res", (float)framebuffer->GetSize().x / 2, framebuffer->GetSize().y / 2, 100, 30, ui->root);

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

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        while (PeekEvent())
        {
            const Event ev = WaitEvent();
            if (ev.id == EVENT_WIDGETACTION)
            {
                changeRes(window, framebuffer);
            }
            ui->ProcessEvent(ev);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

Link to comment
Share on other sites

I made an example for UI bug (old frame stays in new window) and Vulcan crash that happens if you drag new window with mouse.

Update: Also it crashes if you enter window mode after fullscreen mode. (have no idea to mark your checkbox btw xd)

image.thumb.png.830c43f7b4bbfc3a46f799ba08575858.png

main:

#include "UltraEngine.h"
#include "../MainMenu.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    auto menu = MainMenu::create();
    return 0;
}

MainMenu.h:

#pragma once
#include "UltraEngine.h"

using namespace UltraEngine;

class MainMenu : public Object
{
protected:
	MainMenu();
	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;
	void init();
	void initGui();
	void changeRes();
	bool fullscreen = false;
public:
	static std::shared_ptr<MainMenu> create();
};

MainMenu.cpp:

#include "UltraEngine.h"
#include "MainMenu.h"

MainMenu::MainMenu()
{

}

std::shared_ptr<MainMenu> MainMenu::create()
{
    struct Struct : public MainMenu {};
    auto instance = std::make_shared<Struct>();
    instance->init();
    return instance;
}

void MainMenu::init()
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    window = CreateWindow("Ultra Engine", 0, 0, 1680, 1050, 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)
            {
                changeRes();
            }
            if (ev.source == btn2 && ev.id == EVENT_WIDGETACTION)
            {
                fullscreen = !fullscreen;
            }
            ui->ProcessEvent(ev);
        }
        menuWold->Update();
        menuWold->Render(framebuffer);
    }
}

void MainMenu::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 res", (float)framebuffer->GetSize().x / 2, framebuffer->GetSize().y / 2, 200, 200, ui->root);
    btn->SetFontScale(2.0f);

    btn2 = CreateButton("Checkbox", (float)framebuffer->GetSize().x / 2, framebuffer->GetSize().y / 2 + 250, 120, 30, ui->root, BUTTON_CHECKBOX);
}

void MainMenu::changeRes()
{
    if (!fullscreen)
    {
        window = CreateWindow("Ultra Engine", 0, 0, 1920, 1080, window->display, WINDOW_DEFAULT);
    }
    else
    {
        window = CreateWindow("Ultra Engine", 0, 0, 1920, 1080, window->display, WINDOW_DEFAULT | WINDOW_FULLSCREEN);
    }
    framebuffer = CreateFramebuffer(window);
    initGui();
}
Edited by Dreikblack
updated with fullscreen check box
Link to comment
Share on other sites

1. Change res button

2. You will see interface bug

3. Drag window to hit screen border - vulkan crash

4. Restart, click checkbox

5. Changer res button

6. Click this button agian with or without checkbox before it - vulkan crash (looks a bit differently depending what mode will be after first fullscreen)

 

#include "UltraEngine.h"
#include "../MainMenu.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;

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 res", (float)framebuffer->GetSize().x / 2, framebuffer->GetSize().y / 2, 200, 200, ui->root);
    btn->SetFontScale(2.0f);

    btn2 = CreateButton("Checkbox", (float)framebuffer->GetSize().x / 2, framebuffer->GetSize().y / 2 + 250, 120, 30, ui->root, BUTTON_CHECKBOX);
}

void changeRes()
{
    if (!fullscreen)
    {
        window = CreateWindow("Ultra Engine", 0, 0, 1920, 1080, window->display, WINDOW_DEFAULT);
    }
    else
    {
        window = CreateWindow("Ultra Engine", 0, 0, 1920, 1080, window->display, 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, 1680, 1050, 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)
            {
                changeRes();
            }
            if (ev.source == btn2 && ev.id == EVENT_WIDGETACTION)
            {
                fullscreen = !fullscreen;
            }
            ui->ProcessEvent(ev);
        }
        menuWold->Update();
        menuWold->Render(framebuffer);
    }
    return 0;
}

 

  • Thanks 1
Link to comment
Share on other sites

56 minutes ago, Dreikblack said:

Window becomes minimized if i create it fullscreen with resolution lesser than max screen size. Same example above shows it.

Fixed!

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