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