GMS 2 Screen tear only in fullscreen mode

Discussion in 'Programming' started by mdbussen, Oct 26, 2017.

  1. mdbussen

    mdbussen Member

    Joined:
    Jul 8, 2016
    Posts:
    62
    I am experiencing a kind of strange issue on my current project. Whenever I switch to fullscreen mode (using the 'window_set_fullscreen' function), I experiencing consistent screen tearing. This only happens in fullscreen mode; in windowed mode everything works fine with no tearing, regardless of the size of the window. I suspect this is some kind of aliasing problem, because I am still up over 1000+ FPS in the debug overlay. Also, checking the "use synchronization to avoid tearing" checkbox does not fix the screen tearing I am seeing in fullscreen mode.

    My game doesn't do any upscaling or downscaling of the graphics so it should be fairly simple. Whatever the window resolution is, the view port and camera resolution ends up set to the same thing. My laptop monitor is 1600 x 900.

    All of the code pertaining to the display window and camera lives in an "obj_camera" object.

    obj_camera CREATE event:
    Code:
    /// @description Initializes the camera system
    
    // NOTE: This code will break if the display is less than 720p resolution.
    
    //--------------------------------//
    // CONSTANTS
    //--------------------------------//
    
    #macro    WINDOW_MINIMUM_WIDTH    1280
    #macro    WINDOW_MINIMUM_HEIGHT    720
    #macro    WINDOW_CAPTION            "Child of Darkness"
    
    //--------------------------------//
    // MEMBER VARIABLES
    //--------------------------------//
    
    // window width and height is tracked to detect when a
    // window is resized and respond appropriately.
    // These are global because the GUI needs to reference them
    global.window_width = WINDOW_MINIMUM_WIDTH;
    global.window_height = WINDOW_MINIMUM_HEIGHT;
    
    // camera x and y position tells where the camera is focused
    camera_x = 0;
    camera_y = 0;
    
    // set to an object ID to track that object with the camera
    camera_object = NULL;
    
    //--------------------------------//
    // CODE
    //--------------------------------//
    
    //=== First, define the window size and position
    
    // set to default size
    window_set_size(global.window_width, global.window_height);
    
    // center the window
    var width = display_get_width();
    var height = display_get_height();
    var x_pos = (width - WINDOW_MINIMUM_WIDTH) div 2;
    var y_pos = (height - WINDOW_MINIMUM_HEIGHT) div 2;
    window_set_position(x_pos, y_pos);
    
    // set the window caption appropriately
    window_set_caption(WINDOW_CAPTION);
    
    
    //=== Next, define the camera view
    view_camera[0] = camera_create_view(camera_x, camera_y, global.window_width, global.window_height, 0, NULL, 0, 0, 0, 0);
    camera_set_view_size(view_camera[0], global.window_width, global.window_height);
    view_set_camera(0, view_camera[0]);
    obj_camera STEP event:
    Code:
    /// @description Should be called in the step event to update the camera
    
    // Check if the user wants to switch to fullscreen mode
    window_fullscreen_update();
    
    // update the window if the window has been resized
    window_size_update();
    
    obj_camera END STEP event:
    Code:
    // track the camera object if the camera is in tracking mode
    if (camera_object != NULL)
        camera_set_position(camera_object.x, camera_object.y);
    
    // update the camera view
    camera_set_view_pos(view_camera[0], camera_x - global.window_width div 2, camera_y - global.window_height div 2);
    
    window_fullscreen_update script:
    Code:
    /// @description Checks if the user wants to toggle fullscreen mode
    
    if (global.ctl_fullscreen){
        var current_fullscreen_mode = window_get_fullscreen();
        window_set_fullscreen(!current_fullscreen_mode);
        
        // we will update the window dimensions and resolution in a later call so we can exit from the script now
    }
    
    window_size_update script:
    Code:
    /// @description Should be called in the step function to watch for window resizing
    
    if (window_get_width() != global.window_width) or (window_get_height() != global.window_height){
        
        // don't let the window get smaller than the minimum size
        if (window_get_width() < WINDOW_MINIMUM_WIDTH){
            global.window_height = window_get_height();
            window_set_size(WINDOW_MINIMUM_WIDTH, global.window_height);
            alarm[0] = 1;        // set to center window on next frame
        }
        if (window_get_height() < WINDOW_MINIMUM_HEIGHT){
            global.window_width = window_get_width();
            window_set_size(global.window_height, WINDOW_MINIMUM_HEIGHT);
            alarm[0] = 1;        // set to center window on next frame
        }
        
        // update the stored window sizes
        global.window_width = window_get_width();
        global.window_height = window_get_height();
        
        // update the camera settings
        camera_reset();
        
        // dump the new window settings
        camera_debug();
    }
    
    camera_reset script:
    Code:
    /// @description Call this to reset the camera for a new room or window size
    
    view_visible[0] = true;
    view_enabled = true;
    view_wport[0] = global.window_width;
    view_hport[0] = global.window_height;
    view_set_camera(0, view_camera[0]);
    camera_set_view_size(view_camera[0], global.window_width, global.window_height);
    surface_resize(application_surface,global.window_width,global.window_height);
    
    I suspect the problem *might* be with this last script. I had run into problems when switching between rooms with my camera not updating the room viewport correctly which is where this 'camera_reset' script came from; I'm probably doing some overkill stuff in here but I was kind of pounding on it for a while until I figured out I had to resize the application surface.

    Thanks in advance for any help you can give!
     
  2. CMAllen

    CMAllen Member

    Joined:
    Mar 2, 2017
    Posts:
    855
    Define 'tearing' in this particular instance. What exactly are you seeing? People use the term interchangeably with graphical artifacts, but screen tearing has a very specific meaning
     
  3. mdbussen

    mdbussen Member

    Joined:
    Jul 8, 2016
    Posts:
    62
    It looks like something comparable to this picture:

    [​IMG]

    Part of the screen seems like it is frame behind the rest of the screen sometimes. Note I don't think it's ACTUAL screen tearing (as Vsync checkbox does not fix it) but that is somewhat how it looks.
     
  4. CMAllen

    CMAllen Member

    Joined:
    Mar 2, 2017
    Posts:
    855
    Well, that is definitely screen tearing (regardless of cause). Since vsync didn't help, you could try a couple things to help narrow down the possible source (assuming you haven't tried them already):

    1) Lower your game's run speed. The faster your game is running, the more screen updates your game is performing, the greater the chance/frequency of screen tearing.
    2) Test your project on another system with different hardware. It could be GM's render engine isn't playing well with your video card driver, or your video card driver isn't playing well with GM's render engine.
     
    ParodyKnaveBob likes this.
  5. Smiechu

    Smiechu Member

    Joined:
    Jul 14, 2017
    Posts:
    626
    Are you sure v_sync is realy on in the game? What shows fps? Is it a steady value, equal to what you have set in game options?
    You are doing a lot of things with screen/window/view/camera... it is possible that some of this things switch off the v_sync...
    There are also situations where you need to restart the project so the v_sync starts to work...
     
    Last edited: Oct 26, 2017
  6. RangerX

    RangerX Member

    Joined:
    Jun 20, 2016
    Posts:
    2,595
    Also test alternate sync on/off and also in combination with v-sync on/off
     
  7. mdbussen

    mdbussen Member

    Joined:
    Jul 8, 2016
    Posts:
    62
    Thank you for the suggestions!

    1) I tried to lower the game speed from 60fps to 30fps but this did not improve the artifacts I was seeing. I also don't believe it is an fps issue because the debug overlay is showing my fps as 1000+ during normal runtime.

    2) I will try and do this sometime soon. I don't have access to another system at the moment, unfortunately.
     
  8. Smiechu

    Smiechu Member

    Joined:
    Jul 14, 2017
    Posts:
    626
    I ask one more time... what shows built in variable fps... are you sure that v-sync is on?
     
  9. mdbussen

    mdbussen Member

    Joined:
    Jul 8, 2016
    Posts:
    62
    What is "alternate sync"? I only see references to v-sync in the GMS2 documentation...
     
  10. mdbussen

    mdbussen Member

    Joined:
    Jul 8, 2016
    Posts:
    62
    When reporting fps, I am referencing the value that is displayed in the debug_overlay. I believe this takes video rendering times into account. V-sync is off by default (I am referring to the Use synchronization to avoid tearing checkbox being unchecked in the Windows Graphics options). I turned it on and noticed something odd. The fps during normal windowed operation is reported (again on the debug overlay) as ~60fps. But when I put the game into fullscreen mode this jumps up to ~900+fps. Does fullscreen mode not carry over the vsync settings from the previous windowed mode?
     
  11. Smiechu

    Smiechu Member

    Joined:
    Jul 14, 2017
    Posts:
    626
    With sync on... 60fps is a proper value in this situation... this is how it should work... I assume that you have no tearing then...
    But if in full screen you have something else than 60, and experience tearing, than something is wrong...
    I would suggest to implement the fps value somwhere on the game screen and check what happens without the debugger, becouse it can also have influance on performance, and game behavior...

    To be sure, if it's a problem of your coding, I would also recommend to create a simple new project with one moving object and check if the problems are also present...

    Than I would check all screen/graphic related operations... I assume that you have somwhere a code which in result turns of the v-sync...
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice