SDL2 and OpenGL

Hi, I’m upgrading an app using SDL1.2 and OpenGL to SDL2.

I have changed my window creation to use SDL_CreateWindowAndRenderer using just the SDL_WINDOW_OPENGL flag (I don’t need fullscreen) to get a window and renderer.

I don’t get a GL context, I just use GL calls to draw, then call SDL_RenderPresent. That seems to work.

But I also see there are functions SDL_GL_CreateContext, SDL_GL_SwapWindow. I’m not using them. Why does it work without them? Under what conditions should I use or not use them? (Maybe they give me something extra I want, or don’t need?)

One more issue I had was loading images from PNG into a surface which I later create a GL texture from. (I don’t want to change this to use SDL’s textures directly because I may in some cases be running this code without SDL using different PNG loading functions.) I changed that from SDL Image 1.2 to SDL Image 2. However, I find now that surface->format->BytesPerPixel is coming back as 0 when it used to be 3 or 4. Is there a reason for that? I need to know whether the PNG had transparency, so I can create an appropriate GL texture (with or without alpha).

Also, how important is it to call SDL_GL_DeleteContext, SDL_DestroyWindow, SDL_Quit at app exit? What are the consequences of not doing so? If I just call SDL_Quit, will it automatically free any contexts and windows I created? (I just have one actually.)

I’m just trying to simplify my code as much as possible (but no simpler than necessary).

This is on OS X by the way.

I have changed my window creation to use SDL_CreateWindowAndRenderer
using just the SDL_WINDOW_OPENGL flag (I don’t need fullscreen) to get a
window and renderer.

You want SDL_CreateWindow() and not any of the Renderer stuff (that’s a
simple 2D drawing API that is using OpenGL behind the scenes, which you
don’t need if you’re using OpenGL directly.

I don’t get a GL context, I just use GL calls to draw, then call
SDL_RenderPresent. That seems to work.

This is sort of working by accident for you, because the rendering API
is also using OpenGL. Here’s what you should do to create a 800x600 window:

 SDL_Init(SDL_INIT_VIDEO);  // make sure that didn't fail.
 SDL_Window *window = SDL_CreateWindow("My Game's Name",
     SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600,
     SDL_WINDOW_OPENGL);
 // make sure that's not NULL.

 SDL_GLContext glctx = SDL_GL_CreateContext(window);
 // make sure that's not NULL.

 SDL_GL_MakeCurrent(window, glctx);
 // now it is safe to call GL functions.

 // draw some stuff, and when you want to put it to the screen...

 SDL_GL_SwapWindow(window);

 // and repeat.

–ryan.

OK I get it.

Is the SDL_GL_MakeCurrent strictly necessary, if I have one context, and never change it? Will it be current by default?

And is the context/window cleanup necessary, or will that happen by virtue of SDL_Quit?

OK I get it.

Is the SDL_GL_MakeCurrent strictly necessary, if I have one context, and
never change it? Will it be current by default?

Yes.

And is the context/window cleanup necessary, or will that happen by virtue
of SDL_Quit?

SDL_Quit probably just cleans up the window stuff. Regardless, I
would make it a habit to clean up yourself, especially if you’re one
to encapsulate with familiar classes/interfaces and then forget about
implementation.On Wed, Oct 30, 2013 at 5:13 PM, mlepage wrote:


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2013/10/30 mlepage

**
OK I get it.

Is the SDL_GL_MakeCurrent strictly necessary, if I have one context, and
never change it? Will it be current by default?

And is the context/window cleanup necessary, or will that happen by virtue
of SDL_Quit?

Yes, you are required to release any resources you allocated, so after you
are
done with your application, call

SDL_GL_DeleteContext(glctx);
SDL_DestroyWindow(window);
SDL_Quit();

Yes, you are required to release any resources you allocated, so after
you are
done with your application, call

 SDL_GL_DeleteContext(glctx);
 SDL_DestroyWindow(window);
 SDL_Quit();

Fwiw, SDL will destroy all its windows during SDL_Quit()…but it won’t
destroy GL contexts. That’s probably a bug.

–ryan.

Laftur Jeremy wrote:> On Wed, Oct 30, 2013 at 5:13 PM, mlepage <@Marc_A_Lepage> wrote:

OK I get it.

Is the SDL_GL_MakeCurrent strictly necessary, if I have one context, and
never change it? Will it be current by default?

Yes.

So, to be clear, is that “yes it’s necessary” or “yes it will be current by default”?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

[Why can’t I edit a post just after posting?]

Sorry I messed up the quoting in the previous post, I asked a question, Laftur Jeremy answered yes, then I asked which part the yes was affirming.

Because it’s not really a forum; it’s a front-end to a mailing list that makes it look like a forum. But once you “post” something, it gets emailed out to all of us.________________________________
From: mlepage
To: sdl at lists.libsdl.org
Sent: Thursday, October 31, 2013 8:38 AM
Subject: Re: [SDL] SDL2 and OpenGL

[Why can’t I edit a post just after posting?]

Sorry I messed up the quoting in the previous post, I asked a question, Laftur Jeremy answered yes, then I asked which part the yes was affirming.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Yes, the newly created context will be made current upon creation with
SDL_GL_CreateContext. It says so in the function’s documentation.
sorry for being unclear.On Thu, Oct 31, 2013 at 1:15 PM, Mason Wheeler wrote:

Because it’s not really a forum; it’s a front-end to a mailing list that
makes it look like a forum. But once you “post” something, it gets emailed
out to all of us.


From: mlepage
To: sdl at lists.libsdl.org
Sent: Thursday, October 31, 2013 8:38 AM
Subject: Re: [SDL] SDL2 and OpenGL

[Why can’t I edit a post just after posting?]

Sorry I messed up the quoting in the previous post, I asked a question,
Laftur Jeremy answered yes, then I asked which part the yes was affirming.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Ryan, I’ve seen enough people ask if the two can be used together
that I wonder if it’s worth making it explicitly supported. I have a
very simple demo program showing how it can be done, but it’s a bit
clumsy at the moment because of some basic assumptions:

  1. You should create the window, the GL context, and the renderer, in
    that order.

  2. You should find the opengl render driver yourself if possible and
    create your renderer using it. (I have no idea if that’s actually
    necessary if your window is created as an OpenGL window?)

  3. SDL’s render state should be treated as “magic”. That means you
    should preserve its ortho matrix, and probably its blendfunc as well.
    It’s easy enough to recreate other matrices (basically identity) and
    set the color to a known state like ? opaque white.

  4. Depth test (and anything else of the sort) needs to be disabled
    prior to calling SDL’s render functions.

  5. SDL_RenderPresent instead of SDL_GL_SwapBuffers.

Those assumptions work. It could work a little better if I
disregarded them, though. Creating my own ortho matrix gives me the
ability to use a resizable window that works as expected. Letting
SDL find the opengl render driver works too. And I restore the color
and blend mode SDL expects (in fact I can usually just use SDL’s
blend mode since I’d call the same functions the same way 99% of the
time anyway!) But ? it might not be future-proof.

If we want to officially support mixing the two in some fashion, I
see two ways to do it. Either we need to expressly state SDL’s
expectations, expose GL_ResetState, or a bit of both. Exposing the
reset function will cause some unnecessary state thrashing, but
really if one wants speed, one should move their 2D SDL code to use
GL natively.

Bonus: Exposing the reset function gives you all of the OpenGL
targets basically for free. I don’t know enough D3D to know if
D3D_Reset does quite the same thing, but I know it must be a "cheap"
function given how many times the D3D renderer has to call it. :wink:

(BTW, is there any good reason why the OpenGL renderers all take byte
input and then call glColor4f? glColor4ub is pretty standard as an
accelerated path, in my understanding even on OpenGL ES v1?)

JosephOn Wed, Oct 30, 2013 at 03:49:13PM -0400, Ryan C. Gordon wrote:

I have changed my window creation to use SDL_CreateWindowAndRenderer
using just the SDL_WINDOW_OPENGL flag (I don’t need fullscreen) to get a
window and renderer.

You want SDL_CreateWindow() and not any of the Renderer stuff (that’s
a simple 2D drawing API that is using OpenGL behind the scenes, which
you don’t need if you’re using OpenGL directly.

I don’t get a GL context, I just use GL calls to draw, then call
SDL_RenderPresent. That seems to work.

This is sort of working by accident for you, because the rendering
API is also using OpenGL. Here’s what you should do to create a
800x600 window:

SDL_Init(SDL_INIT_VIDEO); // make sure that didn’t fail.
SDL_Window *window = SDL_CreateWindow(“My Game’s Name”,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600,
SDL_WINDOW_OPENGL);
// make sure that’s not NULL.

SDL_GLContext glctx = SDL_GL_CreateContext(window);
// make sure that’s not NULL.

SDL_GL_MakeCurrent(window, glctx);
// now it is safe to call GL functions.

// draw some stuff, and when you want to put it to the screen…

SDL_GL_SwapWindow(window);

// and repeat.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

There’s a bug in the tracker describing a mechanism to do this by forcing
an internal SDL state reset, it’s actually quite simple to implement I
think. Yet, it still sits in the todo list along with the rest of the low
hanging fruits :slight_smile:
El nov 5, 2013 1:44 a.m., “T. Joseph Carter”
escribi?:> Ryan, I’ve seen enough people ask if the two can be used together that I

wonder if it’s worth making it explicitly supported. I have a very simple
demo program showing how it can be done, but it’s a bit clumsy at the
moment because of some basic assumptions:

  1. You should create the window, the GL context, and the renderer, in that
    order.

  2. You should find the opengl render driver yourself if possible and
    create your renderer using it. (I have no idea if that’s actually
    necessary if your window is created as an OpenGL window?)

  3. SDL’s render state should be treated as “magic”. That means you should
    preserve its ortho matrix, and probably its blendfunc as well. It’s easy
    enough to recreate other matrices (basically identity) and set the color to
    a known state like ? opaque white.

  4. Depth test (and anything else of the sort) needs to be disabled prior
    to calling SDL’s render functions.

  5. SDL_RenderPresent instead of SDL_GL_SwapBuffers.

Those assumptions work. It could work a little better if I disregarded
them, though. Creating my own ortho matrix gives me the ability to use a
resizable window that works as expected. Letting SDL find the opengl
render driver works too. And I restore the color and blend mode SDL
expects (in fact I can usually just use SDL’s blend mode since I’d call the
same functions the same way 99% of the time anyway!) But ? it might not be
future-proof.

If we want to officially support mixing the two in some fashion, I see two
ways to do it. Either we need to expressly state SDL’s expectations,
expose GL_ResetState, or a bit of both. Exposing the reset function will
cause some unnecessary state thrashing, but really if one wants speed, one
should move their 2D SDL code to use GL natively.

Bonus: Exposing the reset function gives you all of the OpenGL targets
basically for free. I don’t know enough D3D to know if D3D_Reset does
quite the same thing, but I know it must be a “cheap” function given how
many times the D3D renderer has to call it. :wink:

(BTW, is there any good reason why the OpenGL renderers all take byte
input and then call glColor4f? glColor4ub is pretty standard as an
accelerated path, in my understanding even on OpenGL ES v1?)

Joseph

On Wed, Oct 30, 2013 at 03:49:13PM -0400, Ryan C. Gordon wrote:

I have changed my window creation to use SDL_CreateWindowAndRenderer

using just the SDL_WINDOW_OPENGL flag (I don’t need fullscreen) to get a
window and renderer.

You want SDL_CreateWindow() and not any of the Renderer stuff (that’s a
simple 2D drawing API that is using OpenGL behind the scenes, which you
don’t need if you’re using OpenGL directly.

I don’t get a GL context, I just use GL calls to draw, then call

SDL_RenderPresent. That seems to work.

This is sort of working by accident for you, because the rendering API is
also using OpenGL. Here’s what you should do to create a 800x600 window:

SDL_Init(SDL_INIT_VIDEO); // make sure that didn’t fail.
SDL_Window *window = SDL_CreateWindow(“My Game’s Name”,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600,
SDL_WINDOW_OPENGL);
// make sure that’s not NULL.

SDL_GLContext glctx = SDL_GL_CreateContext(window);
// make sure that’s not NULL.

SDL_GL_MakeCurrent(window, glctx);
// now it is safe to call GL functions.

// draw some stuff, and when you want to put it to the screen…

SDL_GL_SwapWindow(window);

// and repeat.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

If D3D_Reset will do what’s necessary for Direct3D, I’ll add it to my
(ever-growing) todo list. :slight_smile:

JosephOn Tue, Nov 05, 2013 at 09:10:39AM -0200, Gabriel Jacobo wrote:

There’s a bug in the tracker describing a mechanism to do this by forcing
an internal SDL state reset, it’s actually quite simple to implement I
think. Yet, it still sits in the todo list along with the rest of the low
hanging fruits :slight_smile:
El nov 5, 2013 1:44 a.m., “T. Joseph Carter” <@T_Joseph_Carter>
escribi?:

Ryan, I’ve seen enough people ask if the two can be used together that I
wonder if it’s worth making it explicitly supported. I have a very simple
demo program showing how it can be done, but it’s a bit clumsy at the
moment because of some basic assumptions:

  1. You should create the window, the GL context, and the renderer, in that
    order.

  2. You should find the opengl render driver yourself if possible and
    create your renderer using it. (I have no idea if that’s actually
    necessary if your window is created as an OpenGL window?)

  3. SDL’s render state should be treated as “magic”. That means you should
    preserve its ortho matrix, and probably its blendfunc as well. It’s easy
    enough to recreate other matrices (basically identity) and set the color to
    a known state like ? opaque white.

  4. Depth test (and anything else of the sort) needs to be disabled prior
    to calling SDL’s render functions.

  5. SDL_RenderPresent instead of SDL_GL_SwapBuffers.

Those assumptions work. It could work a little better if I disregarded
them, though. Creating my own ortho matrix gives me the ability to use a
resizable window that works as expected. Letting SDL find the opengl
render driver works too. And I restore the color and blend mode SDL
expects (in fact I can usually just use SDL’s blend mode since I’d call the
same functions the same way 99% of the time anyway!) But ? it might not be
future-proof.

If we want to officially support mixing the two in some fashion, I see two
ways to do it. Either we need to expressly state SDL’s expectations,
expose GL_ResetState, or a bit of both. Exposing the reset function will
cause some unnecessary state thrashing, but really if one wants speed, one
should move their 2D SDL code to use GL natively.

Bonus: Exposing the reset function gives you all of the OpenGL targets
basically for free. I don’t know enough D3D to know if D3D_Reset does
quite the same thing, but I know it must be a “cheap” function given how
many times the D3D renderer has to call it. :wink:

(BTW, is there any good reason why the OpenGL renderers all take byte
input and then call glColor4f? glColor4ub is pretty standard as an
accelerated path, in my understanding even on OpenGL ES v1?)

Joseph

On Wed, Oct 30, 2013 at 03:49:13PM -0400, Ryan C. Gordon wrote:

I have changed my window creation to use SDL_CreateWindowAndRenderer

using just the SDL_WINDOW_OPENGL flag (I don’t need fullscreen) to get a
window and renderer.

You want SDL_CreateWindow() and not any of the Renderer stuff (that’s a
simple 2D drawing API that is using OpenGL behind the scenes, which you
don’t need if you’re using OpenGL directly.

I don’t get a GL context, I just use GL calls to draw, then call

SDL_RenderPresent. That seems to work.

This is sort of working by accident for you, because the rendering API is
also using OpenGL. Here’s what you should do to create a 800x600 window:

SDL_Init(SDL_INIT_VIDEO); // make sure that didn’t fail.
SDL_Window *window = SDL_CreateWindow(“My Game’s Name”,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600,
SDL_WINDOW_OPENGL);
// make sure that’s not NULL.

SDL_GLContext glctx = SDL_GL_CreateContext(window);
// make sure that’s not NULL.

SDL_GL_MakeCurrent(window, glctx);
// now it is safe to call GL functions.

// draw some stuff, and when you want to put it to the screen…

SDL_GL_SwapWindow(window);

// and repeat.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org