Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpD3DRenderer.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * D3D renderer for windows 32 display
32  */
33 
34 #include <algorithm>
35 
36 #include <visp3/core/vpConfig.h>
37 
38 #if (defined(_WIN32) & defined(VISP_HAVE_D3D9))
39 #ifndef DOXYGEN_SHOULD_SKIP_THIS
40 
41 #include <visp3/core/vpColor.h>
42 #include <visp3/core/vpMath.h>
43 #include <visp3/gui/vpD3DRenderer.h>
44 
45 BEGIN_VISP_NAMESPACE
46 
47 /*
48  Be careful, when using :
49 
50  pd3dText->LockRect(0, &d3dLRect, &r, 0)
51  ...
52  pd3dText->UnlockRect(0, &d3dLRect, &r, 0)
53 
54  to write directly to the texture's surface,
55  the pointer returned in d3dLRect points to
56  the beginning of the locked suface and not
57  to the beginning of the texture's surface.
58  That's why setBufferPixel and other accesses
59  to this buffer are done in the locked surface
60  coordinates system.
61 
62  Moreover, when directly writing to a texture's surface,
63  you musn't forget to take the pitch of this texture
64  into account (see Direct3D documentation).
65 
66 */
67 
72 vpD3DRenderer::vpD3DRenderer()
73 {
74  pD3D = nullptr;
75  pd3dDevice = nullptr;
76  pSprite = nullptr;
77  pd3dText = nullptr;
78  pd3dVideoText = nullptr;
79  textWidth = 0;
80 
81  // D3D palette
82  vpColor pcolor; // Predefined colors
83  pcolor = vpColor::black;
84  colors[vpColor::id_black] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
85  pcolor = vpColor::lightBlue;
86  colors[vpColor::id_lightBlue] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
87  pcolor = vpColor::blue;
88  colors[vpColor::id_blue] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
89  pcolor = vpColor::darkBlue;
90  colors[vpColor::id_darkBlue] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
91  pcolor = vpColor::cyan;
92  colors[vpColor::id_cyan] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
93  pcolor = vpColor::lightGreen;
94  colors[vpColor::id_lightGreen] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
95  pcolor = vpColor::green;
96  colors[vpColor::id_green] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
97  pcolor = vpColor::darkGreen;
98  colors[vpColor::id_darkGreen] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
99  pcolor = vpColor::lightRed;
100  colors[vpColor::id_lightRed] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
101  pcolor = vpColor::red;
102  colors[vpColor::id_red] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
103  pcolor = vpColor::darkRed;
104  colors[vpColor::id_darkRed] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
105  pcolor = vpColor::white;
106  colors[vpColor::id_white] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
107  pcolor = vpColor::lightGray;
108  colors[vpColor::id_lightGray] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
109  pcolor = vpColor::gray;
110  colors[vpColor::id_gray] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
111  pcolor = vpColor::darkGray;
112  colors[vpColor::id_darkGray] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
113  pcolor = vpColor::yellow;
114  colors[vpColor::id_yellow] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
115  pcolor = vpColor::orange;
116  colors[vpColor::id_orange] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
117  pcolor = vpColor::purple;
118  colors[vpColor::id_purple] = D3DCOLOR_ARGB(0xFF, pcolor.R, pcolor.G, pcolor.B);
119 
120  // initialize the GDI palette
121  pcolor = vpColor::black;
122  colorsGDI[vpColor::id_black] = RGB(pcolor.R, pcolor.G, pcolor.B);
123  pcolor = vpColor::lightBlue;
124  colorsGDI[vpColor::id_lightBlue] = RGB(pcolor.R, pcolor.G, pcolor.B);
125  pcolor = vpColor::blue;
126  colorsGDI[vpColor::id_blue] = RGB(pcolor.R, pcolor.G, pcolor.B);
127  pcolor = vpColor::darkBlue;
128  colorsGDI[vpColor::id_darkBlue] = RGB(pcolor.R, pcolor.G, pcolor.B);
129  pcolor = vpColor::cyan;
130  colorsGDI[vpColor::id_cyan] = RGB(pcolor.R, pcolor.G, pcolor.B);
131  pcolor = vpColor::lightGreen;
132  colorsGDI[vpColor::id_lightGreen] = RGB(pcolor.R, pcolor.G, pcolor.B);
133  pcolor = vpColor::green;
134  colorsGDI[vpColor::id_green] = RGB(pcolor.R, pcolor.G, pcolor.B);
135  pcolor = vpColor::darkGreen;
136  colorsGDI[vpColor::id_darkGreen] = RGB(pcolor.R, pcolor.G, pcolor.B);
137  pcolor = vpColor::lightRed;
138  colorsGDI[vpColor::id_lightRed] = RGB(pcolor.R, pcolor.G, pcolor.B);
139  pcolor = vpColor::red;
140  colorsGDI[vpColor::id_red] = RGB(pcolor.R, pcolor.G, pcolor.B);
141  pcolor = vpColor::darkRed;
142  colorsGDI[vpColor::id_darkRed] = RGB(pcolor.R, pcolor.G, pcolor.B);
143  pcolor = vpColor::white;
144  colorsGDI[vpColor::id_white] = RGB(pcolor.R, pcolor.G, pcolor.B);
145  pcolor = vpColor::lightGray;
146  colorsGDI[vpColor::id_lightGray] = RGB(pcolor.R, pcolor.G, pcolor.B);
147  pcolor = vpColor::gray;
148  colorsGDI[vpColor::id_gray] = RGB(pcolor.R, pcolor.G, pcolor.B);
149  pcolor = vpColor::darkGray;
150  colorsGDI[vpColor::id_darkGray] = RGB(pcolor.R, pcolor.G, pcolor.B);
151  pcolor = vpColor::yellow;
152  colorsGDI[vpColor::id_yellow] = RGB(pcolor.R, pcolor.G, pcolor.B);
153  pcolor = vpColor::orange;
154  colorsGDI[vpColor::id_orange] = RGB(pcolor.R, pcolor.G, pcolor.B);
155  pcolor = vpColor::purple;
156  colorsGDI[vpColor::id_purple] = RGB(pcolor.R, pcolor.G, pcolor.B);
157 
158  // Creates a logical font
159  hFont = CreateFont(18, 0, 0, 0, FW_NORMAL, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
160  CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, nullptr);
161 }
162 
167 vpD3DRenderer::~vpD3DRenderer()
168 {
169  DeleteObject(hFont);
170 
171  if (pd3dDevice != nullptr)
172  pd3dDevice->Release();
173  if (pD3D != nullptr)
174  pD3D->Release();
175  if (pd3dText != nullptr)
176  pd3dText->Release();
177  if (pd3dVideoText != nullptr)
178  pd3dVideoText->Release();
179 }
180 
186 unsigned int vpD3DRenderer::supPowerOf2(unsigned int n)
187 {
188  unsigned int i = 0;
189  while (n > 1) {
190  n >>= 1;
191  i++;
192  }
193  return static_cast<unsigned int>(1 << (i + 1));
194 }
195 
203 bool vpD3DRenderer::init(HWND hwnd, unsigned int width, unsigned int height)
204 {
205  // simple stuff
206  m_rwidth = width;
207  m_rheight = height;
208  hWnd = hwnd;
209 
210  // D3D initialize
211  if (nullptr == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
212  throw vpDisplayException(vpDisplayException::notInitializedError, "Can't initialize D3D!");
213 
214  D3DDISPLAYMODE d3ddm;
215  if (FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
216  throw vpDisplayException(vpDisplayException::notInitializedError, "Can't get the adapter's display mode!");
217 
218  D3DPRESENT_PARAMETERS d3dpp;
219  ZeroMemory(&d3dpp, sizeof(d3dpp));
220  d3dpp.BackBufferCount = 1;
221  d3dpp.Windowed = TRUE;
222  d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
223  d3dpp.BackBufferFormat = d3ddm.Format;
224 
225  // creates a d3d device
226  if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
227  D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dpp, &pd3dDevice)))
228  throw vpDisplayException(vpDisplayException::notInitializedError, "Can't create the Direct3D device!");
229 
230  // disables scene lightning
231  pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
232 
233  // inits the direct3D view (for 2D rendering)
234  initView((float)m_rwidth, (float)m_rheight);
235 
236  // computes texture size (needs to be a power-of-2 large square)
237  textWidth = supPowerOf2((m_rwidth > m_rheight) ? m_rwidth : m_rheight);
238 
239  // creates the system memory texture (the one we will directly modify)
240  // unfortunately, needs to be X8R8G8B8 in order to be able to use GDI
241  // drawing functions
242  if (D3DXCreateTexture(pd3dDevice, textWidth, textWidth, D3DX_DEFAULT, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM,
243  &pd3dText) != D3D_OK) {
244  throw vpDisplayException(vpDisplayException::notInitializedError, "Can't create memory texture!");
245  }
246 
247  // creates the video memory texture (the one we will display) -
248  if (D3DXCreateTexture(pd3dDevice, textWidth, textWidth, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8,
249  D3DPOOL_DEFAULT, &pd3dVideoText) != D3D_OK) {
250  throw vpDisplayException(vpDisplayException::notInitializedError, "Can't create video texture!");
251  }
252 
253  // creates the sprite used to render the texture
254  if (D3DXCreateSprite(pd3dDevice, &pSprite) != S_OK)
255  throw vpDisplayException(vpDisplayException::notInitializedError, "Can't create the texture's sprite!");
256 
257  return true;
258 }
259 
265 void vpD3DRenderer::initView(float WindowWidth, float WindowHeight)
266 {
267  D3DXMATRIX Ortho2D;
268  D3DXMATRIX Identity;
269 
270  D3DXMatrixOrthoLH(&Ortho2D, WindowWidth, WindowHeight, 0.0f, 1.0f);
271  D3DXMatrixIdentity(&Identity);
272 
273  if (pd3dDevice->SetTransform(D3DTS_PROJECTION, &Ortho2D) != D3D_OK ||
274  pd3dDevice->SetTransform(D3DTS_WORLD, &Identity) != D3D_OK ||
275  pd3dDevice->SetTransform(D3DTS_VIEW, &Identity) != D3D_OK)
276  throw vpDisplayException(vpDisplayException::notInitializedError, "Can't set the view!");
277 }
278 
285 void vpD3DRenderer::convert(const vpImage<vpRGBa> &I, unsigned char *imBuffer, unsigned int pitch)
286 {
287  if (m_rscale == 1) {
288  for (unsigned int i = 0; i < m_rheight; ++i) {
289  unsigned int ii_ = i * pitch;
290  for (unsigned int j = 0; j < m_rwidth; ++j) {
291  vpRGBa val = I[i][j];
292  unsigned int index_ = ii_ + j * 4;
293  imBuffer[index_] = val.B;
294  imBuffer[++index_] = val.G;
295  imBuffer[++index_] = val.R;
296  imBuffer[++index_] = val.A;
297  }
298  }
299  }
300  else {
301  for (unsigned int i = 0; i < m_rheight; ++i) {
302  unsigned int i_ = i * m_rscale;
303  unsigned int ii_ = i * pitch;
304  for (unsigned int j = 0; j < m_rwidth; ++j) {
305  vpRGBa val = I[i_][j * m_rscale];
306  unsigned int index_ = ii_ + j * 4;
307  imBuffer[index_] = val.B;
308  imBuffer[++index_] = val.G;
309  imBuffer[++index_] = val.R;
310  imBuffer[++index_] = val.A;
311  }
312  }
313  }
314 }
315 
322 void vpD3DRenderer::convert(const vpImage<unsigned char> &I, unsigned char *imBuffer, unsigned int pitch)
323 {
324  if (m_rscale == 1) {
325  for (unsigned int i = 0; i < m_rheight; ++i) {
326  unsigned int ii_ = i * pitch;
327  for (unsigned int j = 0; j < m_rwidth; ++j) {
328  unsigned char val = I[i][j];
329  unsigned int index_ = ii_ + j * 4;
330  imBuffer[index_] = val;
331  imBuffer[++index_] = val;
332  imBuffer[++index_] = val;
333  imBuffer[++index_] = vpRGBa::alpha_default;
334  }
335  }
336  }
337  else {
338  for (unsigned int i = 0; i < m_rheight; ++i) {
339  unsigned int i_ = i * m_rscale;
340  unsigned int ii_ = i * pitch;
341  for (unsigned int j = 0; j < m_rwidth; ++j) {
342  unsigned char val = I[i_][j * m_rscale];
343  unsigned int index_ = ii_ + j * 4;
344  imBuffer[index_] = val;
345  imBuffer[++index_] = val;
346  imBuffer[++index_] = val;
347  imBuffer[++index_] = vpRGBa::alpha_default;
348  }
349  }
350  }
351 }
352 
361 void vpD3DRenderer::convertROI(const vpImage<unsigned char> &I, unsigned char *imBuffer, unsigned int pitch, int i_min,
362  int j_min, int i_max, int j_max)
363 {
364  int h = i_max - i_min;
365  int w = j_max - j_min;
366 
367  if (m_rscale == 1) {
368  for (int i = 0; i < h; ++i) {
369  unsigned int i_ = i_min + i;
370  unsigned int ii_ = i * pitch;
371  for (int j = 0; j < w; ++j) {
372  unsigned char val = I[i_][j_min + j];
373  unsigned int index_ = ii_ + j * 4;
374  imBuffer[index_] = val;
375  imBuffer[++index_] = val;
376  imBuffer[++index_] = val;
377  imBuffer[++index_] = vpRGBa::alpha_default;
378  }
379  }
380  }
381  else {
382  for (int i = 0; i < h; ++i) {
383  unsigned int i_ = (i_min + i) * m_rscale;
384  unsigned int ii_ = i * pitch;
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;
391  imBuffer[++index_] = vpRGBa::alpha_default;
392  }
393  }
394  }
395 }
396 
405 void vpD3DRenderer::convertROI(const vpImage<vpRGBa> &I, unsigned char *imBuffer, unsigned int pitch, int i_min,
406  int j_min, int i_max, int j_max)
407 {
408  int h = i_max - i_min;
409  int w = j_max - j_min;
410 
411  if (m_rscale == 1) {
412  for (int i = 0; i < h; ++i) {
413  unsigned int i_ = i_min + i;
414  unsigned int ii_ = i * pitch;
415  for (int j = 0; j < w; ++j) {
416  vpRGBa val = I[i_][j_min + j];
417  unsigned int index_ = ii_ + j * 4;
418  imBuffer[index_] = val.B;
419  imBuffer[++index_] = val.G;
420  imBuffer[++index_] = val.R;
421  imBuffer[++index_] = vpRGBa::alpha_default;
422  }
423  }
424  }
425  else {
426  for (int i = 0; i < h; ++i) {
427  unsigned int i_ = (i_min + i) * m_rscale;
428  unsigned int ii_ = i * pitch;
429  for (int j = 0; j < w; ++j) {
430  vpRGBa val = I[i_][(j_min + j) * m_rscale];
431  unsigned int index_ = ii_ + j * 4;
432  imBuffer[index_] = val.B;
433  imBuffer[++index_] = val.G;
434  imBuffer[++index_] = val.R;
435  imBuffer[++index_] = vpRGBa::alpha_default;
436  }
437  }
438  }
439 }
440 
445 void vpD3DRenderer::setImg(const vpImage<vpRGBa> &im)
446 {
447  // if the device has been initialized
448  if (pd3dDevice != nullptr) {
449  D3DLOCKED_RECT d3dLRect;
450 
451  RECT r;
452  r.top = 0;
453  r.left = 0;
454  r.bottom = static_cast<signed long>(m_rheight);
455  r.right = static_cast<signed long>(m_rwidth);
456 
457  // locks the texture to directly access it
458  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
459  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
460  return;
461  }
462 
463  // gets the buffer and pitch of the texture
464  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
465  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
466 
467  // fills this texture with the image data (converted to bgra)
468  convert(im, buf, pitch);
469 
470  // unlocks the texture
471  if (pd3dText->UnlockRect(0) != D3D_OK)
472  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
473  }
474 }
475 
480 void vpD3DRenderer::setImgROI(const vpImage<vpRGBa> &im, const vpImagePoint &iP, unsigned int width,
481  unsigned int height)
482 {
483  // if the device has been initialized
484  if (pd3dDevice != nullptr) {
485  D3DLOCKED_RECT d3dLRect;
486 
487  int i_min = std::max<int>((int)ceil(iP.get_i() / m_rscale), 0);
488  int j_min = std::max<int>((int)ceil(iP.get_j() / m_rscale), 0);
489  int i_max = std::min<int>((int)ceil((iP.get_i() + height) / m_rscale), (int)m_rheight);
490  int j_max = std::min<int>((int)ceil((iP.get_j() + width) / m_rscale), (int)m_rwidth);
491 
492  RECT r;
493  r.top = (LONG)i_min;
494  r.left = (LONG)j_min;
495  r.bottom = (LONG)i_max;
496  r.right = (LONG)j_max;
497 
498  // locks the texture to directly access it
499  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
500  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
501  return;
502  }
503 
504  // gets the buffer and pitch of the texture
505  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
506  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
507 
508  // fills this texture with the image data (converted to bgra)
509  convertROI(im, buf, pitch, i_min, j_min, i_max, j_max);
510 
511  // unlocks the texture
512  if (pd3dText->UnlockRect(0) != D3D_OK)
513  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
514  }
515 }
516 
521 void vpD3DRenderer::setImg(const vpImage<unsigned char> &im)
522 {
523  // if the device has been initialized
524  if (pd3dDevice != nullptr) {
525  D3DLOCKED_RECT d3dLRect;
526 
527  RECT r;
528  r.top = 0;
529  r.left = 0;
530  r.bottom = static_cast<LONG>(m_rheight);
531  r.right = static_cast<LONG>(m_rwidth);
532 
533  // locks the texture to directly access it
534  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
535  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
536  return;
537  }
538 
539  // gets the buffer and pitch of the texture
540  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
541  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
542 
543  // fills this texture with the image data (converted to bgra)
544  convert(im, buf, pitch);
545 
546  // unlocks the texture
547  if (pd3dText->UnlockRect(0) != D3D_OK)
548  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
549  }
550 }
551 
556 void vpD3DRenderer::setImgROI(const vpImage<unsigned char> &im, const vpImagePoint &iP, unsigned int width,
557  unsigned int height)
558 {
559  // if the device has been initialized
560  if (pd3dDevice != nullptr) {
561  D3DLOCKED_RECT d3dLRect;
562 
563  int i_min = std::max<int>((int)ceil(iP.get_i() / m_rscale), 0);
564  int j_min = std::max<int>((int)ceil(iP.get_j() / m_rscale), 0);
565  int i_max = std::min<int>((int)ceil((iP.get_i() + height) / m_rscale), (int)m_rheight);
566  int j_max = std::min<int>((int)ceil((iP.get_j() + width) / m_rscale), (int)m_rwidth);
567 
568  RECT r;
569  r.top = (LONG)i_min;
570  r.left = (LONG)j_min;
571  r.bottom = (LONG)i_max;
572  r.right = (LONG)j_max;
573 
574  // locks the texture to directly access it
575  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
576  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
577  return;
578  }
579 
580  // gets the buffer and pitch of the texture
581  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
582  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
583 
584  // fills this texture with the image data (converted to bgra)
585  convertROI(im, buf, pitch, i_min, j_min, i_max, j_max);
586 
587  // unlocks the texture
588  if (pd3dText->UnlockRect(0) != D3D_OK)
589  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
590  }
591 }
592 
598 bool vpD3DRenderer::render()
599 {
600  // Clears the back buffer to a blue color
601  // pd3dDevice->Clear( 0, nullptr, D3DCLEAR_TARGET,
602  // D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
603 
604  // Begins the scene.
605  pd3dDevice->BeginScene();
606 
607  // Texture rectangle to display
608  RECT r;
609  r.top = 0;
610  r.left = 0;
611  r.bottom = static_cast<LONG>(m_rheight);
612  r.right = static_cast<LONG>(m_rwidth);
613 
614  // Updates the video memory texture with the content of the system
615  // memory texture
616  pd3dDevice->UpdateTexture(pd3dText, pd3dVideoText);
617 
618  // Displays this texture as a sprite
619 
620 #if (D3DX_SDK_VERSION <= 9)
621  pSprite->Begin(); //
622  pSprite->Draw(pd3dVideoText, &r, nullptr, nullptr, nullptr, nullptr, 0xFFFFFFFF);
623 #else
624  pSprite->Begin(0);
625  pSprite->Draw(pd3dVideoText, &r, nullptr, nullptr, 0xFFFFFFFF);
626 #endif
627  pSprite->End();
628 
629  // Ends the scene.
630  pd3dDevice->EndScene();
631  // Presents the backbuffer
632  pd3dDevice->Present(nullptr, nullptr, nullptr, nullptr);
633 
634  return true;
635 }
636 
643 void vpD3DRenderer::setPixel(const vpImagePoint &iP, const vpColor &color)
644 {
645  vpImagePoint iPscaled = iP / m_rscale;
646  if (iPscaled.get_i() < 0 || iPscaled.get_j() < 0 || iPscaled.get_i() >= (int)m_rheight ||
647  iPscaled.get_j() >= (int)m_rwidth) {
648  return;
649  }
650 
651  // if the device has been initialized
652  if (pd3dDevice != nullptr) {
653  D3DLOCKED_RECT d3dLRect;
654 
655  RECT r;
656 
657  r.top = (LONG)iPscaled.get_i();
658  r.left = (LONG)iPscaled.get_j();
659  r.bottom = (LONG)iPscaled.get_i() + 1;
660  r.right = (LONG)iPscaled.get_j() + 1;
661 
662  // locks the texture to directly access it
663  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
664  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
665  return;
666  }
667 
668  // gets the buffer and pitch of the texture
669  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
670  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
671 
672  // the coordinates are in the locked area base
673  setBufferPixel(buf, pitch, 0, 0, color);
674 
675  // unlocks the texture
676  if (pd3dText->UnlockRect(0) != D3D_OK)
677  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
678  }
679 }
680 
688 void vpD3DRenderer::drawLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
689  unsigned int thickness, int style)
690 {
691  // if the device has been initialized
692  if (pd3dDevice != nullptr) {
693  // Will contain the texture's surface drawing context
694  HDC hDCMem;
695 
696  // The texture's surface
697  IDirect3DSurface9 *pd3dSurf;
698  pd3dText->GetSurfaceLevel(0, &pd3dSurf);
699 
700  // We get its DC
701  pd3dSurf->GetDC(&hDCMem);
702 
703  // create the pen
704  HPEN hPen;
705  if (color.id < vpColor::id_unknown)
706  hPen = CreatePen(style, static_cast<int>(thickness), colorsGDI[color.id]);
707  else {
708  COLORREF gdicolor = RGB(color.R, color.G, color.B);
709  hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
710  }
711 
712  // we don't use the bkColor
713  SetBkMode(hDCMem, TRANSPARENT);
714 
715  // select the pen
716  SelectObject(hDCMem, hPen);
717 
718  // Warning: When thickness > 1 and pen style is PS_DASHDOT, the drawing
719  // displays a solid line That's why in that case we implement the dashdot
720  // line manually drawing multiple small lines
721  if (thickness != 1 && style != PS_SOLID) {
722  vpImagePoint ip1_ = ip1;
723  vpImagePoint ip2_ = ip2;
724 
725  double size = 10. * m_rscale;
726  double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
727  bool vertical_line = (int)ip2_.get_j() == (int)ip1_.get_j();
728  if (vertical_line) {
729  if (ip2_.get_i() < ip1_.get_i()) {
730  std::swap(ip1_, ip2_);
731  }
732  }
733  else if (ip2_.get_j() < ip1_.get_j()) {
734  std::swap(ip1_, ip2_);
735  }
736 
737  double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
738  double deltaj = size / length * diff_j;
739  double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
740  double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
741  double orig = ip1_.get_i() - slope * ip1_.get_j();
742 
743  if (vertical_line) {
744  for (unsigned int i = (unsigned int)ip1_.get_i(); i < ip2_.get_i(); i += (unsigned int)(2 * deltai)) {
745  double j = ip1_.get_j();
746 
747  // Move to the starting point
748  MoveToEx(hDCMem, vpMath::round(j / m_rscale), vpMath::round(i / m_rscale), nullptr);
749  // Draw the line
750  LineTo(hDCMem, vpMath::round(j / m_rscale), vpMath::round((i + deltai) / m_rscale));
751  }
752  }
753  else {
754  for (unsigned int j = (unsigned int)ip1_.get_j(); j < ip2_.get_j(); j += (unsigned int)(2 * deltaj)) {
755  double i = slope * j + orig;
756  // Move to the starting point
757  MoveToEx(hDCMem, vpMath::round(j / m_rscale), vpMath::round(i / m_rscale), nullptr);
758  // Draw the line
759  LineTo(hDCMem, vpMath::round((j + deltaj) / m_rscale), vpMath::round((i + deltai) / m_rscale));
760  }
761  }
762  }
763  else {
764  // move to the starting point
765  MoveToEx(hDCMem, vpMath::round(ip1.get_u() / m_rscale), vpMath::round(ip1.get_v() / m_rscale), nullptr);
766  // Draw the line
767  LineTo(hDCMem, vpMath::round(ip2.get_u() / m_rscale), vpMath::round(ip2.get_v() / m_rscale));
768  }
769 
770  // Releases the DC
771  pd3dSurf->ReleaseDC(hDCMem);
772  // Releases the surface's interface
773  pd3dSurf->Release();
774  // Deletes additional objects
775  DeleteObject(hPen);
776  }
777 }
778 
788 void vpD3DRenderer::drawRect(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color,
789  bool fill, unsigned int thickness)
790 {
791  // if the device has been initialized
792  if (pd3dDevice != nullptr) {
793  if (fill == false) {
794  drawLine(topLeft, topLeft + vpImagePoint(0, width), color, thickness);
795  drawLine(topLeft + vpImagePoint(0, width), topLeft + vpImagePoint(height, width), color, thickness);
796  drawLine(topLeft + vpImagePoint(height, width), topLeft + vpImagePoint(height, 0), color, thickness);
797  drawLine(topLeft + vpImagePoint(height, 0), topLeft, color, thickness);
798  }
799  else {
800  vpImagePoint topLeftScaled = topLeft / m_rscale;
801  unsigned int widthScaled = width / m_rscale;
802  unsigned int heightScaled = height / m_rscale;
803 
804  if (topLeftScaled.get_i() > (int)m_rheight - 1 || topLeftScaled.get_j() > (int)m_rwidth - 1 ||
805  topLeftScaled.get_i() + height < 0 || topLeftScaled.get_j() + width < 0) {
806  return;
807  }
808 
809  D3DLOCKED_RECT d3dLRect;
810 
811  RECT r;
812  r.top = (LONG)((topLeftScaled.get_i() > 0) ? topLeftScaled.get_i() : 0);
813  r.left = (LONG)((topLeftScaled.get_j() > 0) ? topLeftScaled.get_j() : 0);
814  r.bottom = (LONG)((topLeftScaled.get_i() + heightScaled < (int)m_rheight) ? topLeftScaled.get_i() + heightScaled
815  : m_rheight - 1);
816  r.right = (LONG)((topLeftScaled.get_j() + widthScaled < (int)m_rwidth) ? topLeftScaled.get_j() + widthScaled
817  : m_rwidth - 1);
818 
819  /* unsigned */ int rectW = r.right - r.left;
820  /* unsigned */ int rectH = r.bottom - r.top;
821 
822  // locks the texture to directly access it
823  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
824  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
825  return;
826  }
827 
828  // gets the buffer and pitch of the texture
829  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
830  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
831 
832  if (topLeftScaled.get_i() >= 0 && topLeftScaled.get_j() + widthScaled < m_rwidth &&
833  topLeftScaled.get_i() + heightScaled < m_rheight && topLeftScaled.get_j() >= 0) {
834  for (int x = 0; x < rectW; ++x) {
835  for (int y = 0; y < rectH; ++y)
836  setBufferPixel(buf, pitch, x, y, color);
837  }
838  }
839 
840  // unlocks the texture
841  if (pd3dText->UnlockRect(0) != D3D_OK)
842  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
843  }
844  }
845 }
846 
851 void vpD3DRenderer::clear(const vpColor &color)
852 {
853  // if the device has been initialized
854  if (pd3dDevice != nullptr) {
855  D3DLOCKED_RECT d3dLRect;
856 
857  RECT r;
858  r.top = 0;
859  r.left = 0;
860  r.bottom = static_cast<LONG>(m_rheight);
861  r.right = static_cast<LONG>(m_rwidth);
862 
863  // locks the texture to directly access it
864  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
865  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
866  return;
867  }
868 
869  // gets the buffer and pitch of the texture
870  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
871  long *buf = (long *)(d3dLRect.pBits);
872 
873  unsigned long c;
874  if (color.id < vpColor::id_unknown)
875  c = colors[color.id];
876  else {
877  c = D3DCOLOR_ARGB(0xFF, color.R, color.G, color.B);
878  }
879  long *end = (long *)(buf + (pitch * m_rheight));
880 
881  // fills the whole image
882  while (buf < end)
883  *buf++ = static_cast<long>(c);
884 
885  // unlocks the texture
886  if (pd3dText->UnlockRect(0) != D3D_OK)
887  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
888  }
889 }
890 
891 // writes current circle pixels using symetry to reduce the algorithm's
892 // complexity
893 void vpD3DRenderer::subDrawCircle(int i, int j, int x, int y, vpColor col, unsigned char *buf, unsigned int pitch,
894  unsigned int maxX, unsigned int maxY)
895 {
896  if (x == 0) {
897  setBufferPixel(buf, pitch, i, j + y, col, maxX, maxY);
898  setBufferPixel(buf, pitch, i, j - y, col, maxX, maxY);
899  setBufferPixel(buf, pitch, i + y, j, col, maxX, maxY);
900  setBufferPixel(buf, pitch, i - y, j, col, maxX, maxY);
901  }
902  else if (x == y) {
903  setBufferPixel(buf, pitch, i + x, j + y, col, maxX, maxY);
904  setBufferPixel(buf, pitch, i - x, j + y, col, maxX, maxY);
905  setBufferPixel(buf, pitch, i + x, j - y, col, maxX, maxY);
906  setBufferPixel(buf, pitch, i - x, j - y, col, maxX, maxY);
907  }
908  else if (x < y) {
909  setBufferPixel(buf, pitch, i + x, j + y, col, maxX, maxY);
910  setBufferPixel(buf, pitch, i - x, j + y, col, maxX, maxY);
911  setBufferPixel(buf, pitch, i + x, j - y, col, maxX, maxY);
912  setBufferPixel(buf, pitch, i - x, j - y, col, maxX, maxY);
913  setBufferPixel(buf, pitch, i + y, j + x, col, maxX, maxY);
914  setBufferPixel(buf, pitch, i - y, j + x, col, maxX, maxY);
915  setBufferPixel(buf, pitch, i + y, j - x, col, maxX, maxY);
916  setBufferPixel(buf, pitch, i - y, j - x, col, maxX, maxY);
917  }
918 }
919 
926 void vpD3DRenderer::drawCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool /*fill*/,
927  unsigned int /*thickness*/)
928 {
929  unsigned int radiusScaled = radius / m_rscale;
930  vpImagePoint centerScaled = center / m_rscale;
931  if (radiusScaled < 1 || vpMath::round(centerScaled.get_i() + radiusScaled) < 0 ||
932  vpMath::round(centerScaled.get_i() - radiusScaled) > (int)m_rheight ||
933  vpMath::round(centerScaled.get_j() + radiusScaled) < 0 ||
934  vpMath::round(centerScaled.get_j() - radiusScaled) > (int)m_rwidth)
935  return;
936 
937  // if the device has been initialized
938  if (pd3dDevice != nullptr) {
939  D3DLOCKED_RECT d3dLRect;
940 
941  RECT rec;
942  int radiusScaled_ = static_cast<int>(radiusScaled);
943  int rleft = (vpMath::round(centerScaled.get_j() - radiusScaled_) > 0)
944  ? vpMath::round(centerScaled.get_j()) - radiusScaled_
945  : 0;
946  int rtop = (vpMath::round(centerScaled.get_i() - radiusScaled_) > 0)
947  ? vpMath::round(centerScaled.get_i()) - radiusScaled_
948  : 0;
949 
950  rec.top = rtop;
951  rec.left = rleft;
952  rec.bottom = (LONG)((vpMath::round(centerScaled.get_i() + radiusScaled_) < (int)m_rheight)
953  ? centerScaled.get_i() + radiusScaled_
954  : m_rheight - 1);
955  rec.right = (LONG)((vpMath::round(centerScaled.get_j() + radiusScaled_) < (int)m_rwidth)
956  ? centerScaled.get_j() + radiusScaled_
957  : m_rwidth - 1);
958 
959  // used as maxX and maxY for setBufferPixel
960  unsigned int rectW = static_cast<unsigned int>(rec.right - rleft);
961  unsigned int rectH = static_cast<unsigned int>(rec.bottom - rtop);
962 
963  // locks the texture to directly access it
964  if (pd3dText->LockRect(0, &d3dLRect, &rec, 0) != D3D_OK) {
965  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
966  return;
967  }
968 
969  // gets the buffer and pitch of the texture
970  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
971  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
972 
973  // Bresenham 's circle algorithm
974 
975  int x = 0;
976  int y = static_cast<int>(radiusScaled);
977  int p = (3 - (y << 1));
978 
979  vpImagePoint ip;
980  ip.set_i(centerScaled.get_i() - rtop);
981  ip.set_j(centerScaled.get_j() - rleft);
982 
983  subDrawCircle(vpMath::round(ip.get_i()), vpMath::round(ip.get_j()), x, y, color, buf, pitch, rectW, rectH);
984  while (x < y) {
985  x++;
986  if (p < 0) {
987  p += ((x << 1) + 1) << 1;
988  }
989  else {
990  y--;
991  p += (((x - y) << 1) + 1) << 1;
992  }
993  subDrawCircle(vpMath::round(ip.get_i()), vpMath::round(ip.get_j()), x, y, color, buf, pitch, rectW, rectH);
994  }
995 
996  // unlocks the texture
997  if (pd3dText->UnlockRect(0) != D3D_OK)
998  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
999  }
1000 }
1001 
1008 void vpD3DRenderer::drawText(const vpImagePoint &ip, const char *text, const vpColor &color)
1009 {
1010  // Will contain the texture's surface drawing context
1011  HDC hDCMem;
1012 
1013  // The texture's surface
1014  IDirect3DSurface9 *pd3dSurf;
1015  pd3dText->GetSurfaceLevel(0, &pd3dSurf);
1016 
1017  // We get its DC
1018  pd3dSurf->GetDC(&hDCMem);
1019 
1020  // Select the font
1021  SelectObject(hDCMem, hFont);
1022 
1023  // set the text color
1024  if (color.id < vpColor::id_unknown)
1025  SetTextColor(hDCMem, colorsGDI[color.id]);
1026  else {
1027  COLORREF gdicolor = RGB(color.R, color.G, color.B);
1028  SetTextColor(hDCMem, gdicolor);
1029  }
1030 
1031  // we don't use the bkColor
1032  SetBkMode(hDCMem, TRANSPARENT);
1033 
1034  SIZE size;
1035  int length = (int)strlen(text);
1036 
1037  // get the displayed string dimensions
1038  GetTextExtentPoint32(hDCMem, text, length, &size);
1039 
1040  // displays the string
1041  TextOut(hDCMem, vpMath::round(ip.get_u() / m_rscale), vpMath::round(ip.get_v() / m_rscale), text, length);
1042 
1043  // Releases the DC
1044  pd3dSurf->ReleaseDC(hDCMem);
1045  // Releases the surface's interface
1046  pd3dSurf->Release();
1047  // Deletes additional objects
1048  DeleteObject(hFont);
1049 }
1050 
1058 void vpD3DRenderer::drawCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness)
1059 {
1060  double i = ip.get_i();
1061  double j = ip.get_j();
1062  vpImagePoint ip1, ip2;
1063 
1064  ip1.set_i(i - size / 2);
1065  ip1.set_j(j);
1066  ip2.set_i(i + size / 2);
1067  ip2.set_j(j);
1068  drawLine(ip1, ip2, color, thickness);
1069 
1070  ip1.set_i(i);
1071  ip1.set_j(j - size / 2);
1072  ip2.set_i(i);
1073  ip2.set_j(j + size / 2);
1074 
1075  drawLine(ip1, ip2, color, thickness);
1076 }
1077 
1085 void vpD3DRenderer::drawArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int w,
1086  unsigned int h, unsigned int thickness)
1087 {
1088  double a = ip2.get_i() - ip1.get_i();
1089  double b = ip2.get_j() - ip1.get_j();
1090  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
1091 
1092  // if ( ( a==0 ) && ( b==0 ) )
1093  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
1094  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
1095  // DisplayCrossLarge(i1,j1,3,col) ;
1096  }
1097  else {
1098  a /= lg;
1099  b /= lg;
1100 
1101  vpImagePoint ip3;
1102  ip3.set_i(ip2.get_i() - w * a);
1103  ip3.set_j(ip2.get_j() - w * b);
1104 
1105  vpImagePoint ip4;
1106  ip4.set_i(ip3.get_i() - b * h);
1107  ip4.set_j(ip3.get_j() + a * h);
1108 
1109  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
1110  drawLine(ip2, ip4, color, thickness);
1111 
1112  ip4.set_i(ip3.get_i() + b * h);
1113  ip4.set_j(ip3.get_j() - a * h);
1114 
1115  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
1116  drawLine(ip2, ip4, color, thickness);
1117 
1118  drawLine(ip1, ip2, color, thickness);
1119  }
1120 }
1121 
1128 void TextureToRGBa(vpImage<vpRGBa> &I, unsigned char *imBuffer, unsigned int pitch)
1129 {
1130  unsigned int j = I.getWidth();
1131 
1132  unsigned int k = 0;
1133  for (unsigned int i = 0; i < I.getHeight() * I.getWidth(); ++i) {
1134  // go to the next line
1135  if (j == 0) {
1136  k += pitch - (I.getWidth() * 4);
1137  j = I.getWidth();
1138  }
1139 
1140  // simple conversion from bgra to rgba
1141  I.bitmap[i].B = imBuffer[k + 0];
1142  I.bitmap[i].G = imBuffer[k + 1];
1143  I.bitmap[i].R = imBuffer[k + 2];
1144  I.bitmap[i].A = imBuffer[k + 3];
1145 
1146  k += 4;
1147  j--;
1148  }
1149 }
1150 
1155 void vpD3DRenderer::getImage(vpImage<vpRGBa> &I)
1156 {
1157  // if the device has been initialized
1158  if (pd3dDevice != nullptr) {
1159 
1160  // resize the destination image as needed
1161  I.resize(m_rheight, m_rwidth);
1162 
1163  D3DLOCKED_RECT d3dLRect;
1164 
1165  RECT r;
1166  r.top = 0;
1167  r.left = 0;
1168  r.bottom = static_cast<LONG>(m_rheight);
1169  r.right = static_cast<LONG>(m_rwidth);
1170 
1171  // locks the whole texture to directly access it
1172  if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
1173  std::cout << "D3D : Couldn't lock the texture!" << std::endl;
1174  return;
1175  }
1176 
1177  // gets the buffer and pitch of the texture
1178  unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
1179  unsigned char *buf = (unsigned char *)d3dLRect.pBits;
1180 
1181  // fills this image with the texture's data
1182  TextureToRGBa(I, buf, pitch);
1183 
1184  // unlocks the texture
1185  if (pd3dText->UnlockRect(0) != D3D_OK)
1186  std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
1187  }
1188 }
1189 
1190 END_VISP_NAMESPACE
1191 
1192 #elif !defined(VISP_BUILD_SHARED_LIBS)
1193 // Work around to avoid warning: libvisp_gui.a(vpD3DRenderer.cpp.o) has no symbols
1194 void dummy_vpD3DRenderer() { };
1195 #endif
1196 #endif
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
static const vpColor white
Definition: vpColor.h:212
vpColorIdentifier id
Definition: vpColor.h:206
static const vpColor red
Definition: vpColor.h:217
static const vpColor darkGray
Definition: vpColor.h:215
static const vpColor cyan
Definition: vpColor.h:226
static const vpColor orange
Definition: vpColor.h:227
static const vpColor darkRed
Definition: vpColor.h:218
static const vpColor blue
Definition: vpColor.h:223
static const vpColor lightGray
Definition: vpColor.h:213
static const vpColor lightBlue
Definition: vpColor.h:222
static const vpColor darkGreen
Definition: vpColor.h:221
static const vpColor darkBlue
Definition: vpColor.h:224
static const vpColor purple
Definition: vpColor.h:228
static const vpColor lightGreen
Definition: vpColor.h:219
static const vpColor yellow
Definition: vpColor.h:225
@ id_lightBlue
Definition: vpColor.h:184
@ id_yellow
Definition: vpColor.h:190
@ id_darkGray
Definition: vpColor.h:170
@ id_green
Definition: vpColor.h:180
@ id_darkRed
Definition: vpColor.h:176
@ id_lightGray
Definition: vpColor.h:166
@ id_red
Definition: vpColor.h:174
@ id_lightRed
Definition: vpColor.h:172
@ id_white
Definition: vpColor.h:164
@ id_black
Definition: vpColor.h:162
@ id_blue
Definition: vpColor.h:186
@ id_darkGreen
Definition: vpColor.h:182
@ id_gray
Definition: vpColor.h:168
@ id_lightGreen
Definition: vpColor.h:178
@ id_purple
Definition: vpColor.h:196
@ id_orange
Definition: vpColor.h:194
@ id_cyan
Definition: vpColor.h:192
@ id_darkBlue
Definition: vpColor.h:188
@ id_unknown
Definition: vpColor.h:199
static const vpColor lightRed
Definition: vpColor.h:216
static const vpColor black
Definition: vpColor.h:211
static const vpColor green
Definition: vpColor.h:220
static const vpColor gray
Definition: vpColor.h:214
Error that can be emitted by the vpDisplay class and its derivatives.
@ notInitializedError
Display not initialized.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
void set_j(double jj)
Definition: vpImagePoint.h:309
double get_j() const
Definition: vpImagePoint.h:125
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_i(double ii)
Definition: vpImagePoint.h:298
double get_u() const
Definition: vpImagePoint.h:136
double get_i() const
Definition: vpImagePoint.h:114
double get_v() const
Definition: vpImagePoint.h:147
unsigned int getWidth() const
Definition: vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:542
Type * bitmap
points toward the bitmap
Definition: vpImage.h:135
unsigned int getHeight() const
Definition: vpImage.h:181
static double sqr(double x)
Definition: vpMath.h:203
static int round(double x)
Definition: vpMath.h:410
Definition: vpRGBa.h:65
unsigned char B
Blue component.
Definition: vpRGBa.h:169
unsigned char R
Red component.
Definition: vpRGBa.h:167
unsigned char G
Green component.
Definition: vpRGBa.h:168
@ alpha_default
Definition: vpRGBa.h:67
unsigned char A
Additionnal component.
Definition: vpRGBa.h:170