4
\$\begingroup\$

I want to use SDL2 (2.0.4) with C to create an OpenGL 3.3 (core) context. But it seems to default to whatever compatibility profile my computer supports. Works fine with LWJGL2 and Java.

Here is my C code with SDL2.

#include <SDL2/SDL.h>
#include <SDL2/SDL_events.h>
#include <epoxy/gl.h>
#include <epoxy/glx.h>

void main(){
    //set opengl attributes, supposed to happen before window creation
    SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); //OpenGL core profile
    SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 3); //OpenGL 3+
    SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 3); //OpenGL 3.3

    if (SDL_Init (SDL_INIT_EVENTS | SDL_INIT_VIDEO) < 0){
        printf ("sdl init error: %s", SDL_GetError());
        return;
    }
    SDL_Window* window = SDL_CreateWindow (
        "SDL2 Problem",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        0,
        0,
        SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP
    );
    if (window == NULL){
        printf ("could not create window: %s\n", SDL_GetError());
        return;
    }

    //initialize OpenGL stuff
    SDL_GLContext openglContext = SDL_GL_CreateContext (window);
    printf ("glGetString (GL_VERSION) returns %s\n", glGetString (GL_VERSION));
    SDL_GL_DeleteContext (openglContext);
    SDL_DestroyWindow (window);
    SDL_Quit();
}

The output is

glGetString (GL_VERSION) returns 3.0 Mesa 11.2.0

So why is it not giving me an OpenGL 3.3 core profile? Here is my Java code with LWJGL2 (2.9.3)

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ContextAttribs;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;

public class withLWJGL2{
    public static void main (String [] args){
        try{
            PixelFormat pixelFormat = new PixelFormat();
            ContextAttribs contextAttribs = new ContextAttribs (3, 3);//opengl 3.3
            Display.create (pixelFormat, contextAttribs);
        }
        catch (LWJGLException e){
            e.printStackTrace();
            System.exit(0);
        }

        // check version string
        System.out.println ("glGetString (GL_VERSION) returns " + GL11.glGetString (GL11.GL_VERSION));

        Display.destroy();
    }
}

The output is

glGetString (GL_VERSION) returns 3.3 (Core Profile) Mesa 11.2.0

Works just fine! The output of

glxinfo | grep version

is

server glx version string: 1.4
client glx version string: 1.4
GLX version: 1.4
    Max core profile version: 3.3
    Max compat profile version: 3.0
    Max GLES1 profile version: 1.1
    Max GLES[23] profile version: 3.0
OpenGL core profile version string: 3.3 (Core Profile) Mesa 11.2.0
OpenGL core profile shading language version string: 3.30
OpenGL version string: 3.0 Mesa 11.2.0
OpenGL shading language version string: 1.30
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 11.2.0
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00

My computer is running GalliumOS 2.0, which is based on Ubuntu. Just to make sure it wasn't a problem with that computer I tried it on my other computer, running Ubuntu 16.04 and using NVIDIA. The ouput of the C code with SDL2 is

glGetString (GL_VERSION) returns 4.5.0 NVIDIA 361.42

So again it is not setting the version of the OpenGL context to OpenGL 3.3. The output of the Java code with LWJGL2 on this computer is

glGetString (GL_VERSION) returns 3.3.0 NVIDIA 361.42

Works just fine! Output of

glxinfo | grep version

is

server glx version string: 1.4
client glx version string: 1.4
GLX version: 1.4
OpenGL core profile version string: 4.5.0 NVIDIA 361.42
OpenGL core profile shading language version string: 4.50 NVIDIA
OpenGL version string: 4.5.0 NVIDIA 361.42
OpenGL shading language version string: 4.50 NVIDIA
OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 361.42
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
    GL_EXT_shader_implicit_conversions, GL_EXT_shader_integer_mix, 

So in both cases the LWJGL2 works but the SDL2 seems to default to the highest compatibility profile that the drivers support. How can I get a 3.3 (core) profile with SDL2?

\$\endgroup\$
  • \$\begingroup\$ What if you set GL attributes after SDL init? \$\endgroup\$ – HolyBlackCat Oct 16 '16 at 21:18
  • \$\begingroup\$ That was it! I'll post an answer. \$\endgroup\$ – Austin Oct 16 '16 at 23:10
  • \$\begingroup\$ @HolyBlackCat maybe post it as answer \$\endgroup\$ – Bálint Oct 17 '16 at 5:51
4
\$\begingroup\$

Put your SDL_GL_SetAttribute() calls after SDL_Init().

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.