added addTextOpenGl function

This commit is contained in:
Vladislav Vinogradov 2011-11-28 11:50:46 +00:00
parent 2a4fb155e1
commit 9817252b23
5 changed files with 370 additions and 58 deletions

View File

@ -151,6 +151,11 @@ CV_EXPORTS void pointCloudShow(const string& winname, const gpu::GlCamera& camer
CV_EXPORTS void pointCloudShow(const string& winname, const gpu::GlCamera& camera, InputArray points,
InputArray colors = noArray());
CV_EXPORTS void addTextOpenGl(const string& winname, const string& text, Point org, Scalar color = Scalar::all(255),
const string& fontName = "Courier New", int fontHeight = 12,
int fontWeight = CV_FONT_NORMAL, int fontStyle = CV_STYLE_NORMAL);
CV_EXPORTS void clearTextOpenGl(const string& winname);
//Only for Qt
CV_EXPORTS CvFont fontQt(const string& nameFont, int pointSize=-1,

View File

@ -63,7 +63,8 @@ enum { CV_FONT_LIGHT = 25,//QFont::Light,
enum { CV_STYLE_NORMAL = 0,//QFont::StyleNormal,
CV_STYLE_ITALIC = 1,//QFont::StyleItalic,
CV_STYLE_OBLIQUE = 2 //QFont::StyleOblique
CV_STYLE_OBLIQUE = 2,//QFont::StyleOblique
CV_STYLE_UNDERLINE = 4
};
/* ---------*/
@ -257,6 +258,12 @@ CVAPI(void) cvCreateOpenGLCallback( const char* window_name, CvOpenGLCallback ca
CVAPI(void) cvSetOpenGlContext(const char* window_name);
CVAPI(void) cvUpdateWindow(const char* window_name);
CVAPI(void) cvAddTextOpenGl(const char* winname, const char* text, CvPoint org, CvScalar color CV_DEFAULT(cvScalar(255.0, 255.0, 255.0, 255.0)),
const char* fontName CV_DEFAULT("Courier New"), int fontHeight CV_DEFAULT(12),
int fontWeight CV_DEFAULT(CV_FONT_NORMAL), int fontStyle CV_DEFAULT(CV_STYLE_NORMAL));
CVAPI(void) cvClearTextOpenGl(const char* winname);
/****************************************************************************************\
* Working with Video Files and Cameras *
\****************************************************************************************/

View File

@ -597,6 +597,35 @@ void cv::pointCloudShow(const string& winname, const gpu::GlCamera& camera, Inpu
#endif
}
// OpenGL text
void cv::addTextOpenGl(const string& winname, const string& text, Point org, Scalar color, const string& fontName, int fontHeight, int fontWeight, int fontStyle)
{
cvAddTextOpenGl(winname.c_str(), text.c_str(), org, color, fontName.c_str(), fontHeight, fontWeight, fontStyle);
}
void cv::clearTextOpenGl(const string& winname)
{
cvClearTextOpenGl(winname.c_str());
}
#if (!defined WIN32 && !defined _WIN32) || defined HAVE_QT
CV_IMPL void cvAddTextOpenGl(const char*, const char*, CvPoint, CvScalar, const char*, int, int, int)
{
CV_Error(CV_OpenGlNotSupported, "This function works only under WIN32");
}
CV_IMPL void cvClearTextOpenGl(const char*)
{
CV_Error(CV_OpenGlNotSupported, "This function works only under WIN32");
}
#endif // (!defined WIN32 && !defined _WIN32) || defined HAVE_QT
// Without OpenGL
#ifndef HAVE_OPENGL
#ifndef HAVE_QT
@ -616,6 +645,16 @@ CV_IMPL void cvUpdateWindow(const char*)
CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support");
}
CV_IMPL void cvAddTextOpenGl(const char*, const char*, CvPoint, CvScalar, const char*, int, int, int)
{
CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support");
}
CV_IMPL void cvClearTextOpenGl(const char*)
{
CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support");
}
void icvSetOpenGlCleanCallback(const char*, CvOpenGlCleanCallback, void*)
{
CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support");

View File

@ -56,6 +56,9 @@
#ifdef HAVE_OPENGL
#include <memory>
#include <algorithm>
#include <vector>
#include <functional>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/gpumat.hpp"
#include <GL\gl.h>
@ -134,6 +137,217 @@ typedef struct CvTrackbar
}
CvTrackbar;
// OpenGL support
#ifdef HAVE_OPENGL
namespace
{
class OpenGlFont
{
public:
OpenGlFont(HDC hDC, 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&);
};
int getFontWidthW32(int fontWeight)
{
int weight = 0;
switch(fontWeight)
{
case CV_FONT_LIGHT:
weight = 200;
break;
case CV_FONT_NORMAL:
weight = FW_NORMAL;
break;
case CV_FONT_DEMIBOLD:
weight = 550;
break;
case CV_FONT_BOLD:
weight = FW_BOLD;
break;
case CV_FONT_BLACK:
weight = FW_BLACK;
break;
default:
cvError(CV_StsBadArg, "getFontWidthW32", "Unsopported fonr width", __FILE__, __LINE__);
};
return weight;
}
OpenGlFont::OpenGlFont(HDC hDC, const std::string& fontName, int fontHeight, int fontWeight, int fontStyle)
: fontName_(), fontHeight_(0), fontWeight_(0), fontStyle_(0), base_(0)
{
base_ = glGenLists(96);
HFONT font = CreateFont
(
-fontHeight, // height
0, // cell width
0, // Angle of Escapement
0, // Orientation Angle
getFontWidthW32(fontWeight), // font weight
fontStyle & CV_STYLE_ITALIC ? TRUE : FALSE, // Italic
fontStyle & CV_STYLE_UNDERLINE ? TRUE : FALSE, // Underline
FALSE, // StrikeOut
ANSI_CHARSET, // CharSet
OUT_TT_PRECIS, // OutPrecision
CLIP_DEFAULT_PRECIS, // ClipPrecision
ANTIALIASED_QUALITY, // Quality
FF_DONTCARE | DEFAULT_PITCH, // PitchAndFamily
fontName.c_str() // FaceName
);
SelectObject(hDC, font);
if (!wglUseFontBitmaps(hDC, 32, 96, base_))
cvError(CV_OpenGlApiCallError, "OpenGlText::set", "Can't create font", __FILE__, __LINE__);
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(HDC hDC);
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;
};
HDC hDC_;
std::vector< cv::Ptr<OpenGlFont> > fonts_;
std::vector<Text> text_;
};
OpenGlText::OpenGlText(HDC hDC) : hDC_(hDC)
{
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(hDC_, 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;
@ -178,11 +392,12 @@ typedef struct CvWindow
void* glCleanData;
cv::gpu::GlFuncTab* glFuncTab;
OpenGlText* glText;
#endif
}
CvWindow;
#define HG_BUDDY_WIDTH 130
#ifndef TBIF_SIZE
@ -743,6 +958,8 @@ namespace
void initGl(CvWindow* window)
{
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
std::auto_ptr<GlFuncTab_W32> glFuncTab(new GlFuncTab_W32);
// Load extensions
@ -872,6 +1089,11 @@ namespace
CV_CheckGlError();
if (window->glText)
window->glText->draw(window->width, window->height);
CV_CheckGlError();
if (!SwapBuffers(window->dc))
CV_ERROR( CV_OpenGlApiCallError, "Can't swap OpenGL buffers" );
@ -919,57 +1141,6 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
if (window != 0)
{
result = 1;
#ifdef HAVE_OPENGL
if (window->useGl && !(flags & CV_WINDOW_OPENGL))
{
wglMakeCurrent(window->dc, window->hGLRC);
if (window->glCleanCallback)
{
window->glCleanCallback(window->glCleanData);
window->glCleanCallback = 0;
window->glCleanData = 0;
}
releaseGlContext(window);
window->dc = CreateCompatibleDC(0);
window->hGLRC = 0;
window->useGl = false;
}
else if (!window->useGl && (flags & CV_WINDOW_OPENGL))
{
if (window->dc && window->image)
DeleteObject(SelectObject(window->dc, window->image));
if (window->dc)
DeleteDC(window->dc);
bool useGl = false;
HDC hGLDC = 0;
HGLRC hGLRC = 0;
createGlContext(window->hwnd, hGLDC, hGLRC, useGl);
if (!useGl)
{
window->dc = CreateCompatibleDC(0);
window->hGLRC = 0;
window->useGl = false;
result = 0;
}
else
{
window->dc = hGLDC;
window->hGLRC = hGLRC;
window->useGl = true;
initGl(window);
}
}
#endif // HAVE_OPENGL
EXIT;
}
@ -1038,6 +1209,8 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
window->glCleanCallback = 0;
window->glCleanData = 0;
window->glText = 0;
#endif
window->last_key = 0;
@ -1093,6 +1266,67 @@ CV_IMPL void cvSetOpenGlContext(const char* name)
__END__;
}
CV_IMPL void cvAddTextOpenGl(const char* name, const char* text, CvPoint org, CvScalar color, const char* fontName, int fontHeight, int fontWeight, int fontStyle)
{
CV_FUNCNAME( "cvSetOpenGlContext" );
__BEGIN__;
CvWindow* window;
if(!name)
CV_ERROR( CV_StsNullPtr, "NULL name string" );
window = icvFindWindowByName( name );
if (!window)
CV_ERROR( CV_StsNullPtr, "NULL window" );
if (!window->useGl)
CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" );
if (!wglMakeCurrent(window->dc, window->hGLRC))
CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" );
if (!window->glText)
window->glText = new OpenGlText(window->dc);
window->glText->add(text, org, color, fontName, fontHeight, fontWeight, fontStyle);
InvalidateRect(window->hwnd, 0, 0);
__END__;
}
CV_IMPL void cvClearTextOpenGl(const char* name)
{
CV_FUNCNAME( "cvSetOpenGlContext" );
__BEGIN__;
CvWindow* window;
if(!name)
CV_ERROR( CV_StsNullPtr, "NULL name string" );
window = icvFindWindowByName( name );
if (!window)
CV_ERROR( CV_StsNullPtr, "NULL window" );
if (!window->useGl)
CV_ERROR( CV_OpenGlNotSupported, "Window doesn't support OpenGL" );
if (!wglMakeCurrent(window->dc, window->hGLRC))
CV_ERROR( CV_OpenGlApiCallError, "Can't Activate The GL Rendering Context" );
if (window->glText)
{
window->glText->clear();
InvalidateRect(window->hwnd, 0, 0);
}
__END__;
}
CV_IMPL void cvUpdateWindow(const char* name)
{
CV_FUNCNAME( "cvUpdateWindow" );
@ -1172,6 +1406,9 @@ static void icvRemoveWindow( CvWindow* window )
if (window->useGl)
{
wglMakeCurrent(window->dc, window->hGLRC);
if (window->glText)
delete window->glText;
if (window->glCleanCallback)
{

View File

@ -1,11 +1,13 @@
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include "opencv2/core/core.hpp"
#include "opencv2/core/gpumat.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/contrib/contrib.hpp"
using namespace std;
using namespace cv;
@ -187,13 +189,15 @@ int main(int argc, const char* argv[])
reprojectImageTo3D(disp, points, Q);
namedWindow("OpenGL Sample", WINDOW_OPENGL);
const string windowName = "OpenGL Sample";
namedWindow(windowName, WINDOW_OPENGL);
int fov = 0;
createTrackbar("Fov", "OpenGL Sample", &fov, 100);
createTrackbar("Fov", windowName, &fov, 100);
int mouse[2] = {0, 0};
setMouseCallback("OpenGL Sample", mouseCallback, mouse);
setMouseCallback(windowName, mouseCallback, mouse);
GlArrays pointCloud;
@ -211,8 +215,14 @@ int main(int argc, const char* argv[])
const Point3d leftVec(-1.0, 0.0, 0.0);
Point3d pos;
TickMeter tm;
const int step = 20;
int frame = 0;
while (true)
{
tm.start();
int key = waitKey(1);
if (key >= 0)
key = key & 0xff;
@ -220,7 +230,7 @@ int main(int argc, const char* argv[])
if (key == 27)
break;
double aspect = getWindowProperty("OpenGL Sample", WND_PROP_ASPECT_RATIO);
double aspect = getWindowProperty(windowName, WND_PROP_ASPECT_RATIO);
const double posStep = 0.1;
@ -256,7 +266,21 @@ int main(int argc, const char* argv[])
camera.setCameraPos(pos, yaw, pitch, 0.0);
pointCloudShow("OpenGL Sample", camera, pointCloud);
pointCloudShow(windowName, camera, pointCloud);
tm.stop();
if (frame++ >= step)
{
ostringstream fps;
fps << "FPS: " << step / tm.getTimeSec();
clearTextOpenGl(windowName);
addTextOpenGl(windowName, fps.str(), Point(0, 0), Scalar::all(255), "Courier New", 16);
frame = 0;
tm.reset();
}
}
return 0;