Skip to content

Commit 3e34cec

Browse files
committed
Merge pull request opencv#19408 from crackwitz:ogl-wndprop-vsync
2 parents 6ca46af + ab0e1c5 commit 3e34cec

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

modules/highgui/include/opencv2/highgui.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ enum WindowPropertyFlags {
202202
WND_PROP_ASPECT_RATIO = 2, //!< window's aspect ration (can be set to WINDOW_FREERATIO or WINDOW_KEEPRATIO).
203203
WND_PROP_OPENGL = 3, //!< opengl support.
204204
WND_PROP_VISIBLE = 4, //!< checks whether the window exists and is visible
205-
WND_PROP_TOPMOST = 5 //!< property to toggle normal window being topmost or not
205+
WND_PROP_TOPMOST = 5, //!< property to toggle normal window being topmost or not
206+
WND_PROP_VSYNC = 6 //!< enable or disable VSYNC (in OpenGL mode)
206207
};
207208

208209
//! Mouse Events see cv::MouseCallback

modules/highgui/src/precomp.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ double cvGetPropTopmost_COCOA(const char* name);
115115
void cvSetPropTopmost_W32(const char* name, const bool topmost);
116116
void cvSetPropTopmost_COCOA(const char* name, const bool topmost);
117117

118+
double cvGetPropVsync_W32(const char* name);
119+
void cvSetPropVsync_W32(const char* name, const bool enabled);
120+
118121
//for QT
119122
#if defined (HAVE_QT)
120123
CvRect cvGetWindowRect_QT(const char* name);

modules/highgui/src/window.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu
9292
#endif
9393
break;
9494

95+
case cv::WND_PROP_VSYNC:
96+
#if defined (HAVE_WIN32UI)
97+
cvSetPropVsync_W32(name, (prop_value != 0));
98+
#else
99+
// not implemented yet for other toolkits
100+
#endif
101+
break;
102+
95103
default:;
96104
}
97105
}
@@ -182,6 +190,14 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id)
182190
#endif
183191
break;
184192

193+
case cv::WND_PROP_VSYNC:
194+
#if defined (HAVE_WIN32UI)
195+
return cvGetPropVsync_W32(name);
196+
#else
197+
return -1;
198+
#endif
199+
break;
200+
185201
default:
186202
return -1;
187203
}

modules/highgui/src/window_w32.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,89 @@ void cvSetPropTopmost_W32(const char* name, const bool topmost)
596596
}
597597
}
598598

599+
double cvGetPropVsync_W32(const char* name)
600+
{
601+
#ifndef HAVE_OPENGL
602+
CV_UNUSED(name);
603+
CV_Error(Error::OpenGlNotSupported, "Library was built without OpenGL support");
604+
#else
605+
if (!name)
606+
CV_Error(Error::StsNullPtr, "'name' argument must not be NULL");
607+
608+
CvWindow* window = icvFindWindowByName(name);
609+
if (!window)
610+
CV_Error_(Error::StsBadArg, ("there is no window named '%s'", name));
611+
612+
// https://www.khronos.org/opengl/wiki/Swap_Interval
613+
// https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_extensions_string.txt
614+
// https://www.khronos.org/registry/OpenGL/extensions/EXT/WGL_EXT_swap_control.txt
615+
616+
if (!wglMakeCurrent(window->dc, window->hGLRC))
617+
CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context");
618+
619+
typedef const char* (APIENTRY* PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
620+
PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsString = NULL;
621+
wglGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
622+
if (wglGetExtensionsString == NULL)
623+
return -1; // wglGetProcAddress failed to get wglGetExtensionsStringEXT
624+
625+
const char* wgl_extensions = wglGetExtensionsString();
626+
if (wgl_extensions == NULL)
627+
return -1; // Can't get WGL extensions string
628+
629+
if (strstr(wgl_extensions, "WGL_EXT_swap_control") == NULL)
630+
return -1; // WGL extensions don't contain WGL_EXT_swap_control
631+
632+
typedef int (APIENTRY* PFNWGLGETSWAPINTERVALPROC)(void);
633+
PFNWGLGETSWAPINTERVALPROC wglGetSwapInterval = 0;
634+
wglGetSwapInterval = (PFNWGLGETSWAPINTERVALPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
635+
if (wglGetSwapInterval == NULL)
636+
return -1; // wglGetProcAddress failed to get wglGetSwapIntervalEXT
637+
638+
return wglGetSwapInterval();
639+
#endif
640+
}
641+
642+
void cvSetPropVsync_W32(const char* name, const bool enable_vsync)
643+
{
644+
#ifndef HAVE_OPENGL
645+
CV_UNUSED(name);
646+
CV_UNUSED(enable_vsync);
647+
CV_Error(Error::OpenGlNotSupported, "Library was built without OpenGL support");
648+
#else
649+
if (!name)
650+
CV_Error(Error::StsNullPtr, "'name' argument must not be NULL");
651+
652+
CvWindow* window = icvFindWindowByName(name);
653+
if (!window)
654+
CV_Error_(Error::StsBadArg, ("there is no window named '%s'", name));
655+
656+
if (!wglMakeCurrent(window->dc, window->hGLRC))
657+
CV_Error(Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context");
658+
659+
typedef const char* (APIENTRY* PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
660+
PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsString = NULL;
661+
wglGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
662+
if (wglGetExtensionsString == NULL)
663+
CV_Error(Error::OpenGlApiCallError, "wglGetProcAddress failed to get wglGetExtensionsStringEXT");
664+
665+
const char* wgl_extensions = wglGetExtensionsString();
666+
if (wgl_extensions == NULL)
667+
CV_Error(Error::OpenGlApiCallError, "Can't get WGL extensions string");
668+
669+
if (strstr(wgl_extensions, "WGL_EXT_swap_control") == NULL)
670+
CV_Error(Error::OpenGlApiCallError, "WGL extensions don't contain WGL_EXT_swap_control");
671+
672+
typedef BOOL(APIENTRY* PFNWGLSWAPINTERVALPROC)(int);
673+
PFNWGLSWAPINTERVALPROC wglSwapInterval = 0;
674+
wglSwapInterval = (PFNWGLSWAPINTERVALPROC)wglGetProcAddress("wglSwapIntervalEXT");
675+
if (wglSwapInterval == NULL)
676+
CV_Error(Error::OpenGlApiCallError, "wglGetProcAddress failed to get wglSwapIntervalEXT");
677+
678+
wglSwapInterval(enable_vsync);
679+
#endif
680+
}
681+
599682
void cv::setWindowTitle(const String& winname, const String& title)
600683
{
601684
CvWindow* window = icvFindWindowByName(winname.c_str());

0 commit comments

Comments
 (0)