Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Support OpenGL GTK3 New API#25822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
asmorkalov merged 10 commits intoopencv:4.xfrommqcmd196:gtk3-gl-support
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
[GTK3][OpenGL] Support OpenGL GTK3 new API with test codes
  • Loading branch information
@mqcmd196
mqcmd196 committedJul 5, 2024
commitb42405a42e04d8567e6084cc1d70bf333f527ad3
7 changes: 6 additions & 1 deletionCMakeLists.txt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1464,9 +1464,14 @@ if(WITH_GTK OR HAVE_GTK)
else()
status(" GTK+:" "NO")
endif()

if(HAVE_GTK)
status( " GThread :" HAVE_GTHREAD THEN "YES (ver ${GTHREAD_VERSION})" ELSE NO)
status( " GtkGlExt:" HAVE_GTKGLEXT THEN "YES (ver ${GTKGLEXT_VERSION})" ELSE NO)
if(HAVE_GTK3)
status( " Epoxy:" HAVE_EPOXY THEN "YES (ver ${EPOXY_VERSION})" ELSE NO)
else()
status( " GtkGlExt:" HAVE_GTKGLEXT THEN "YES (ver ${GTKGLEXT_VERSION})" ELSE NO)
endif()
endif()
endif()

Expand Down
2 changes: 1 addition & 1 deletioncmake/OpenCVFindLibsGUI.cmake
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -62,7 +62,7 @@ endif()
# --- OpenGl ---
ocv_clear_vars(HAVE_OPENGL HAVE_QT_OPENGL)
if(WITH_OPENGL)
if(WITH_WIN32UI OR (HAVE_QT AND QT_QTOPENGL_FOUND) OR HAVE_GTKGLEXT)
if(WITH_WIN32UI OR (HAVE_QT AND QT_QTOPENGL_FOUND) OR(HAVE_GTK3 AND HAVE_EPOXY) OR (HAVE_GTK AND NOT HAVE_GTK3 ANDHAVE_GTKGLEXT))
find_package (OpenGL QUIET)
if(OPENGL_FOUND)
set(HAVE_OPENGL TRUE)
Expand Down
2 changes: 1 addition & 1 deletionmodules/core/include/opencv2/core/opengl.hpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ This section describes OpenGL interoperability.

To enable OpenGL support, configure OpenCV using CMake with WITH_OPENGL=ON . Currently OpenGL is
supported only with WIN32, GTK and Qt backends on Windows and Linux (MacOS and Android are not
supported). For GTK backend gtkglext-1.0 library is required.
supported). For GTK-2.0 backend gtkglext-1.0 library is required. For GTK-3+ backend liepoxy is required.

To use OpenGL functionality you should first create OpenGL context (window or frame buffer). You can
do this with namedWindow function or with other OpenGL toolkit (GLUT, for example).
Expand Down
8 changes: 8 additions & 0 deletionsmodules/highgui/CMakeLists.txt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -218,6 +218,10 @@ if(TARGET ocv.3rdparty.gtk3 OR TARGET ocv.3rdparty.gtk2)
)
if(__gtk_dependency STREQUAL "ocv.3rdparty.gtk3")
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK3")
if(OPENGL_LIBRARIES)
list(APPEND HIGHGUI_LIBRARIES "${OPENGL_LIBRARIES}")
list(APPEND HIGHGUI_LIBRARIES "${EPOXY_LIBRARIES}")
endif()
elseif(__gtk_dependency STREQUAL "ocv.3rdparty.gtk2")
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK2")
else()
Expand DownExpand Up@@ -323,6 +327,10 @@ if(HIGHGUI_ENABLE_PLUGINS)
ocv_target_compile_definitions(${the_module} PRIVATE ENABLE_PLUGINS)
if(TARGET opencv_test_highgui)
ocv_target_compile_definitions(opencv_test_highgui PRIVATE ENABLE_PLUGINS)
if(OPENGL_LIBRARIES)
ocv_target_link_libraries(opencv_test_highgui ${OPENGL_LIBRARIES})
ocv_target_link_libraries(opencv_test_highgui ${EPOXY_LIBRARIES})
endif()
endif()
endif()

Expand Down
35 changes: 22 additions & 13 deletionsmodules/highgui/cmake/detect_gtk.cmake
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,25 +26,34 @@ if(WITH_GTK)
else()
ocv_add_external_target(gthread "${GTHREAD_INCLUDE_DIRS}" "${GTHREAD_LIBRARIES}" "HAVE_GTHREAD")
endif()
if((WITH_OPENGL OR HAVE_OPENGL) AND HAVE_GTK2)
ocv_check_modules(GTKGLEXT gtkglext-1.0)
if(HAVE_GTKGLEXT)
# HACK for https://github.com/opencv/opencv/issues/20850
# pkg-config reports some include directories that do not exist. Just filter them out.
set(GTKGLEXT_INCLUDE_DIRS_EXISTS "")
foreach(p ${GTKGLEXT_INCLUDE_DIRS})
if (EXISTS "${p}")
list(APPEND GTKGLEXT_INCLUDE_DIRS_EXISTS "${p}")
endif()
endforeach()
ocv_add_external_target(gtkglext "${GTKGLEXT_INCLUDE_DIRS_EXISTS}" "${GTKGLEXT_LIBRARIES}" "HAVE_GTKGLEXT")
if((WITH_OPENGL OR HAVE_OPENGL) AND (HAVE_GTK2 OR HAVE_GTK3))
if(HAVE_GTK2)
ocv_check_modules(GTKGLEXT gtkglext-1.0)
if(HAVE_GTKGLEXT)
# HACK for https://github.com/opencv/opencv/issues/20850
# pkg-config reports some include directories that do not exist. Just filter them out.
set(GTKGLEXT_INCLUDE_DIRS_EXISTS "")
foreach(p ${GTKGLEXT_INCLUDE_DIRS})
if (EXISTS "${p}")
list(APPEND GTKGLEXT_INCLUDE_DIRS_EXISTS "${p}")
endif()
endforeach()
ocv_add_external_target(gtkglext "${GTKGLEXT_INCLUDE_DIRS}" "${GTKGLEXT_LIBRARIES}" "HAVE_GTKGLEXT")
endif()
endif()
if(HAVE_GTK3)
ocv_check_modules(EPOXY epoxy)
message(STATUS "obidbg EPOXY_INCLUDE_DIRS: ${EPOXY_INCLUDE_DIRS}")
if(HAVE_EPOXY)
ocv_add_external_target(epoxy "${EPOXY_INCLUDE_DIRS}" "${EPOXY_LIBRARIES}" "HAVE_EPOXY")
endif()
endif()
endif()
elseif(HAVE_GTK)
ocv_add_external_target(gtk "${GTK_INCLUDE_DIRS}" "${GTK_LIBRARIES}" "${GTK_DEFINES};HAVE_GTK")
endif()

if(WITH_OPENGL AND HAVE_GTKGLEXT)
if(WITH_OPENGL)
find_package(OpenGL QUIET)
if(OPENGL_FOUND)
set(HAVE_OPENGL TRUE)
Expand Down
109 changes: 97 additions & 12 deletionsmodules/highgui/src/window_gtk.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -46,10 +46,7 @@

#include <gtk/gtk.h>

#if (GTK_MAJOR_VERSION == 3) && defined(HAVE_OPENGL)
#undef HAVE_OPENGL // no support with GTK3
#endif
#if defined(HAVE_OPENGL) && !defined(HAVE_GTKGLEXT)
#if (GTK_MAJOR_VERSION == 2) && defined(HAVE_OPENGL) && !defined(HAVE_GTKGLEXT)
#undef HAVE_OPENGL // gtkglext is required
#endif

Expand All@@ -68,9 +65,14 @@
#endif

#ifdef HAVE_OPENGL
#ifdef GTK_VERSION3
#include <gtk/gtkglarea.h>
#include <epoxy/gl.h>
#else
#include <gtk/gtkgl.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include <GL/gl.h>
#endif

#include <opencv2/core/utils/logger.hpp>
Expand DownExpand Up@@ -570,7 +572,7 @@ struct CvWindow : CvUIBase
last_key(0), flags(0), status(0),
on_mouse(NULL), on_mouse_param(NULL)
#ifdef HAVE_OPENGL
,useGl(false), glDrawCallback(NULL), glDrawData(NULL)
,useGl(false), glDrawCallback(NULL), glDrawData(NULL), glArea(NULL)
#endif
{
CV_LOG_INFO(NULL, "OpenCV/UI: creating GTK window: " << window_name);
Expand All@@ -597,6 +599,7 @@ struct CvWindow : CvUIBase

CvOpenGlDrawCallback glDrawCallback;
void* glDrawData;
GtkWidget* glArea;
#endif
};

Expand DownExpand Up@@ -640,7 +643,7 @@ CV_IMPL int cvInitSystem( int argc, char** argv )

setlocale(LC_NUMERIC,"C");

#ifdefHAVE_OPENGL
#if defined(HAVE_OPENGL) && not defined(GTK_VERSION3) // GTK3+ uses GtkGLArea so no need to check for GtkGLExt
if (!gtk_gl_init_check(&argc, &argv))
{
hasError = true;
Expand DownExpand Up@@ -907,11 +910,40 @@ double cvGetOpenGlProp_GTK(const char* name)
// OpenGL support

#ifdef HAVE_OPENGL

namespace
{

#ifdef GTK_VERSION3

void glRealizeCallback(GtkGLArea* area, gpointer user_data){
gtk_gl_area_make_current(area);
if (gtk_gl_area_get_error(area) != NULL)
CV_Error(cv::Error::OpenGlApiCallError, "OpenGL context is not initialized");
}

gboolean glRenderCallback(GtkGLArea* area, GdkGLContext* context, gpointer user_data){
CvWindow* window = (CvWindow*)user_data;
gtk_gl_area_make_current(area);
if (gtk_gl_area_get_error(area) != NULL) {
CV_Error(cv::Error::OpenGlApiCallError, "OpenGL context is not initialized");
return FALSE;
}
if(window->glDrawCallback) {
window->glDrawCallback(window->glDrawData);
}
// gtk_gl_area_queue_render(area);
return TRUE;
}

#endif

void createGlContext(CvWindow* window)
{
#ifdef GTK_VERSION3
g_signal_connect(window->glArea, "realize", G_CALLBACK(glRealizeCallback), window);
g_signal_connect(window->glArea, "render", G_CALLBACK(glRenderCallback), window);
#else

GdkGLConfig* glconfig;

// Try double-buffered visual
Expand All@@ -923,11 +955,24 @@ namespace
if (!gtk_widget_set_gl_capability(window->widget, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE))
CV_Error( cv::Error::OpenGlApiCallError, "Can't Create A GL Device Context" );

#endif

window->useGl = true;
}

void drawGl(CvWindow* window)
{
#ifdef GTK_VERSION3

GtkGLArea* gtkGlArea = GTK_GL_AREA(window->glArea);
if (gtk_gl_area_get_error(gtkGlArea) != NULL)
CV_Error(cv::Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context");

if (window->glDrawCallback)
window->glDrawCallback(window->glDrawData);

#else

GdkGLContext* glcontext = gtk_widget_get_gl_context(window->widget);
GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(window->widget);

Expand All@@ -947,6 +992,8 @@ namespace
glFlush();

gdk_gl_drawable_gl_end(gldrawable);

#endif
}
}

Expand DownExpand Up@@ -1041,12 +1088,27 @@ static std::shared_ptr<CvWindow> namedWindow_(const std::string& name, int flags

window->frame = gtk_window_new( GTK_WINDOW_TOPLEVEL );

window->paned = gtk_vbox_new( FALSE, 0 );
window->widget = cvImageWidgetNew( flags );

#if defined(HAVE_OPENGL) && defined(GTK_VERSION3)
if (flags & cv::WINDOW_OPENGL) {
window->glArea = gtk_gl_area_new();
gtk_container_add(GTK_CONTAINER(window->frame), window->glArea);
gtk_widget_show(window->glArea);
} else {
window->paned = gtk_vbox_new( FALSE, 0 );
gtk_box_pack_end( GTK_BOX(window->paned), window->widget, TRUE, TRUE, 0 );
gtk_widget_show( window->widget );
gtk_container_add( GTK_CONTAINER(window->frame), window->paned );
gtk_widget_show( window->paned );
}
#else
window->paned = gtk_vbox_new( FALSE, 0 );
gtk_box_pack_end( GTK_BOX(window->paned), window->widget, TRUE, TRUE, 0 );
gtk_widget_show( window->widget );
gtk_container_add( GTK_CONTAINER(window->frame), window->paned );
gtk_widget_show( window->paned );
#endif

#ifndef HAVE_OPENGL
if (flags & cv::WINDOW_OPENGL)
Expand DownExpand Up@@ -1122,9 +1184,6 @@ static std::shared_ptr<CvWindow> namedWindow_(const std::string& name, int flags

CV_IMPL void cvSetOpenGlContext(const char* name)
{
GdkGLContext* glcontext;
GdkGLDrawable* gldrawable;

CV_Assert(name && "NULL name string");

CV_LOCK_MUTEX();
Expand All@@ -1136,11 +1195,24 @@ CV_IMPL void cvSetOpenGlContext(const char* name)
if (!window->useGl)
CV_Error( cv::Error::OpenGlNotSupported, "Window doesn't support OpenGL" );

#ifdef GTK_VERSION3

if(gtk_gl_area_get_error(GTK_GL_AREA(window->glArea)) != NULL)
CV_Error( cv::Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context");

#else

GdkGLContext* glcontext;
GdkGLDrawable* gldrawable;

glcontext = gtk_widget_get_gl_context(window->widget);
gldrawable = gtk_widget_get_gl_drawable(window->widget);

if (!gdk_gl_drawable_make_current(gldrawable, glcontext))
CV_Error( cv::Error::OpenGlApiCallError, "Can't Activate The GL Rendering Context" );

#endif

}

CV_IMPL void cvUpdateWindow(const char* name)
Expand All@@ -1154,7 +1226,20 @@ CV_IMPL void cvUpdateWindow(const char* name)
return;

// window does not refresh without this
#ifdef GTK_VERSION3

if ( GTK_IS_GL_AREA(window->glArea) ){
gtk_gl_area_queue_render(GTK_GL_AREA(window->glArea));
} else {
gtk_widget_queue_draw( GTK_WIDGET(window->widget));
}

#else

gtk_widget_queue_draw( GTK_WIDGET(window->widget) );

#endif

}

CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback callback, void* userdata)
Expand Down
75 changes: 73 additions & 2 deletionsmodules/highgui/test/test_gui.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -253,6 +253,77 @@ TEST(Highgui_GUI, currentUIFramework)
EXPECT_GT(framework.size(), 0); // builtin backends
#endif
}


#if (!defined(ENABLE_PLUGINS) \
&& !defined HAVE_GTK \
&& !defined HAVE_QT \
&& !defined HAVE_WIN32UI \
&& !defined HAVE_COCOA \
&& !defined HAVE_WAYLAND \
) || !defined(HAVE_OPENGL)
TEST(Highgui_GUI, DISABLED_gl)
#else
#include<epoxy/gl.h>
#include<GL/gl.h>
static GLuint create_shader(const char* source, GLenum type) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
return shader;
}
struct DrawData
{
GLuint vao, vbo, program;
};
void draw(void* userdata){
DrawData* data = static_cast<DrawData*>(userdata);
glBindVertexArray(data->vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
}
TEST(Highgui_GUI, gl)
#endif
{
const std::string window_name("gl_test_window");
const Size image_size(800, 600);
EXPECT_NO_THROW(destroyAllWindows());
ASSERT_NO_THROW(namedWindow(window_name, WINDOW_OPENGL));
ASSERT_NO_THROW(resizeWindow(window_name, image_size));
DrawData data;
const char *vertex_shader_source =
"#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
"}\n";
const char *fragment_shader_source =
"#version 330 core\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(1.0, 1.0, 1.0, 1.0); // white\n"
"}\n";
GLuint vertex_shader = create_shader(vertex_shader_source, GL_VERTEX_SHADER);
GLuint fragment_shader = create_shader(fragment_shader_source, GL_FRAGMENT_SHADER);
data.program = glCreateProgram();
glAttachShader(data.program, vertex_shader);
glAttachShader(data.program, fragment_shader);
glLinkProgram(data.program);
glUseProgram(data.program);
GLfloat vertices[] = {
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
glGenVertexArrays(1, &data.vao);
glBindVertexArray(data.vao);
glGenBuffers(1, &data.vbo);
glBindBuffer(GL_ARRAY_BUFFER, data.vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
ASSERT_NO_THROW(setOpenGlDrawCallback(window_name, draw, &data));
EXPECT_NO_THROW(waitKey(10000));
EXPECT_NO_THROW(setOpenGlDrawCallback(window_name, 0));
EXPECT_NO_THROW(destroyAllWindows());
}
}} // namespace

[8]ページ先頭

©2009-2025 Movatter.jp