Tearing with cocos2d-x on PC at native resolution, fullscreen, 60fps - opengl

I'm programming a game with cocos2d-x for Windows, Linux and MacOS (for the moment I develop and test on Windows 10). I already have a system to change settings (either fullscreen or windowed with different resolutions but always a ratio of 16:9).
I've implemented a prototype of my levels system, with only a few sprites and the ability to move horizontally. In windowed mode everything is ok, but in fullscreen mode at native resolution I experience some tearing, though the resolution is set to 60 fps, on a 60 Hz screen (and the fps counter actually displays 60).
When investigating this issue, I've read on the thread OpenGL tearing with fullscreen native resolution that this may be due to bypassing the DWM compositor in fullscreen native resolution, which is otherwise doing some kind of vsync.
I would like to force vsync but I've not found any function neither in class cocos2d::Director nor cocos2d::GLView to do this, and with cocos2d-x I can't do this on a low-level (never using OpenGL directly).
Any idea of how to remove tearing / force vsync?

Related

Is fullscreen really better than windowed mode in a Direct3D 12 application?

I'm trying to learn Direct3D 12 to do some simple 3D graphics for fun.
I've heard that pure fullscreen is the way to go for maximum fps, but now that I'm testing it, fullscreen seems way, way worse than windowed mode.
For example, a static color on a WS_BORDER window (with fullscreen size), and Windowed set to TRUE in the DXGI_SWAP_CHAIN_FULLSCREEN_DESC, can be rendered (with triple-buffering) at about 5000 fps on my computer.
On the other hand, a static color on a WS_POPUP window, Windowed set to FALSE in the DXGI_SWAP_CHAIN_FULLSCREEN_DESC and also IDXGISwapChain3::SetFullscreenState(TRUE, nullptr) called, only renders (with triple-buffering) at about 3000 fps.
Should this be the case or am I missing something?
The story of "fullscreen" for Direct3D is a complex one, and from the other comments/answers in this thread continues be a confused one.
For DirectX 12 on Windows 10, there is no FullScreen Exclusive mode (FSE). When you use SetFullscreenState with either of the modern DXGI_SWAP_EFFECT_FLIP_DISCARD or DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL effect modes then use are really using emulated Fullscreen Exclusive mode (eFSE). DirectX 12 does not support using the the older 'blt-style' effects DXGI_SWAP_EFFECT_DISCARD or DXGI_SWAP_EFFECT_SEQUENTIAL.
If you run with a borderless window that is maximized to cover the entire screen in "windowed mode", it's the same performance as using "eFSE".
There are some 3rd party video card vendor APIs and scenarios that require you use "fullcreen mode" rather than "windowed mode", so in those cases there's a difference.
The other issue is if you are trying to change the display mode vs. using the native resolution. The performance impacts here are the "pixel-fill' rate for the render target size. There are techniques for scaling performance by rendering to an 'offscreen' render target size and then scaling that up to the native resolution of a backbuffer vs. changing the display mode to try to reduce the size of the backbuffer.
See The Care and Feeding of Modern Swap Chains and Demystifying Fullscreen Optimizations.

Full screen Direct3D9 device only displays at native resolution when second monitor is plugged in

With a single monitor my program works in both windowed and full screen mode (using any resolution chosen from EnumAdapterModes), but when I plug in my second monitor (running the same code) I can create a full screen device at any resolution from EnumAdapterModes, but only at the native resolution (1600 x 900) does it display the scene, otherwise the screen is just black among other problems listed below.
What I've discovered so far:
This problem does not occur in windowed or multihead mode
I can still render to a texture (I had to switch modes to display it though)
All function calls return success codes (including TestCooperativeLevel)
If I try to draw to the back buffer using Clear or the DrawPrimitive functions or call Present (which still leaves a black screen), than calls to GetRenderTargetData fail and attempting to lock a volume texture will return different slice pitches at sub levels
Commercial games that use Direct3D9 (Portal) don't have any problem switching between resolutions with my second monitor plugged in so there must be a solution
The problem seems to be related to the back buffer created by the Direct3D9 run time but the only solution I can come up with is to force multihead mode on devices with multiple monitors, any ideas?
Question that seems to have the same problem but lacks a solution: How do I render a fullscreen frame with a different resolution than my display?
Finally figured it out, seems to be a driver bug in Windows Vista and later and using Direct3D9Ex fixed the problem.
I didn't want to use Direct3D9Ex because it was only introduced on Windows Vista and I wanted to support Windows XP as a minimum, but MSDN has some sample code on how to support both so it's all good.

C++ & Allegro 4.2 - I need graphics to stretch in windowed mode

I am using C++ with Allegro 4.2 to build a windows game.
I want stretchable graphics in windowed mode.
I'm am one who likes giving users of my programs lots of options; I always hate when I'm playing a game in windowed mode and I'm either not allowed to stretch the window or the content inside the window doesn't stretch with it (this sucks a lot for 640x480 size games played on high resolution screens that don't even allow for fullscreen; requiring a magnify tool to play it properly). I'm wondering if there is some way in Allegro or perhaps if there is another programming library that allows the graphics to stretch with the shape of the window itself. I already know how to have my Allegro applications switch to fullscreen mode; I'm trying to improve the windowed mode.
A big reason for this is because my artstyle is low-resolution art (I call it "Bitmap Brothers" style); it's very good for games since it's organized and easy to edit. I don't want to have to go higher than 640x480 to increase the size because it's far to high for low-resolution art, but my window remains too small during windowed mode.
I noticed that Allegro 5.0.8 has this line of code:
al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);
At the end it says "ALLEGRO_RESIZABLE", could that be the feature I'm looking for? If so, just how much does Allegro change from 4.2 to 5+?
Allegro 4 doesn't support user-resizable windows.
Allegro 5 does (as you've noted), but it is completely rewritten and is not backward compatible at all. Still, I would highly recommend that you switch to it as development on Allegro 4 is all but dead.

Compiz and OpenGL window

I've written an OpenGL application in Linux through GLX. It uses double buffering with glXSwapBuffers and Sync to VBlank set via NVIDIA X Server Settings. I'm using Compiz and have smooth moving of windows and no tearing (Sync to VBlank enabled in Compiz settings).
But when I
Try to move or resize the OpenGL window or
Move other windows through the area occupied by the OpenGL window
the system stutters and freezes for 3-4 seconds. Moving other
windows outside the area occupied by the OpenGL window is smooth as always.
Moreover the problem only arises if the OpenGL application is in the
loop of producing frames of animation therefore swapping the buffers.
If the content is static and the application is not swapping the buffers there are no problems,moving the various windows is smooth.
Could be a synchronization issue between my application and Compiz?
I don't know if it's still in the same shape as a few years ago, but…
Your description matches very well a Compiz SNAFU. Every window resize triggers the recreation of a texture that will receive the window contents. Texture creation is a costly operation and hence should be avoided. Unfortunately the Compiz developers don't seems the brightest ones, because they did not realize there's an obvious solution to this problem: Windows in X11 can be reparented without much cost (every Window manager does this several times), it's called stacking. Compiz is a window manager.
So why doesn't Compiz keep a desktop sized window around into which it reparents those windows that are about to be resized, gets its constant sized window texture from there and after finishing the resize operation reparents the window into its decoration frame?
I don't know why this is the case. Anyway, some things Compiz does are not very smart.
If you want to fix this, well: Compiz is open source and I just described what to do.

SDL window management with OpenGL and DirectX

I'm porting a small graphics engine from DirectX 9 to OpenGL. The engine uses SDL (now ported to 2.0) to manage input and window creation.
I want to know how to correctly handle window events for both OpenGL and DirectX. I'm interested in these for Desktop platforms (linux, OSX and windows)
Window resolution change
Full screen to windowed / windowed to fullscreen handling
Alt+tab handling -
I've tried to search through the net but information is quite not focused in one place. I imagine many others faced the same problem before.
Are there any resources to read guidelines on that kind of handling for my engine?
Is it possible to handle resolution change without losing transfered resources to the renderer system in both OpenGL and DirectX?
Window resolution change
OpenGL itself requires no special treatment for this. Unfortunately SDL goes through a full window reinitialization, including the OpenGL context on a window size change, which means, that all OpenGL state objects (that is, textures, vertex buffers, shaders and so on) are lost.
This is however a limitation of SDL.
Personally I thus prefer GLFW for creating a OpenGL window and context. You can still use SDL for other things though (like audio, networking, image loading and such).
Full screen to windowed / windowed to fullscreen handling
The is effectively a window size change as well. See above.
Alt+tab handling -
OpenGL requires no special effort for this. Just minimize the window when Alt+Tab-ing out and stop the game loop. When the window gets restored just continue the game loop.