-
Posts
2,500 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Posts posted by reepblue
-
-
12 minutes ago, Josh said:
Currently there is no merging / collapsing of brushes when a map is loaded. It's not as important in Ultra as it was in Leadwerks, because draw calls don't slow Ultra down much. I plan to add a Map::Build() command, or add some load flag that controls whether brushes get collapsed. Once that is in, then the original brushes will be gone, so there won't be anything to reload from a game save file.
Hmm, this does solve my problem of identifying what is level geometry and what is a decorative model. I can just use the As<Brush>() cast. I guess if brush collapsing returns, please put back the public "collapsedbrush" bool or something like you had in Leadwerks.
I also want to mention that when I loaded my save file with Map::Load(), I noticed my materials lost their normal maps. These kinds of things are hard to write examples for as it requires a lot of code and assets to showcase the problem. Maybe it's a side effect from the same problem here.
-
-
5 minutes ago, Josh said:
This is in the asset editor window?
Top one is from the Asset browser, correct. Sorry for not making that clear.
The bottom screen is from the Map Tab.
-
Found a new bug with the Save/Load system. I think the brushes are being re-created. This example has a transparent material in the scene, and it gets opaquer after each reload.
Load the map, Press F5, and then press F6 to see the results.
#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_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Load scene auto scene = LoadMap(world, "Maps/savetest3.ultra"); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { if (window->KeyHit(KEY_F5)) { //Save the starting scene to a file scene->Save("game.sav"); } //Reload the starting scene when space key is pressed if (window->KeyHit(KEY_F6)) { scene->Reload("game.sav"); } world->Update(); world->Render(framebuffer); } return 0; }
-
Diffrent problem, but related. When the sound is resumed, it starts from the beginning. Replace the sound with the one attached.
-
In the asset browser, I can't seem to change the Collision Type or gravity settings for a gltf+bin model. Might be a carry over from a previous bug. Also, for appearance, it's missing the "Static Reflection" option.
Checked items are marked as False on the Map panel.
I'll report more when I find them...
- 1
-
Pausing/Resuming speakers aren't working as expected.
#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_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->SetFov(70); camera->SetPosition(0, 0, -3); camera->Listen(); //Create a light auto light = CreateBoxLight(world); light->SetRotation(35, 45, 0); light->SetRange(-10, 10); //Create a box auto box = CreateBox(world); box->SetColor(0, 0, 1); //Sound auto sound = LoadSound("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Sound/notification.wav"); auto speaker = CreateSpeaker(sound); speaker->SetPosition(box->GetPosition(true)); speaker->SetRange(10); auto speakerloop = CreateSpeaker(sound); speakerloop->SetPosition(box->GetPosition(true)); speakerloop->SetRange(10); speakerloop->SetLooping(true); auto speakerstate = speaker->GetState(); auto speakerloopstate = speakerloop->GetState(); bool paused = false; //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { // P Plays the normal non-looping speaker if (window->KeyHit(KEY_P)) { speaker->Play(); } // L Plays the looping speaker if (window->KeyHit(KEY_L)) { speakerloop->Play(); } // Space pauses both speakers if (window->KeyHit(KEY_SPACE)) { if (!paused) { speaker->Pause(); speakerloop->Pause(); paused = true; } else { speaker->Resume(); speakerloop->Resume(); paused = false; } } // Report the state if (speaker->GetState() != speakerstate) { Print("Normal Speaker state at: " + String(speaker->GetState())); speakerstate = speaker->GetState(); } if (speakerloop->GetState() != speakerloopstate) { Print("Looping Speaker state at: " + String(speakerloop->GetState())); speakerloopstate = speakerloop->GetState(); } //Move and turn with the arrow keys - best experienced with headphones if (window->KeyDown(KEY_UP)) camera->Move(0, 0, 0.1); if (window->KeyDown(KEY_DOWN)) camera->Move(0, 0, -0.1); if (window->KeyDown(KEY_LEFT)) camera->Turn(0, -1, 0); if (window->KeyDown(KEY_RIGHT)) camera->Turn(0, 1, -0); world->Update(); world->Render(framebuffer); } return 0; }
Right now, I have to do this hack in my project.
void GameSpeaker::Pause() { if (speaker) { if (speaker->GetState() == SPEAKER_PLAYING) { pausetime = speaker->GetTime(); speaker->Pause(); } } } void GameSpeaker::Resume() { if (speaker) { if (speaker->GetState() == SPEAKER_PAUSED || pausetime > 0) { speaker->SetTime(pausetime); speaker->Play(); pausetime = 0; } } }
-
I'm trying to make an editor extension that'll create new files from the editor. I'm working on a "Create New Material" function, but I get an error with the Save command saying it expects usedata type and not a string, although I feel like this code is correct.
local extension = {} function CreateNewMaterial() local file = RequestFile("Select Material Location", "", "Ultra Engine Material File (*.mat):mat", 0, true) if file ~= nil then local mat = CreateMaterial() if mat ~= nil then mat:SetColor(1,1,1,1) local shaderfamily = LoadShaderFamily("Shaders/PBR.fam") if shaderfamily then mat:SetShaderFamily(shaderfamily) shaderfamily = nil end mat:Save(file); end end end function extension.hook(event, extension) if event.id == EVENT_WIDGETACTION then if event.source == extension.menuitem then CreateNewMaterial() end end end -------------------------------------------------------------------- -- Add menu item -------------------------------------------------------------------- local menu = program.menu:FindChild("Create", false) if menu ~= nil then local submenu = menu:FindChild("Asset", false) if submenu == nil then submenu = CreateMenu("Asset", menu) end extension.menuitem = CreateMenu("Material", submenu) end ListenEvent(EVENT_WIDGETACTION, extension.menuitem, extension.hook, extension)
I also tried making a table and saving it, but it didn't work ether.
local a = ctable() a["material"] = nil a["material"]["shaderFamily"] = "Shaders/PBR.fam" SaveTable(a, file)
What am I doing wrong here?
-
Old attachment but this demonstrates that the components are no longer being loaded although it's registered.
-
Color is the most important but I can check the others.
-
I still see DDS as the engine's native texture format as you don't need a plugin to load such textures.
- 1
-
11 hours ago, Josh said:
Hmmm...I still have not made up my mind. What is our "native" texture format? DDS, Basis, or KTX2?
I assumed it was DDS for traditional games, basis for simulations, and ktx for if Ultra runs on something like the quest.
The question I've ran into is what is the best modeling format since gltf is technically 3 formats.
-
This map demonstrates the crash.
- 1
-
I'm playing around with the editor and noticed when I set a light (Such as a point light) to static, my app crashes as soon as it renders in the camera.
I'm noticing this from the editor, but I think this example will reproduce the results when pressing space.
#include "UltraEngine.h" #include "Components/Motion/Mover.hpp" using namespace UltraEngine; int main(int argc, const char* argv[]) { //Plugin for texture loading auto plugin = LoadPlugin("Plugins/FITextureLoader"); //Get display auto displays = GetDisplays(); //Create window auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_TITLEBAR | WINDOW_CENTER); //Create framebuffer auto framebuffer = CreateFramebuffer(window); //Create world auto world = CreateWorld(); world->SetAmbientLight(0.1); world->RecordStats(true); //Create camera auto camera = CreateCamera(world); camera->SetClearColor(0.25); camera->SetPosition(0, 2, 0); camera->Move(0, 0, -5); //Build scene auto tunnel = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/tunnel_t.glb"); tunnel->SetRotation(0, 180, 0); tunnel->Staticize(); auto cage = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fancage.glb"); cage->Staticize(); auto fan = LoadModel(world, "https://github.com/UltraEngine/Documentation/raw/master/Assets/Models/Underground/fanblades.glb"); fan->SetPosition(0, 2, 0); auto mover = fan->AddComponent<Mover>(); mover->rotation.z = 300; auto light = CreatePointLight(world); light->SetColor(2, 2, 2); light->SetRange(10); light->SetPosition(0, 2, 2); light->SetColor(4.0); //Display text auto orthocam = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); orthocam->SetClearMode(CLEAR_DEPTH); orthocam->SetRenderLayers(128); orthocam->SetPosition(float(framebuffer->size.x) * 0.5, float(framebuffer->size.y) * 0.5f); auto font = LoadFont("Fonts/arial.ttf"); auto text = CreateSprite(world, font, "Shadow polygons: 0", 14.0 * displays[0]->scale); text->SetPosition(2, framebuffer->size.y - 16.0f * displays[0]->scale); text->SetRenderLayers(128); auto text2 = CreateSprite(world, font, "Press space to make the light static.", 14.0 * displays[0]->scale); text2->SetPosition(2, framebuffer->size.y - 16.0f * 2.0f * displays[0]->scale); text2->SetRenderLayers(128); //Main loop while (!window->KeyHit(KEY_ESCAPE) and !window->Closed()) { world->Update(); world->Render(framebuffer); if (window->KeyHit(KEY_SPACE)) { light->Staticize(); text2->SetHidden(true); } text->SetText("Shadow polygons: " + String(world->renderstats.shadowpolygons)); } return 0; }
-
1. Place a probe in the map
2. Build GI.
3. Edit the Probe's appearance (Like Color).
4. Rebuild GI.
5 Notice the Probes go back to how they were.
- 1
-
FYI, don't do this, The window didn't draw correctly at 100% scaling.
#include "UltraEngine.h" #include "Components/Motion/Mover.hpp" #include "Components/Player/CameraControls.hpp" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto cl = ParseCommandLine(argc, argv); RegisterComponent<Mover>(); RegisterComponent<CameraControls>(); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * 2, 720 * 2, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Load the map WString mapname = "Maps/start.ultra"; if (cl["map"].is_string()) mapname = std::string(cl["map"]); auto scene = LoadMap(world, mapname); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); } return 0; }
Do something like this.
#include "UltraEngine.h" #include "Components/Motion/Mover.hpp" #include "Components/Player/CameraControls.hpp" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto cl = ParseCommandLine(argc, argv); RegisterComponent<Mover>(); RegisterComponent<CameraControls>(); //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * (int)displays[0]->GetScale(), 720 * (int)displays[0]->GetScale(), displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Load the map WString mapname = "Maps/start.ultra"; if (cl["map"].is_string()) mapname = std::string(cl["map"]); auto scene = LoadMap(world, mapname); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); } return 0; }
Only thing is that you need to cast the float to an int which might cause problems.
-
Maybe have the asset browser also prompt for a name change when the user saves other Leadwerks assets.
- 1
-
7 minutes ago, Josh said:
What do you mean?
I mean that it wasn't a big deal when the environment settings didn't save in the map files, but now that bug was fixed, the multiple dialog boxes became more annoying as there was a reason to apply skyboxes and such. 🤣
I haven't tried Ultra since Sunday, I probably should boot up my PC after work and check everything out.
-
1 hour ago, Josh said:
The plugin is FITextureLoader.dll. FreeImage.dll is not a plugin, it is a required DLL the plugin DLL must use.
I think the names of plugins should have a universal prefix so people know what to actually load.
- 2
-
I ran into this but forgot about it since the feature didn't work anyway. Now that it should be fixed, this is pretty annoying.
-
17 hours ago, Josh said:
Fixed.
I removed the fog settings because fog is a per-camera settings and the other stuff is all per-world.
I am not sure how fog and post-effects should be handled yet. Intuitively it seems like they would be set for the world, but I need to determine the rules that are in place for cameras that are created in code and in the scene, and whether cameras should have their own individual settings for these, and how that interacts with the per-map setting.
I mean, it was the same thing in Leadwerks and although confusing at first, I understood how it worked after a while.
I think the map should store the fog/post effect information and then the end user should be able to apply them in the load function of their component. It might be too much, but that's just a quick idea I had.
-
9 hours ago, Josh said:
This only happens with spot lights, right?
All lights minus environment.
-
1. Create a json component file with these contents.
{ "component": { "properties": [ { "name": "filter", "label": "Filter", "value": "" }, { "name": "size", "label": "Size", "value": [0.0, 0.0, 0.0] } ] } }
2. Create an entity and attach the component script to it.
3. Change both values to anything.
4. Create a new entity, attach the same component.
You should see that "Size" is back to 0,0,0, but the "Filter" property got carried over from the first entity.
- 1
-
9 minutes ago, Josh said:
Oh, okay it just looks like the ambient light is not being saved in the game save.
As I mentioned here, a lot of scene properties don't get saved from the editor. Not sure if this carries over to user saves.
But can't wait to try this. I've been very conservative about making components because I couldn't test reloading them.
More Editor UI elements not updating.
in Bug Reports
Posted
Understandable. I'll await for it's return.