瀏覽代碼

vsync support

-works on windows
-may not work on X11, if so please fix
-OSX does not seem to support disabling vsync
Juan Linietsky 9 年之前
父節點
當前提交
2420e46b44

+ 11 - 0
core/bind/core_bind.cpp

@@ -436,6 +436,15 @@ Error _OS::set_thread_name(const String& p_name) {
 	return Thread::set_name(p_name);
 };
 
+void _OS::set_use_vsync(bool p_enable) {
+	OS::get_singleton()->set_use_vsync(p_enable);
+}
+
+bool _OS::is_vsnc_enabled() const {
+
+	return OS::get_singleton()->is_vsnc_enabled();
+}
+
 
 /*
 enum Weekday {
@@ -1110,6 +1119,8 @@ void _OS::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("set_thread_name","name"),&_OS::set_thread_name);
 
+	ObjectTypeDB::bind_method(_MD("set_use_vsync","enable"),&_OS::set_use_vsync);
+	ObjectTypeDB::bind_method(_MD("is_vsnc_enabled"),&_OS::is_vsnc_enabled);
 
 	BIND_CONSTANT( DAY_SUNDAY );
 	BIND_CONSTANT( DAY_MONDAY );

+ 3 - 0
core/bind/core_bind.h

@@ -282,6 +282,9 @@ public:
 
 	Error set_thread_name(const String& p_name);
 
+	void set_use_vsync(bool p_enable);
+	bool is_vsnc_enabled() const;
+
 	static _OS *get_singleton() { return singleton; }
 
 	_OS();

+ 8 - 0
core/os/os.cpp

@@ -539,6 +539,14 @@ String OS::get_joy_guid(int p_device) const {
 void OS::set_context(int p_context) {
 
 }
+void OS::set_use_vsync(bool p_enable) {
+
+}
+
+bool OS::is_vsnc_enabled() const{
+
+	return true;
+}
 
 OS::OS() {
 	last_error=NULL;

+ 3 - 0
core/os/os.h

@@ -420,6 +420,9 @@ public:
 
 	virtual void set_context(int p_context);
 
+	virtual void set_use_vsync(bool p_enable);
+	virtual bool is_vsnc_enabled() const;
+
 	bool is_hidpi_allowed() const { return _allow_hidpi; }
 	OS();
 	virtual ~OS();

+ 5 - 1
drivers/gl_context/context_gl.h

@@ -52,7 +52,11 @@ public:
 	virtual void swap_buffers()=0;
 	
 	virtual Error initialize()=0;
-	
+
+	virtual void set_use_vsync(bool p_use)=0;
+	virtual bool is_using_vsync() const=0;
+
+
 	
 	
 	ContextGL();	

+ 3 - 0
main/main.cpp

@@ -109,6 +109,7 @@ static String locale;
 static bool use_debug_profiler=false;
 static bool force_lowdpi=false;
 static int init_screen=-1;
+static bool use_vsync=true;
 
 static String unescape_cmdline(const String& p_str) {
 
@@ -726,6 +727,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 	GLOBAL_DEF("display/fullscreen",video_mode.fullscreen);
 	GLOBAL_DEF("display/resizable",video_mode.resizable);
 	GLOBAL_DEF("display/borderless_window", video_mode.borderless_window);
+	use_vsync = GLOBAL_DEF("display/use_vsync", use_vsync);
 	GLOBAL_DEF("display/test_width",0);
 	GLOBAL_DEF("display/test_height",0);
 	OS::get_singleton()->_pixel_snap=GLOBAL_DEF("display/use_2d_pixel_snap",false);
@@ -876,6 +878,7 @@ Error Main::setup2() {
 		OS::get_singleton()->set_window_position(init_custom_pos);
 	}
 
+	OS::get_singleton()->set_use_vsync(use_vsync);
 
 	register_core_singletons();
 

+ 16 - 1
platform/windows/context_gl_win.cpp

@@ -96,6 +96,20 @@ static GLWrapperFuncPtr wrapper_get_proc_address(const char* p_function) {
 }
 */
 
+void ContextGL_Win::set_use_vsync(bool p_use) {
+
+	if (wglSwapIntervalEXT) {
+		wglSwapIntervalEXT(p_use?1:0);
+	}
+	use_vsync=p_use;
+
+}
+
+bool ContextGL_Win::is_using_vsync() const {
+
+	return use_vsync;
+}
+
 
 Error ContextGL_Win::initialize() {
 
@@ -184,7 +198,7 @@ Error ContextGL_Win::initialize() {
 		printf("Activated GL 3.1 context");
 	}
 
-
+	wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)  wglGetProcAddress ("wglSwapIntervalEXT");
 //	glWrapperInit(wrapper_get_proc_address);
 
 	return OK;
@@ -194,6 +208,7 @@ ContextGL_Win::ContextGL_Win(HWND hwnd,bool p_opengl_3_context) {
 
 	opengl_3_context=p_opengl_3_context;
 	hWnd=hwnd;
+	use_vsync=false;
 }
 
 ContextGL_Win::~ContextGL_Win() {

+ 8 - 0
platform/windows/context_gl_win.h

@@ -49,6 +49,8 @@
 
 #include <windows.h>
 
+typedef bool (APIENTRY *PFNWGLSWAPINTERVALEXTPROC) (int interval);
+
 class ContextGL_Win : public ContextGL {
 
 	HDC hDC;
@@ -56,6 +58,10 @@ class ContextGL_Win : public ContextGL {
 	unsigned int pixel_format;
 	HWND hWnd;
 	bool opengl_3_context;
+	bool use_vsync;
+
+
+	PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
 public:
 
 
@@ -69,6 +75,8 @@ public:
 
 	virtual Error initialize();
 
+	virtual void set_use_vsync(bool p_use);
+	virtual bool is_using_vsync() const;
 
 	ContextGL_Win(HWND hwnd,bool p_opengl_3_context);
 	~ContextGL_Win();

+ 15 - 0
platform/windows/os_windows.cpp

@@ -2269,6 +2269,21 @@ String OS_Windows::get_joy_guid(int p_device) const {
 	return input->get_joy_guid_remapped(p_device);
 }
 
+void OS_Windows::set_use_vsync(bool p_enable) {
+
+	if (gl_context)
+		gl_context->set_use_vsync(p_enable);
+}
+
+bool OS_Windows::is_vsnc_enabled() const{
+
+	if (gl_context)
+		return gl_context->is_using_vsync();
+
+	return true;
+}
+
+
 OS_Windows::OS_Windows(HINSTANCE _hInstance) {
 
 	key_event_pos=0;

+ 3 - 0
platform/windows/os_windows.h

@@ -283,6 +283,9 @@ public:
 	virtual bool is_joy_known(int p_device);
 	virtual String get_joy_guid(int p_device) const;
 
+	virtual void set_use_vsync(bool p_enable);
+	virtual bool is_vsnc_enabled() const;
+
 	OS_Windows(HINSTANCE _hInstance);
 	~OS_Windows();
 

+ 11 - 0
platform/x11/context_gl_x11.cpp

@@ -176,6 +176,16 @@ int ContextGL_X11::get_window_height() {
 	return xwa.height;
 }
 
+void ContextGL_X11::set_use_vsync(bool p_use) {
+	GLXDrawable drawable = glXGetCurrentDrawable();
+	glXSwapIntervalEXT(x11_display, drawable, p_use?1:0);
+	use_vsync=p_use;
+}
+bool ContextGL_X11::is_using_vsync() const {
+
+	return use_vsync;
+}
+
 
 ContextGL_X11::ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context) : x11_window(p_x11_window) {
 
@@ -189,6 +199,7 @@ ContextGL_X11::ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,con
 	glx_minor=glx_major=0;
 	p = memnew( ContextGL_X11_Private );
 	p->glx_context=0;
+	use_vsync=false;
 }
 
 

+ 4 - 0
platform/x11/context_gl_x11.h

@@ -55,6 +55,7 @@ class ContextGL_X11 : public ContextGL {
 	bool direct_render;
 	int glx_minor,glx_major;
 	bool opengl_3_context;
+	bool use_vsync;
 public:
 
 	virtual void release_current();
@@ -65,6 +66,9 @@ public:
 
 	virtual Error initialize();
 
+	virtual void set_use_vsync(bool p_use);
+	virtual bool is_using_vsync() const;
+
 	ContextGL_X11(::Display *p_x11_display,::Window &p_x11_window,const OS::VideoMode& p_default_video_mode,bool p_opengl_3_context);
 	~ContextGL_X11();
 

+ 14 - 0
platform/x11/os_x11.cpp

@@ -1952,6 +1952,20 @@ String OS_X11::get_joy_guid(int p_device) const {
 	return input->get_joy_guid_remapped(p_device);
 }
 
+void OS_X11::set_use_vsync(bool p_enable) {
+	if (context_gl)
+		return context_gl->set_use_vsync(p_enable);
+}
+
+bool OS_X11::is_vsnc_enabled() const {
+
+	if (context_gl)
+		return context_gl->is_using_vsync();
+
+	return true;
+}
+
+
 void OS_X11::set_context(int p_context) {
 
 	XClassHint* classHint = NULL;

+ 3 - 0
platform/x11/os_x11.h

@@ -240,6 +240,9 @@ public:
 
 	virtual void set_context(int p_context);
 
+	virtual void set_use_vsync(bool p_enable);
+	virtual bool is_vsnc_enabled() const;
+
 	void run();
 
 	OS_X11();