38 #include <visp3/core/vpConfig.h>
40 #if ( defined(VISP_HAVE_GDI) )
42 #ifndef DOXYGEN_SHOULD_SKIP_THIS
44 #include <visp3/gui/vpGDIRenderer.h>
49 vpGDIRenderer::vpGDIRenderer()
50 : m_bmp(NULL), m_bmp_width(0), m_bmp_height(0)
53 int bpp = GetDeviceCaps(GetDC(NULL), BITSPIXEL);
56 "vpGDIRenderer supports only 32bits depth: screen is %dbits depth!", bpp);
58 InitializeCriticalSection(&m_criticalSection);
107 vpGDIRenderer::~vpGDIRenderer()
110 DeleteCriticalSection(&m_criticalSection);
114 DeleteObject(m_hFont);
123 bool vpGDIRenderer::init(HWND hWindow,
unsigned int width,
unsigned int height)
132 m_hFont = CreateFont(18, 0, 0, 0, FW_NORMAL,
false,
false,
false,
133 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
134 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
135 DEFAULT_PITCH | FF_DONTCARE, NULL);
155 void vpGDIRenderer::setImgROI(
const vpImage<vpRGBa>& I,
const vpImagePoint &iP,
const unsigned int width,
const unsigned int height )
158 convertROI(I, iP, width, height);
180 convertROI(I, iP, width, height);
186 bool vpGDIRenderer::render()
190 HDC hDCScreen = BeginPaint(m_hWnd, &ps);
193 HDC hDCMem = CreateCompatibleDC(hDCScreen);
196 EnterCriticalSection(&m_criticalSection);
197 SelectObject(hDCMem, m_bmp);
200 BitBlt(hDCScreen, 0, 0,
201 static_cast<int>( m_rwidth ),
202 static_cast<int>( m_rheight ),
203 hDCMem, 0, 0, SRCCOPY);
205 LeaveCriticalSection(&m_criticalSection);
207 DeleteObject(hDCMem);
209 EndPaint(m_hWnd, &ps);
222 unsigned char * imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
225 for(
unsigned int i=0, k=0 ; i<m_rwidth * m_rheight * 4 ; i+=4, k++) {
233 for (
unsigned int i = 0; i < m_rheight; i++) {
234 unsigned int i_ = i*m_rscale;
235 unsigned int ii_ = i*m_rwidth;
236 for (
unsigned int j = 0; j < m_rwidth; j++) {
237 vpRGBa val = I[i_][j*m_rscale];
238 unsigned int index_ = (ii_ + j) * 4;
239 imBuffer[ index_] = val.
B;
240 imBuffer[++index_] = val.
G;
241 imBuffer[++index_] = val.
R;
242 imBuffer[++index_] = val.
A;
248 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
260 void vpGDIRenderer::convertROI(
const vpImage<vpRGBa> &I,
const vpImagePoint &iP,
const unsigned int width,
const unsigned int height)
262 int i_min = std::max((
int)ceil(iP.
get_i() / m_rscale), 0);
263 int j_min = std::max((
int)ceil(iP.
get_j() / m_rscale), 0);
264 int i_max = std::min((
int)ceil((iP.
get_i() + height) / m_rscale), (int)m_rheight);
265 int j_max = std::min((
int)ceil((iP.
get_j() + width) / m_rscale), (int)m_rwidth);
267 int h = i_max - i_min;
268 int w = j_max - j_min;
271 unsigned char * imBuffer =
new unsigned char[w * h * 4];
276 bitmap = bitmap + (int)(i_min*iwidth + j_min);
279 for (
int i=0 ; i < w * h * 4 ; i+=4)
281 imBuffer[i+0] = (bitmap+k)->B;
282 imBuffer[i+1] = (bitmap+k)->G;
283 imBuffer[i+2] = (bitmap+k)->R;
284 imBuffer[i+3] = (bitmap+k)->A;
289 bitmap = bitmap+iwidth;
295 for (
int i = 0; i < h; i++) {
296 unsigned int i_ = (i_min + i)*m_rscale;
297 unsigned int ii_ = i*w;
298 for (
int j = 0; j < w; j++) {
299 vpRGBa val = I[i_][(j_min + j)*m_rscale];
300 unsigned int index_ = (ii_ + j) * 4;
301 imBuffer[index_] = val.
B;
302 imBuffer[++index_] = val.
G;
303 imBuffer[++index_] = val.
R;
304 imBuffer[++index_] = val.
A;
310 updateBitmapROI(imBuffer, i_min, j_min, w, h);
325 unsigned char * imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
328 for (
unsigned int i = 0, k = 0; i < m_rwidth * m_rheight * 4; i += 4, k++)
330 imBuffer[i + 0] = I.
bitmap[k];
331 imBuffer[i + 1] = I.
bitmap[k];
332 imBuffer[i + 2] = I.
bitmap[k];
337 for (
unsigned int i = 0; i < m_rheight; i++) {
338 unsigned int i_ = i*m_rscale;
339 unsigned int ii_ = i*m_rwidth;
340 for (
unsigned int j = 0; j < m_rwidth; j++) {
341 unsigned char val = I[i_][j*m_rscale];
342 unsigned int index_ = (ii_ + j) * 4;
343 imBuffer[index_] = val;
344 imBuffer[++index_] = val;
345 imBuffer[++index_] = val;
352 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
367 int i_min = std::max((
int)ceil(iP.
get_i() / m_rscale), 0);
368 int j_min = std::max((
int)ceil(iP.
get_j() / m_rscale), 0);
369 int i_max = std::min((
int)ceil((iP.
get_i() + height) / m_rscale), (int)m_rheight);
370 int j_max = std::min((
int)ceil((iP.
get_j() + width) / m_rscale), (int)m_rwidth);
372 int h = i_max - i_min;
373 int w = j_max - j_min;
376 unsigned char * imBuffer =
new unsigned char[w * h * 4];
379 for (
int i = 0; i < h; i++) {
380 unsigned int i_ = i_min + i;
381 unsigned int ii_ = i*w;
382 for (
int j = 0; j < w; j++) {
383 unsigned char val = I[i_][j_min + j];
384 unsigned int index_ = (ii_ + j) * 4;
385 imBuffer[index_] = val;
386 imBuffer[++index_] = val;
387 imBuffer[++index_] = val;
393 for (
int i = 0; i < h; i++) {
394 unsigned int i_ = (i_min + i)*m_rscale;
395 unsigned int ii_ = i*w;
396 for (
int j = 0; j < w; j++) {
397 unsigned char val = I[i_][(j_min + j)*m_rscale];
398 unsigned int index_ = (ii_ + j) * 4;
399 imBuffer[index_] = val;
400 imBuffer[++index_] = val;
401 imBuffer[++index_] = val;
408 updateBitmapROI(imBuffer, i_min, j_min, w, h);
424 bool vpGDIRenderer::updateBitmap(HBITMAP& hBmp,
unsigned char * imBuffer,
425 unsigned int w,
unsigned int h)
429 EnterCriticalSection(&m_criticalSection);
432 if( (m_bmp_width == w) && (m_bmp_height == h) && w != 0 && h != 0)
435 SetBitmapBits(hBmp, w * h * 4, imBuffer);
445 if( (hBmp = CreateBitmap(static_cast<int>(w),static_cast<int>(h),
446 1,32,(
void*)imBuffer)) == NULL)
453 LeaveCriticalSection(&m_criticalSection);
468 bool vpGDIRenderer::updateBitmapROI(
unsigned char * imBuffer,
int i_min,
int j_min,
int w,
int h)
470 HBITMAP htmp = CreateBitmap(w, h, 1, 32, (
void*)imBuffer);
473 HDC hDCScreen = GetDC(m_hWnd);
474 HDC hDCMem = CreateCompatibleDC(hDCScreen);
475 HDC hDCMem2 = CreateCompatibleDC(hDCScreen);
478 EnterCriticalSection(&m_criticalSection);
479 SelectObject(hDCMem, m_bmp);
480 SelectObject(hDCMem2, htmp);
482 BitBlt(hDCMem, j_min, i_min, w, h, hDCMem2, 0, 0,SRCCOPY);
483 LeaveCriticalSection(&m_criticalSection);
486 ReleaseDC(m_hWnd, hDCScreen);
502 HDC hDCScreen = GetDC(m_hWnd);
503 HDC hDCMem = CreateCompatibleDC(hDCScreen);
506 EnterCriticalSection(&m_criticalSection);
507 SelectObject(hDCMem, m_bmp);
513 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
520 LeaveCriticalSection(&m_criticalSection);
523 ReleaseDC(m_hWnd, hDCScreen);
536 unsigned int thickness,
int style)
538 HDC hDCScreen= NULL, hDCMem = NULL;
543 hDCScreen = GetDC(m_hWnd);
544 if(!hDCScreen)
continue;
545 hDCMem = CreateCompatibleDC(hDCScreen);
547 ReleaseDC(m_hWnd, hDCScreen);
553 hPen = CreatePen(style, static_cast<int>(thickness), m_colors[color.
id]);
555 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
556 hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
560 ReleaseDC(m_hWnd, hDCScreen);
563 if(!SetBkMode(hDCMem, TRANSPARENT)){
566 ReleaseDC(m_hWnd, hDCScreen);
571 EnterCriticalSection(&m_criticalSection);
573 if(!SelectObject(hDCMem, m_bmp)){
574 LeaveCriticalSection(&m_criticalSection);
577 ReleaseDC(m_hWnd, hDCScreen);
582 if(!SelectObject(hDCMem, hPen)){
583 LeaveCriticalSection(&m_criticalSection);
586 ReleaseDC(m_hWnd, hDCScreen);
594 hDCScreen = GetDC(m_hWnd);
595 hDCMem = CreateCompatibleDC(hDCScreen);
598 hPen = CreatePen(style, static_cast<int>(thickness), m_colors[color.
id]);
600 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
601 hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
603 SetBkMode(hDCMem, TRANSPARENT);
606 EnterCriticalSection(&m_criticalSection);
607 SelectObject(hDCMem, m_bmp);
610 SelectObject(hDCMem, hPen);
614 if (thickness != 1 && style != PS_SOLID) {
615 double size = 10.*m_rscale;
617 double deltaj = size / length*(ip2.
get_j() - ip1.
get_j());
618 double deltai = size / length*(ip2.
get_i() - ip1.
get_i());
620 double orig = ip1.
get_i() - slope*ip1.
get_j();
621 for (
unsigned int j = (
unsigned int)ip1.
get_j(); j < ip2.
get_j(); j += (
unsigned int)(2 * deltaj)) {
622 double i = slope*j + orig;
636 LeaveCriticalSection(&m_criticalSection);
640 ReleaseDC(m_hWnd, hDCScreen);
652 void vpGDIRenderer::drawRect(
const vpImagePoint &topLeft,
653 unsigned int width,
unsigned int height,
654 const vpColor &color,
bool fill,
655 unsigned int thickness)
657 if (thickness == 0) thickness = 1;
659 HDC hDCScreen = GetDC(m_hWnd);
660 HDC hDCMem = CreateCompatibleDC(hDCScreen);
664 COLORREF gdicolor = RGB(0,0,0);
667 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
669 gdicolor = RGB(color.
R, color.
G, color.
B);
670 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
676 lBrush.lbStyle = BS_SOLID;
678 lBrush.lbColor = m_colors[color.
id];
680 lBrush.lbColor = gdicolor;
683 else lBrush.lbStyle = BS_HOLLOW;
684 HBRUSH hbrush = CreateBrushIndirect(&lBrush);
687 EnterCriticalSection(&m_criticalSection);
688 SelectObject(hDCMem, m_bmp);
691 SelectObject(hDCMem, hbrush);
693 SelectObject(hDCMem, hPen);
703 LeaveCriticalSection(&m_criticalSection);
705 DeleteObject(hbrush);
708 ReleaseDC(m_hWnd, hDCScreen);
715 void vpGDIRenderer::clear(
const vpColor &color)
720 drawRect(ip, m_rwidth, m_rheight, color,
true, 0);
732 void vpGDIRenderer::drawCircle(
const vpImagePoint ¢er,
unsigned int radius,
733 const vpColor &color,
bool fill,
unsigned int thickness)
737 HDC hDCScreen = GetDC(m_hWnd);
738 HDC hDCMem = CreateCompatibleDC(hDCScreen);
743 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
745 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
746 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
751 lBrush.lbStyle = BS_HOLLOW;
752 HBRUSH hbrush = CreateBrushIndirect(&lBrush);
755 int radius_ =
static_cast<int>(radius);
762 EnterCriticalSection(&m_criticalSection);
763 SelectObject(hDCMem, m_bmp);
766 SelectObject(hDCMem, hbrush);
768 SelectObject(hDCMem, hPen);
772 Ellipse(hDCMem, x1, y1, x2, y2);
782 Ellipse(hDCMem, x1, y1, x2, y2);
789 LeaveCriticalSection(&m_criticalSection);
791 DeleteObject(hbrush);
794 ReleaseDC(m_hWnd, hDCScreen);
804 void vpGDIRenderer::drawText(
const vpImagePoint &ip,
const char * text,
808 HDC hDCScreen = GetDC(m_hWnd);
809 HDC hDCMem = CreateCompatibleDC(hDCScreen);
812 EnterCriticalSection(&m_criticalSection);
813 SelectObject(hDCMem, m_bmp);
816 SelectObject(hDCMem, m_hFont);
820 SetTextColor(hDCMem, m_colors[color.
id]);
822 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
823 SetTextColor(hDCMem, gdicolor);
827 SetBkMode(hDCMem, TRANSPARENT);
830 int length = (int) strlen(text);
833 GetTextExtentPoint32(hDCMem, text, length, &size);
841 LeaveCriticalSection(&m_criticalSection);
844 ReleaseDC(m_hWnd, hDCScreen);
856 void vpGDIRenderer::drawCross(
const vpImagePoint &ip,
unsigned int size,
857 const vpColor &color,
unsigned int thickness)
859 int half_size =
static_cast<int>( size/2 / m_rscale);
866 HDC hDCScreen = GetDC(m_hWnd);
867 HDC hDCMem = CreateCompatibleDC(hDCScreen);
872 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
874 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
875 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
879 EnterCriticalSection(&m_criticalSection);
880 SelectObject(hDCMem, m_bmp);
883 SelectObject(hDCMem, hPen);
899 LeaveCriticalSection(&m_criticalSection);
903 ReleaseDC(m_hWnd, hDCScreen);
920 unsigned int w,
unsigned int h,
unsigned int thickness)
922 double a = ip2.
get_i() / m_rscale - ip1.
get_i() / m_rscale;
923 double b = ip2.
get_j() / m_rscale - ip1.
get_j() / m_rscale;
933 HDC hDCScreen = GetDC(m_hWnd);
934 HDC hDCMem = CreateCompatibleDC(hDCScreen);
939 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
941 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
942 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
946 EnterCriticalSection(&m_criticalSection);
947 SelectObject(hDCMem, m_bmp);
950 SelectObject(hDCMem, hPen);
1002 LeaveCriticalSection(&m_criticalSection);
1006 ReleaseDC(m_hWnd, hDCScreen);
1016 unsigned int size = m_rwidth*m_rheight *4;
1017 unsigned char * imBuffer =
new unsigned char[size];
1020 GetBitmapBits(m_bmp, static_cast<LONG>(size), (
void *)imBuffer);
1023 I.
resize(m_rheight, m_rwidth);
1026 for(
unsigned int i=0 ; i<size ; i+=4)
1028 I.
bitmap[i>>2].
R = imBuffer[i+2];
1029 I.
bitmap[i>>2].
G = imBuffer[i+1];
1030 I.
bitmap[i>>2].
B = imBuffer[i+0];
1037 #elif !defined(VISP_BUILD_SHARED_LIBS)
1039 void dummy_vpGDIRenderer() {};
unsigned int getWidth() const
unsigned char B
Blue component.
Type * bitmap
points toward the bitmap
static const vpColor black
static const vpColor darkRed
Class to define colors available for display functionnalities.
static const vpColor lightGray
static const vpColor darkBlue
unsigned char G
Green component.
static const vpColor green
static int round(const double x)
VISP_EXPORT double measureTimeMs()
static const vpColor lightRed
static const vpColor orange
void set_i(const double ii)
static const vpColor cyan
static const vpColor lightGreen
static double sqr(double x)
unsigned char A
Additionnal component.
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
static const vpColor gray
static const vpColor darkGray
void set_j(const double jj)
Error that can be emited by the vpDisplay class and its derivates.
unsigned char R
Red component.
static const vpColor darkGreen
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static const vpColor yellow
static const vpColor lightBlue
static const vpColor purple
static const vpColor white
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
static const vpColor blue