07-03-2019, 11:10 AM
(This post was last modified: 07-03-2019, 11:32 AM by Brian Beuken.)
Well it had to happen, the new Raspi4 is a lovely machine with some impressive graphic potential, but it does not work the same way as all the other Raspberries so the book examples won't work, there has to be a new version of the graphics startup code.
The previous Raspberries used Broadcom IV graphic drivers with binaries and libs located in opt/vc/lib and opt/vc/include
The Pi4 still has these libraries and locations but they don't work on the 4, though you can use the Buster OS with any other Raspberry.
1st things 1st you need mesa libs which can be installed by opening a terminal and typing
sudo apt-get install libgles2-mesa-dev
Now you need to change some of your project library needs and directory access. The increased number of libs needed to run on the older RPis has been reduced to just 3, EGL, GLES2 AND X11 (other display systems are possible though but not right now)
And include libs are now usr/lib for the libraries and usr/include for the h files
Also, and this is very important, do not disable the OpenGL drivers as we had to do in older Raspberry's
If you are using one of the multi build configs on the site, basically Raspberry has reverted to the normal way to build a Linux project, so remove the RASPBERRY pre processor instruction and let it build like a normal Linux build and it should be fine.
Here's the init code to set up an X11 window, EGL and get ready to work with OpenGLES2.0
I will put new builds forPi4 up on the site as soon as I can, if you need help, just ping me on here or drop me a mail
The previous Raspberries used Broadcom IV graphic drivers with binaries and libs located in opt/vc/lib and opt/vc/include
The Pi4 still has these libraries and locations but they don't work on the 4, though you can use the Buster OS with any other Raspberry.
1st things 1st you need mesa libs which can be installed by opening a terminal and typing
sudo apt-get install libgles2-mesa-dev
Now you need to change some of your project library needs and directory access. The increased number of libs needed to run on the older RPis has been reduced to just 3, EGL, GLES2 AND X11 (other display systems are possible though but not right now)
And include libs are now usr/lib for the libraries and usr/include for the h files
Also, and this is very important, do not disable the OpenGL drivers as we had to do in older Raspberry's
If you are using one of the multi build configs on the site, basically Raspberry has reverted to the normal way to build a Linux project, so remove the RASPBERRY pre processor instruction and let it build like a normal Linux build and it should be fine.
Here's the init code to set up an X11 window, EGL and get ready to work with OpenGLES2.0
Code:
///
// CreateEGLContext()
//
// Creates an EGL rendering context and all associated elements
static Display* x_display = NULL;
void Graphics::init_ogl(Target_State *state, int width, int height, int FBResX, int FBResY)
{
#define ES_WINDOW_RGB 0
state->width = width;
state->height = height;
EGLint numConfigs;
EGLint majorVersion;
EGLint minorVersion;
EGLDisplay display;
EGLContext context;
EGLSurface surface;
EGLConfig config;
EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
/* create a native window */
Window root;
XSetWindowAttributes swa;
XSetWindowAttributes xattr;
Atom wm_state;
XWMHints hints;
XEvent xev;
EGLConfig ecfg;
EGLint num_config;
Window win;
Screen *screen;
/*
* X11 native display initialization
*/
x_display = XOpenDisplay(NULL);
if (x_display == NULL)
{
printf("Sorry to say we can't create an Xwindow and this will fail");
exit(0); //return ; // we need to trap this;
}
eglBindAPI(EGL_OPENGL_ES_API);
root = DefaultRootWindow(x_display);
screen = ScreenOfDisplay(x_display, 0);
state->width = width;
state->height = height;
swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask | KeyReleaseMask;
swa.background_pixmap = None;
swa.background_pixel = 0;
swa.border_pixel = 0;
swa.override_redirect = true;
win = XCreateWindow(
x_display,
root,
0,
0,
width,
height,
0,
CopyFromParent,
InputOutput,
CopyFromParent,
CWEventMask,
&swa);
XSelectInput(x_display, win, KeyPressMask | KeyReleaseMask);
xattr.override_redirect = TRUE;
XChangeWindowAttributes(x_display, win, CWOverrideRedirect, &xattr);
hints.input = TRUE;
hints.flags = InputHint;
XSetWMHints(x_display, win, &hints);
char* title = (char*)"x11 window Maze3dHunt";
// make the window visible on the screen
XMapWindow(x_display, win);
XStoreName(x_display, win, title);
// get identifiers for the provided atom name strings
wm_state = XInternAtom(x_display, "_NET_WM_STATE", FALSE);
memset(&xev, 0, sizeof(xev));
xev.type = ClientMessage;
xev.xclient.window = win;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 1;
xev.xclient.data.l[1] = FALSE;
XSendEvent(
x_display,
DefaultRootWindow(x_display),
FALSE,
SubstructureNotifyMask,
&xev);
state->nativewindow = (EGLNativeWindowType) win;
// Get Display
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY)
{
printf("Sorry to say we have an EGLinit error and this will fail");
EGLint err = eglGetError();
return; // EGL_FALSE;
}
// Initialize EGL
if (!eglInitialize(display, &majorVersion,&minorVersion))
{
printf("Sorry to say we have an EGLinit error and this will fail");
EGLint err = eglGetError();
return;// EGL_FALSE;
}
// Get configs
if (!eglGetConfigs(display, NULL, 0, &numConfigs))
{
printf("Sorry to say we have EGL config errors and this will fail");
EGLint err = eglGetError();
return;// EGL_FALSE;
}
// Choose config
if (!eglChooseConfig(display, attribute_list, &config, 1, &numConfigs))
{
printf("Sorry to say we have config choice issues, and this will fail");
EGLint err = eglGetError();
return;// EGL_FALSE;
}
// Create a surface
surface = eglCreateWindowSurface(display, config, state->nativewindow, NULL);
if (surface == EGL_NO_SURFACE)
{
EGLint err = eglGetError();
return;// EGL_FALSE;
}
// Create a GL context
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
if (context == EGL_NO_CONTEXT)
{
EGLint err = eglGetError();
return;// EGL_FALSE;
}
// Make the context current
if (!eglMakeCurrent(display, surface, surface, context))
{
EGLint err = eglGetError();
return;// EGL_FALSE;
}
state->display = display;
state->surface = surface;
state->context = context;
// just for fun lets see what we can do with this GPU
printf("This SBC supports version %i.%i of EGL\n", majorVersion, minorVersion);
printf("This GPU supplied by :%s\n", glGetString(GL_VENDOR));
printf("This GPU supports :%s\n", glGetString(GL_VERSION));
printf("This GPU Renders with :%s\n", glGetString(GL_RENDERER));
printf("This GPU supports :%s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
printf("This GPU supports these extensions :%s\n", glGetString(GL_EXTENSIONS));
EGLBoolean GLtest = eglGetConfigAttrib( display,
config,
EGL_MAX_SWAP_INTERVAL,
&minorVersion);
EGLBoolean test = eglSwapInterval(display, 1); // 1 to lock speed to 60fps (assuming we are able to maintain it), 0 for immediate swap (may cause tearing) which will indicate actual frame rate
// on xu4 this seems to have no effect
// Some OpenGLES2.0 states that we might need
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(TRUE);
glDepthRangef(0.0f, 1.0f);
glClearDepthf(1.0f);
//these are the options you can have for the depth, play with them?
//#define GL_NEVER 0x0200
//#define GL_LESS 0x0201
//#define GL_EQUAL 0x0202
//#define GL_LEQUAL 0x0203
//#define GL_GREATER 0x0204
//#define GL_NOTEQUAL 0x0205
//#define GL_GEQUAL 0x0206
//
glViewport(0, 0, state->width, state->height);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glCullFace(GL_BACK);
if (glGetError() == GL_NO_ERROR) return ;
else
printf("Oh bugger, Some part of the EGL/OGL graphic init failed\n");
}
I will put new builds forPi4 up on the site as soon as I can, if you need help, just ping me on here or drop me a mail
Brian Beuken
Lecturer in Game Programming at Breda University of Applied Sciences.
Author of The Fundamentals of C/C++ Game Programming: Using Target-based Development on SBC's
Lecturer in Game Programming at Breda University of Applied Sciences.
Author of The Fundamentals of C/C++ Game Programming: Using Target-based Development on SBC's