From 0403746636e4873c690de7f6823069c5954ee743 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Mon, 28 Nov 2011 12:35:05 +0000 Subject: [PATCH] implemented addTextOpenGl under Gtk --- modules/highgui/src/window_gtk.cpp | 269 +++++++++++++++++++++++++++-- modules/highgui/src/window_w32.cpp | 4 +- 2 files changed, 256 insertions(+), 17 deletions(-) diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp index 94a8fe4ef1..417bb823b3 100644 --- a/modules/highgui/src/window_gtk.cpp +++ b/modules/highgui/src/window_gtk.cpp @@ -398,6 +398,217 @@ typedef struct CvTrackbar } CvTrackbar; + + + +// OpenGL support + +#ifdef HAVE_OPENGL + +namespace +{ + class OpenGlFont + { + public: + OpenGlFont(const std::string& fontName, int fontHeight, int fontWeight, int fontStyle); + ~OpenGlFont(); + + void draw(const char* str, int len, CvPoint org, CvScalar color, int width, int height) const; + + inline const std::string& fontName() const { return fontName_; } + inline int fontHeight() const { return fontHeight_; } + inline int fontWeight() const { return fontWeight_; } + inline int fontStyle() const { return fontStyle_; } + + private: + std::string fontName_; + int fontHeight_; + int fontWeight_; + int fontStyle_; + + GLuint base_; + + OpenGlFont(const OpenGlFont&); + OpenGlFont& operator =(const OpenGlFont&); + }; + + PangoWeight getFontWidthPango(int fontWeight) + { + PangoWeight weight; + + switch(fontWeight) + { + case CV_FONT_LIGHT: + weight = PANGO_WEIGHT_LIGHT; + break; + case CV_FONT_NORMAL: + weight = PANGO_WEIGHT_NORMAL; + break; + case CV_FONT_DEMIBOLD: + weight = PANGO_WEIGHT_SEMIBOLD; + break; + case CV_FONT_BOLD: + weight = PANGO_WEIGHT_BOLD; + break; + case CV_FONT_BLACK: + weight = PANGO_WEIGHT_ULTRABOLD; + break; + default: + cvError(CV_StsBadArg, "getFontWidthPango", "Unsopported font width", __FILE__, __LINE__); + }; + + return weight; + } + + OpenGlFont::OpenGlFont(const std::string& fontName, int fontHeight, int fontWeight, int fontStyle) + : fontName_(), fontHeight_(0), fontWeight_(0), fontStyle_(0), base_(0) + { + base_ = glGenLists(96); + + PangoFontDescription* fontDecr = pango_font_description_new(); + + pango_font_description_set_size(fontDecr, fontHeight); + + pango_font_description_set_family_static(fontDecr, fontName.c_str()); + + pango_font_description_set_weight(fontDecr, getFontWidthPango(fontWeight)); + + PangoStyle pangoStyle = fontStyle & CV_STYLE_ITALIC ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL; + pango_font_description_set_style(fontDecr, pangoStyle); + + PangoFont* pangoFont = gdk_gl_font_use_pango_font(fontDecr, 32, 96, base_); + + if (!pangoFont) + cvError(CV_OpenGlApiCallError, "OpenGlFont", "Can't create font", __FILE__, __LINE__); + + pango_font_description_free(fontDecr); + + fontName_ = fontName; + fontHeight_ = fontHeight; + fontWeight_ = fontWeight; + fontStyle_ = fontStyle; + } + + OpenGlFont::~OpenGlFont() + { + if (base_) + glDeleteLists(base_, 96); + } + + void OpenGlFont::draw(const char* str, int len, CvPoint org, CvScalar color, int width, int height) const + { + if (base_) + { + glPushAttrib(GL_LIST_BIT); + glListBase(base_ - 32); + + glColor4dv(color.val); + glRasterPos2f(static_cast(org.x) / width, static_cast((org.y + fontHeight_)) / height); + glCallLists(len, GL_UNSIGNED_BYTE, str); + + glPopAttrib(); + + CV_CheckGlError(); + } + } + + class OpenGlText + { + public: + OpenGlText(); + + void add(const std::string& text, CvPoint org, CvScalar color, const std::string& fontName, int fontHeight, int fontWeight, int fontStyle); + inline void clear() { text_.clear(); } + + void draw(int width, int height) const; + + private: + struct Text + { + std::string str; + + CvPoint org; + CvScalar color; + + cv::Ptr font; + }; + + std::vector< cv::Ptr > fonts_; + + std::vector text_; + }; + + OpenGlText::OpenGlText() + { + fonts_.reserve(5); + text_.reserve(5); + } + + class FontCompare : public std::unary_function, bool> + { + public: + inline FontCompare(const std::string& fontName, int fontHeight, int fontWeight, int fontStyle) + : fontName_(fontName), fontHeight_(fontHeight), fontWeight_(fontWeight), fontStyle_(fontStyle) + { + } + + bool operator ()(const cv::Ptr& font) + { + return font->fontName() == fontName_ && font->fontHeight() == fontHeight_ && font->fontWeight() == fontWeight_ && font->fontStyle() == fontStyle_; + } + + private: + std::string fontName_; + int fontHeight_; + int fontWeight_; + int fontStyle_; + }; + + void OpenGlText::add(const std::string& str, CvPoint org, CvScalar color, const std::string& fontName, int fontHeight, int fontWeight, int fontStyle) + { + std::vector< cv::Ptr >::iterator fontIt = + std::find_if(fonts_.begin(), fonts_.end(), FontCompare(fontName, fontHeight, fontWeight, fontStyle)); + + if (fontIt == fonts_.end()) + { + fonts_.push_back(new OpenGlFont(fontName, fontHeight, fontWeight, fontStyle)); + fontIt = fonts_.end() - 1; + } + + Text text; + text.str = str; + text.org = org; + text.color = color; + text.font = *fontIt; + + text_.push_back(text); + } + + void OpenGlText::draw(int width, int height) const + { + glDisable(GL_DEPTH_TEST); + + static cv::gpu::GlCamera glCamera; + glCamera.setupProjectionMatrix(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + for (size_t i = 0, size = text_.size(); i < size; ++i) + { + const Text& text = text_[i]; + text.font->draw(text.str.c_str(), text.str.length(), text.org, text.color, width, height); + } + } +} + +#endif // HAVE_OPENGL + + + + + + typedef struct CvWindow { int signature; @@ -431,6 +642,8 @@ typedef struct CvWindow CvOpenGlCleanCallback glCleanCallback; void* glCleanData; + + OpenGlText* glText; #endif } CvWindow; @@ -944,6 +1157,9 @@ namespace CV_CheckGlError(); + if (window->glText) + window->glText->draw(window->widget->allocation.width, window->widget->allocation.height); + if (gdk_gl_drawable_is_double_buffered (gldrawable)) gdk_gl_drawable_swap_buffers(gldrawable); else @@ -1058,6 +1274,14 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) #else if (flags & CV_WINDOW_OPENGL) createGlContext(window); + + window->glDrawCallback = 0; + window->glDrawData = 0; + + window->glCleanCallback = 0; + window->glCleanData = 0; + + window->glText = 0; #endif // @@ -1144,15 +1368,17 @@ CV_IMPL void cvSetOpenGlContext(const char* name) CV_IMPL void cvAddTextOpenGl(const char* name, const char* text, CvPoint org, CvScalar color, const char* fontName, int fontHeight, int fontWeight, int fontStyle) { + CvWindow* window; + GdkGLContext* glcontext; + GdkGLDrawable* gldrawable; + CV_FUNCNAME( "cvAddTextOpenGl" ); - __BEGIN__; + /*__BEGIN__; CV_ERROR( CV_OpenGlNotSupported, "Not Implemented" ); - __END__; + __END__;*/ - /*__BEGIN__; - - CvWindow* window; + __BEGIN__; if(!name) CV_ERROR( CV_StsNullPtr, "NULL name string" ); @@ -1164,28 +1390,35 @@ CV_IMPL void cvAddTextOpenGl(const char* name, const char* text, CvPoint org, Cv if (!window->useGl) CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); - if (!wglMakeCurrent(window->dc, window->hGLRC)) + 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_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); if (!window->glText) - window->glText = new OpenGlText(window->dc); + window->glText = new OpenGlText; window->glText->add(text, org, color, fontName, fontHeight, fontWeight, fontStyle); - InvalidateRect(window->hwnd, 0, 0); + gtk_widget_queue_draw( GTK_WIDGET(window->widget) ); - __END__;*/ + __END__; } CV_IMPL void cvClearTextOpenGl(const char* name) { + CvWindow* window; + GdkGLContext* glcontext; + GdkGLDrawable* gldrawable; + CV_FUNCNAME( "cvClearTextOpenGl" ); - __BEGIN__; + /*__BEGIN__; CV_ERROR( CV_OpenGlNotSupported, "Not Implemented" ); - __END__; + __END__;*/ - /*__BEGIN__; + __BEGIN__; CvWindow* window; @@ -1199,16 +1432,19 @@ CV_IMPL void cvClearTextOpenGl(const char* name) if (!window->useGl) CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" ); - if (!wglMakeCurrent(window->dc, window->hGLRC)) + 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_OpenGlApiCallError, "Can't Activate The GL Rendering Context" ); if (window->glText) { window->glText->clear(); - InvalidateRect(window->hwnd, 0, 0); + gtk_widget_queue_draw( GTK_WIDGET(window->widget) ); } - __END__;*/ + __END__; } CV_IMPL void cvUpdateWindow(const char* name) @@ -1306,6 +1542,9 @@ static void icvDeleteWindow( CvWindow* window ) GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(window->widget); gdk_gl_drawable_make_current(gldrawable, glcontext); + + if (window->glText) + delete window->glText; if (window->glCleanCallback) { diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp index e6afcc300e..0572dc5cba 100644 --- a/modules/highgui/src/window_w32.cpp +++ b/modules/highgui/src/window_w32.cpp @@ -190,7 +190,7 @@ namespace weight = FW_BLACK; break; default: - cvError(CV_StsBadArg, "getFontWidthW32", "Unsopported fonr width", __FILE__, __LINE__); + cvError(CV_StsBadArg, "getFontWidthW32", "Unsopported font width", __FILE__, __LINE__); }; return weight; @@ -222,7 +222,7 @@ namespace SelectObject(hDC, font); if (!wglUseFontBitmaps(hDC, 32, 96, base_)) - cvError(CV_OpenGlApiCallError, "OpenGlText::set", "Can't create font", __FILE__, __LINE__); + cvError(CV_OpenGlApiCallError, "OpenGlFont", "Can't create font", __FILE__, __LINE__); fontName_ = fontName; fontHeight_ = fontHeight; -- GitLab