Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using Extensions
#1
I generally don't use many extensions, but now that we're getting into OpenGLES3.0 its important to make use of them, and they can be confusing.
I just tried to use some on Raspberry and discovered some interesting issues, namely a missing lib called libdl  which needs to be added if you are going to use extensions on a current Raspberry. Not sure about other boards as I don't have one set up, but if you get a link error add dl

Using an extension requires that you set it up first and that is the first minefield, you can of course list the extensions your system supports using somethng like
printf("This GPU supports these extensions :%s\n", glGetString(GL_EXTENSIONS));

Which will give you a nice list of "extensions" for a Raspberry like this. 

This GPU supports these extensions      :GL_OES_compressed_ETC1_RGB8_texture GL_OES_compressed_paletted_texture GL_OES_texture_npot GL_OES_depth24 GL_OES_vertex_half_float GL_OES_EGL_image GL_OES_EGL_image_external GL_EXT_discard_framebuffer GL_OES_rgb8_rgba8 GL_OES_depth32 GL_OES_mapbuffer GL_EXT_texture_format_BGRA8888 GL_APPLE_rgb_422 GL_EXT_debug_marker 

I put "extensions" in quotes becuase these are not the names of the functions but rather a grouping for the extensions actually available. 

This is a mix, some of these extensions are types, and some are functions. The types we don't care too much about just adding #include <GLES2/gl2ext.h> will give us access to the types that are associated with that name....for example "extension"  GL_OES_rgb8_rgba8 


Code:
* GL_OES_rgb8_rgba8 */

#ifndef GL_OES_rgb8_rgba8
#define GL_RGB8_OES                                             0x8051
#define GL_RGBA8_OES                                            0x8058
#endif


Gives us, 2 new defines that are associated with calls that set up RGBA. We can define types just by adding the GL2Ext.h file.
You may have to define the type in your pre-processor but I've not noticed it. It tends to set them all up these days, so be sure you use them in the correct functions.

Functions are a bit harder.  Depending on your system and the current version of the drivers it has,  you have to interrogate the system to get the addresses of the functions, and you also have to create alias values for them.
The Raspberry does not have a lot of extension functions but lets look at one as an example
GL_OES_mapbuffer

If we look in the GL2ext.h file for this we find


Code:
/* GL_OES_mapbuffer */

#ifndef GL_OES_mapbuffer
#define GL_OES_mapbuffer 0
#ifdef GL_GLEXT_PROTOTYPES

GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid** params);

#endif

typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid** params);
#endif

Which is a bit confusing.. but what that extension is telling us is that there are 3 functions that relate to it, called. glMapBufferOES glUnmapBufferOES  and glGetBufferPointervOES

What we want to do now is create 3 alias functions, called glMapBuffer glUnmapBuffer and glGetBufferPointerv

 
We can leave the OES if we want  but tradition states we remove it, Now notice the typedef, and you can also see that the 3 functions return very different types.  void*, GLboolean and void.
and there is somehing called a PFNLGL XXXXXXX PROC where XXXXXXX is replaced by the name of the function..(in caps) That will intenally define what the signature of the function is going to be and ensure we get the right result back from the function. As well as setting up what values are passed.

This is a clunky system but it is how we can create a function and send and recieve the expected values.
We need to define our funciton in an accessable space, I tend to use my graphic class since graphics are most likely to use extensions So if you need to use these outside of graphic routines, make sure you can access the class.

PFNGLMAPBUFFEROESPROC glMapBuffer = NULL;

So we've made that..now we have to load it with the address of the function...which is something EGL does for us with a standard function  Again set this up in the graphic class init.

glMapBuffer =  (PFNGLMAPBUFFEROESPROC)eglGetProcAddress("glMapBufferOES");
And now glMapBuffer is available

eglGetProcAddress asks the OpenGLES2 libs if it has a function called glMapBufferOES and of course it has. (it will return null otherwise) So now we can use glMapBuffer as a function like this.  

unsigned char* framedata = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);

Now the function can work as if it is a standard gl function, and GL_WRITE_ONLY_OES is activated as part of its types it needs.
(now, there does seem to be a few issues with mapbuffer on raspberry, but this example still stands on how to make and use an extension)

Each extension has its own PFNGLXXXXXXXPROC make sure you define your alias with that specific typedef and though you can use any name at all, keeping the name of the function with or without the makers value is a good plan to keep it readable.

There a good explanation here https://community.nxp.com/docs/DOC-101502

If you are going to use extensions, then it means you can only be certain that your code may only run on the same systems you build it on. That means you need to be careful if running on a similar, or older, or ever newer machine to check that the extension is available, if not you need to either not use that function, or use a different method. Never assume that becuase a Raspberry has a function, that an Odroid or a Nano Pi also has it.. Make sure when you use an extension to provide an alternative. Preferably not a crash

Here's some useful info on extension being available. though this is for windows so uses wgl not egl and talk of nvidia is a bit optomistic for SBC's Big Grin
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 



Reply
#2
Making sticky
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 



Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)