Example using OpenGL 3.0+ with SDL2 and GLEW
I decided to port one of my simple for-learning-purposes OpenGL applications over to SDL2 from GLFW last night. I ran in to a few problems along the way, I’ll share my solutions with you here. The main problem was that SDL2 doesn’t handle extension loading for you like GLFW does. Easy enough to solve, just use GLEW right? Well yes, but the caveat here isn’t so obvious.
Without GLEW my program compiled but returned a bunch of warnings about “implicit declaration of function ‘glClear'” and so forth, for all OpenGL functions. This is to be expected, given that you need to manually load OpenGL functions when using SDL2.
After inserting the GLEW header and glewInit() my program compiled just fine, but gave a segfault as soon as it tried to compile one of my shaders. The error string returned with glewGetErrorString() was “Missing GL Version”, not exactly helpful. The solution to my particular problem was in my placement of glewInit(). This function MUST be run AFTER the following have been completed:
1. Creating a window with the SDL_WINDOW_OPENGL flag.
2. Creating a valid OpenGL context with SDL_GL_CreateContext()
3. Setting the newly created context as current with SDL_GL_MakeCurrent()
It was that third step that threw me off, but after moving things around my program was able to compile and run properly.
I came across a few other useful tidbits that may help others in similar situations. The “Missing GL Version” is returned for a number of different reasons. A common cause is that GLEW was not configured to make use of features in OpenGL versions greater than 2.0. By default, GLEW is only configured to make use of features available in OpenGL 2.0 and lower. The solution to this is adding the following line before glewInit():
glewExperimental = GL_TRUE;
Additionally, you can explicitly tell SDL2 which version of OpenGL you want to target with the following lines. In my case, version 3.3:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
You can download the source code for my OpenGL with SDL2 sample program here. It draws a triangle with red, green, and blue corners. Quit by pressing the escape key.
I’ve tried your solution, but I’m still getting an error. Where there is “GLenum glew_status = glewInit(),” The error I’m receiving is:
‘glewGetContext’ : indentifier not found.
glewGetContext is not defined.
~SDL2 + GLew 1.10~
That’s a puzzler. What system are you running on? Are you sure you’re including/linking all the libraries correctly? What happens if you try to compile+run my sample app with the command in the comment at the top of the C file?
It was an error on my behalf. I downloaded the wrong version instead of downloading the pre-built GLew library. Everything is working now.
Have you ever used ASSIMP with OpenGL? There is only one tutorial on Youtube using ASSIMP with SDL, but it is riddled with errors and outdated.
No, I haven’t. I’m still pretty new to OpenGL myself, and haven’t had the time to research it much more lately. ASSIMP does sound very relevant to my interests though (I’d like to write 3D games for the Oculus Rift in the near future). If I get around to experimenting with it I’ll either write about it or email you.
Thanks Brandon, really helpful explanation.
Thanks for this source. It’s the first time I’ve been able to get SDL2/OpenGL to render anything to my screen.
I had to change a few things and removed the colored vertexes since they weren’t working.
Modified source: http://u4e.us/c/main.c
You’re welcome! I’m glad you were able to make progress with it. OpenGL definitely has a steep learning curve and takes some hurdle-jumping to get up and running, but once you do it a time (or several) it becomes easier to get working many places.
Thanks a lot! This was really helpful!
I was able to get it to compile under Windows CodeBlocks, but only if I modified the include section as follows:
#include // For GL undeclared error
#include
#include
#undef main // To fix ‘SDL_main’ error
#include // for FILE
However when it runs it generates a fault at line:
GLuint shader = glCreateShader(eShaderType);
Any idea how to compile this so that it runs in Windows? I can’t find a simple Hello World example that uses SDL2 and OpenGL3.
Thanks!
1. To fix ‘SDL_main’ error should like this :
int main(int argc, char* args[]){
return 0;
}
2. I use MAKEFILE and mingw-w64 :
## flags
CC = g++
CFLAGS = -m64 -Wall
LFLAGS = -m64
## Addon Packegs
CFLAGS += `pkg-config “SDL2_image >= 2.0.0” “SDL2_mixer >= 2.0.0” “SDL2_net >= 2.0.0” “SDL2_ttf >= 2.0.0” “glew >= 1.12.0” –cflags`
LFLAGS += `pkg-config “SDL2_image >= 2.0.0” “SDL2_mixer >= 2.0.0” “SDL2_net >= 2.0.0” “SDL2_ttf >= 2.0.0” “glew >= 1.12.0” –libs`
CFLAGS += -Wno-sign-compare
LFLAGS += -lopengl32
I tried to use SDL2 + OpenGL 3 and your solution for me was very helpful. But I did not want to use the extra libraries (GLEW) and I was able to.
I modified a bit of your code:
//#include // removed
#define GL_GLEXT_PROTOTYPES // unlocking prototypes defined in glext.h – prevent generating compiler warnings (maybe exist another solution …)
#include
#include // header file for OpenGL
GLuint BuildShaderProgram(const char *vsPath, const char *fsPath);
GLuint CreateShader(GLenum eShaderType, const char *strShaderFile);
int main()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
return 1;
// type of context must be set prior to creating the first window (SDL Wiki)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_Window *window = SDL_CreateWindow("My Game Window",
(…)
/* GLEW functions are no longer needed:
glewExperimental = GL_TRUE;
GLenum glew_status = glewInit();
if (glew_status != 0)
{
fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));
return 1;
}*/
(…)
It works great and the compiler status is: 0 error(s), 0 warning(s).
I use: Code::Blocks 13.12, under: Linux Ubuntu 14.10
That’s very interesting, I’m glad there’s a solution to build this without GLEW. Thanks for sharing, I’ll definitely try this next time I’m working on an OpenGL application!