xguyor
Topic Author
Posts: 6
Joined: 11 Apr 2024, 19:03

Canvas.Clip wont work when integrating to sdl

08 Jul 2024, 17:56

Hi,
the problem is that clipping rectangle is not working properly - > area is not clipped or clipped when i unclip it gradually it instantly unclips
this is the way i clip and unclip:
//inside an existing canvas frame
        <Canvas.Clip>
            <RectangleGeometry   x:Name="FsTextClip" Rect="0,0,942.76,365.07"/>
        </Canvas.Clip>
          <!--Gradually unclip fs_text -->
          <RectAnimation Storyboard.TargetName="FsTextClip"
                         Storyboard.TargetProperty="Rect"
                         From="0,0,0,204.58"
                         To="0,0,613.66,204.58"
                         Duration="0:0:0.6"
                         BeginTime="0:0:2.8"/>
                         
i am following this work flow to create the iview from the user control loading the xaml:
        Noesis::Init();
        Noesis::GUI::SetErrorHandler(CustomErrorHandler);
        auto resource_path = getUiResourcesDirPath();
        Noesis::GUI::SetXamlProvider(Noesis::MakePtr<NoesisApp::LocalXamlProvider>(resource_path.c_str()));
        Noesis::GUI::SetFontProvider(Noesis::MakePtr<NoesisApp::LocalFontProvider>(resource_path.c_str()));
        Noesis::GUI::SetTextureProvider(Noesis::MakePtr<NoesisApp::LocalTextureProvider>(resource_path.c_str()));
        uc = Noesis::MakePtr<WelcomeScreenUC>();
        activeView = Noesis::GUI::CreateView(activeScreen->getFrameWorkElement());
        activeView->SetFlags(Noesis::RenderFlags_PPAA | Noesis::RenderFlags_LCD);
        activeView->SetSize(width, height);
        activeView->GetRenderer()->Init(device);
        activeView->SetEmulateTouch(true);
UserControl initialization (added a lot to make sure none is missing):
void WelcomeScreenUC::InitializeComponent()
{
    Noesis::RegisterComponent<WelcomeScreenUC>();

    Noesis::TypeOf<NoesisApp::Interaction>();
    Noesis::TypeOf<NoesisApp::StyleInteraction>();

    Noesis::RegisterComponent<NoesisApp::BehaviorCollection>();
    Noesis::RegisterComponent<NoesisApp::TriggerCollection>();
    Noesis::RegisterComponent<NoesisApp::StyleTriggerCollection>();
    Noesis::RegisterComponent<NoesisApp::StyleBehaviorCollection>();
    Noesis::RegisterComponent<NoesisApp::EventTrigger>();
    Noesis::RegisterComponent<NoesisApp::PropertyChangedTrigger>();
    Noesis::RegisterComponent<NoesisApp::DataTrigger>();
    Noesis::RegisterComponent<NoesisApp::KeyTrigger>();
    Noesis::RegisterComponent<NoesisApp::GamepadTrigger>();
    Noesis::RegisterComponent<NoesisApp::StoryboardCompletedTrigger>();
    Noesis::RegisterComponent<NoesisApp::TimerTrigger>();
    Noesis::RegisterComponent<NoesisApp::MouseDragElementBehavior>();
    Noesis::RegisterComponent<NoesisApp::TranslateZoomRotateBehavior>();
    Noesis::RegisterComponent<NoesisApp::ConditionBehavior>();
    Noesis::RegisterComponent<NoesisApp::ConditionalExpression>();
    Noesis::RegisterComponent<NoesisApp::ComparisonCondition>();
    Noesis::RegisterComponent<NoesisApp::GoToStateAction>();
    Noesis::RegisterComponent<NoesisApp::InvokeCommandAction>();
    Noesis::RegisterComponent<NoesisApp::ChangePropertyAction>();
    Noesis::RegisterComponent<NoesisApp::ControlStoryboardAction>();
    Noesis::RegisterComponent<NoesisApp::RemoveElementAction>();
    Noesis::RegisterComponent<NoesisApp::LaunchUriOrFileAction>();
    Noesis::RegisterComponent<NoesisApp::PlaySoundAction>();
    Noesis::RegisterComponent<NoesisApp::SetFocusAction>();
    Noesis::RegisterComponent<NoesisApp::SelectAction>();
    Noesis::RegisterComponent<NoesisApp::SelectAllAction>();
//    Noesis::RegisterComponent<Noesis::EnumConverter<NoesisApp::ComparisonConditionType>>();
//    Noesis::RegisterComponent<Noesis::EnumConverter<NoesisApp::ForwardChaining>>();
//    Noesis::RegisterComponent<Noesis::EnumConverter<NoesisApp::KeyTriggerFiredOn>>();
//    Noesis::RegisterComponent<Noesis::EnumConverter<NoesisApp::GamepadTriggerFiredOn>>();
//    Noesis::RegisterComponent<Noesis::EnumConverter<NoesisApp::GamepadButton>>();
//    Noesis::RegisterComponent<Noesis::EnumConverter<NoesisApp::ControlStoryboardOption>>();
    Noesis::GUI::LoadComponent(this, Noesis::Uri("welcomeScreen.xaml"));
}
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: Canvas.Clip wont work when integrating to sdl

08 Jul 2024, 18:27

I created a small sample in xamltoy that works as expected:



It seems that the problem could be in the integration side. Are you defining a depth/stencil buffer in your active render target where the UI is being rendered?
 
xguyor
Topic Author
Posts: 6
Joined: 11 Apr 2024, 19:03

Re: Canvas.Clip wont work when integrating to sdl

09 Jul 2024, 08:39

Hello my friend and thank you for the reply,

Your example behaves the same as i described above, unclipping occurs instantly and not gradually from left to right.
this is the rendering logic i use:
///  (SmRenderTick() is a method i created to count time since start of rendering and procceeds each iteration by 16 millisecs (for 60hz rendering)
         activeView->Update(SmRenderTick());
        activeView->GetRenderer()->UpdateRenderTree();
        activeView->GetRenderer()->RenderOffscreen();
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glViewport(0, 0, width, height);
        glClearColor(0.0f, 0.0f, 0.25f, 0.0f);
        glClearStencil(0);
        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        activeView->GetRenderer()->Render( false,true);
i also tries something like this after reading your suggestion and it acts the same:
void ScreenManager::renderActiveScreen() {
    if (activeView)
    {
        if (update_rendering_time)
        {
            SmIncrementRenderTick();
            activeView->Update(SmRenderTick());
        }

        // Update Noesis render tree and offscreen rendering
        activeView->GetRenderer()->UpdateRenderTree();
        activeView->GetRenderer()->RenderOffscreen();

        // Bind the default framebuffer
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        // Set the viewport
        glViewport(0, 0, width, height);

        // Clear the color, depth, and stencil buffers
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

        // Enable stencil test
        glEnable(GL_STENCIL_TEST);
        glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
        glStencilFunc(GL_ALWAYS, 1, 0xFF);
        glStencilMask(0xFF);

        // Render Noesis
        activeView->GetRenderer()->Render(false, true);

        // Reset stencil settings (if needed for subsequent rendering)
        glStencilMask(0x00);
        glDisable(GL_STENCIL_TEST);
    }
}
 
User avatar
jsantos
Site Admin
Posts: 4822
Joined: 20 Jan 2012, 17:18
Contact:

Re: Canvas.Clip wont work when integrating to sdl

09 Jul 2024, 19:02

This is an integration issue on your side, your stencil is not properly configured or you are not clearing it per frame.

Please, have a look at the IntegrationGLUT sample included in the SDK. The sample provided by @sfernandez works fine there.

This is explained in the render section of the Integration Guide.

My recommendation is using RenderDoc for taking captures in our example and in yours to see the differences.
 
xguyor
Topic Author
Posts: 6
Joined: 11 Apr 2024, 19:03

Re: Canvas.Clip wont work when integrating to sdl

11 Jul 2024, 11:19

Hi,
The animation i working fine with the glutIntegration example,
i created a similar setup to run the same xaml (Your example) in the SDL logic:

The animation is not showing (not even instantly), just a blue screen.
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <NsApp/ThemeProviders.h>
#include <NsRender/GLFactory.h>
#include <NsGui/FontProperties.h>
#include <NsGui/IntegrationAPI.h>
#include <NsGui/IRenderer.h>
#include <NsGui/IView.h>
#include <NsGui/Grid.h>

static Noesis::IView* _view;
static SDL_Window* window;

static void NoesisInit()
{
    Noesis::SetLogHandler([](const char*, uint32_t, uint32_t level, const char*, const char* msg)
                          {
                              // [TRACE] [DEBUG] [INFO] [WARNING] [ERROR]
                              const char* prefixes[] = { "T", "D", "I", "W", "E" };
                              printf("[NOESIS/%s] %s\n", prefixes[level], msg);
                          });

    // https://www.noesisengine.com/docs/Gui.Core.Licensing.html
    Noesis::GUI::SetLicense(NS_LICENSE_NAME, NS_LICENSE_KEY);

    // Noesis initialization. This must be the first step before using any NoesisGUI functionality
    Noesis::GUI::Init();

    // Setup theme
    NoesisApp::SetThemeProviders();

    // For simplicity purposes we are not using resource providers in this sample. ParseXaml() is
    // enough if there is no extra XAML dependencies
    Noesis::Ptr<Noesis::Grid> xaml(Noesis::GUI::ParseXaml<Noesis::Grid>(R"(
        <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
            <Grid.Resources>
                <Storyboard x:Key="anim">
                    <RectAnimation Storyboard.TargetName="FsTextClipRect" Storyboard.TargetProperty="Rect"
                                   From="0,0,0,204.58" To="0,0,613.66,204.58" Duration="0:0:0.6" BeginTime="0:0:1"/>
                </Storyboard>
            </Grid.Resources>
            <Grid.Triggers>
                <EventTrigger RoutedEvent="Grid.Loaded">
                    <BeginStoryboard Storyboard="{StaticResource anim}"/>
                </EventTrigger>
            </Grid.Triggers>
            <Canvas Width="600" Height="200" Background="Silver">
                <Canvas.Clip>
                    <RectangleGeometry x:Name="FsTextClipRect" Rect="0,0,0,204.58"/>
                </Canvas.Clip>
                <TextBlock Text="This is a text inside a canvas that will reveal with an animation."/>
            </Canvas>
        </Grid>
    )"));

    // View creation to render and interact with the user interface
    _view = Noesis::GUI::CreateView(xaml).GiveOwnership();
    _view->SetFlags(Noesis::RenderFlags_PPAA | Noesis::RenderFlags_LCD);

    // Renderer initialization with an OpenGL device
    _view->GetRenderer()->Init(NoesisApp::GLFactory::CreateDevice(false));
}

static void Render()
{
    // Update view (layout, animations, ...)
    _view->Update(SDL_GetTicks() / 1000.0f);

    // Offscreen rendering phase populates textures needed by the on-screen rendering
    _view->GetRenderer()->UpdateRenderTree();
    _view->GetRenderer()->RenderOffscreen();

    // Restore the GPU state
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    int width, height;
    SDL_GetWindowSize(window, &width, &height);
    glViewport(0, 0, width, height);

    glClearColor(0.0f, 0.0f, 0.25f, 0.0f);
    glClearStencil(0);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Rendering is done in the active framebuffer
    _view->GetRenderer()->Render(false,true);

    // Swap buffers
    SDL_GL_SwapWindow(window);
}

int main(int argc, char** argv)
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
        return -1;
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

    window = SDL_CreateWindow("NoesisGUI - SDL2 integration", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1000, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
    if (!window)
    {
        printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
        return -1;
    }

    SDL_GLContext context = SDL_GL_CreateContext(window);
    if (!context)
    {
        printf("OpenGL context could not be created! SDL_Error: %s\n", SDL_GetError());
        return -1;
    }

    SDL_GL_SetSwapInterval(1); // Enable vsync

    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
    {
        printf("Error initializing GLEW!\n");
        return -1;
    }

    NoesisInit();

    bool running = true;
    SDL_Event event;

    while (running)
    {
        while (SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT)
            {
                running = false;
            }
        }

        Render();
    }

    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

Who is online

Users browsing this forum: No registered users and 7 guests