简体   繁体   中英

Context creation fails

I'm learning OpenGL so I was experimenting with drawing 2D images. I first put everything in the main function of my C++ program. It worked fine (2 triangles were drawn).

I decided to make the program clearer by making separate classes, ... But now it isn't working anymore. When I want to make the OpenGL Context, it fails. When I display the error I get :

Failed creating OpenGL context at version requested

In the tutorial I am reading they said this error is most likely due to the fact that the version of OpenGL isn't supported by your graphics card, but if this was the case, it shouldn't work when I put all the code in the main procedure.

This is the part where it goes wrong (context creation) :

bool OpenGL_Scene::initializeWindow() {
    // Initialize the SDL
    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        cout << "Error while initializing the SDL : " << SDL_GetError() << endl;
        SDL_Quit();

        return false;
    }

    // Configure OpenGL

    // Use version 3.1
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1

    // Double buffering
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);  // Buffer has a depth of 24 bits

    // Make the window
    this->window = SDL_CreateWindow(this->windowTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->windowWidth, this->windowHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); // SDL_WINDOW_OPENGL necessary to specify that the window will have an OpenGL context attached to it.

    if(this->window == 0) // Initialization failed
    {
        cout << "Error while creating the window : " << SDL_GetError() << endl;
        SDL_Quit();

        return false;
    }

    // Make the OpenGL context given the SDL window
    this->OpenGL_Context = SDL_GL_CreateContext(this->window);

    // Make sure the creation of the context succeeded. If not the problem is probably that the version of OpenGL isn't supported by the graphics card.
    if(this->OpenGL_Context == 0)
    {
        cout << "Could not create the OpenGL context : " << SDL_GetError() << endl;

        SDL_DestroyWindow(window);
        SDL_Quit();
        return false;
    }

    return true;
};

In the last few lines the error get displayed so the program results in :

Could not create the OpenGL context : Failed creating OpenGL context at version requested

I searched a lot to find a solution and found this : SO topic

So in the above code I tried :

// Configure OpenGL

// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1

// Double buffering
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);      // ADDING THIS AVOIDS THAT THE CONTEXT COULD NOT BE CREATED BUT THEN WHEN WE DRAW SOMETHING WE DON'T SEE ANYTHING

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);  // Buffer has a depth of 24 bits

Now when I run the program with this extra line, the context is created (without errors so OpenGL_Context != 0 ) but nothing is drawn . I omitted the part of the code where I am drawing, because it worked before and I didn't changed anything.

Does someone has an idea what could be the problem?

PS : I'm working on a Macbook Pro (OS X Yosemite (10.10.4)) and my graphics card is an NVIDIA GeForce GT 650M 1024 MB

EDIT : I tried debugging the code that draws the triangles but I really don't see the error (mainly because I'm really really new to OpenGL). Underneath you can find the drawing code. Notice that I don't initialize GLEW anymore as it isn't necessary (according to the comments).

void OpenGL_Scene::mainLoop() {
    bool end = false;

    // Make vertices (punten) in a table
    // !!! WARNING : Use 1 table for ALL vertices !!! Don't use a separate table for each of the forms, this would slow down the program because you have to send each of the tables to OpenGL !!!

    float vertices[] = {-0.5, -0.5,   0.0, 0.5,   0.5, -0.5,      // 3 Points for first triangle --> (-0.5, -0.5) , (0.0, 0.5) and (0.5, -0.5)  (All in (x, y) --> 2D)
                    -0.8, -0.8,   -0.3, -0.8,   -0.8, -0.3};  // 3 Points for second triangle

    // Before we start drawing, clear the screen
    glClear(GL_COLOR_BUFFER_BIT);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(0); // Activate the table we passed to OpenGL using the identifier (index) passed to OpenGL (in this case 0)

    // Now that OpenGL knows which vertices it has to display we are going to specify what it has to do with these vertices
    glDrawArrays(GL_TRIANGLES, 0, 6); // Draw both triangles

    glDisableVertexAttribArray(0);   // Because it isn't necessary anymore
    SDL_GL_SwapWindow(this->window); // Refresh the screen

    while(!end) {
        // Listen to events and play with them
        SDL_WaitEvent(&this->events); // Will wait for an event and assign it to "events" variable

        if(this->events.window.event == SDL_WINDOWEVENT_HIDDEN)
            cout << "The user has hidden the window !" << endl;
        else if(this->events.window.event == SDL_WINDOWEVENT_CLOSE) {
            cout << "The user closed the window !" << endl;

            glClear(GL_COLOR_BUFFER_BIT); // Clear the screen
            SDL_GL_SwapWindow(this->window);    // Refresh the window

            end = true;
        }  
    }
    // Quitting the SDL and OpenGL properly is done by the destructor
}

So now when I execute the project, first I make the window (this is succesfull) and then I call the mainLoop procedure (from above). I stepped trough the drawing code using the debugger, all the procedures were called (glClear, ...) but nothing appears in the window (it stays black).

I found the error. I was initializing OpenGL after initializing the SDL, this is why the context could not be created without forcing to go into "Core Profile".

The correct order in "initializeWindow" is :

// Configure OpenGL

// Use version 3.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // OpenGL 3.x
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); // OpenGL x.1 --> OpenGL 3.1

// Double buffering
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Use double buffering (0 to not use it)
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);  // Buffer has a depth of 24 bits

// Initialize the SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
    cout << "Error while initializing the SDL : " << SDL_GetError() << endl;
    SDL_Quit();

    return false;
}

Doing so the context is created successfully.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM