GameMaker Screen tear only in fullscreen mode

M

mdbussen

Guest
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!
 

CMAllen

Member
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
 
M

mdbussen

Guest
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
It looks like something comparable to this picture:



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.
 

CMAllen

Member
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.
 

Smiechu

Member
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:
M

mdbussen

Guest
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.
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.
 

Smiechu

Member
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.
I ask one more time... what shows built in variable fps... are you sure that v-sync is on?
 
M

mdbussen

Guest
I ask one more time... what shows built in variable fps... are you sure that v-sync is on?
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?
 

Smiechu

Member
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?
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...
 
Top