39#include <visp3/core/vpConfig.h>
41#if (defined(VISP_HAVE_GDI))
43#ifndef DOXYGEN_SHOULD_SKIP_THIS
45#include <visp3/gui/vpGDIRenderer.h>
50vpGDIRenderer::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);
107vpGDIRenderer::~vpGDIRenderer()
110 DeleteCriticalSection(&m_criticalSection);
114 DeleteObject(m_hFont);
123bool 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);
156 convertROI(I, iP, width, height);
179 convertROI(I, iP, width, height);
185bool vpGDIRenderer::render()
189 HDC hDCScreen = BeginPaint(m_hWnd, &ps);
192 HDC hDCMem = CreateCompatibleDC(hDCScreen);
195 EnterCriticalSection(&m_criticalSection);
196 SelectObject(hDCMem, m_bmp);
199 BitBlt(hDCScreen, 0, 0,
static_cast<int>(m_rwidth),
static_cast<int>(m_rheight), hDCMem, 0, 0, SRCCOPY);
201 LeaveCriticalSection(&m_criticalSection);
203 DeleteObject(hDCMem);
205 EndPaint(m_hWnd, &ps);
218 unsigned char *imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
221 for (
unsigned int i = 0, k = 0; i < m_rwidth * m_rheight * 4; i += 4, k++) {
222 imBuffer[i + 0] = I.
bitmap[k].B;
223 imBuffer[i + 1] = I.
bitmap[k].G;
224 imBuffer[i + 2] = I.
bitmap[k].R;
225 imBuffer[i + 3] = I.
bitmap[k].A;
228 for (
unsigned int i = 0; i < m_rheight; i++) {
229 unsigned int i_ = i * m_rscale;
230 unsigned int ii_ = i * m_rwidth;
231 for (
unsigned int j = 0; j < m_rwidth; j++) {
232 vpRGBa val = I[i_][j * m_rscale];
233 unsigned int index_ = (ii_ + j) * 4;
234 imBuffer[index_] = val.
B;
235 imBuffer[++index_] = val.
G;
236 imBuffer[++index_] = val.
R;
237 imBuffer[++index_] = val.
A;
243 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
258 int i_min = (std::max)((
int)ceil(iP.
get_i() / m_rscale), 0);
259 int j_min = (std::max)((
int)ceil(iP.
get_j() / m_rscale), 0);
260 int i_max = (std::min)((
int)ceil((iP.
get_i() + height) / m_rscale), (
int)m_rheight);
261 int j_max = (std::min)((
int)ceil((iP.
get_j() + width) / m_rscale), (
int)m_rwidth);
263 int h = i_max - i_min;
264 int w = j_max - j_min;
267 unsigned char *imBuffer =
new unsigned char[w * h * 4];
272 bitmap = bitmap + (int)(i_min * iwidth + j_min);
275 for (
int i = 0; i < w * h * 4; i += 4) {
276 imBuffer[i + 0] = (bitmap + k)->B;
277 imBuffer[i + 1] = (bitmap + k)->G;
278 imBuffer[i + 2] = (bitmap + k)->R;
279 imBuffer[i + 3] = (bitmap + k)->A;
283 bitmap = bitmap + iwidth;
288 for (
int i = 0; i < h; i++) {
289 unsigned int i_ = (i_min + i) * m_rscale;
290 unsigned int ii_ = i * w;
291 for (
int j = 0; j < w; j++) {
292 vpRGBa val = I[i_][(j_min + j) * m_rscale];
293 unsigned int index_ = (ii_ + j) * 4;
294 imBuffer[index_] = val.
B;
295 imBuffer[++index_] = val.
G;
296 imBuffer[++index_] = val.
R;
297 imBuffer[++index_] = val.
A;
303 updateBitmapROI(imBuffer, i_min, j_min, w, h);
317 unsigned char *imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
320 for (
unsigned int i = 0, k = 0; i < m_rwidth * m_rheight * 4; i += 4, k++) {
321 imBuffer[i + 0] = I.
bitmap[k];
322 imBuffer[i + 1] = I.
bitmap[k];
323 imBuffer[i + 2] = I.
bitmap[k];
327 for (
unsigned int i = 0; i < m_rheight; i++) {
328 unsigned int i_ = i * m_rscale;
329 unsigned int ii_ = i * m_rwidth;
330 for (
unsigned int j = 0; j < m_rwidth; j++) {
331 unsigned char val = I[i_][j * m_rscale];
332 unsigned int index_ = (ii_ + j) * 4;
333 imBuffer[index_] = val;
334 imBuffer[++index_] = val;
335 imBuffer[++index_] = val;
342 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
357 int i_min = (std::max)((
int)ceil(iP.
get_i() / m_rscale), 0);
358 int j_min = (std::max)((
int)ceil(iP.
get_j() / m_rscale), 0);
359 int i_max = (std::min)((
int)ceil((iP.
get_i() + height) / m_rscale), (
int)m_rheight);
360 int j_max = (std::min)((
int)ceil((iP.
get_j() + width) / m_rscale), (
int)m_rwidth);
362 int h = i_max - i_min;
363 int w = j_max - j_min;
366 unsigned char *imBuffer =
new unsigned char[w * h * 4];
369 for (
int i = 0; i < h; i++) {
370 unsigned int i_ = i_min + i;
371 unsigned int ii_ = i * w;
372 for (
int j = 0; j < w; j++) {
373 unsigned char val = I[i_][j_min + j];
374 unsigned int index_ = (ii_ + j) * 4;
375 imBuffer[index_] = val;
376 imBuffer[++index_] = val;
377 imBuffer[++index_] = val;
382 for (
int i = 0; i < h; i++) {
383 unsigned int i_ = (i_min + i) * m_rscale;
384 unsigned int ii_ = i * w;
385 for (
int j = 0; j < w; j++) {
386 unsigned char val = I[i_][(j_min + j) * m_rscale];
387 unsigned int index_ = (ii_ + j) * 4;
388 imBuffer[index_] = val;
389 imBuffer[++index_] = val;
390 imBuffer[++index_] = val;
397 updateBitmapROI(imBuffer, i_min, j_min, w, h);
413bool vpGDIRenderer::updateBitmap(HBITMAP &hBmp,
unsigned char *imBuffer,
unsigned int w,
unsigned int h)
417 EnterCriticalSection(&m_criticalSection);
420 if ((m_bmp_width == w) && (m_bmp_height == h) && w != 0 && h != 0) {
422 SetBitmapBits(hBmp, w * h * 4, imBuffer);
429 if ((hBmp = CreateBitmap(
static_cast<int>(w),
static_cast<int>(h), 1, 32, (
void *)imBuffer)) == NULL)
436 LeaveCriticalSection(&m_criticalSection);
450bool vpGDIRenderer::updateBitmapROI(
unsigned char *imBuffer,
int i_min,
int j_min,
int w,
int h)
452 HBITMAP htmp = CreateBitmap(w, h, 1, 32, (
void *)imBuffer);
455 HDC hDCScreen = GetDC(m_hWnd);
456 HDC hDCMem = CreateCompatibleDC(hDCScreen);
457 HDC hDCMem2 = CreateCompatibleDC(hDCScreen);
460 EnterCriticalSection(&m_criticalSection);
461 SelectObject(hDCMem, m_bmp);
462 SelectObject(hDCMem2, htmp);
464 BitBlt(hDCMem, j_min, i_min, w, h, hDCMem2, 0, 0, SRCCOPY);
465 LeaveCriticalSection(&m_criticalSection);
468 ReleaseDC(m_hWnd, hDCScreen);
483 HDC hDCScreen = GetDC(m_hWnd);
484 HDC hDCMem = CreateCompatibleDC(hDCScreen);
487 EnterCriticalSection(&m_criticalSection);
488 SelectObject(hDCMem, m_bmp);
493 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
499 LeaveCriticalSection(&m_criticalSection);
502 ReleaseDC(m_hWnd, hDCScreen);
513 unsigned int thickness,
int style)
515 HDC hDCScreen = NULL, hDCMem = NULL;
520 hDCScreen = GetDC(m_hWnd);
523 hDCMem = CreateCompatibleDC(hDCScreen);
525 ReleaseDC(m_hWnd, hDCScreen);
531 hPen = CreatePen(style,
static_cast<int>(thickness), m_colors[color.
id]);
533 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
534 hPen = CreatePen(style,
static_cast<int>(thickness), gdicolor);
538 ReleaseDC(m_hWnd, hDCScreen);
541 if (!SetBkMode(hDCMem, TRANSPARENT)) {
544 ReleaseDC(m_hWnd, hDCScreen);
549 EnterCriticalSection(&m_criticalSection);
551 if (!SelectObject(hDCMem, m_bmp)) {
552 LeaveCriticalSection(&m_criticalSection);
555 ReleaseDC(m_hWnd, hDCScreen);
560 if (!SelectObject(hDCMem, hPen)) {
561 LeaveCriticalSection(&m_criticalSection);
564 ReleaseDC(m_hWnd, hDCScreen);
572 hDCScreen = GetDC(m_hWnd);
573 hDCMem = CreateCompatibleDC(hDCScreen);
576 hPen = CreatePen(style,
static_cast<int>(thickness), m_colors[color.
id]);
578 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
579 hPen = CreatePen(style,
static_cast<int>(thickness), gdicolor);
581 SetBkMode(hDCMem, TRANSPARENT);
584 EnterCriticalSection(&m_criticalSection);
585 SelectObject(hDCMem, m_bmp);
588 SelectObject(hDCMem, hPen);
593 if (thickness != 1 && style != PS_SOLID) {
597 double size = 10. * m_rscale;
599 bool vertical_line = (int)ip2_.
get_j() == (int)ip1_.
get_j();
602 std::swap(ip1_, ip2_);
605 std::swap(ip1_, ip2_);
608 double diff_j = vertical_line ? 1 : ip2_.
get_j() - ip1_.
get_j();
609 double deltaj = size / length * diff_j;
610 double deltai = size / length * (ip2_.
get_i() - ip1_.
get_i());
611 double slope = (ip2_.
get_i() - ip1_.
get_i()) / diff_j;
612 double orig = ip1_.
get_i() - slope * ip1_.
get_j();
615 for (
unsigned int i = (
unsigned int)ip1_.
get_i(); i < ip2_.
get_i(); i += (
unsigned int)(2 * deltai)) {
616 double j = ip1_.
get_j();
624 for (
unsigned int j = (
unsigned int)ip1_.
get_j(); j < ip2_.
get_j(); j += (
unsigned int)(2 * deltaj)) {
625 double i = slope * j + orig;
639 LeaveCriticalSection(&m_criticalSection);
643 ReleaseDC(m_hWnd, hDCScreen);
655void vpGDIRenderer::drawRect(
const vpImagePoint &topLeft,
unsigned int width,
unsigned int height,
const vpColor &color,
656 bool fill,
unsigned int thickness)
661 HDC hDCScreen = GetDC(m_hWnd);
662 HDC hDCMem = CreateCompatibleDC(hDCScreen);
666 COLORREF gdicolor = RGB(0, 0, 0);
669 hPen = CreatePen(PS_SOLID,
static_cast<int>(thickness), m_colors[color.
id]);
671 gdicolor = RGB(color.
R, color.
G, color.
B);
672 hPen = CreatePen(PS_SOLID,
static_cast<int>(thickness), gdicolor);
678 lBrush.lbStyle = BS_SOLID;
680 lBrush.lbColor = m_colors[color.
id];
682 lBrush.lbColor = gdicolor;
685 lBrush.lbStyle = BS_HOLLOW;
686 HBRUSH hbrush = CreateBrushIndirect(&lBrush);
689 EnterCriticalSection(&m_criticalSection);
690 SelectObject(hDCMem, m_bmp);
693 SelectObject(hDCMem, hbrush);
695 SelectObject(hDCMem, hPen);
704 LeaveCriticalSection(&m_criticalSection);
706 DeleteObject(hbrush);
709 ReleaseDC(m_hWnd, hDCScreen);
716void vpGDIRenderer::clear(
const vpColor &color)
721 drawRect(ip, m_rwidth, m_rheight, color,
true, 0);
732void vpGDIRenderer::drawCircle(
const vpImagePoint ¢er,
unsigned int radius,
const vpColor &color,
bool fill,
733 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);
775 while (x2 - x1 > 0) {
780 Ellipse(hDCMem, x1, y1, x2, y2);
787 LeaveCriticalSection(&m_criticalSection);
789 DeleteObject(hbrush);
792 ReleaseDC(m_hWnd, hDCScreen);
801void vpGDIRenderer::drawText(
const vpImagePoint &ip,
const char *text,
const vpColor &color)
804 HDC hDCScreen = GetDC(m_hWnd);
805 HDC hDCMem = CreateCompatibleDC(hDCScreen);
808 EnterCriticalSection(&m_criticalSection);
809 SelectObject(hDCMem, m_bmp);
812 SelectObject(hDCMem, m_hFont);
816 SetTextColor(hDCMem, m_colors[color.
id]);
818 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
819 SetTextColor(hDCMem, gdicolor);
823 SetBkMode(hDCMem, TRANSPARENT);
826 int length = (int)strlen(text);
829 GetTextExtentPoint32(hDCMem, text, length, &size);
837 LeaveCriticalSection(&m_criticalSection);
840 ReleaseDC(m_hWnd, hDCScreen);
850void vpGDIRenderer::drawCross(
const vpImagePoint &ip,
unsigned int size,
const vpColor &color,
unsigned int thickness)
852 int half_size =
static_cast<int>(size / 2 / m_rscale);
859 HDC hDCScreen = GetDC(m_hWnd);
860 HDC hDCMem = CreateCompatibleDC(hDCScreen);
865 hPen = CreatePen(PS_SOLID,
static_cast<int>(thickness), m_colors[color.
id]);
867 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
868 hPen = CreatePen(PS_SOLID,
static_cast<int>(thickness), gdicolor);
872 EnterCriticalSection(&m_criticalSection);
873 SelectObject(hDCMem, m_bmp);
876 SelectObject(hDCMem, hPen);
891 LeaveCriticalSection(&m_criticalSection);
895 ReleaseDC(m_hWnd, hDCScreen);
909 unsigned int h,
unsigned int thickness)
911 double a = ip2.
get_i() / m_rscale - ip1.
get_i() / m_rscale;
912 double b = ip2.
get_j() / m_rscale - ip1.
get_j() / m_rscale;
922 HDC hDCScreen = GetDC(m_hWnd);
923 HDC hDCMem = CreateCompatibleDC(hDCScreen);
928 hPen = CreatePen(PS_SOLID,
static_cast<int>(thickness), m_colors[color.
id]);
930 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
931 hPen = CreatePen(PS_SOLID,
static_cast<int>(thickness), gdicolor);
935 EnterCriticalSection(&m_criticalSection);
936 SelectObject(hDCMem, m_bmp);
939 SelectObject(hDCMem, hPen);
941 if ((a == 0) && (b == 0)) {
986 LeaveCriticalSection(&m_criticalSection);
990 ReleaseDC(m_hWnd, hDCScreen);
1000 unsigned int size = m_rwidth * m_rheight * 4;
1001 unsigned char *imBuffer =
new unsigned char[size];
1004 GetBitmapBits(m_bmp,
static_cast<LONG
>(size), (
void *)imBuffer);
1007 I.
resize(m_rheight, m_rwidth);
1010 for (
unsigned int i = 0; i < size; i += 4) {
1011 I.
bitmap[i >> 2].R = imBuffer[i + 2];
1012 I.
bitmap[i >> 2].G = imBuffer[i + 1];
1013 I.
bitmap[i >> 2].B = imBuffer[i + 0];
1020#elif !defined(VISP_BUILD_SHARED_LIBS)
1023void dummy_vpGDIRenderer(){};
Class to define RGB colors available for display functionalities.
static const vpColor white
static const vpColor darkGray
static const vpColor black
static const vpColor cyan
static const vpColor orange
static const vpColor darkRed
static const vpColor blue
static const vpColor lightGray
static const vpColor lightBlue
static const vpColor darkGreen
static const vpColor darkBlue
static const vpColor purple
static const vpColor lightGreen
static const vpColor yellow
static const vpColor lightRed
static const vpColor green
static const vpColor gray
Error that can be emitted by the vpDisplay class and its derivatives.
@ depthNotSupportedError
Color depth not supported.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
Definition of the vpImage class member functions.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Type * bitmap
points toward the bitmap
static double sqr(double x)
static int round(double x)
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
unsigned char A
Additionnal component.
VISP_EXPORT double measureTimeMs()