1

I ran into a strange problem recently. I wrote an application class which uses a very simple renderer to draw some models on screen. The camera is movable.

I ran the program on my laptop. Initially I noticed that nothing was being drawn on screen (the screen was being cleared by the correct color, however). Then I noticed that the screen would update itself IF I clicked on the decoration frame and moved the window: this way, the models became visible, but would not move unless I clicked and moved the decoration frame again.

I tested my program on a desktop computer, and everything worked fine; the camera moved smoothly.

Eventually, I got the program to work on my laptop, but I have to set SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 0 ); and disable buffer swapping.

Below is the main application class. In the execution loop, I call the application state stack to loop & render (the application state actually owns the renderer).

In case it is of any consequence, my laptop has intel HD 4000 graphics, and the desktop has a GTX 670.

App::App() : _running( false ),
             _deltaTime( 0u ),
             _elapsedTime( 0u ),
             _mainWindow( nullptr ),
             _glContext(),
             _stack() {
    //ctor
}

App::~App() {
    SDL_GL_DeleteContext( _glContext );
    SDL_DestroyWindow( _mainWindow );
    SDL_Quit();
}

void App::execute() {
    _initialize();

    static const float millisecondsPerFrame = 17;

    while ( _running ) {
        //get the delta time & update elapsed time
        uint32_t oldTime = _elapsedTime;
        _elapsedTime = SDL_GetTicks();
        _deltaTime = _elapsedTime - oldTime;

        _processEvents();

        _loop( _deltaTime / 1000.0f );
        _render();

        //apply possible state changes made to the stack
        _stack.applyPendingChanges();

        int usedTime = SDL_GetTicks() - int ( _elapsedTime );

        //sleep the remainder of the cycle if we didn't use the entire update cycle
        if ( millisecondsPerFrame - usedTime > 0 ) {
            SDL_Delay( uint32_t ( millisecondsPerFrame - usedTime ) );
        }
    }
}

void App::_initialize() {

    //initialize random number generator
    nge::srand();

    _running = true;

    _initializeSDL();
    _initializeOpenGL();

    SDL_GL_MakeCurrent( _mainWindow, _glContext );

    //attempt to set late swap tearing
    int res = SDL_GL_SetSwapInterval( -1 );
    //returns 0 on success
    //returns -1 if swap interval is not supported
    if ( res == -1 ) {
        std::cout << "App::_initializeSDL> " << SDL_GetError() << "\n\n";
        SDL_GL_SetSwapInterval( 1 );
    }

    _stack.registerState<GameState>( AppStateID::Game );
    _stack.pushState( AppStateID::Game );
    _stack.applyPendingChanges();
}

void App::_initializeSDL() {
    SDL_Init( SDL_INIT_VIDEO );
    SDL_Init( SDL_INIT_TIMER );

    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );

    SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK,
                        SDL_GL_CONTEXT_PROFILE_CORE );

    SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );

    /**
    For some reason, on my Samsung Series 9, double buffering does not
    work.
    */
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 0 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
    SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 );
    //anti-aliasing
    SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
    SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 4 );

    _mainWindow =  SDL_CreateWindow( "window",
                               SDL_WINDOWPOS_UNDEFINED,
                               SDL_WINDOWPOS_UNDEFINED,
                               800,
                               600,
                               SDL_WINDOW_OPENGL |
                               SDL_WINDOW_RESIZABLE |
                               SDL_WINDOW_MAXIMIZED |
                               SDL_WINDOW_SHOWN );

    _glContext = SDL_GL_CreateContext( _mainWindow );
}

void App::_initializeOpenGL() {
    //initialize GLEW
    glewExperimental = GL_TRUE;

    if ( glewInit() != GLEW_OK ) {
        std::cerr << "glewInit failed." << std::endl;
        std::exit( EXIT_FAILURE );
    }

    glEnable( GL_DEPTH_TEST );
    //enable culling
    glEnable( GL_CULL_FACE );
    glCullFace( GL_BACK );

    glDepthFunc( GL_LEQUAL );
    glEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS );

    std::cout << "OpenGL version: " << glGetString( GL_VERSION ) << std::endl;
    std::cout << "GLSL version: " << glGetString( GL_SHADING_LANGUAGE_VERSION ) << std::endl;
    std::cout << "Vendor: " << glGetString( GL_VENDOR ) << std::endl;
    std::cout << "Renderer: " << glGetString( GL_RENDERER ) << std::endl << std::endl;

    //make sure OpenGL 3.3 is available
    ASSERT( GLEW_VERSION_3_3, "OpenGL 3.3 API is not available" );
}

void App::_processEvents() {
    SDL_Event event;
        while ( SDL_PollEvent( &event ) ) {

            if ( event.type == SDL_QUIT ) {
                _running = false;
            }
        }
}

void App::_loop( float delta ) {
    _stack.loop( delta );
}

void App::_render() {
    _stack.render();
    //SDL_GL_SwapWindow( _mainWindow );
}
Nelarius
  • 181
  • 2
  • 10

1 Answers1

1

The first thing that I would check are GPU drivers on the laptop. Make sure that the drivers version matches the drivers version on the desktop.

Second thing is to add error printing. From here :

window = SDL_CreateWindow("OpenGL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_OPENGL);
if (!window) {
    fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
    return;
}

context = SDL_GL_CreateContext(window);
if (!context) {
    fprintf(stderr, "Couldn't create context: %s\n", SDL_GetError());
    return;
}

Third thing to check are requested buffers. Maybe the GPU or drivers do not support double buffering, or depth size of 16 bits, or some other parameter that you requested. So, play with parameters in the initializeSDL() function, and find the one that works on your laptop.

BЈовић
  • 62,405
  • 41
  • 173
  • 273