How do I create a GL application for portability?

I found that GL needs different settings for different systems in order to work properly. For example, on my desktop, if I query the 3.3 main profile context everything works. On Mac, I have to set the 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 of defining:

  • Are all GL features related to my applications supported and
  • What combination of version, profile (kernel or not) and forward compatibility flag do I need to get it to work?
+3


source to share


1 answer


I don't think there is a magic bullet here. To a large extent, you will have to do appropriate runtime checking and provide alternative paths that make the most of the available functionality.

When I write an OpenGL application, I usually define a "caps" table, for example:

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!
};

      

This is where I post all the information about the function collected at startup with glGet

and by testing the function pointers. Then when you use a feature / function I always check for availability, providing a fallback if possible. For example:.



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

      

Of course, there are some minimal options you can decide what hardware must have in order to run your software. For example: Must have at least OpenGL 2.1 with GLSL v120 support. This is perfectly normal and expected.

On the differences between baseline and compatible profiles, if you want to support them, there are some OpenGL features you will have to avoid. For example: Always paint with VBOs. They are the norm for Core and existed prior to that through extensions.

+1


source







All Articles