Josh Posted September 17, 2022 Author Share Posted September 17, 2022 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 More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 For my large project I have found a few things - I have this error being shown once compiled yet it still seems to run. 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 More sharing options...
Josh Posted September 17, 2022 Author Share Posted September 17, 2022 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 More sharing options...
Josh Posted September 17, 2022 Author Share Posted September 17, 2022 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. 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 More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 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 More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 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! 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 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 More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 ListDisplays() is GetDisplays() Link to comment Share on other sites More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 CreateRect() and CreateText() for Sprites, are they replaced or gone? Link to comment Share on other sites More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 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 More sharing options...
Josh Posted September 17, 2022 Author Share Posted September 17, 2022 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! 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 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(). 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 More sharing options...
Josh Posted September 17, 2022 Author Share Posted September 17, 2022 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) 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 More sharing options...
Josh Posted September 17, 2022 Author Share Posted September 17, 2022 56 minutes ago, SpiderPig said: CreateRect() and CreateText() for Sprites, are they replaced or gone? CreateSprite() 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 More sharing options...
reepblue Posted September 17, 2022 Share Posted September 17, 2022 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 Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
klepto2 Posted September 17, 2022 Share Posted September 17, 2022 @Josh let me first try some things, it might be due a failed installation. I had to restore a backup, which might not be complete. If not we can try the remote dbg route. Windows 10 Pro 64-Bit-Version NVIDIA Geforce 1080 TI Link to comment Share on other sites More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 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! And removing verts too? Maybe SetVertices() as well, I have needed to clear them before. Link to comment Share on other sites More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 10 hours ago, Josh said: 3. Mouseposition Z is the wheel position. I have needed to set the scroll wheel to zero before. Can't remember why, but I remember it be useful. Link to comment Share on other sites More sharing options...
SpiderPig Posted September 17, 2022 Share Posted September 17, 2022 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"); Developer.zip 1 Link to comment Share on other sites More sharing options...
SpiderPig Posted September 18, 2022 Share Posted September 18, 2022 Can Ultra still be compiled for 32bit as well as 64bit? In the old Steam BETA you had options for Debug 64f and Release 64f. Link to comment Share on other sites More sharing options...
Josh Posted September 18, 2022 Author Share Posted September 18, 2022 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. 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 More sharing options...
SpiderPig Posted September 18, 2022 Share Posted September 18, 2022 Now that Canvas isn't a thing, how do we get Widgets to display over a camera? Used to be camera->AddCanvas() I think... Link to comment Share on other sites More sharing options...
Josh Posted September 18, 2022 Author Share Posted September 18, 2022 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. 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 More sharing options...
SpiderPig Posted September 18, 2022 Share Posted September 18, 2022 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 More sharing options...
SpiderPig Posted September 18, 2022 Share Posted September 18, 2022 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 More sharing options...
Josh Posted September 18, 2022 Author Share Posted September 18, 2022 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. 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 More sharing options...
SpiderPig Posted September 18, 2022 Share Posted September 18, 2022 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 More sharing options...
Recommended Posts