implemented addTextOpenGl under Gtk
authorVladislav Vinogradov <no@email>
Mon, 28 Nov 2011 12:35:05 +0000 (12:35 +0000)
committerVladislav Vinogradov <no@email>
Mon, 28 Nov 2011 12:35:05 +0000 (12:35 +0000)
modules/highgui/src/window_gtk.cpp
modules/highgui/src/window_w32.cpp

index 94a8fe4..417bb82 100644 (file)
@@ -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<float>(org.x) / width, static_cast<float>((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<OpenGlFont> font;
+        };
+
+        std::vector< cv::Ptr<OpenGlFont> > fonts_;
+
+        std::vector<Text> text_;
+    };
+
+    OpenGlText::OpenGlText()
+    {
+        fonts_.reserve(5);
+        text_.reserve(5);
+    }
+
+    class FontCompare : public std::unary_function<cv::Ptr<OpenGlFont>, 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<OpenGlFont>& 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<OpenGlFont> >::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)
         {
index e6afcc3..0572dc5 100644 (file)
@@ -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;