Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4OpenGLWin32Viewer : Class to provide Wind 27 // functionality for Ope 28 // 29 // 27/06/2003 : G.Barrand : implementation (at 30 31 #include "G4OpenGLWin32Viewer.hh" 32 #include "G4VViewer.hh" 33 #include "G4VSceneHandler.hh" 34 #include "G4OpenGLSceneHandler.hh" 35 #include "G4Scene.hh" 36 37 #include "G4ios.hh" 38 #include "G4VisExtent.hh" 39 #include "G4LogicalVolume.hh" 40 #include "G4VSolid.hh" 41 #include "G4Point3D.hh" 42 #include "G4Normal3D.hh" 43 44 #include "G4SystemOfUnits.hh" 45 46 ////////////////////////////////////////////// 47 void G4OpenGLWin32Viewer::SetView ( 48 ) 49 ////////////////////////////////////////////// 50 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 51 { 52 if(!fHDC) return; 53 if(!fHGLRC) return; 54 ::wglMakeCurrent(fHDC,fHGLRC); 55 G4OpenGLViewer::SetView (); 56 } 57 58 ////////////////////////////////////////////// 59 void G4OpenGLWin32Viewer::ShowView ( 60 ) 61 ////////////////////////////////////////////// 62 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 63 { 64 if(!fHDC) return; 65 glFlush (); 66 // Empty the Windows message queue : 67 MSG event; 68 while ( ::PeekMessage(&event, NULL, 0, 0, PM 69 ::TranslateMessage(&event); 70 ::DispatchMessage (&event); 71 } 72 } 73 74 ////////////////////////////////////////////// 75 void G4OpenGLWin32Viewer::GetWin32Connection ( 76 ) 77 ////////////////////////////////////////////// 78 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 79 { 80 } 81 82 ////////////////////////////////////////////// 83 void G4OpenGLWin32Viewer::CreateGLWin32Context 84 ) 85 ////////////////////////////////////////////// 86 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 87 { 88 } 89 90 ////////////////////////////////////////////// 91 void G4OpenGLWin32Viewer::CreateMainWindow ( 92 ) 93 ////////////////////////////////////////////// 94 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 95 { 96 if(fWindow) return; //Done. 97 98 // Bill Gates stuff... 99 static const char className[] = "G4OpenGLWin 100 static G4bool done = false; 101 if(done==false) { 102 WNDCLASS wc; 103 wc.style = CS_HREDRAW | CS_VREDRAW; 104 wc.lpfnWndProc = (WNDPROC)WindowProc; 105 wc.cbClsExtra = 0; 106 wc.cbWndExtra = 0; 107 wc.hInstance = ::GetModuleHandle(NULL); 108 wc.hIcon = LoadIcon (NULL, IDI_APPLICATIO 109 wc.hCursor = LoadCursor(NULL,IDC_CROSS); 110 wc.hbrBackground = NULL; 111 wc.lpszMenuName = className; 112 wc.lpszClassName = className; 113 ::RegisterClass(&wc); 114 done = true; 115 } 116 117 ResizeWindow(fVP.GetWindowSizeHintX(),fVP.Ge 118 119 G4int x_res=GetSystemMetrics(SM_CXSCREEN); 120 G4int y_res=GetSystemMetrics(SM_CYSCREEN); 121 122 //FIXME : NOT tested ! 123 fWindow = ::CreateWindowEx(0, className,fNam 124 WS_OVERLAPPEDWINDOW, 125 //WS_CHILD | WS_VISIBLE, 126 // 0,0, 127 fVP.GetWindowAbsolu 128 fVP.GetWindowAbsolu 129 getWinWidth(), getWinHeight(), 130 NULL, NULL, 131 ::GetModuleHandle(NULL), 132 NULL); 133 if(!fWindow) return; 134 135 ::SetWindowLongPtr(fWindow,GWLP_USERDATA,LON 136 137 // initialize OpenGL rendering : 138 fHDC = ::GetDC(fWindow); 139 if( fHDC && (SetWindowPixelFormat(fHDC)==TRU 140 fHGLRC = ::wglCreateContext(fHDC); 141 } 142 143 if(fHDC && fHGLRC) { 144 ::wglMakeCurrent(fHDC,fHGLRC); 145 } 146 147 //G.Barrand : avoid to indirectly pass in 148 // WindowProc/[WM_SIZE,WM_PAINT 149 // from this method. Else we have 150 fInCreateWindow = true; 151 152 ::SetForegroundWindow(fWindow); 153 ::ShowWindow(fWindow,SW_SHOWDEFAULT); 154 ::UpdateWindow(fWindow); 155 ::DrawMenuBar(fWindow); 156 157 fInCreateWindow = false; 158 } 159 160 ////////////////////////////////////////////// 161 G4OpenGLWin32Viewer::G4OpenGLWin32Viewer ( 162 G4OpenGLSceneHandler& scene 163 ) 164 :G4VViewer (scene, -1) 165 ,G4OpenGLViewer (scene) 166 ,fMouseHovered(false) 167 ,fMousePressed(false) 168 ,fMousePressedX(0) 169 ,fMousePressedY(0) 170 ,fHDC(0) 171 ,fWindow(0) 172 ,fHGLRC(0) 173 ,fInCreateWindow(false) 174 ////////////////////////////////////////////// 175 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 176 { 177 } 178 179 ////////////////////////////////////////////// 180 G4OpenGLWin32Viewer::~G4OpenGLWin32Viewer ( 181 ) 182 ////////////////////////////////////////////// 183 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 184 { 185 // This is the end (Jim Morisson). 186 if (fViewId >= 0) { 187 if(wglGetCurrentContext()!=NULL) wglMakeCu 188 if(fHGLRC) { 189 wglDeleteContext(fHGLRC); 190 fHGLRC = NULL; 191 } 192 193 if(fWindow) { 194 ::SetWindowLongPtr(fWindow,GWLP_USERDATA 195 if(fHDC) ::ReleaseDC(fWindow,fHDC); 196 ::DestroyWindow(fWindow); 197 } 198 } 199 } 200 201 ////////////////////////////////////////////// 202 LRESULT CALLBACK G4OpenGLWin32Viewer::WindowPr 203 HWND aWindow 204 ,UINT aMessage 205 ,WPARAM aWParam 206 ,LPARAM aLParam 207 ) 208 ////////////////////////////////////////////// 209 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 210 { 211 switch (aMessage) { 212 case WM_SIZE: { 213 //FIXME : have to handle WM_RESIZE 214 // Seems to be done (ovidio.pena AT upm. 215 auto* This = (G4OpenGLWin32Viewer*) 216 ::GetWindowLongPtr(aWindow, 217 if (This) { 218 This->fWinSize_x = (G4int) LOWORD(aLPa 219 This->fWinSize_y = (G4int) HIWORD(aLPa 220 if (!This->fInCreateWindow) { 221 This->SetView(); 222 glViewport(0, 0, This->fWinSize_x, T 223 This->DrawView(); 224 } 225 } 226 return 0; 227 } 228 229 case WM_PAINT: { 230 PAINTSTRUCT ps; 231 BeginPaint(aWindow, &ps); 232 auto* This = (G4OpenGLWin32Viewer*) 233 ::GetWindowLongPtr(aWindow, 234 if (This) { 235 //FIXME : To have an automatic refresh 236 // Seems to be done (ovidio.pena AT up 237 if(!This->fInCreateWindow) { 238 This->SetView(); 239 This->ClearView(); 240 This->DrawView(); 241 } 242 } 243 EndPaint(aWindow, &ps); 244 return 0; 245 } 246 247 case WM_LBUTTONDOWN: { 248 auto* This = (G4OpenGLWin32Viewer*) 249 ::GetWindowLongPtr(aWindow, 250 This->TrackMouse(LOWORD(aLParam), HIWORD 251 return 0; 252 } 253 254 case WM_RBUTTONDOWN: { 255 auto* This = (G4OpenGLWin32Viewer*) 256 ::GetWindowLongPtr(aWindow, 257 This->TrackMouse(LOWORD(aLParam), HIWORD 258 return 0; 259 } 260 261 case WM_LBUTTONUP: { 262 auto* This = (G4OpenGLWin32Viewer*) 263 ::GetWindowLongPtr(aWindow, 264 This->ReleaseMouse(); 265 return 0; 266 } 267 268 case WM_RBUTTONUP: { 269 auto* This = (G4OpenGLWin32Viewer*) 270 ::GetWindowLongPtr(aWindow, 271 This->ReleaseMouse(); 272 return 0; 273 } 274 275 case WM_MOUSEHOVER: { 276 auto* This = (G4OpenGLWin32Viewer*) 277 ::GetWindowLongPtr(aWindow, 278 This->fMouseHovered = true; 279 return 0; 280 } 281 282 case WM_MOUSELEAVE: { 283 auto* This = (G4OpenGLWin32Viewer*) 284 ::GetWindowLongPtr(aWindow, 285 This->fMouseHovered = false; 286 return 0; 287 } 288 289 case WM_MOUSEMOVE: { 290 auto* This = (G4OpenGLWin32Viewer*) 291 ::GetWindowLongPtr(aWindow, 292 293 if (!This->fMouseHovered) { 294 // mouse hover/leave tracking 295 TRACKMOUSEEVENT tme; 296 tme.cbSize = sizeof(tme); 297 tme.dwFlags = TME_HOVER | TME_LEAVE; 298 tme.hwndTrack = aWindow; 299 tme.dwHoverTime = HOVER_DEFAULT; 300 ::TrackMouseEvent(&tme); 301 This->fMouseHovered = true; 302 } 303 304 if (This->fMousePressed) { 305 G4int x = (G4int) LOWORD(aLParam); 306 G4int y = (G4int) HIWORD(aLParam); 307 G4int dx = x - This->fMousePressedX; 308 G4int dy = y - This->fMousePressedY; 309 This->fMousePressedX = x; 310 This->fMousePressedY = y; 311 312 if (aWParam == MK_LBUTTON) { // Rotat 313 This->SetRotation(dx, dy); 314 } 315 316 if (aWParam == MK_RBUTTON) { // Shift 317 This->SetShift(dx, dy); 318 } 319 320 This->SetView(); 321 This->ClearView(); 322 This->DrawView(); 323 } 324 325 return 0; 326 } 327 328 case WM_MOUSEWHEEL: { 329 auto* This = (G4OpenGLWin32Viewer*) 330 ::GetWindowLongPtr(aWindow, 331 332 G4int delta = (short) HIWORD(aWParam); 333 334 This->SetZoom(delta); 335 336 This->SetView(); 337 This->ClearView(); 338 This->DrawView(); 339 return 0; 340 } 341 342 default: 343 return DefWindowProc(aWindow, aMessage, 344 } 345 // return DefWindowProc(aWindow,aMessage,aWPa 346 } 347 348 ////////////////////////////////////////////// 349 G4bool G4OpenGLWin32Viewer::SetWindowPixelForm 350 HDC aHdc 351 ) 352 ////////////////////////////////////////////// 353 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 354 { 355 // The ungessable... 356 357 PIXELFORMATDESCRIPTOR pfd; 358 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 359 pfd.nVersion = 1; 360 pfd.dwFlags = 361 PFD_DRAW_TO_WINDOW | 362 PFD_SUPPORT_OPENGL | 363 PFD_DOUBLEBUFFER | 364 PFD_STEREO_DONTCARE; 365 pfd.iPixelType = PFD_TYPE_RGBA; 366 pfd.cColorBits = 32; 367 pfd.cRedBits = 8; 368 pfd.cRedShift = 16; 369 pfd.cGreenBits = 8; 370 pfd.cGreenShift = 8; 371 pfd.cBlueBits = 8; 372 pfd.cBlueShift = 0; 373 pfd.cAlphaBits = 0; 374 pfd.cAlphaShift = 0; 375 pfd.cAccumBits = 64; 376 pfd.cAccumRedBits = 16; 377 pfd.cAccumGreenBits = 16; 378 pfd.cAccumBlueBits = 16; 379 pfd.cAccumAlphaBits = 0; 380 pfd.cDepthBits = 32; 381 pfd.cStencilBits = 8; 382 pfd.cAuxBuffers = 0; 383 pfd.iLayerType = PFD_MAIN_PLANE; 384 pfd.bReserved = 0; 385 pfd.dwLayerMask = 0; 386 pfd.dwVisibleMask = 0; 387 pfd.dwDamageMask = 0; 388 389 G4int pixelIndex = ::ChoosePixelFormat(aHdc, 390 if (pixelIndex==0) { 391 pixelIndex = 1; 392 if (::DescribePixelFormat(aHdc, 393 pixelIndex, 394 sizeof(PIXELFORMATDESCRIPTOR), 395 &pfd)==0) { 396 return false; 397 } 398 } 399 if (::SetPixelFormat(aHdc,pixelIndex,&pfd)== 400 return true; 401 } 402 403 ////////////////////////////////////////////// 404 void G4OpenGLWin32Viewer::TrackMouse( 405 G4int x 406 ,G4int y 407 ) 408 ////////////////////////////////////////////// 409 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 410 { 411 fMousePressed = true; 412 fMousePressedX = x; 413 fMousePressedY = y; 414 } 415 416 ////////////////////////////////////////////// 417 void G4OpenGLWin32Viewer::ReleaseMouse( 418 ) 419 ////////////////////////////////////////////// 420 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 421 { 422 fMousePressed = false; 423 fMousePressedX = 0; 424 fMousePressedY = 0; 425 } 426 427 ////////////////////////////////////////////// 428 void G4OpenGLWin32Viewer::SetShift( 429 G4int dx 430 ,G4int dy 431 ) 432 ////////////////////////////////////////////// 433 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 434 { 435 const G4double sceneRadius = GetSceneHandler 436 ->GetExtent().Get 437 const G4double scale = 300; // Roughly pixe 438 const G4double dxScene = dx*sceneRadius/scal 439 const G4double dyScene = dy*sceneRadius/scal 440 fVP.IncrementPan(-dxScene,dyScene); 441 } 442 443 ////////////////////////////////////////////// 444 void G4OpenGLWin32Viewer::SetRotation( 445 G4int dx 446 ,G4int dy 447 ) 448 ////////////////////////////////////////////// 449 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 450 { 451 // Simple ad-hoc algorithms (borrowed from G 452 const G4Vector3D& x_prime = fVP.GetViewpoint 453 .cross(fVP.GetUp 454 const G4Vector3D& y_prime = x_prime.cross(fV 455 const G4double scale = 200; // Roughly pixe 456 G4Vector3D newViewpointDirection = fVP.GetVi 457 newViewpointDirection += dx*x_prime/scale; 458 newViewpointDirection += dy*y_prime/scale; 459 fVP.SetViewpointDirection(newViewpointDirect 460 461 if (fVP.GetRotationStyle() == G4ViewParamete 462 G4Vector3D newUpVector = fVP.GetUpVector 463 newUpVector += dx*x_prime/scale; 464 newUpVector += dy*y_prime/scale; 465 fVP.SetUpVector(newUpVector.unit()); 466 } 467 } 468 469 ////////////////////////////////////////////// 470 void G4OpenGLWin32Viewer::SetZoom( 471 G4int delta 472 ) 473 ////////////////////////////////////////////// 474 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 475 { 476 if (fVP.GetFieldHalfAngle() == 0.) { // O 477 const G4double scale = 500; // Empiri 478 fVP.MultiplyZoomFactor(1. + delta/scal 479 } else { // P 480 const G4double scale = fVP.GetFieldHal 481 fVP.SetDolly(fVP.GetDolly() + delta/sc 482 } 483 } 484 485