User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

[Solved] NsApp and using NoesisGui with Glad

17 Sep 2022, 00:27

Hey y'all,

I'm investigating switching to NoesisGUI for a long-term project of mine. I've managed to compile and run the samples, and I'm slowly working through the `IntegrationGLUT` example, which I'm assuming it closest to what I'm trying to achieve. I have two questions so far:

1. I'm not quite clear on the reason for separating out code needed to run the simplest NoesisGUI examples into a separate folder? Specifically this function call in the `IntegrationGLUT` example:
_view->GetRenderer()->Init(NoesisApp::GLFactory::CreateDevice(false));
Relies on CreateDevice which is inside NoesisAPP, which isn't part of the core or the include files. I would have thought it fairly essential to grab a renderer?

2. Does anyone have any experience integrating NoesisGUI with GLAD (as opposed to GLUT)? I'm building my project in LibCinder which uses GLAD, and I'm hopeful I can mostly follow the integration example for GLUT given that they're both just variants of initializing OpenGL extensions.

Thanks in advance!
Gazoo
Last edited by Gazoo on 17 Sep 2022, 06:10, edited 1 time in total.
 
User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Re: NsApp and using NoesisGui with Glad

17 Sep 2022, 05:14

Minor update on my end regarding my two questions:

1. From more reading, my understanding is that a portion of NoesisGui functionality is determined to be 'not core' and therefore not a part of the main Noesis library. I wasn't aware until now that all of the 'separate application code' also compiles into a separate library (NoesisApp.lib), which makes the integration easier. That being said, it's somewhat unclear what folders to include for easy integration. For example, to run the 'Hello World' example, two Noesis application parts are need - the GL factory and the Theme provider.

The GLFactory and associated files is found here "Src\Packages\Render\GLRenderDevice\Include", where as the theme provider is found here "Src\Packages\App\Theme\Include". I was a bit surprised to see the Render folder being outside of the App folder. Perhaps there's no deeper meaning to this.

2. Having built the NoesisApp library I can now compile and run my application linked with NoesisGui - Yay success!. Unfortunately, I've yet to actually render anything from NoesisGui. LibCinder which I use as the application framework sets up a 'standard' viewport allowing me to get a rectangle rendered into the active framebuffer with this simple code:
	ci::gl::clear( ci::Color::black() );
	ci::gl::color( ci::Color::white() );
	ci::gl::drawSolidRect( ci::Rectf(100, 100, 300, 300) );
This rectangle vanishes when I call the following function:
_view->GetRenderer()->Init( NoesisApp::GLFactory::CreateDevice( true ) );
Clearly the OpenGL context is being altered but despite the white rectangle disappearing, I unfortunately, don't see anything from NoesisGUI. The log doesn't show any errors, I'm hoping perhaps someone can point out something silly I'm doing. I acknowledge that the code itself doesn't reveal how Cinder sets up its rendering, but it should be writing straight into the standard framebuffer as I can get it to render that white rectangle.

Any and all advice is much appreciated. My full application code is as follows:
#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/Log.h"

#include "NoesisPCH.h"
#include "NsRender/RenderDevice.h"

// NoesisApp
#include "NsApp/ThemeProviders.h"
#include "NsRender/GLFactory.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class CinderProjectApp : public App {
public:
	void setup() override;
	void mouseDown( MouseEvent event ) override;
	void update() override;
	void draw() override;

private:

	Noesis::IView* _view;

};

void CinderProjectApp::setup()
{
	bool appendToLog = true;
	ci::log::LogManager::instance()->clearLoggers();
	ci::log::makeLogger<ci::log::LoggerFile>( "Sandbox.log", appendToLog );

	CI_LOG_I( "Setting up NoesisGUI" );

	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 );

		switch (level)
		{
		case 0: // Trace
			CI_LOG_V(msg);
			break;
		case 1: // Debug
			CI_LOG_D( msg );
			break;
		case 2: // Info
			CI_LOG_I(msg);
			break;
		case 3: // Warning
			CI_LOG_W( msg );
			break;
		case 4: // Error
			CI_LOG_E( msg );
			break;

		}

	} );

	Noesis::GUI::SetLicense( "monkey", "key" );

	Noesis::GUI::Init();

	// Setup theme
	NoesisApp::SetThemeProviders();
	Noesis::GUI::LoadApplicationResources( "Theme/NoesisTheme.DarkBlue.xaml" );

	// 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">
            <Grid.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Offset="0" Color="#FF123F61"/>
                    <GradientStop Offset="0.6" Color="#FF0E4B79"/>
                    <GradientStop Offset="0.7" Color="#FF106097"/>
                </LinearGradientBrush>
            </Grid.Background>
            <Viewbox>
                <StackPanel Margin="50">
                    <Button Content="Hello World!" Margin="0,30,0,0"/>
                    <Rectangle Height="5" Margin="-10,20,-10,0">
                        <Rectangle.Fill>
                            <RadialGradientBrush>
                                <GradientStop Offset="0" Color="#40000000"/>
                                <GradientStop Offset="1" Color="#00000000"/>
                            </RadialGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                </StackPanel>
            </Viewbox>
        </Grid>
    )" ) );

	// View creation to render and interact with the user interface
	// We transfer the ownership to a global pointer instead of a Ptr<> because there is no way
	// in GLUT to do shutdown and we don't want the Ptr<> to be released at global time
	_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( true ) );
}

void CinderProjectApp::mouseDown( MouseEvent event )
{
}

void CinderProjectApp::update()
{

	// Update view (layout, animations, ...)
	//_view->Update( glutGet( GLUT_ELAPSED_TIME ) / 1000.0 );
	_view->Update( App::getElapsedSeconds() );

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

void CinderProjectApp::draw()
{

	// Draws a clear white rect...
	ci::gl::clear( ci::Color::black() );
	ci::gl::color( ci::Color::white() );

	ci::gl::drawSolidRect( ci::Rectf(100, 100, 300, 300) );


	_view->GetRenderer()->Render();

	//// If you are going to render here with your own engine you need to restore the GPU state
	//// because noesis changes it. In this case only framebuffer and viewport need to be restored
	//glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	//glViewport( 0, 0, glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_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();

	//glutSwapBuffers();
	//glutPostRedisplay();
}

// Enable stencil-buffer
auto options = ci::app::RendererGl::Options().stencil();

CINDER_APP( CinderProjectApp, ci::app::RendererGl( options ) )
 
User avatar
Gazoo
Topic Author
Posts: 36
Joined: 14 Sep 2022, 10:00
Contact:

Re: NsApp and using NoesisGui with Glad

17 Sep 2022, 06:09

All solved! This was the missing culprit!
_view->SetSize( 800, 800 );
 
User avatar
jsantos
Site Admin
Posts: 3905
Joined: 20 Jan 2012, 17:18
Contact:

Re: [Solved] NsApp and using NoesisGui with Glad

20 Sep 2022, 16:41

Relies on CreateDevice which is inside NoesisAPP, which isn't part of the core or the include files. I would have thought it fairly essential to grab a renderer?
As you discovered, Noesis core library is operating system and rendering API agnostic. You must implement the filesystem (providers), window, renderer, etc. As this is not an easy step, we provide reference implementation for many operating systems and renderers.

Who is online

Users browsing this forum: Google [Bot], jayk.techabbot and 32 guests