Jump to content

SpiderPig

Members
  • Posts

    2,285
  • Joined

  • Last visited

Posts posted by SpiderPig

  1. That's what I was thinking too.  Though it seems a panel can only have texture assigned to it if the interface has been created with a world and I can't get two interfaces working with one world.  I can create another world for this purpose but I need two framebuffers, one for each window, and that dosn't work very well.

  2. I'm rendering two worlds to two separate windows with a UI overlay.  The moment I render the 2nd world it cause FPS to drop and rendering is very choppy in both windows.  I've also noticed that the window position in CreateWindow() seems to have no effect.

    #include "UltraEngine.h"
    
    using namespace UltraEngine;
    
    #define RENDERLAYER_1 2
    #define RENDERLAYER_2 4
    
    int main(int argc, const char* argv[])
    {
        auto displays = GetDisplays();
    
        //WINDOW A
        auto window = CreateWindow("WindowA", 0, 0, 512, 512, displays[0]);
        auto framebuffer = CreateFramebuffer(window);
        auto world = CreateWorld();
        world->RecordStats(true);
        auto font = LoadFont("Fonts/arial.ttf");
    
        auto camera = CreateCamera(world);
        camera->SetPosition(0, 0, -2);
    
        auto ui_camera = CreateCamera(world, UltraEngine::PROJECTION_ORTHOGRAPHIC);
        ui_camera->SetRenderLayers(RENDERLAYER_1);
        ui_camera->SetPosition(framebuffer->size.x / 2.0f, framebuffer->size.y / 2.0f);
        ui_camera->SetClearMode(UltraEngine::CLEAR_DEPTH);
    
        auto ui = CreateInterface(world, font, framebuffer->size);
        ui->background->SetColor(0, 0, 0, 0);
        ui->SetRenderLayers(RENDERLAYER_1);
    
        //WINDOW B
        auto worldB = CreateWorld();
        worldB->RecordStats(true);
        auto windowB = CreateWindow("WindowB", 800, 0, 512, 512, displays[0]);
        auto framebufferB = CreateFramebuffer(windowB);
        auto cameraB = CreateCamera(worldB);
        cameraB->SetPosition(0, 0, -2);
    
        auto ui_cameraB = CreateCamera(worldB, UltraEngine::PROJECTION_ORTHOGRAPHIC);
        ui_cameraB->SetRenderLayers(RENDERLAYER_2);
        ui_cameraB->SetPosition(framebufferB->size.x / 2.0f, framebufferB->size.y / 2.0f);
        ui_cameraB->SetClearMode(UltraEngine::CLEAR_DEPTH);
    
        auto uiB = CreateInterface(worldB, font, framebufferB->size);
        uiB->background->SetColor(0, 0, 0, 0);
        uiB->SetRenderLayers(RENDERLAYER_2);
    
        auto fpsA = CreateLabel("FPS : 0", 10, 10, 100, 20, ui->root);
        auto fpsB = CreateLabel("FPS : 0", 10, 10, 100, 20, uiB->root);
    
        auto boxA = CreateBox(world);
        boxA->SetColor(1, 0, 0);
    
        auto boxB = CreateBox(worldB);
        boxB->SetColor(0, 1, 0);
    
        while (true)
        {
            while (UltraEngine::PeekEvent()) {
                auto event = UltraEngine::WaitEvent();
                switch (event.id) {
                case UltraEngine::EVENT_WINDOWCLOSE:
                    if (event.source == window) {
                        return 0;
                    }
                    break;
                }
    
                ui->ProcessEvent(event);
                uiB->ProcessEvent(event);
            }
    
            fpsA->SetText("FPS : " + WString(world->renderstats.framerate));
            fpsB->SetText("FPS : " + WString(worldB->renderstats.framerate));
    
            boxA->Turn(0.1f, 0.1f, 0.2f);
            boxB->Turn(0.2f, 0.1f, 0.1f);
    
            worldB->Update();
            worldB->Render(framebufferB, false);
    
            world->Update();
            world->Render(framebuffer, false);
        }
        return 0;
    }

     

  3. While the example here works, it seems if you are overlaying an interface over a 3D environment the panel won't show the assigned texture.  I first noticed this in my project where I wanted to show the real-time render of a 2nd camera on the panel.

    749502057_PanelTexture.jpg.0e47287fb18646db4db474dda0fc511c.jpg

    #include "UltraEngine.h"
    
    using namespace UltraEngine;
    
    int main(int argc, const char* argv[])
    {
        auto displays = GetDisplays();
        auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0]);
        auto framebuffer = CreateFramebuffer(window);
        auto world = CreateWorld();
        auto font = LoadFont("Fonts/arial.ttf");
    
        auto ui = CreateInterface(world, font, framebuffer->size);
        ui->background->SetColor(0, 0, 0, 0);
    
        //Create and position camera
        auto camera = CreateCamera(world);
        camera->SetPosition(0, 1, -2);
    
        int RENDERLAYER_1 = 2;
        auto ui_camera = CreateCamera(world, UltraEngine::PROJECTION_ORTHOGRAPHIC);
        ui_camera->SetRenderLayers(RENDERLAYER_1);
        ui_camera->SetPosition(framebuffer->size.x / 2.0f, framebuffer->size.y / 2.0f);
        ui_camera->SetClearMode(UltraEngine::CLEAR_DEPTH);
    
        auto panel = CreatePanel(0, 0, 512, 512, ui->root);
        auto tex = LoadTexture("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Materials/Ground/river_small_rocks_diff_4k.dds");
        panel->SetTexture(tex);
    
        auto box = CreateBox(world);
        box->SetColor(1, 0, 0);
    
        while (true)
        {
            while (UltraEngine::PeekEvent()) {
                auto event = UltraEngine::WaitEvent();
                switch (event.id) {
                case UltraEngine::EVENT_WINDOWCLOSE:
                    if (event.source == window) {
                        return 0;
                    }
                    break;
                }
    
                ui->ProcessEvent(event);
            }
    
            world->Update();
            world->Render(framebuffer);
        }
        return 0;
    }

     

  4. Thanks.  It's actually 3 times slower to do that per pixel than to convert the whole pixmap and access the pixel data directly.

    I am I correct in saying that for an RGBA16 format, the data here 2 bytes per channel?

    char* data = pixmap->pixels->Data();

    I need a value between 0 and 255 but I'm not positive if bit shifting like this is the right way.  And then I'm not positive how to get back the 0 - 255 range.

    auto r = (data[index] << 8) | data[index + 1];
    auto g = (data[index + 2] << 8) | data[index + 3];
    auto b = (data[index + 4] << 8) | data[index + 5];
    auto a = (data[index + 6] << 8) | data[index + 7];
    
    index += 8;

     

  5. How can I access the pixel data from a pixmap generated with TextureBuffer::Capture()?  I want to access the pixel data directly like this:

    auto captures = texture_buffer->GetCaptures();
    if (captures.size() != 0) {
        auto pixmap = captures[0];
        auto data = pixmap->pixels->Data();
    
        int x = 0, y = 0, stride = 4;
        auto i = ((y * pixmap->size.x) + x) * stride;
    
        auto r = data[0];
        auto g = data[1];
        auto b = data[2];
        auto a = data[3];
    }

    I've also tried this but it shows an error saying it "Bytes per block must be four or less"

    auto pix = pixmap->ReadPixel(x, y);
    auto r = Red(pix);
    auto g = Green(pix);
    auto b = Blue(pix);
    auto a = Alpha(pix);

    I can convert the pixmap from TEXTURE_RGB16 to TEXTURE_RGBA and both code will work but it's far too slow for my situation (I'm doing it once per frame).

     

  6. On 5/15/2022 at 8:40 PM, Josh said:

    If you retrieve a texture from the GPU into system memory, that will be extremely slow.

    I'm thinking about giving this a go as it's not really a real time application I want this for.  How slow do you think this could be though for a 512x512 image rendered with a camera?  1FPS?

  7. Not sure if this is a bug or not a good way to use the physics engine ;)

    The box will still collide with the floor if you store it's collider elsewhere and set the boxes collider to nullptr.  Are colliders unique to the object they are applied too?

    #include "UltraEngine.h"
    
    using namespace UltraEngine;
    
    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 framebuffer = CreateFramebuffer(window);
        auto world = CreateWorld();
        world->SetGravity(0.0f, -2.0f, 0.0f);
    
        auto camera = CreateCamera(world);
        camera->SetClearColor(0.125);
        camera->SetPosition(0, 0, -8);
        camera->SetDebugPhysicsMode(true);
    
        auto light = CreateDirectionalLight(world);
        light->SetRotation(35, 35, 0);
    
        auto box = CreateBox(world);
        box->SetMass(1.0f);
        box->SetColor(0, 1, 0);
    
        auto store = box->GetCollider();
        box->SetCollider(nullptr);//Will still collide...
    
        auto floor = CreateBox(world, 10, .1, 10);
        floor->SetPosition(0, -2, 0);
    
        while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
        {
            world->Update();
            world->Render(framebuffer);
        }
        return 0;
    }

     

  8. Never mind.  Physics objects in two separate worlds don't collide at all.  It turns out that the code I was using to transfer a collider from an entity to a pivot was flawed.

    auto box = CreateBox(worldA);
    
    //Transfer Collider to 2nd world
    auto pivot = CreatePivot(worldB);
    pivot->SetCollider(box->GetCollider());
    
    box->SetCollider(nullptr);

    It seems that if I set an entities collider to another object and then remove that collider from the original entity, although the collider is no longer visible when debugging physics, that box still collides.  :huh:

×
×
  • Create New...