Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I design my GL application for portability?

I am discovering that GL needs different settings on different systems to run correctly. For instance, on my desktop if I request a version 3.3 core-profile context everything works. On a Mac, I have to set the forward-compatibility flag as well. My netbook claims to only support version 2.1, but has most of the 3.1 features as extensions. (So I have to request 2.1.)

My question is, is there a general way to determine:

  1. Whether all of the GL features my application needs are supported, and
  2. What combination of version, profile (core or not), and forward compatibility flag I need to make it work?
like image 227
Dan Avatar asked Nov 22 '25 19:11

Dan


1 Answers

I don't think there is any magic bullet here. It's pretty much going to be up to you to do the appropriate runtime checking and provided alternate paths that make the most out of the available features.

When I'm writing an OpenGL app, I usually define a "caps" table, like this:

struct GLInfo {

    // GL extensions/features as booleans for direct access:
    int hasVAO;                      // GL_ARB_vertex_array_object........: Has VAO support? Allows faster switching between vertex formats.
    int hasPBO;                      // GL_ARB_pixel_buffer_object........: Supports Pixel Buffer Objects?
    int hasFBO;                      // GL_ARB_framebuffer_object.........: Supports Framebuffer objects for offscreen rendering?
    int hasGPUMemoryInfo;            // GL_NVX_gpu_memory_info............: GPU memory info/stats.
    int hasDebugOutput;              // GL_ARB_debug_output...............: Allows GL to generate debug and profiling messages.
    int hasExplicitAttribLocation;   // GL_ARB_explicit_attrib_location...: Allows the use of "layout(location = N)" in GLSL code.
    int hasSeparateShaderObjects;    // GL_ARB_separate_shader_objects....: Allows creation of "single stage" programs that can be combined at use time.
    int hasUniformBuffer;            // GL_ARB_uniform_buffer_object......: Uniform buffer objects (UBOs).
    int hasTextureCompressionS3TC;   // GL_EXT_texture_compression_s3tc...: Direct use of S3TC compressed textures.
    int hasTextureCompressionRGTC;   // GL_ARB_texture_compression_rgtc...: Red/Green texture compression: RGTC/AT1N/ATI2N.
    int hasTextureFilterAnisotropic; // GL_EXT_texture_filter_anisotropic.: Anisotropic texture filtering!
};

Where I place all the feature information collected at startup with glGet and by testing function pointers. Then, when using a feature/function, I always check first for availability, providing a fallback if possible. E.g.:

if (glInfo.hasVAO) 
{
    draw_with_VAO(); 
}
else
{
    draw_with_VB_only();
}

Of course that there are some minimal features that you might decide the hardware must have in order to run your software. E.g.: Must have at least OpenGL 2.1 with support for GLSL v120. This is perfectly normal and expected.

About the diferences between core and compatibility profile, if you wish to support both, there are some OpenGL features that you will have to avoid. For example: Always draw using VBOs. They are the norm on Core and existed before via extensions.

like image 54
glampert Avatar answered Nov 25 '25 08:11

glampert