I'm using SDL2 and C++11 to build a game engine (just as a personal project, for fun and for practice), and one of the things I want to do is try and have the graphics driver use the latest supported version of OpenGL, and vary how the graphics portion of the engine renders based on the version. This way I can use the newest features of OpenGL where they are relevant and useful, but also support older hardware. There are two methods I can think of:
Detecting the latest supported version of OpenGL and using that, but I can't think of any way to do that. Yes, I have tried Google.
Using trial and error, where I start from the newest version (4.3, but my GTX 460 only supports up to 4.2, even though I updated the drivers), and if that fails (which I detect by checking for SDL to return a NULL context), I lower the version number and try again.
The method I use (#2) fails immediately upon creation of the 4.3 context. I know my graphics drivers only support 4.2 right now, but I had thought that GLX was designed to throw an error, give a NULL context, and let your program keep going, but instead it can't get past the failed creation of the context. Is my assumption about how GLX behaves wrong? Is there a way to detect the latest supported version without creating a context?
Because I know some people prefer to see complete and minimal source that demonstrates the error, here it is:
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
int main() {
if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 ) {
return -1;
}
SDL_Window* window = SDL_CreateWindow( "SDL Window", 0, 0, 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
if( window == nullptr ) {
return -1;
}
unsigned int major = 4;
unsigned int minor = 3;
SDL_GLContext context = nullptr;
while( context == nullptr ) {
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, major );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, minor );
context = SDL_GL_CreateContext( window );
if( context == nullptr ) {
if( minor == 0 && major > 1 ) {
--major;
minor = 9;
}
else if( minor > 0 ) {
--minor;
}
else {
SDL_DestroyWindow( window );
return -1;
}
}
}
SDL_Delay( 5000 );
SDL_GL_DeleteContext( context );
SDL_DestroyWindow( window );
return 0;
}
Also, if I change that code to start with a 4.2 context instead of a 4.3, it works just fine. So the error is in creating a 4.3 context specifically.