comparison Samples/Sdl/FusionMprSdl.cpp @ 938:eaaa9b574e05 toa2019073101

Fixed the Stone samples wrt the recent API changes (SdlOpenGLViewport, ICompositor...)
author Benjamin Golinvaux <bgo@osimis.io>
date Wed, 31 Jul 2019 10:58:16 +0200
parents f9ae731fdc25
children efc5b62b9539
comparison
equal deleted inserted replaced
937:86ac61a040c9 938:eaaa9b574e05
101 } 101 }
102 102
103 void FusionMprSdlApp::DisplayInfoText() 103 void FusionMprSdlApp::DisplayInfoText()
104 { 104 {
105 // do not try to use stuff too early! 105 // do not try to use stuff too early!
106 if (compositor_.get() == NULL) 106 ICompositor* pCompositor = &(viewport_.GetCompositor());
107 if (pCompositor == NULL)
107 return; 108 return;
108 109
109 std::stringstream msg; 110 std::stringstream msg;
110 111
111 for (std::map<std::string, std::string>::const_iterator kv = infoTextMap_.begin(); 112 for (std::map<std::string, std::string>::const_iterator kv = infoTextMap_.begin();
114 msg << kv->first << " : " << kv->second << std::endl; 115 msg << kv->first << " : " << kv->second << std::endl;
115 } 116 }
116 std::string msgS = msg.str(); 117 std::string msgS = msg.str();
117 118
118 TextSceneLayer* layerP = NULL; 119 TextSceneLayer* layerP = NULL;
119 if (GetScene()->HasLayer(FIXED_INFOTEXT_LAYER_ZINDEX)) 120 if (GetScene().HasLayer(FIXED_INFOTEXT_LAYER_ZINDEX))
120 { 121 {
121 TextSceneLayer& layer = dynamic_cast<TextSceneLayer&>( 122 TextSceneLayer& layer = dynamic_cast<TextSceneLayer&>(
122 GetScene()->GetLayer(FIXED_INFOTEXT_LAYER_ZINDEX)); 123 GetScene().GetLayer(FIXED_INFOTEXT_LAYER_ZINDEX));
123 layerP = &layer; 124 layerP = &layer;
124 } 125 }
125 else 126 else
126 { 127 {
127 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); 128 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer);
129 layer->SetColor(0, 255, 0); 130 layer->SetColor(0, 255, 0);
130 layer->SetFontIndex(1); 131 layer->SetFontIndex(1);
131 layer->SetBorder(20); 132 layer->SetBorder(20);
132 layer->SetAnchor(BitmapAnchor_TopLeft); 133 layer->SetAnchor(BitmapAnchor_TopLeft);
133 //layer->SetPosition(0,0); 134 //layer->SetPosition(0,0);
134 GetScene()->SetLayer(FIXED_INFOTEXT_LAYER_ZINDEX, layer.release()); 135 GetScene().SetLayer(FIXED_INFOTEXT_LAYER_ZINDEX, layer.release());
135 } 136 }
136 // position the fixed info text in the upper right corner 137 // position the fixed info text in the upper right corner
137 layerP->SetText(msgS.c_str()); 138 layerP->SetText(msgS.c_str());
138 double cX = compositor_->GetCanvasWidth() * (-0.5); 139 double cX = viewport_.GetCompositor().GetCanvasWidth() * (-0.5);
139 double cY = compositor_->GetCanvasHeight() * (-0.5); 140 double cY = viewport_.GetCompositor().GetCanvasHeight() * (-0.5);
140 GetScene()->GetCanvasToSceneTransform().Apply(cX,cY); 141 GetScene().GetCanvasToSceneTransform().Apply(cX,cY);
141 layerP->SetPosition(cX, cY); 142 layerP->SetPosition(cX, cY);
142 } 143 }
143 144
144 void FusionMprSdlApp::DisplayFloatingCtrlInfoText(const PointerEvent& e) 145 void FusionMprSdlApp::DisplayFloatingCtrlInfoText(const PointerEvent& e)
145 { 146 {
146 ScenePoint2D p = e.GetMainPosition().Apply(GetScene()->GetCanvasToSceneTransform()); 147 ScenePoint2D p = e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform());
147 148
148 char buf[128]; 149 char buf[128];
149 sprintf(buf, "S:(%0.02f,%0.02f) C:(%0.02f,%0.02f)", 150 sprintf(buf, "S:(%0.02f,%0.02f) C:(%0.02f,%0.02f)",
150 p.GetX(), p.GetY(), 151 p.GetX(), p.GetY(),
151 e.GetMainPosition().GetX(), e.GetMainPosition().GetY()); 152 e.GetMainPosition().GetX(), e.GetMainPosition().GetY());
152 153
153 if (GetScene()->HasLayer(FLOATING_INFOTEXT_LAYER_ZINDEX)) 154 if (GetScene().HasLayer(FLOATING_INFOTEXT_LAYER_ZINDEX))
154 { 155 {
155 TextSceneLayer& layer = 156 TextSceneLayer& layer =
156 dynamic_cast<TextSceneLayer&>(GetScene()->GetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX)); 157 dynamic_cast<TextSceneLayer&>(GetScene().GetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX));
157 layer.SetText(buf); 158 layer.SetText(buf);
158 layer.SetPosition(p.GetX(), p.GetY()); 159 layer.SetPosition(p.GetX(), p.GetY());
159 } 160 }
160 else 161 else
161 { 162 {
163 layer->SetColor(0, 255, 0); 164 layer->SetColor(0, 255, 0);
164 layer->SetText(buf); 165 layer->SetText(buf);
165 layer->SetBorder(20); 166 layer->SetBorder(20);
166 layer->SetAnchor(BitmapAnchor_BottomCenter); 167 layer->SetAnchor(BitmapAnchor_BottomCenter);
167 layer->SetPosition(p.GetX(), p.GetY()); 168 layer->SetPosition(p.GetX(), p.GetY());
168 GetScene()->SetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX, layer.release()); 169 GetScene().SetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX, layer.release());
169 } 170 }
170 } 171 }
171 172
172 void FusionMprSdlApp::HideInfoText() 173 void FusionMprSdlApp::HideInfoText()
173 { 174 {
174 GetScene()->DeleteLayer(FLOATING_INFOTEXT_LAYER_ZINDEX); 175 GetScene().DeleteLayer(FLOATING_INFOTEXT_LAYER_ZINDEX);
175 } 176 }
176 177
177 void FusionMprSdlApp::HandleApplicationEvent( 178 void FusionMprSdlApp::HandleApplicationEvent(
178 const SDL_Event & event) 179 const SDL_Event & event)
179 { 180 {
189 keyboardState[SDL_SCANCODE_LALT]) 190 keyboardState[SDL_SCANCODE_LALT])
190 { 191 {
191 // The "left-ctrl" key is down, while no tracker is present 192 // The "left-ctrl" key is down, while no tracker is present
192 // Let's display the info text 193 // Let's display the info text
193 PointerEvent e; 194 PointerEvent e;
194 e.AddPosition(compositor_->GetPixelCenterCoordinates( 195 e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
195 event.button.x, event.button.y)); 196 event.button.x, event.button.y));
196 197
197 DisplayFloatingCtrlInfoText(e); 198 DisplayFloatingCtrlInfoText(e);
198 } 199 }
199 else 200 else
202 //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)"; 203 //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)";
203 if (activeTracker_.get() != NULL) 204 if (activeTracker_.get() != NULL)
204 { 205 {
205 //LOG(TRACE) << "(activeTracker_.get() != NULL)"; 206 //LOG(TRACE) << "(activeTracker_.get() != NULL)";
206 PointerEvent e; 207 PointerEvent e;
207 e.AddPosition(compositor_->GetPixelCenterCoordinates( 208 e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
208 event.button.x, event.button.y)); 209 event.button.x, event.button.y));
209 210
210 //LOG(TRACE) << "event.button.x = " << event.button.x << " " << 211 //LOG(TRACE) << "event.button.x = " << event.button.x << " " <<
211 // "event.button.y = " << event.button.y; 212 // "event.button.y = " << event.button.y;
212 LOG(TRACE) << "activeTracker_->PointerMove(e); " << 213 LOG(TRACE) << "activeTracker_->PointerMove(e); " <<
221 else if (event.type == SDL_MOUSEBUTTONUP) 222 else if (event.type == SDL_MOUSEBUTTONUP)
222 { 223 {
223 if (activeTracker_) 224 if (activeTracker_)
224 { 225 {
225 PointerEvent e; 226 PointerEvent e;
226 e.AddPosition(compositor_->GetPixelCenterCoordinates(event.button.x, event.button.y)); 227 e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(event.button.x, event.button.y));
227 activeTracker_->PointerUp(e); 228 activeTracker_->PointerUp(e);
228 if (!activeTracker_->IsAlive()) 229 if (!activeTracker_->IsAlive())
229 activeTracker_.reset(); 230 activeTracker_.reset();
230 } 231 }
231 } 232 }
232 else if (event.type == SDL_MOUSEBUTTONDOWN) 233 else if (event.type == SDL_MOUSEBUTTONDOWN)
233 { 234 {
234 PointerEvent e; 235 PointerEvent e;
235 e.AddPosition(compositor_->GetPixelCenterCoordinates( 236 e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
236 event.button.x, event.button.y)); 237 event.button.x, event.button.y));
237 if (activeTracker_) 238 if (activeTracker_)
238 { 239 {
239 activeTracker_->PointerDown(e); 240 activeTracker_->PointerDown(e);
240 if (!activeTracker_->IsAlive()) 241 if (!activeTracker_->IsAlive())
268 LOG(WARNING) << "You cannot change the active tool when an interaction" 269 LOG(WARNING) << "You cannot change the active tool when an interaction"
269 " is taking place"; 270 " is taking place";
270 } 271 }
271 break; 272 break;
272 case SDLK_s: 273 case SDLK_s:
273 controller_->FitContent(compositor_->GetCanvasWidth(), 274 controller_->FitContent(viewport_.GetCompositor().GetCanvasWidth(),
274 compositor_->GetCanvasHeight()); 275 viewport_.GetCompositor().GetCanvasHeight());
275 break; 276 break;
276 277
277 case SDLK_z: 278 case SDLK_z:
278 LOG(TRACE) << "SDLK_z has been pressed. event.key.keysym.mod == " << event.key.keysym.mod; 279 LOG(TRACE) << "SDLK_z has been pressed. event.key.keysym.mod == " << event.key.keysym.mod;
279 if (event.key.keysym.mod & KMOD_CTRL) 280 if (event.key.keysym.mod & KMOD_CTRL)
307 break; 308 break;
308 309
309 case SDLK_c: 310 case SDLK_c:
310 TakeScreenshot( 311 TakeScreenshot(
311 "screenshot.png", 312 "screenshot.png",
312 compositor_->GetCanvasWidth(), 313 viewport_.GetCompositor().GetCanvasWidth(),
313 compositor_->GetCanvasHeight()); 314 viewport_.GetCompositor().GetCanvasHeight());
314 break; 315 break;
315 316
316 default: 317 default:
317 break; 318 break;
318 } 319 }
338 return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker 339 return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker
339 (controller_, e)); 340 (controller_, e));
340 341
341 case SDL_BUTTON_RIGHT: 342 case SDL_BUTTON_RIGHT:
342 return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker 343 return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker
343 (controller_, e, compositor_->GetCanvasHeight())); 344 (controller_, e, viewport_.GetCompositor().GetCanvasHeight()));
344 345
345 case SDL_BUTTON_LEFT: 346 case SDL_BUTTON_LEFT:
346 { 347 {
347 //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:"; 348 //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:";
348 // TODO: we need to iterate on the set of measuring tool and perform 349 // TODO: we need to iterate on the set of measuring tool and perform
370 case FusionMprGuiTool_Pan: 371 case FusionMprGuiTool_Pan:
371 return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker( 372 return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker(
372 controller_, e)); 373 controller_, e));
373 case FusionMprGuiTool_Zoom: 374 case FusionMprGuiTool_Zoom:
374 return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker( 375 return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker(
375 controller_, e, compositor_->GetCanvasHeight())); 376 controller_, e, viewport_.GetCompositor().GetCanvasHeight()));
376 //case GuiTool_AngleMeasure: 377 //case GuiTool_AngleMeasure:
377 // return new AngleMeasureTracker(GetScene(), e); 378 // return new AngleMeasureTracker(GetScene(), e);
378 //case GuiTool_CircleMeasure: 379 //case GuiTool_CircleMeasure:
379 // return new CircleMeasureTracker(GetScene(), e); 380 // return new CircleMeasureTracker(GetScene(), e);
380 //case GuiTool_EllipseMeasure: 381 //case GuiTool_EllipseMeasure:
407 , broker_(broker) 408 , broker_(broker)
408 , oracleObservable_(broker) 409 , oracleObservable_(broker)
409 , oracle_(*this) 410 , oracle_(*this)
410 , currentTool_(FusionMprGuiTool_Rotate) 411 , currentTool_(FusionMprGuiTool_Rotate)
411 , undoStack_(new UndoStack) 412 , undoStack_(new UndoStack)
413 , viewport_("Hello", 1024, 1024, false) // False means we do NOT let Windows treat this as a legacy application that needs to be scaled
412 { 414 {
413 //oracleObservable.RegisterObserverCallback 415 //oracleObservable.RegisterObserverCallback
414 //(new Callable 416 //(new Callable
415 // <FusionMprSdlApp, SleepOracleCommand::TimeoutMessage>(*this, &FusionMprSdlApp::Handle)); 417 // <FusionMprSdlApp, SleepOracleCommand::TimeoutMessage>(*this, &FusionMprSdlApp::Handle));
416 418
425 oracleObservable_.RegisterObserverCallback 427 oracleObservable_.RegisterObserverCallback
426 (new Callable 428 (new Callable
427 <FusionMprSdlApp, OracleCommandExceptionMessage>(*this, &FusionMprSdlApp::Handle)); 429 <FusionMprSdlApp, OracleCommandExceptionMessage>(*this, &FusionMprSdlApp::Handle));
428 430
429 controller_ = boost::shared_ptr<ViewportController>( 431 controller_ = boost::shared_ptr<ViewportController>(
430 new ViewportController(undoStack_, broker_)); 432 new ViewportController(undoStack_, broker_, viewport_));
431 433
432 controller_->RegisterObserverCallback( 434 controller_->RegisterObserverCallback(
433 new Callable<FusionMprSdlApp, ViewportController::SceneTransformChanged> 435 new Callable<FusionMprSdlApp, ViewportController::SceneTransformChanged>
434 (*this, &FusionMprSdlApp::OnSceneTransformChanged)); 436 (*this, &FusionMprSdlApp::OnSceneTransformChanged));
435 437
464 466
465 p[3] = 255; 467 p[3] = 255;
466 p[4] = 0; 468 p[4] = 0;
467 p[5] = 0; 469 p[5] = 0;
468 470
469 GetScene()->SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i)); 471 GetScene().SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i));
470 } 472 }
471 } 473 }
472 474
473 void FusionMprSdlApp::DisableTracker() 475 void FusionMprSdlApp::DisableTracker()
474 { 476 {
481 483
482 void FusionMprSdlApp::TakeScreenshot(const std::string& target, 484 void FusionMprSdlApp::TakeScreenshot(const std::string& target,
483 unsigned int canvasWidth, 485 unsigned int canvasWidth,
484 unsigned int canvasHeight) 486 unsigned int canvasHeight)
485 { 487 {
486 CairoCompositor compositor(*GetScene(), canvasWidth, canvasHeight); 488 CairoCompositor compositor(GetScene(), canvasWidth, canvasHeight);
487 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1); 489 compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1);
488 compositor.Refresh(); 490 compositor.Refresh();
489 491
490 Orthanc::ImageAccessor canvas; 492 Orthanc::ImageAccessor canvas;
491 compositor.GetCanvas().GetReadOnlyAccessor(canvas); 493 compositor.GetCanvas().GetReadOnlyAccessor(canvas);
555 557
556 void FusionMprSdlApp::SetVolume1(int depth, 558 void FusionMprSdlApp::SetVolume1(int depth,
557 const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume, 559 const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume,
558 OrthancStone::ILayerStyleConfigurator* style) 560 OrthancStone::ILayerStyleConfigurator* style)
559 { 561 {
560 source1_.reset(new OrthancStone::VolumeSceneLayerSource(*controller_->GetScene(), depth, volume)); 562 source1_.reset(new OrthancStone::VolumeSceneLayerSource(controller_->GetScene(), depth, volume));
561 563
562 if (style != NULL) 564 if (style != NULL)
563 { 565 {
564 source1_->SetConfigurator(style); 566 source1_->SetConfigurator(style);
565 } 567 }
567 569
568 void FusionMprSdlApp::SetVolume2(int depth, 570 void FusionMprSdlApp::SetVolume2(int depth,
569 const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume, 571 const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume,
570 OrthancStone::ILayerStyleConfigurator* style) 572 OrthancStone::ILayerStyleConfigurator* style)
571 { 573 {
572 source2_.reset(new OrthancStone::VolumeSceneLayerSource(*controller_->GetScene(), depth, volume)); 574 source2_.reset(new OrthancStone::VolumeSceneLayerSource(controller_->GetScene(), depth, volume));
573 575
574 if (style != NULL) 576 if (style != NULL)
575 { 577 {
576 source2_->SetConfigurator(style); 578 source2_->SetConfigurator(style);
577 } 579 }
578 } 580 }
579 581
580 void FusionMprSdlApp::SetStructureSet(int depth, 582 void FusionMprSdlApp::SetStructureSet(int depth,
581 const boost::shared_ptr<OrthancStone::DicomStructureSetLoader>& volume) 583 const boost::shared_ptr<OrthancStone::DicomStructureSetLoader>& volume)
582 { 584 {
583 source3_.reset(new OrthancStone::VolumeSceneLayerSource(*controller_->GetScene(), depth, volume)); 585 source3_.reset(new OrthancStone::VolumeSceneLayerSource(controller_->GetScene(), depth, volume));
584 } 586 }
585 587
586 void FusionMprSdlApp::Run() 588 void FusionMprSdlApp::Run()
587 { 589 {
588 // False means we do NOT let Windows treat this as a legacy application 590 // False means we do NOT let Windows treat this as a legacy application
589 // that needs to be scaled 591 // that needs to be scaled
590 SdlOpenGLContext window("Hello", 1024, 1024, false); 592 controller_->FitContent(viewport_.GetCanvasWidth(), viewport_.GetCanvasHeight());
591
592 controller_->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight());
593 593
594 glEnable(GL_DEBUG_OUTPUT); 594 glEnable(GL_DEBUG_OUTPUT);
595 glDebugMessageCallback(OpenGLMessageCallback, 0); 595 glDebugMessageCallback(OpenGLMessageCallback, 0);
596 596
597 compositor_.reset(new OpenGLCompositor(window, *GetScene())); 597 viewport_.GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
598
599 compositor_->SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
600 FONT_SIZE_0, Orthanc::Encoding_Latin1); 598 FONT_SIZE_0, Orthanc::Encoding_Latin1);
601 compositor_->SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT, 599 viewport_.GetCompositor().SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT,
602 FONT_SIZE_1, Orthanc::Encoding_Latin1); 600 FONT_SIZE_1, Orthanc::Encoding_Latin1);
603 601
604 602
605 //////// from loader 603 //////// from loader
606 { 604 {
673 671
674 //// END from loader 672 //// END from loader
675 673
676 while (!g_stopApplication) 674 while (!g_stopApplication)
677 { 675 {
678 compositor_->Refresh(); 676 viewport_.GetCompositor().Refresh();
679 677
680 //////// from loader 678 //////// from loader
681 if (source1_.get() != NULL) 679 if (source1_.get() != NULL)
682 { 680 {
683 source1_->Update(plane_); 681 source1_->Update(plane_);
711 event.key.repeat == 0 /* Ignore key bounce */) 709 event.key.repeat == 0 /* Ignore key bounce */)
712 { 710 {
713 switch (event.key.keysym.sym) 711 switch (event.key.keysym.sym)
714 { 712 {
715 case SDLK_f: 713 case SDLK_f:
716 window.GetWindow().ToggleMaximize(); 714 viewport_.GetWindow().ToggleMaximize();
717 break; 715 break;
718 716
719 case SDLK_s: 717 case SDLK_s:
720 controller_->FitContent( 718 controller_->FitContent(viewport_.GetCanvasWidth(), viewport_.GetCanvasHeight());
721 window.GetCanvasWidth(), window.GetCanvasHeight());
722 break; 719 break;
723 720
724 case SDLK_q: 721 case SDLK_q:
725 g_stopApplication = true; 722 g_stopApplication = true;
726 break; 723 break;
731 HandleApplicationEvent(event); 728 HandleApplicationEvent(event);
732 } 729 }
733 SDL_Delay(1); 730 SDL_Delay(1);
734 } 731 }
735 732
736 // the following is paramount because the compositor holds a reference
737 // to the scene and we do not want this reference to become dangling
738 compositor_.reset(NULL);
739
740 //// from loader 733 //// from loader
741 734
742 //Orthanc::SystemToolbox::ServerBarrier(); 735 //Orthanc::SystemToolbox::ServerBarrier();
743 736
744 /** 737 /**