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(){};
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