Trying to understand the RPI4/Buster situation in OF 11

First issue, from
https://openframeworks.cc/setup/raspberrypi/raspberry-pi-getting-started/


    Select 7 Advanced Options and hit Enter
        Select GL Driver and hit Enter
        Select either GL Driver Fake KMS or GL Driver Full KMS or from the options and hit Enter

I believe this conflicts with the previous paragraph


    Select 3 Boot Options
    Select B1 Console or B2 Console Autologin

The above advice will result in

pi@RPI4:~/OF_11/openFrameworks/apps/myApps/emptyExample/bin $ ./emptyExample 
[ error ] ofAppGLFWWindow: 65544: X11: Failed to open display :0
[ error ] ofAppGLFWWindow: couldn't init GLFW
[ error ] ofAppGLFWWindow: 65537: The GLFW library is not initialized
[notice ] 
emptyExample: /build/glfw3-UExs5r/glfw3-3.2.1/src/window.c:412: glfwWindowShouldClose: Assertion `window != NULL' failed.
[verbose] ofSignalHandler: Aborted
emptyExample: /build/glfw3-UExs5r/glfw3-3.2.1/src/window.c:421: glfwSetWindowShouldClose: Assertion `window != NULL' failed.
Aborted

Main issue/Question

Should ofGetEGLDisplay/ofGetEGLContext work with the below?

I have things setup as

Driver: GL (Fake KMS) OpenGL desktop driver with fake KMS
Boot Options: Desktop AutoLogin

Single file sample code:

#include "ofMain.h"


class ofApp : public ofBaseApp{
	public:
		void setup()
		{
			ofLog() << glGetString(GL_VERSION);
		}

		void update() { }
		
		bool hasProbed = false;
		
		void draw()
		{
		
			if (!hasProbed)
			{
				bool hasDisplay = false;
				bool hasContext = false;
				ofAppGLFWWindow* winptr = static_cast<ofAppGLFWWindow*>(ofGetWindowPtr());
				GLFWwindow* glfwWindow = winptr->getGLFWWindow();
				EGLContext eglDisplay = ofGetEGLDisplay();


				if (eglDisplay == EGL_NO_DISPLAY)
				{
					ofLog() << "EGL_NO_DISPLAY";
				}else
				{
					hasDisplay = true;
				}

				EGLContext eglContext = ofGetEGLContext();
				if (eglContext == EGL_NO_CONTEXT)
				{
					ofLog() << "EGL_NO_CONTEXT";
				}else
				{
					hasContext = true;
				}	
				hasProbed = true;
				ofLog() << "hasDisplay: " << hasDisplay;
				ofLog() << "hasContext: " << hasContext;
				
				auto x11Window = ofGetWindowPtr()->getX11Window();
				if(x11Window)
				{
					ofLog() << "HAS X11 WINDOW";
				}
			}
			
		}
};

int main( )
{

	bool isTARGET_OPENGLES = false;
	bool isTARGET_LINUX = false;
	
	#if defined(TARGET_OPENGLES)
		isTARGET_OPENGLES = true;
	#endif
	
	
	#if defined(TARGET_LINUX)
		isTARGET_LINUX = true;
	#endif
	
	ofSetLogLevel(OF_LOG_VERBOSE);
	
	ofLog() << "isTARGET_OPENGLES: " << isTARGET_OPENGLES;
	ofLog() << "isTARGET_LINUX: " << isTARGET_LINUX;
#if 1
    ofGLESWindowSettings settings;
	settings.setSize(1280, 720);
    settings.setGLESVersion(2);
    ofCreateWindow(settings);
    ofRunApp( new ofApp());
#else
	ofSetupOpenGL(1280, 720, OF_WINDOW);
	ofRunApp( new ofApp());	
#endif
}

Using the default ofSetupOpenGL path I get a blank X11 window and the following

[notice ] isTARGET_OPENGLES: 1
[notice ] isTARGET_LINUX: 1
[verbose] GL Version:OpenGL ES-CM 1.1 Mesa 19.2.0-rc1
[notice ] OpenGL ES-CM 1.1 Mesa 19.2.0-rc1
[notice ] EGL_NO_DISPLAY
[notice ] EGL_NO_CONTEXT
[notice ] hasDisplay: 0
[notice ] hasContext: 0

If I switch to using ofGLESWindowSettings I get

[notice ] isTARGET_OPENGLES: 1
[notice ] isTARGET_LINUX: 1
[verbose] GL Version:OpenGL ES 3.0 Mesa 19.2.0-rc1
[verbose] ofShader: checkAndCreateProgram(): creating GLSL program
[verbose] ofShader: setupShaderFromSource(): GL_VERTEX_SHADER shader compiled
[verbose] ofShader: setupShaderFromSource(): GL_FRAGMENT_SHADER shader compiled
[verbose] ofShader: linkProgram(): attaching GL_FRAGMENT_SHADER shader to program 1
[verbose] ofShader: linkProgram(): attaching GL_VERTEX_SHADER shader to program 1
[verbose] ofShader: checkProgramLinkStatus(): program 1 linked
[notice ] OpenGL ES 3.0 Mesa 19.2.0-rc1
[notice ] EGL_NO_DISPLAY
[notice ] EGL_NO_CONTEXT
[notice ] hasDisplay: 0
[notice ] hasContext: 0
1 Like

After trying a few things I’ve realized

ofAppEGLWindow is essentially reserved for the RPI 0-3 for pre-Buster. Even the customEGLWindowSettingsExample ends up being a ofAppGLFWWindow under Buster

Hey @jvcleave
Thats correct. PI 0-3 can use the old approach if you disable the GL driver and make sure you set the legacy approach in the makefile.

PI 4 has to use the GL driver and can use either EGL or GLFW windowing but both will need the X window environment. Pi 3 in Stretch and newer should be able to do the same.

Its a little confusing for sure!! :slight_smile:

ps: you’re right that first line shouldn’t be in the setup guide. will remove.

Thanks Theo! Should ofGetEGLDisplay/ofGetEGLContext be working? Even though everything seems to be OpenGL ES and running/drawing those calls don’t return anything.

I was able to get a new EGLContext, etc adapting this in case it helps someone in the future
https://wiki.maemo.org/SimpleGL_example

It didn’t help my case but the code is here

By default with 0.11.0 on Pi 4 and Buster you should get a GLFW window unless you comment out: USE_GLFW_WINDOW = 1

So EGL being null makes sense out of the box.
Do the examples work for you with the GL Driver enabled and USE_GLFW_WINDOW = 1 commented out in the makefile?

Then it should be using EGL Window via X.

Ok I got it going! - thanks @theo

My biggest mistake was using USE_GLFW_WINDOW = 0 as opposed to commenting it out :upside_down_face:

Winning Combo

CONFIG

  • RPI4
  • Buster
  • Desktop Autologin Desktop GUI, automatically logged in as ‘pi’ user
  • GL (Fake KMS) OpenGL desktop driver with fake KMS

config.linuxarmv6l.default.mk changes

USE_PI_LEGACY = 0
#USE_GLFW_WINDOW = 1

This uses ofAppEGLWindow and gives me a valid EGL Context, Display and Surface with

#if !defined(TARGET_GLFW_WINDOW)
    ofAppEGLWindow* winptr = static_cast<ofAppEGLWindow*>(ofGetWindowPtr());
	if(winptr)
	{
		auto eglDisplay = winptr->getEglDisplay();
		
		if (eglDisplay == EGL_NO_DISPLAY)
		{
			ofLog() << "display: EGL_NO_DISPLAY";
			
		}else
		{
			ofLog() << "display: IS VALID";
			
		}
		
		auto eglContext = winptr->getEglContext();
		
		if (eglContext == EGL_NO_CONTEXT)
		{
			ofLog() << "context: EGL_NO_CONTEXT";
			
		}else
		{
			ofLog() << "context: IS VALID";
			
		}
		auto surface = winptr->getEglSurface();
		
		if (surface == EGL_NO_SURFACE)
		{
			ofLog() << "surface: EGL_NO_SURFACE";
			
		}else
		{
			ofLog() << "surface: IS VALID";
			
		}
	}
#endif
1 Like

Yay!
Glad its working! :slight_smile:

Yeah I think if we wanted to add support for a EGL window without X for the RPI4 we need to use DRM

Found this example that runs EGL without X

This also may be coming via to GLFW as well as I think this branch is DRM based