Jump to content

Ultra Engine testing


Josh
 Share

Recommended Posts

The only way I can investigate it is to do a remote debugging sessions like spiderpig and I did. In his case, I found there was a problem with the Vulkan initialization. There are a lot of weird possible configurations of complicated features, so it's easy to make mistakes there and hard to test on one machine.

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

For my large project I have found a few things -

 

I have this error being shown once compiled yet it still seems to run.

ExternCError.png.e10f38db7a07bb2d9d35de9aaf039f95.png

Widget::SetPosition() missing

Widget::SetSize() missing

Widget::Hide() and Show() is inaccessible

Window::GetMousePosition returns an iVec3 but SetMousePosition only takes an iVec2 or two integers

Camera->UnProject() still takes a Vec3 for mouse position.

no * operator for iVec3 multiplied by a  float

ATan2() missing?

Listener class missing?

Model::Hide() missing

Entity::SetValue() missing

String::Len() missing

Mesh::Finalize() inaccessible

Mesh::vertices.resize(my_vertex_count);  Won't let me resize the vertex or indices of a mesh anymore.  I like to resize the array then use indexing to place them.  Faster on large meshes.  Or push_back().

Is ListDisplays() redundant?

Is the "Canvas" class redundant?

CreateInterface() is declared thusly;  3rd parameter is for something?

friend shared_ptr<Interface> CreateInterface(shared_ptr<World> world, shared_ptr<Framebuffer>, const float);

 

 

 

Link to comment
Share on other sites

16 minutes ago, SpiderPig said:

Mesh::vertices.resize(my_vertex_count);  Won't let me resize the vertex or indices of a mesh anymore.  I like to resize the array then use indexing to place them.  Faster on large meshes.  Or push_back().

Is ListDisplays() redundant?

Is the "Canvas" class redundant?

CreateInterface() is declared thusly;  3rd parameter is for something?

friend shared_ptr<Interface> CreateInterface(shared_ptr<World> world, shared_ptr<Framebuffer>, const float);

The non-critical errors might just be because intellisense hasn't finished updating.

1. The Mesh::vertices member is read-only by design. Use the mesh commands to modify the mesh.
2. Why would ListDisplays() be redundant?
3. There is no Canvas class.
4. CreateInterface(shared_ptr<World> world, shared_ptr<Font> font, const iVec2& size)
 

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, SpiderPig said:

Widget::SetPosition() missing

Widget::SetSize() missing

Widget::Hide() and Show() is inaccessible

Window::GetMousePosition returns an iVec3 but SetMousePosition only takes an iVec2 or two integers

Camera->UnProject() still takes a Vec3 for mouse position.

no * operator for iVec3 multiplied by a  float

ATan2() missing?

Listener class missing?

Model::Hide() missing

Entity::SetValue() missing

String::Len() missing

Mesh::Finalize() inaccessible

1, 2. Use Widget::SetShape() instead of SetPosition and SetSize().
3. Mouseposition Z is the wheel position.
4. Z is the distance in front of the camera
5. iVec3 is an integer vector, and should not be multiplied by a float, only an integer.
6. Just call ATan() with two parameters. GLSL does it the same way.
7. Entity->Listen(). No listener class. :)
8. Model::SetHidden(true). 
9. Entity::SetValue...try SetField()
10. String::Length() not Len().
11. You don't need to call Mesh::Finalize() anymore, it will be done automatically when you modify a mesh, before the world render.

  • 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

2 minutes ago, Josh said:

1. The Mesh::vertices member is read-only by design. Use the mesh commands to modify the mesh.
2. Why would ListDisplays() be redundant?
3. There is no Canvas class.
4. CreateInterface(shared_ptr<World> world, shared_ptr<Font> font, const iVec2& size)

1.  Adding vertices and primitives one at a time is slow for large meshes (if nothings changed under the hood since the Steam BETA)  I'm talking terrain chunks that could be 500k to 1 million vertices strong.  Resizing the vector once is faster than 1million resizes.

2.  It says it is undefined...

3. Is it just the Interface class then?

9 minutes ago, Josh said:

The non-critical errors might just be because intellisense hasn't finished updating.

Maybe... they are in fresh project with only main.cpp open.  The build succeeds... but there's 97 errors (debug and release).  I'll list the source files if you need me too.

Link to comment
Share on other sites

10 minutes ago, Josh said:

1, 2. Use Widget::SetShape() instead of SetPosition and SetSize().
3. Mouseposition Z is the wheel position.
4. Z is the distance in front of the camera
5. iVec3 is an integer vector, and should not be multiplied by a float, only an integer.
6. Just call ATan() with two parameters. GLSL does it the same way.
7. Entity->Listen(). No listener class. :)
8. Model::SetHidden(true). 
9. Entity::SetValue...try SetField()
10. String::Length() not Len().
11. You don't need to call Mesh::Finalize() anymore, it will be done automatically when you modify a mesh, before the world render.

1. I like SetShape() - but most of the time I find myself needing to set the position OR the size.  Rarely I find myself needing to do both unless I'm creating the widget.  With SetShape() I'd first have to retrieve the position or size and set it to what it already is just to satisfy the function.  Too much typing! :P

2.  How does Entity::Listen() work?  Do we call it on Camera setup for example?  my_camera->Listen()?

3.  SetHidden(true).  Too many letters to type :P  Show() and Hide() are just easier and instantly makes sense when you read them.

4.  String::length() with a lower case exists.  Is that intentional?

Link to comment
Share on other sites

I think for Meshes there needs to be something like this

vector<Vertex> vertices;
vector<Indice> indices;

vertices.resize(10000);
indices.resize(5000);

//Build mesh

my_mesh->SetVertices(vertices);
my_mesh->SetIndices(indices);

 

I've built some terrains and some very deep octree visualizations using the Mesh class and I know AddVertex() and AddPrimitive() take a very long time if you call a lot of them.  Indexing the vertex and indices arrays brought creating them down to a bearably time frame.

Link to comment
Share on other sites

1 hour ago, SpiderPig said:

1. I like SetShape() - but most of the time I find myself needing to set the position OR the size.  Rarely I find myself needing to do both unless I'm creating the widget.  With SetShape() I'd first have to retrieve the position or size and set it to what it already is just to satisfy the function.  Too much typing! :P

2.  How does Entity::Listen() work?  Do we call it on Camera setup for example?  my_camera->Listen()?

3.  SetHidden(true).  Too many letters to type :P  Show() and Hide() are just easier and instantly makes sense when you read them.

4.  String::length() with a lower case exists.  Is that intentional?

The reason SetShape() is used is because if you set the position and size in two different commands, there is a visible intermediate state that SetShape() eliminates, because it sets both at once. I have not found Widget resizing / moving to be a very frequent operation, since most of the time you will just let the widget layout take care of all that.

Entity::Listen() turns any entity into the listener. If you just call this on the camera, then all sounds will be relative to the player's view.

SetHidden / GetHidden was used for consistency with the rest of the API.

String::length() is the STL string method, which can also be called. This works because Ultra Strings are extensions of STL strings, which is nice because you can provide an Ultra String or WString to any command that accepts an STL string. The official command is String::GetSize() though (not Length()). See what I said about API consistency? Everything has been designed to try to eliminate guessing of method names, which I still do in Leadwerks sometimes. This is also why ListDIsplays() was renamed to GetDisplays().

  • 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

Regarding large mesh building, the reason it would be slow with very big meshes is because the STL vector is being frequently resized as it grows, so it keeps allocating and copying a larger and larger block of memory. I'm not sure what should be done, maybe some new methods like this:

Mesh::AddVertices(const std::vector<Vertex>& verts)
Mesh::AddIndices(const std::vector<uint32_t>& indices)

 

  • Upvote 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

Last night my app stopped working as expected. I had a layout on how I wanted scene loading to work but now the "menu" doesn't disappear and I was too frustrated to figure out why.

I think I'm just going to wait until everything settled before writing code I want to ship with.

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

8 hours ago, Josh said:

Regarding large mesh building, the reason it would be slow with very big meshes is because the STL vector is being frequently resized as it grows, so it keeps allocating and copying a larger and larger block of memory. I'm not sure what should be done, maybe some new methods like this:



Mesh::AddVertices(const std::vector<Vertex>& verts)
Mesh::AddIndices(const std::vector<uint32_t>& indices)

That's what I was thinking.  Commands like that would be perfect!  :D

 

And removing verts too?  Maybe SetVertices() as well, I have needed to clear them before.

Link to comment
Share on other sites

Found a few more things;

1. CreateTextField() still compiles with an Interface as an argument but it leads to an unresolved external symbol error.  Setting it to use the root of the interface works.

2.  CreateTextArea() is the same.  Still compiles but won't link.

3. CreateInterface() takes an unknown float as the 3rd parameter and links with unresolved symbol.   I don't need it - just think it's there by accident...

4. frambuffer is nullptr when using the flag WINDOW_RESIZEABLE in the CreateWindow()

auto window = CreateWindow("MyApp", 0, 0, 1440, 900, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR | WINDOW_RESIZABLE);
auto framebuffer = CreateFramebuffer(window);

5.  Getting this error when loading a material in a fresh project.  (Files attached)

auto mat = LoadMaterial("Materials\\Developer\\bluegrid.mat");

MaterialError.thumb.png.65a77b4daaa8b78264c8285a283465b1.png

Developer.zip

  • Like 1
Link to comment
Share on other sites

3 hours ago, SpiderPig said:

1. CreateTextField() still compiles with an Interface as an argument but it leads to an unresolved external symbol error.  Setting it to use the root of the interface works.

2.  CreateTextArea() is the same.  Still compiles but won't link.

3. CreateInterface() takes an unknown float as the 3rd parameter and links with unresolved symbol.   I don't need it - just think it's there by accident...

4. frambuffer is nullptr when using the flag WINDOW_RESIZEABLE in the CreateWindow()

1, 2, 3. These must be due to old friend declarations in other classes. I'll remove those.
4. This is the correct behavior. If you want a resizable window, call ASyncRender(false) before anything else in your program. This works with resizable windows but uses a single thread for rendering and game logic, like Leadwerks does, so it will run much slower. There's a long explanation of how and why this works somewhere earlier in this thread.

To load the Leadwerks material, you might need need to first load the Leadwerks plugin. However, some of the material properties are up-in-the-air right now so it might not work still.

  • 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

Create a camera that uses orthographic projection, position it at half the framebuffer size, and use the render layer feature to control which objects it can draw:

https://www.ultraengine.com/community/topic/61132-try-the-client-app/page/6/?tab=comments#comment-296705

It's a little more work to set up, but it allows a lot of control that Leadwerks 2D rendering never had. You can make post-processing effects appear below or on top of 2D rendering. You can render 3D on top of 2D. You can have multiple layers of 2D graphics. And it uses the depth buffer for ordering, so everything draws super fast, unlike most 2D renderers which draw primitives one at a time in order.

  • 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

I like that idea a lot.  When I implemented it in my project though I had no 3D objects showing up.  I ran this code in a fresh project and the box was not visible.  I think it should be in view in the centre of the screen...

 

#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, 800, 600, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

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

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

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);
    camera->SetRotation(45, 0, 0);
    camera->Move(0, 0, -10);
    camera->SetFOV(70);

    auto uicam = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    uicam->SetRenderLayers(RENDERLAYER_1);
    uicam->SetPosition(framebuffer->size.x / 2, framebuffer->size.y / 2);
    auto ui = CreateInterface(world, LoadFont("Fonts/arial.ttf"), framebuffer->size);
    ui->SetRenderLayers(RENDERLAYER_1);

    auto sz = ui->root->ClientSize();
    auto textarea = CreateTextArea(10, 10, sz.x - 20, 100, ui->root, TEXTAREA_WORDWRAP);

    WString s;

    for (int n = 0; n < 300; ++n)
    {
        s += String(n) + "\n";
    }

    textarea->SetLayout(1, 1, 1, 1);

    //ui->SetScale(displays[0]->scale);
    textarea->SetText(s);

    auto box = CreateBox(world);

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

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

 

Link to comment
Share on other sites

I've noticed that objects still pop in an out as you move the camera sometimes.  This has been something I've noticed since the Steam BETA.

Run this and hold space to move the box.  Follow the box by moving the mouse and the box will disappear sometimes.

#include "UltraEngine.h"

using namespace UltraEngine;

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

    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);
    camera->SetRotation(45, 0, 0);
    camera->Move(0, 0, -10);
    camera->SetFOV(70);

    auto box = CreateBox(world);

    auto mousepos = Vec3();
    float lookspeed = 0.1f;
    float looksmoothing = 0.5f;

    auto _displaySize = window->GetSize();
    float cx = Round((float)_displaySize.x / 2.0f);
    float cy = Round((float)_displaySize.y / 2.0f);
    window->SetMousePosition(cx, cy);

    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyDown(KEY_SPACE)) {
            box->Move(0.05, 0, 0);
        }

        float dx = 0.0f, dy = 0.0f;
        _displaySize = window->GetSize();
        cx = Round((float)_displaySize.x / 2.0f);
        cy = Round((float)_displaySize.y / 2.0f);
        auto mpos = Vec3(window->GetMousePosition().x, window->GetMousePosition().y, window->GetMousePosition().z);
        window->SetMousePosition(cx, cy);
        mpos = mpos * looksmoothing + mousepos * (1 - looksmoothing);
        dx = (mpos.x - cx) * lookspeed;
        dy = (mpos.y - cy) * lookspeed;

        auto camrot = camera->GetRotation();
        camrot.x += dy;
        camrot.y += dx;
        camera->SetRotation(camrot);
        mousepos = mpos;

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

 

Link to comment
Share on other sites

4 hours ago, SpiderPig said:

I ran this code in a fresh project and the box was not visible.  I think it should be in view in the centre of the screen...

Call uicam->SetClearMode(CLEAR_DEPTH) so it shows the previously rendered color underneath.

2 hours ago, SpiderPig said:

I've noticed that objects still pop in an out as you move the camera sometimes. 

This happens because culling is performed asynchronously, and visibility sets are reused to draw several frames. If it only happens in debug mode it's not a problem. Otherwise there is a camera frustum prediction feature I can toggle on and off that I am still toying with.

  • 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

20 minutes ago, Josh said:

Call uicam->SetClearMode(CLEAR_COLOR) so it shows the previously rendered color underneath.

Once at setup or per frame?  I tried both and it made no difference.

21 minutes ago, Josh said:

This happens because culling is performed asynchronously, and visibility sets are reused to draw several frames. If it only happens in debug mode it's not a problem. Otherwise there is a camera frustum prediction feature I can toggle on and off that I am still toying with.

It's exactly the same in release too.  It doesn't vanish too early at the edge of the frustum which I could understand in debug, it can vanish in the middle of the screen...

Link to comment
Share on other sites

  • Josh changed the title to Ultra Engine testing
  • Josh locked this topic
Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...