PDA

View Full Version : glewInit fails on fullscreen



BartGs
08-14-2015, 09:13 AM
I'm busy working my way through my first opengl tutorial and came across something that I can't figure out how to fix. The following code is everything I have right now:

#define GLEW_STATIC
#include <stdio.h>
#include <glew.h>
#include <SDL.h>
#include <SDL_opengl.h>

bool CheckShaderCompiled(GLuint shader)
{
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);

if (status != GL_TRUE)
{
char buffer[512];
glGetShaderInfoLog(shader, 512, NULL, buffer);
return false;
}

return true;
}

int main(int argc, char *argv[])
{
//Init SDL
SDL_Init(SDL_INIT_VIDEO);

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);

//SDL_Window* window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);

SDL_GLContext context = SDL_GL_CreateContext(window);

//Init GLEW
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if( err != GLEW_OK )
{
exit(1);
}

//Vertex Array Objects
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

//Vertices
float vertices[] = {
0.0f, 0.5f, // Vertex 1 (X, Y)
0.5f, -0.5f, // Vertex 2 (X, Y)
-0.5f, -0.5f // Vertex 3 (X, Y)
};

GLuint vbo;//Vertex Buffer Object
glGenBuffers(1, &vbo); // Generate 1 buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

//Vertex Shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const GLchar* vertexSource = "#version 150\nin vec2 position;\nvoid main()\n{\ngl_Position = vec4(position, 0.0, 1.0);\n}\n";
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
CheckShaderCompiled(vertexShader);

//Fragment Shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* fragmentSource = "#version 150\nout vec4 outColor;\nvoid main()\n{\noutColor = vec4(1.0, 1.0, 1.0, 1.0);\n}\n";
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
CheckShaderCompiled(fragmentShader);

//Combining shaders into a program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);

//Making the link between vertex data and attributes
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);

//Game loop
SDL_Event windowEvent;
bool windowOpen = true;
while (windowOpen)
{
if (SDL_PollEvent(&windowEvent))
{
if (windowEvent.type == SDL_QUIT) windowOpen = false;
if (windowEvent.type == SDL_KEYUP && windowEvent.key.keysym.sym == SDLK_ESCAPE) windowOpen = false;
}

//Draw
glDrawArrays(GL_TRIANGLES, 0, 3);

SDL_GL_SwapWindow(window);
}

//Dispose of SDL
SDL_GL_DeleteContext(context);

SDL_Quit();
return 0;
}

When I make the following line active (windowed mode):

SDL_Window* window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
Everything works fine and I see a triangle appear in the window.

But when I make the following line active (fullscreen):

SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);
The application exits because glewInit() comes back with an error code 1. If I remove the error check after glewInit, the application crashes on
glGenVertexArrays(1, &vao);

What am I doing wrong? How can I get fullscreen to work?

jf1989
08-20-2015, 05:21 AM
In creating your SDL window you've removed the SDL_WINDOW_OPENGL flag from window creation. This means that SDL will not handle setting up an OpenGL context, and so when you try to initialise glew with glewInit there is no context and the call to glewInit fails. When setting up an OpenGL context, you can do things like specifying which OpenGL version you wish to use and in what mode. However, SDL does not expose this functionality and simply asks for the latest OpenGL version with all the backwards compatibility features on.

Anyway, to solve your issue, you need to bitwise OR together the flags for an SDL_WINDOW_OPENGL and SDL_WINDOW_FULLSCREEN_DESKTOP. This changes your line of code from:


SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP);

to


SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_OPENGL);

The API documentation for the SDL_CreateWindow call can be found on the SDL website's wiki, which is a very good reference. It gives a nice overview of the options you have for window creation. I would post a link, but my account is new and I am not allowed :-(.