Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
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
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
72vpD3DRenderer::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
167vpD3DRenderer::~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
186unsigned 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
203bool 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(static_cast<float>(m_rwidth), static_cast<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
265void 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)
277}
278
285void 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
322void 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
361void 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
405void 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
445void 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
480void 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>(static_cast<int>(ceil(iP.get_i() / m_rscale)), 0);
488 int j_min = std::max<int>(static_cast<int>(ceil(iP.get_j() / m_rscale)), 0);
489 int i_max = std::min<int>(static_cast<int>(ceil((iP.get_i() + height) / m_rscale)), static_cast<int>(m_rheight));
490 int j_max = std::min<int>(static_cast<int>(ceil((iP.get_j() + width) / m_rscale)), static_cast<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
521void 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
556void 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>(static_cast<int>(ceil(iP.get_i() / m_rscale)), 0);
564 int j_min = std::max<int>(static_cast<int>(ceil(iP.get_j() / m_rscale)), 0);
565 int i_max = std::min<int>(static_cast<int>(ceil((iP.get_i() + height) / m_rscale)), static_cast<int>(m_rheight));
566 int j_max = std::min<int>(static_cast<int>(ceil((iP.get_j() + width) / m_rscale)), static_cast<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
598bool 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
643void 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() >= static_cast<int>(m_rheight) ||
647 iPscaled.get_j() >= static_cast<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
689void vpD3DRenderer::drawLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
690 unsigned int thickness, int style)
691{
692 // if the device has been initialized
693 if (pd3dDevice != nullptr) {
694 // Will contain the texture's surface drawing context
695 HDC hDCMem;
696
697 // The texture's surface
698 IDirect3DSurface9 *pd3dSurf;
699 pd3dText->GetSurfaceLevel(0, &pd3dSurf);
700
701 // We get its DC
702 pd3dSurf->GetDC(&hDCMem);
703
704 // create the pen
705 HPEN hPen;
706 if (color.id < vpColor::id_unknown)
707 hPen = CreatePen(style, static_cast<int>(thickness), colorsGDI[color.id]);
708 else {
709 COLORREF gdicolor = RGB(color.R, color.G, color.B);
710 hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
711 }
712
713 // we don't use the bkColor
714 SetBkMode(hDCMem, TRANSPARENT);
715
716 // select the pen
717 SelectObject(hDCMem, hPen);
718
719 // Warning: When thickness > 1 and pen style is PS_DASHDOT, the drawing
720 // displays a solid line That's why in that case we implement the dashdot
721 // line manually drawing multiple small lines
722 if (thickness != 1 && style != PS_SOLID) {
723 vpImagePoint ip1_ = ip1;
724 vpImagePoint ip2_ = ip2;
725
726 double size = 10. * m_rscale;
727 double length = sqrt(vpMath::sqr(ip2_.get_i() - ip1_.get_i()) + vpMath::sqr(ip2_.get_j() - ip1_.get_j()));
728 bool vertical_line = static_cast<int>(ip2_.get_j()) == static_cast<int>(ip1_.get_j());
729 if (vertical_line) {
730 if (ip2_.get_i() < ip1_.get_i()) {
731 std::swap(ip1_, ip2_);
732 }
733 }
734 else if (ip2_.get_j() < ip1_.get_j()) {
735 std::swap(ip1_, ip2_);
736 }
737
738 double diff_j = vertical_line ? 1 : ip2_.get_j() - ip1_.get_j();
739 double deltaj = size / length * diff_j;
740 double deltai = size / length * (ip2_.get_i() - ip1_.get_i());
741 double slope = (ip2_.get_i() - ip1_.get_i()) / diff_j;
742 double orig = ip1_.get_i() - slope * ip1_.get_j();
743
744 if (vertical_line) {
745 for (unsigned int i = static_cast<unsigned int>(ip1_.get_i()); i < ip2_.get_i(); i += static_cast<unsigned int>(2 * deltai)) {
746 double j = ip1_.get_j();
747
748 // Move to the starting point
749 MoveToEx(hDCMem, vpMath::round(j / m_rscale), vpMath::round(i / m_rscale), nullptr);
750 // Draw the line
751 LineTo(hDCMem, vpMath::round(j / m_rscale), vpMath::round((i + deltai) / m_rscale));
752 }
753 }
754 else {
755 for (unsigned int j = static_cast<unsigned int>(ip1_.get_j()); j < ip2_.get_j(); j += static_cast<unsigned int>(2 * deltaj)) {
756 double i = slope * j + orig;
757 // Move to the starting point
758 MoveToEx(hDCMem, vpMath::round(j / m_rscale), vpMath::round(i / m_rscale), nullptr);
759 // Draw the line
760 LineTo(hDCMem, vpMath::round((j + deltaj) / m_rscale), vpMath::round((i + deltai) / m_rscale));
761 }
762 }
763 }
764 else {
765 // move to the starting point
766 MoveToEx(hDCMem, vpMath::round(ip1.get_u() / m_rscale), vpMath::round(ip1.get_v() / m_rscale), nullptr);
767 // Draw the line
768 LineTo(hDCMem, vpMath::round(ip2.get_u() / m_rscale), vpMath::round(ip2.get_v() / m_rscale));
769 }
770
771 // Releases the DC
772 pd3dSurf->ReleaseDC(hDCMem);
773 // Releases the surface's interface
774 pd3dSurf->Release();
775 // Deletes additional objects
776 DeleteObject(hPen);
777 }
778}
779
789void vpD3DRenderer::drawRect(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color,
790 bool fill, unsigned int thickness)
791{
792 // if the device has been initialized
793 if (pd3dDevice != nullptr) {
794 if (fill == false) {
795 drawLine(topLeft, topLeft + vpImagePoint(0, width), color, thickness);
796 drawLine(topLeft + vpImagePoint(0, width), topLeft + vpImagePoint(height, width), color, thickness);
797 drawLine(topLeft + vpImagePoint(height, width), topLeft + vpImagePoint(height, 0), color, thickness);
798 drawLine(topLeft + vpImagePoint(height, 0), topLeft, color, thickness);
799 }
800 else {
801 vpImagePoint topLeftScaled = topLeft / m_rscale;
802 unsigned int widthScaled = width / m_rscale;
803 unsigned int heightScaled = height / m_rscale;
804
805 if (topLeftScaled.get_i() > static_cast<int>(m_rheight) - 1 || topLeftScaled.get_j() > static_cast<int>(m_rwidth) - 1 ||
806 topLeftScaled.get_i() + height < 0 || topLeftScaled.get_j() + width < 0) {
807 return;
808 }
809
810 D3DLOCKED_RECT d3dLRect;
811
812 RECT r;
813 r.top = (LONG)((topLeftScaled.get_i() > 0) ? topLeftScaled.get_i() : 0);
814 r.left = (LONG)((topLeftScaled.get_j() > 0) ? topLeftScaled.get_j() : 0);
815 r.bottom = (LONG)((topLeftScaled.get_i() + heightScaled < static_cast<int>(m_rheight)) ? topLeftScaled.get_i() + heightScaled
816 : m_rheight - 1);
817 r.right = (LONG)((topLeftScaled.get_j() + widthScaled < static_cast<int>(m_rwidth)) ? topLeftScaled.get_j() + widthScaled
818 : m_rwidth - 1);
819
820 /* unsigned */ int rectW = r.right - r.left;
821 /* unsigned */ int rectH = r.bottom - r.top;
822
823 // locks the texture to directly access it
824 if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
825 std::cout << "D3D : Couldn't lock the texture!" << std::endl;
826 return;
827 }
828
829 // gets the buffer and pitch of the texture
830 unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
831 unsigned char *buf = (unsigned char *)d3dLRect.pBits;
832
833 if (topLeftScaled.get_i() >= 0 && topLeftScaled.get_j() + widthScaled < m_rwidth &&
834 topLeftScaled.get_i() + heightScaled < m_rheight && topLeftScaled.get_j() >= 0) {
835 for (int x = 0; x < rectW; ++x) {
836 for (int y = 0; y < rectH; ++y)
837 setBufferPixel(buf, pitch, x, y, color);
838 }
839 }
840
841 // unlocks the texture
842 if (pd3dText->UnlockRect(0) != D3D_OK)
843 std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
844 }
845 }
846}
847
852void vpD3DRenderer::clear(const vpColor &color)
853{
854 // if the device has been initialized
855 if (pd3dDevice != nullptr) {
856 D3DLOCKED_RECT d3dLRect;
857
858 RECT r;
859 r.top = 0;
860 r.left = 0;
861 r.bottom = static_cast<LONG>(m_rheight);
862 r.right = static_cast<LONG>(m_rwidth);
863
864 // locks the texture to directly access it
865 if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
866 std::cout << "D3D : Couldn't lock the texture!" << std::endl;
867 return;
868 }
869
870 // gets the buffer and pitch of the texture
871 unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
872 long *buf = (long *)(d3dLRect.pBits);
873
874 unsigned long c;
875 if (color.id < vpColor::id_unknown)
876 c = colors[color.id];
877 else {
878 c = D3DCOLOR_ARGB(0xFF, color.R, color.G, color.B);
879 }
880 long *end = (long *)(buf + (pitch * m_rheight));
881
882 // fills the whole image
883 while (buf < end)
884 *buf++ = static_cast<long>(c);
885
886 // unlocks the texture
887 if (pd3dText->UnlockRect(0) != D3D_OK)
888 std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
889 }
890}
891
892// writes current circle pixels using symetry to reduce the algorithm's
893// complexity
894void vpD3DRenderer::subDrawCircle(int i, int j, int x, int y, vpColor col, unsigned char *buf, unsigned int pitch,
895 unsigned int maxX, unsigned int maxY)
896{
897 if (x == 0) {
898 setBufferPixel(buf, pitch, i, j + y, col, maxX, maxY);
899 setBufferPixel(buf, pitch, i, j - y, col, maxX, maxY);
900 setBufferPixel(buf, pitch, i + y, j, col, maxX, maxY);
901 setBufferPixel(buf, pitch, i - y, j, col, maxX, maxY);
902 }
903 else if (x == y) {
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 setBufferPixel(buf, pitch, i - x, j - y, col, maxX, maxY);
908 }
909 else if (x < y) {
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 - x, j - y, 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 setBufferPixel(buf, pitch, i - y, j - x, col, maxX, maxY);
918 }
919}
920
927void vpD3DRenderer::drawCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool /*fill*/,
928 unsigned int /*thickness*/)
929{
930 unsigned int radiusScaled = radius / m_rscale;
931 vpImagePoint centerScaled = center / m_rscale;
932 if (radiusScaled < 1 || vpMath::round(centerScaled.get_i() + radiusScaled) < 0 ||
933 vpMath::round(centerScaled.get_i() - radiusScaled) > static_cast<int>(m_rheight) ||
934 vpMath::round(centerScaled.get_j() + radiusScaled) < 0 ||
935 vpMath::round(centerScaled.get_j() - radiusScaled) > static_cast<int>(m_rwidth))
936 return;
937
938 // if the device has been initialized
939 if (pd3dDevice != nullptr) {
940 D3DLOCKED_RECT d3dLRect;
941
942 RECT rec;
943 int radiusScaled_ = static_cast<int>(radiusScaled);
944 int rleft = (vpMath::round(centerScaled.get_j() - radiusScaled_) > 0)
945 ? vpMath::round(centerScaled.get_j()) - radiusScaled_
946 : 0;
947 int rtop = (vpMath::round(centerScaled.get_i() - radiusScaled_) > 0)
948 ? vpMath::round(centerScaled.get_i()) - radiusScaled_
949 : 0;
950
951 rec.top = rtop;
952 rec.left = rleft;
953 rec.bottom = (LONG)((vpMath::round(centerScaled.get_i() + radiusScaled_) < static_cast<int>(m_rheight))
954 ? centerScaled.get_i() + radiusScaled_
955 : m_rheight - 1);
956 rec.right = (LONG)((vpMath::round(centerScaled.get_j() + radiusScaled_) < static_cast<int>(m_rwidth))
957 ? centerScaled.get_j() + radiusScaled_
958 : m_rwidth - 1);
959
960 // used as maxX and maxY for setBufferPixel
961 unsigned int rectW = static_cast<unsigned int>(rec.right - rleft);
962 unsigned int rectH = static_cast<unsigned int>(rec.bottom - rtop);
963
964 // locks the texture to directly access it
965 if (pd3dText->LockRect(0, &d3dLRect, &rec, 0) != D3D_OK) {
966 std::cout << "D3D : Couldn't lock the texture!" << std::endl;
967 return;
968 }
969
970 // gets the buffer and pitch of the texture
971 unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
972 unsigned char *buf = (unsigned char *)d3dLRect.pBits;
973
974 // Bresenham 's circle algorithm
975
976 int x = 0;
977 int y = static_cast<int>(radiusScaled);
978 int p = (3 - (y << 1));
979
980 vpImagePoint ip;
981 ip.set_i(centerScaled.get_i() - rtop);
982 ip.set_j(centerScaled.get_j() - rleft);
983
984 subDrawCircle(vpMath::round(ip.get_i()), vpMath::round(ip.get_j()), x, y, color, buf, pitch, rectW, rectH);
985 while (x < y) {
986 x++;
987 if (p < 0) {
988 p += ((x << 1) + 1) << 1;
989 }
990 else {
991 y--;
992 p += (((x - y) << 1) + 1) << 1;
993 }
994 subDrawCircle(vpMath::round(ip.get_i()), vpMath::round(ip.get_j()), x, y, color, buf, pitch, rectW, rectH);
995 }
996
997 // unlocks the texture
998 if (pd3dText->UnlockRect(0) != D3D_OK)
999 std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
1000 }
1001}
1002
1009void vpD3DRenderer::drawText(const vpImagePoint &ip, const char *text, const vpColor &color)
1010{
1011 // Will contain the texture's surface drawing context
1012 HDC hDCMem;
1013
1014 // The texture's surface
1015 IDirect3DSurface9 *pd3dSurf;
1016 pd3dText->GetSurfaceLevel(0, &pd3dSurf);
1017
1018 // We get its DC
1019 pd3dSurf->GetDC(&hDCMem);
1020
1021 // Select the font
1022 SelectObject(hDCMem, hFont);
1023
1024 // set the text color
1025 if (color.id < vpColor::id_unknown)
1026 SetTextColor(hDCMem, colorsGDI[color.id]);
1027 else {
1028 COLORREF gdicolor = RGB(color.R, color.G, color.B);
1029 SetTextColor(hDCMem, gdicolor);
1030 }
1031
1032 // we don't use the bkColor
1033 SetBkMode(hDCMem, TRANSPARENT);
1034
1035 SIZE size;
1036 int length = static_cast<int>(strlen(text));
1037
1038 // get the displayed string dimensions
1039 GetTextExtentPoint32(hDCMem, text, length, &size);
1040
1041 // displays the string
1042 TextOut(hDCMem, vpMath::round(ip.get_u() / m_rscale), vpMath::round(ip.get_v() / m_rscale), text, length);
1043
1044 // Releases the DC
1045 pd3dSurf->ReleaseDC(hDCMem);
1046 // Releases the surface's interface
1047 pd3dSurf->Release();
1048 // Deletes additional objects
1049 DeleteObject(hFont);
1050}
1051
1059void vpD3DRenderer::drawCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness)
1060{
1061 double i = ip.get_i();
1062 double j = ip.get_j();
1063 vpImagePoint ip1, ip2;
1064
1065 ip1.set_i(i - size / 2);
1066 ip1.set_j(j);
1067 ip2.set_i(i + size / 2);
1068 ip2.set_j(j);
1069 drawLine(ip1, ip2, color, thickness);
1070
1071 ip1.set_i(i);
1072 ip1.set_j(j - size / 2);
1073 ip2.set_i(i);
1074 ip2.set_j(j + size / 2);
1075
1076 drawLine(ip1, ip2, color, thickness);
1077}
1078
1088void vpD3DRenderer::drawArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int w,
1089 unsigned int h, unsigned int thickness)
1090{
1091 double a = ip2.get_i() - ip1.get_i();
1092 double b = ip2.get_j() - ip1.get_j();
1093 double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
1094
1095 // if ( ( a==0 ) && ( b==0 ) )
1096 if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
1097 (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
1098 // DisplayCrossLarge(i1,j1,3,col) ;
1099 }
1100 else {
1101 a /= lg;
1102 b /= lg;
1103
1104 vpImagePoint ip3;
1105 ip3.set_i(ip2.get_i() - w * a);
1106 ip3.set_j(ip2.get_j() - w * b);
1107
1108 vpImagePoint ip4;
1109 ip4.set_i(ip3.get_i() - b * h);
1110 ip4.set_j(ip3.get_j() + a * h);
1111
1112 if (lg > 2 * vpImagePoint::distance(ip2, ip4))
1113 drawLine(ip2, ip4, color, thickness);
1114
1115 ip4.set_i(ip3.get_i() + b * h);
1116 ip4.set_j(ip3.get_j() - a * h);
1117
1118 if (lg > 2 * vpImagePoint::distance(ip2, ip4))
1119 drawLine(ip2, ip4, color, thickness);
1120
1121 drawLine(ip1, ip2, color, thickness);
1122 }
1123}
1124
1131void TextureToRGBa(vpImage<vpRGBa> &I, unsigned char *imBuffer, unsigned int pitch)
1132{
1133 unsigned int j = I.getWidth();
1134
1135 unsigned int k = 0;
1136 for (unsigned int i = 0; i < I.getHeight() * I.getWidth(); ++i) {
1137 // go to the next line
1138 if (j == 0) {
1139 k += pitch - (I.getWidth() * 4);
1140 j = I.getWidth();
1141 }
1142
1143 // simple conversion from bgra to rgba
1144 I.bitmap[i].B = imBuffer[k + 0];
1145 I.bitmap[i].G = imBuffer[k + 1];
1146 I.bitmap[i].R = imBuffer[k + 2];
1147 I.bitmap[i].A = imBuffer[k + 3];
1148
1149 k += 4;
1150 j--;
1151 }
1152}
1153
1158void vpD3DRenderer::getImage(vpImage<vpRGBa> &I)
1159{
1160 // if the device has been initialized
1161 if (pd3dDevice != nullptr) {
1162
1163 // resize the destination image as needed
1164 I.resize(m_rheight, m_rwidth);
1165
1166 D3DLOCKED_RECT d3dLRect;
1167
1168 RECT r;
1169 r.top = 0;
1170 r.left = 0;
1171 r.bottom = static_cast<LONG>(m_rheight);
1172 r.right = static_cast<LONG>(m_rwidth);
1173
1174 // locks the whole texture to directly access it
1175 if (pd3dText->LockRect(0, &d3dLRect, &r, 0) != D3D_OK) {
1176 std::cout << "D3D : Couldn't lock the texture!" << std::endl;
1177 return;
1178 }
1179
1180 // gets the buffer and pitch of the texture
1181 unsigned int pitch = static_cast<unsigned int>(d3dLRect.Pitch);
1182 unsigned char *buf = (unsigned char *)d3dLRect.pBits;
1183
1184 // fills this image with the texture's data
1185 TextureToRGBa(I, buf, pitch);
1186
1187 // unlocks the texture
1188 if (pd3dText->UnlockRect(0) != D3D_OK)
1189 std::cout << "D3D : Couldn't unlock the texture!" << std::endl;
1190 }
1191}
1192
1193END_VISP_NAMESPACE
1194
1195#elif !defined(VISP_BUILD_SHARED_LIBS)
1196// Work around to avoid warning: libvisp_gui.a(vpD3DRenderer.cpp.o) has no symbols
1197void dummy_vpD3DRenderer() { }
1198#endif
1199#endif
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
static const vpColor white
Definition vpColor.h:193
static const vpColor red
Definition vpColor.h:198
static const vpColor darkGray
Definition vpColor.h:196
static const vpColor cyan
Definition vpColor.h:207
static const vpColor orange
Definition vpColor.h:208
static const vpColor darkRed
Definition vpColor.h:199
static const vpColor blue
Definition vpColor.h:204
static const vpColor lightGray
Definition vpColor.h:194
static const vpColor lightBlue
Definition vpColor.h:203
static const vpColor darkGreen
Definition vpColor.h:202
static const vpColor darkBlue
Definition vpColor.h:205
static const vpColor purple
Definition vpColor.h:209
static const vpColor lightGreen
Definition vpColor.h:200
static const vpColor yellow
Definition vpColor.h:206
@ id_lightBlue
Definition vpColor.h:173
@ id_yellow
Definition vpColor.h:176
@ id_darkGray
Definition vpColor.h:166
@ id_green
Definition vpColor.h:171
@ id_darkRed
Definition vpColor.h:169
@ id_lightGray
Definition vpColor.h:164
@ id_red
Definition vpColor.h:168
@ id_lightRed
Definition vpColor.h:167
@ id_white
Definition vpColor.h:163
@ id_black
Definition vpColor.h:162
@ id_blue
Definition vpColor.h:174
@ id_darkGreen
Definition vpColor.h:172
@ id_gray
Definition vpColor.h:165
@ id_lightGreen
Definition vpColor.h:170
@ id_purple
Definition vpColor.h:179
@ id_orange
Definition vpColor.h:178
@ id_cyan
Definition vpColor.h:177
@ id_darkBlue
Definition vpColor.h:175
@ id_unknown
Definition vpColor.h:181
static const vpColor lightRed
Definition vpColor.h:197
static const vpColor black
Definition vpColor.h:192
static const vpColor green
Definition vpColor.h:201
static const vpColor gray
Definition vpColor.h:195
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 ...
void set_j(double jj)
double get_j() const
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_i(double ii)
double get_u() const
double get_i() const
double get_v() const
Definition of the vpImage class member functions.
Definition vpImage.h:131
static double sqr(double x)
Definition vpMath.h:203
static int round(double x)
Definition vpMath.h:413
unsigned char B
Blue component.
Definition vpRGBa.h:327
unsigned char R
Red component.
Definition vpRGBa.h:325
unsigned char G
Green component.
Definition vpRGBa.h:326
@ alpha_default
Definition vpRGBa.h:76
unsigned char A
Additional component.
Definition vpRGBa.h:328