39 #include <visp3/core/vpConfig.h>
41 #if (defined(VISP_HAVE_GDI))
43 #ifndef DOXYGEN_SHOULD_SKIP_THIS
45 #include <visp3/gui/vpGDIRenderer.h>
50 vpGDIRenderer::vpGDIRenderer() : m_bmp(NULL), m_bmp_width(0), m_bmp_height(0), timelost(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, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
133 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, NULL);
154 const unsigned int height)
157 convertROI(I, iP, width, height);
177 const unsigned int 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, static_cast<int>(m_rwidth), static_cast<int>(m_rheight), hDCMem, 0, 0, SRCCOPY);
202 LeaveCriticalSection(&m_criticalSection);
204 DeleteObject(hDCMem);
206 EndPaint(m_hWnd, &ps);
219 unsigned char *imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
222 for (
unsigned int i = 0, k = 0; i < m_rwidth * m_rheight * 4; i += 4, k++) {
223 imBuffer[i + 0] = I.
bitmap[k].B;
224 imBuffer[i + 1] = I.
bitmap[k].G;
225 imBuffer[i + 2] = I.
bitmap[k].R;
226 imBuffer[i + 3] = I.
bitmap[k].A;
229 for (
unsigned int i = 0; i < m_rheight; i++) {
230 unsigned int i_ = i * m_rscale;
231 unsigned int ii_ = i * m_rwidth;
232 for (
unsigned int j = 0; j < m_rwidth; j++) {
233 vpRGBa val = I[i_][j * m_rscale];
234 unsigned int index_ = (ii_ + j) * 4;
235 imBuffer[index_] = val.
B;
236 imBuffer[++index_] = val.
G;
237 imBuffer[++index_] = val.
R;
238 imBuffer[++index_] = val.
A;
244 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
257 const unsigned int height)
259 int i_min = (std::max)((
int)ceil(iP.
get_i() / m_rscale), 0);
260 int j_min = (std::max)((
int)ceil(iP.
get_j() / m_rscale), 0);
261 int i_max = (std::min)((
int)ceil((iP.
get_i() + height) / m_rscale), (int)m_rheight);
262 int j_max = (std::min)((
int)ceil((iP.
get_j() + width) / m_rscale), (int)m_rwidth);
264 int h = i_max - i_min;
265 int w = j_max - j_min;
268 unsigned char *imBuffer =
new unsigned char[w * h * 4];
273 bitmap = bitmap + (int)(i_min * iwidth + j_min);
276 for (
int i = 0; i < w * h * 4; i += 4) {
277 imBuffer[i + 0] = (bitmap + k)->B;
278 imBuffer[i + 1] = (bitmap + k)->G;
279 imBuffer[i + 2] = (bitmap + k)->R;
280 imBuffer[i + 3] = (bitmap + k)->A;
284 bitmap = bitmap + iwidth;
289 for (
int i = 0; i < h; i++) {
290 unsigned int i_ = (i_min + i) * m_rscale;
291 unsigned int ii_ = i * w;
292 for (
int j = 0; j < w; j++) {
293 vpRGBa val = I[i_][(j_min + j) * m_rscale];
294 unsigned int index_ = (ii_ + j) * 4;
295 imBuffer[index_] = val.
B;
296 imBuffer[++index_] = val.
G;
297 imBuffer[++index_] = val.
R;
298 imBuffer[++index_] = val.
A;
304 updateBitmapROI(imBuffer, i_min, j_min, w, h);
318 unsigned char *imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
321 for (
unsigned int i = 0, k = 0; i < m_rwidth * m_rheight * 4; i += 4, k++) {
322 imBuffer[i + 0] = I.
bitmap[k];
323 imBuffer[i + 1] = I.
bitmap[k];
324 imBuffer[i + 2] = I.
bitmap[k];
328 for (
unsigned int i = 0; i < m_rheight; i++) {
329 unsigned int i_ = i * m_rscale;
330 unsigned int ii_ = i * m_rwidth;
331 for (
unsigned int j = 0; j < m_rwidth; j++) {
332 unsigned char val = I[i_][j * m_rscale];
333 unsigned int index_ = (ii_ + j) * 4;
334 imBuffer[index_] = val;
335 imBuffer[++index_] = val;
336 imBuffer[++index_] = val;
343 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
356 const unsigned int height)
358 int i_min = (std::max)((
int)ceil(iP.
get_i() / m_rscale), 0);
359 int j_min = (std::max)((
int)ceil(iP.
get_j() / m_rscale), 0);
360 int i_max = (std::min)((
int)ceil((iP.
get_i() + height) / m_rscale), (int)m_rheight);
361 int j_max = (std::min)((
int)ceil((iP.
get_j() + width) / m_rscale), (int)m_rwidth);
363 int h = i_max - i_min;
364 int w = j_max - j_min;
367 unsigned char *imBuffer =
new unsigned char[w * h * 4];
370 for (
int i = 0; i < h; i++) {
371 unsigned int i_ = i_min + i;
372 unsigned int ii_ = i * w;
373 for (
int j = 0; j < w; j++) {
374 unsigned char val = I[i_][j_min + j];
375 unsigned int index_ = (ii_ + j) * 4;
376 imBuffer[index_] = val;
377 imBuffer[++index_] = val;
378 imBuffer[++index_] = val;
383 for (
int i = 0; i < h; i++) {
384 unsigned int i_ = (i_min + i) * m_rscale;
385 unsigned int ii_ = i * w;
386 for (
int j = 0; j < w; j++) {
387 unsigned char val = I[i_][(j_min + j) * m_rscale];
388 unsigned int index_ = (ii_ + j) * 4;
389 imBuffer[index_] = val;
390 imBuffer[++index_] = val;
391 imBuffer[++index_] = val;
398 updateBitmapROI(imBuffer, i_min, j_min, w, h);
414 bool vpGDIRenderer::updateBitmap(HBITMAP &hBmp,
unsigned char *imBuffer,
unsigned int w,
unsigned int h)
418 EnterCriticalSection(&m_criticalSection);
421 if ((m_bmp_width == w) && (m_bmp_height == h) && w != 0 && h != 0) {
423 SetBitmapBits(hBmp, w * h * 4, imBuffer);
430 if ((hBmp = CreateBitmap(static_cast<int>(w), static_cast<int>(h), 1, 32, (
void *)imBuffer)) == NULL)
437 LeaveCriticalSection(&m_criticalSection);
451 bool vpGDIRenderer::updateBitmapROI(
unsigned char *imBuffer,
int i_min,
int j_min,
int w,
int h)
453 HBITMAP htmp = CreateBitmap(w, h, 1, 32, (
void *)imBuffer);
456 HDC hDCScreen = GetDC(m_hWnd);
457 HDC hDCMem = CreateCompatibleDC(hDCScreen);
458 HDC hDCMem2 = CreateCompatibleDC(hDCScreen);
461 EnterCriticalSection(&m_criticalSection);
462 SelectObject(hDCMem, m_bmp);
463 SelectObject(hDCMem2, htmp);
465 BitBlt(hDCMem, j_min, i_min, w, h, hDCMem2, 0, 0, SRCCOPY);
466 LeaveCriticalSection(&m_criticalSection);
469 ReleaseDC(m_hWnd, hDCScreen);
484 HDC hDCScreen = GetDC(m_hWnd);
485 HDC hDCMem = CreateCompatibleDC(hDCScreen);
488 EnterCriticalSection(&m_criticalSection);
489 SelectObject(hDCMem, m_bmp);
494 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
500 LeaveCriticalSection(&m_criticalSection);
503 ReleaseDC(m_hWnd, hDCScreen);
514 unsigned int thickness,
int style)
516 HDC hDCScreen = NULL, hDCMem = NULL;
521 hDCScreen = GetDC(m_hWnd);
524 hDCMem = CreateCompatibleDC(hDCScreen);
526 ReleaseDC(m_hWnd, hDCScreen);
532 hPen = CreatePen(style, static_cast<int>(thickness), m_colors[color.
id]);
534 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
535 hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
539 ReleaseDC(m_hWnd, hDCScreen);
542 if (!SetBkMode(hDCMem, TRANSPARENT)) {
545 ReleaseDC(m_hWnd, hDCScreen);
550 EnterCriticalSection(&m_criticalSection);
552 if (!SelectObject(hDCMem, m_bmp)) {
553 LeaveCriticalSection(&m_criticalSection);
556 ReleaseDC(m_hWnd, hDCScreen);
561 if (!SelectObject(hDCMem, hPen)) {
562 LeaveCriticalSection(&m_criticalSection);
565 ReleaseDC(m_hWnd, hDCScreen);
573 hDCScreen = GetDC(m_hWnd);
574 hDCMem = CreateCompatibleDC(hDCScreen);
577 hPen = CreatePen(style, static_cast<int>(thickness), m_colors[color.
id]);
579 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
580 hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
582 SetBkMode(hDCMem, TRANSPARENT);
585 EnterCriticalSection(&m_criticalSection);
586 SelectObject(hDCMem, m_bmp);
589 SelectObject(hDCMem, hPen);
594 if (thickness != 1 && style != PS_SOLID) {
595 double size = 10. * m_rscale;
597 double deltaj = size / length * (ip2.
get_j() - ip1.
get_j());
598 double deltai = size / length * (ip2.
get_i() - ip1.
get_i());
600 double orig = ip1.
get_i() - slope * ip1.
get_j();
601 for (
unsigned int j = (
unsigned int)ip1.
get_j(); j < ip2.
get_j(); j += (
unsigned int)(2 * deltaj)) {
602 double i = slope * j + orig;
615 LeaveCriticalSection(&m_criticalSection);
619 ReleaseDC(m_hWnd, hDCScreen);
631 void vpGDIRenderer::drawRect(
const vpImagePoint &topLeft,
unsigned int width,
unsigned int height,
const vpColor &color,
632 bool fill,
unsigned int thickness)
637 HDC hDCScreen = GetDC(m_hWnd);
638 HDC hDCMem = CreateCompatibleDC(hDCScreen);
642 COLORREF gdicolor = RGB(0, 0, 0);
645 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
647 gdicolor = RGB(color.
R, color.
G, color.
B);
648 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
654 lBrush.lbStyle = BS_SOLID;
656 lBrush.lbColor = m_colors[color.
id];
658 lBrush.lbColor = gdicolor;
661 lBrush.lbStyle = BS_HOLLOW;
662 HBRUSH hbrush = CreateBrushIndirect(&lBrush);
665 EnterCriticalSection(&m_criticalSection);
666 SelectObject(hDCMem, m_bmp);
669 SelectObject(hDCMem, hbrush);
671 SelectObject(hDCMem, hPen);
680 LeaveCriticalSection(&m_criticalSection);
682 DeleteObject(hbrush);
685 ReleaseDC(m_hWnd, hDCScreen);
692 void vpGDIRenderer::clear(
const vpColor &color)
697 drawRect(ip, m_rwidth, m_rheight, color,
true, 0);
708 void vpGDIRenderer::drawCircle(
const vpImagePoint ¢er,
unsigned int radius,
const vpColor &color,
bool fill,
709 unsigned int thickness)
713 HDC hDCScreen = GetDC(m_hWnd);
714 HDC hDCMem = CreateCompatibleDC(hDCScreen);
719 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
721 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
722 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
727 lBrush.lbStyle = BS_HOLLOW;
728 HBRUSH hbrush = CreateBrushIndirect(&lBrush);
731 int radius_ = static_cast<int>(radius);
738 EnterCriticalSection(&m_criticalSection);
739 SelectObject(hDCMem, m_bmp);
742 SelectObject(hDCMem, hbrush);
744 SelectObject(hDCMem, hPen);
748 Ellipse(hDCMem, x1, y1, x2, y2);
751 while (x2 - x1 > 0) {
756 Ellipse(hDCMem, x1, y1, x2, y2);
763 LeaveCriticalSection(&m_criticalSection);
765 DeleteObject(hbrush);
768 ReleaseDC(m_hWnd, hDCScreen);
777 void vpGDIRenderer::drawText(
const vpImagePoint &ip,
const char *text,
const vpColor &color)
780 HDC hDCScreen = GetDC(m_hWnd);
781 HDC hDCMem = CreateCompatibleDC(hDCScreen);
784 EnterCriticalSection(&m_criticalSection);
785 SelectObject(hDCMem, m_bmp);
788 SelectObject(hDCMem, m_hFont);
792 SetTextColor(hDCMem, m_colors[color.
id]);
794 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
795 SetTextColor(hDCMem, gdicolor);
799 SetBkMode(hDCMem, TRANSPARENT);
802 int length = (int)strlen(text);
805 GetTextExtentPoint32(hDCMem, text, length, &size);
813 LeaveCriticalSection(&m_criticalSection);
816 ReleaseDC(m_hWnd, hDCScreen);
826 void vpGDIRenderer::drawCross(
const vpImagePoint &ip,
unsigned int size,
const vpColor &color,
unsigned int thickness)
828 int half_size = static_cast<int>(size / 2 / m_rscale);
835 HDC hDCScreen = GetDC(m_hWnd);
836 HDC hDCMem = CreateCompatibleDC(hDCScreen);
841 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
843 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
844 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
848 EnterCriticalSection(&m_criticalSection);
849 SelectObject(hDCMem, m_bmp);
852 SelectObject(hDCMem, hPen);
868 LeaveCriticalSection(&m_criticalSection);
872 ReleaseDC(m_hWnd, hDCScreen);
886 unsigned int h,
unsigned int thickness)
888 double a = ip2.
get_i() / m_rscale - ip1.
get_i() / m_rscale;
889 double b = ip2.
get_j() / m_rscale - ip1.
get_j() / m_rscale;
899 HDC hDCScreen = GetDC(m_hWnd);
900 HDC hDCMem = CreateCompatibleDC(hDCScreen);
905 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
907 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
908 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
912 EnterCriticalSection(&m_criticalSection);
913 SelectObject(hDCMem, m_bmp);
916 SelectObject(hDCMem, hPen);
918 if ((a == 0) && (b == 0)) {
963 LeaveCriticalSection(&m_criticalSection);
967 ReleaseDC(m_hWnd, hDCScreen);
977 unsigned int size = m_rwidth * m_rheight * 4;
978 unsigned char *imBuffer =
new unsigned char[size];
981 GetBitmapBits(m_bmp, static_cast<LONG>(size), (
void *)imBuffer);
984 I.
resize(m_rheight, m_rwidth);
987 for (
unsigned int i = 0; i < size; i += 4) {
988 I.
bitmap[i >> 2].R = imBuffer[i + 2];
989 I.
bitmap[i >> 2].G = imBuffer[i + 1];
990 I.
bitmap[i >> 2].B = imBuffer[i + 0];
997 #elif !defined(VISP_BUILD_SHARED_LIBS)
1000 void dummy_vpGDIRenderer(){};