Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4OpenGLWin32Viewer.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4OpenGLWin32Viewer : Class to provide Windows specific
27// functionality for OpenGL
28//
29// 27/06/2003 : G.Barrand : implementation (at last !).
30
32#include "G4VViewer.hh"
33#include "G4VSceneHandler.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//////////////////////////////////////////////////////////////////////////////
48)
49//////////////////////////////////////////////////////////////////////////////
50//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
51{
52 if(!fHDC) return;
53 if(!fHGLRC) return;
54 ::wglMakeCurrent(fHDC,fHGLRC);
56}
57
58//////////////////////////////////////////////////////////////////////////////
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_REMOVE) ) {
69 ::TranslateMessage(&event);
70 ::DispatchMessage (&event);
71 }
72}
73
75{
77 if (fSceneHandler.GetScene() && fSceneHandler.GetScene()->GetEndOfEventModelList().size()) {
78 fNeedKernelVisit = true;
79 }
80 }
81}
82
83//////////////////////////////////////////////////////////////////////////////
85)
86//////////////////////////////////////////////////////////////////////////////
87//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
88{
89}
90
91//////////////////////////////////////////////////////////////////////////////
93)
94//////////////////////////////////////////////////////////////////////////////
95//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
96{
97}
98
99//////////////////////////////////////////////////////////////////////////////
101)
102//////////////////////////////////////////////////////////////////////////////
103//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
104{
105 if(fWindow) return; //Done.
106
107 // Bill Gates stuff...
108 static const char className[] = "G4OpenGLWin32";
109 static G4bool done = false;
110 if(done==false) {
111 WNDCLASS wc;
112 wc.style = CS_HREDRAW | CS_VREDRAW;
113 wc.lpfnWndProc = (WNDPROC)WindowProc;
114 wc.cbClsExtra = 0;
115 wc.cbWndExtra = 0;
116 wc.hInstance = ::GetModuleHandle(NULL);
117 wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
118 wc.hCursor = LoadCursor(NULL,IDC_CROSS);
119 wc.hbrBackground = NULL;
120 wc.lpszMenuName = (PTSTR)className;
121 wc.lpszClassName = (PTSTR)className;
122 ::RegisterClass(&wc);
123 done = true;
124 }
125
126 ResizeWindow(fVP.GetWindowSizeHintX(),fVP.GetWindowSizeHintY());
127
128 G4int x_res=GetSystemMetrics(SM_CXSCREEN);
129 G4int y_res=GetSystemMetrics(SM_CYSCREEN);
130
131 //FIXME : NOT tested !
132 fWindow = ::CreateWindowEx(0, (PTSTR)className, (PTSTR)fName.c_str(),
133 WS_OVERLAPPEDWINDOW,
134 //WS_CHILD | WS_VISIBLE,
135 // 0,0,
136 fVP.GetWindowAbsoluteLocationHintX(x_res),
137 fVP.GetWindowAbsoluteLocationHintY(y_res),
139 NULL, NULL,
140 ::GetModuleHandle(NULL),
141 NULL);
142 if(!fWindow) return;
143
144 ::SetWindowLongPtr(fWindow,GWLP_USERDATA,LONG_PTR(this));
145
146 // initialize OpenGL rendering :
147 fHDC = ::GetDC(fWindow);
148 if( fHDC && (SetWindowPixelFormat(fHDC)==TRUE) ) {
149 fHGLRC = ::wglCreateContext(fHDC);
150 }
151
152 if(fHDC && fHGLRC) {
153 ::wglMakeCurrent(fHDC,fHGLRC);
154 }
155
156 //G.Barrand : avoid to indirectly pass in
157 // WindowProc/[WM_SIZE,WM_PAINT]/This->DrawView()
158 // from this method. Else we have crash.
159 fInCreateWindow = true;
160
161 ::SetForegroundWindow(fWindow);
162 ::ShowWindow(fWindow,SW_SHOWDEFAULT);
163 ::UpdateWindow(fWindow);
164 ::DrawMenuBar(fWindow);
165
166 fInCreateWindow = false;
167}
168
169//////////////////////////////////////////////////////////////////////////////
172)
173:G4VViewer (scene, -1)
174,G4OpenGLViewer (scene)
175,fMouseHovered(false)
176,fMousePressed(false)
179,fHDC(0)
180,fWindow(0)
181,fHGLRC(0)
182,fInCreateWindow(false)
183//////////////////////////////////////////////////////////////////////////////
184//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
185{
186}
187
188//////////////////////////////////////////////////////////////////////////////
190)
191//////////////////////////////////////////////////////////////////////////////
192//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
193{
194 // This is the end (Jim Morisson).
195 if (fViewId >= 0) {
196 if(wglGetCurrentContext()!=NULL) wglMakeCurrent(NULL,NULL);
197 if(fHGLRC) {
198 wglDeleteContext(fHGLRC);
199 fHGLRC = NULL;
200 }
201
202 if(fWindow) {
203 ::SetWindowLongPtr(fWindow,GWLP_USERDATA,LONG(NULL));
204 if(fHDC) ::ReleaseDC(fWindow,fHDC);
205 ::DestroyWindow(fWindow);
206 }
207 }
208}
209
210//////////////////////////////////////////////////////////////////////////////
211LRESULT CALLBACK G4OpenGLWin32Viewer::WindowProc(
212 HWND aWindow
213,UINT aMessage
214,WPARAM aWParam
215,LPARAM aLParam
216)
217//////////////////////////////////////////////////////////////////////////////
218//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
219{
220 switch (aMessage) {
221 case WM_SIZE: {
222 //FIXME : have to handle WM_RESIZE
223 // Seems to be done (ovidio.pena AT upm.es, 2021/02/23)
224 auto* This = (G4OpenGLWin32Viewer*)
225 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
226 if (This) {
227 This->fWinSize_x = (G4int) LOWORD(aLParam);
228 This->fWinSize_y = (G4int) HIWORD(aLParam);
229 if (!This->fInCreateWindow) {
230 This->SetView();
231 glViewport(0, 0, This->fWinSize_x, This->fWinSize_y);
232 This->DrawView();
233 }
234 }
235 return 0;
236 }
237
238 case WM_PAINT: {
239 PAINTSTRUCT ps;
240 BeginPaint(aWindow, &ps);
241 auto* This = (G4OpenGLWin32Viewer*)
242 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
243 if (This) {
244 //FIXME : To have an automatic refresh someone have to redraw here.
245 // Seems to be done (ovidio.pena AT upm.es, 2021/02/23)
246 if(!This->fInCreateWindow) {
247 This->SetView();
248 This->ClearView();
249 This->DrawView();
250 }
251 }
252 EndPaint(aWindow, &ps);
253 return 0;
254 }
255
256 case WM_LBUTTONDOWN: {
257 auto* This = (G4OpenGLWin32Viewer*)
258 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
259 This->TrackMouse(LOWORD(aLParam), HIWORD(aLParam));
260 return 0;
261 }
262
263 case WM_RBUTTONDOWN: {
264 auto* This = (G4OpenGLWin32Viewer*)
265 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
266 This->TrackMouse(LOWORD(aLParam), HIWORD(aLParam));
267 return 0;
268 }
269
270 case WM_LBUTTONUP: {
271 auto* This = (G4OpenGLWin32Viewer*)
272 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
273 This->ReleaseMouse();
274 return 0;
275 }
276
277 case WM_RBUTTONUP: {
278 auto* This = (G4OpenGLWin32Viewer*)
279 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
280 This->ReleaseMouse();
281 return 0;
282 }
283
284 case WM_MOUSEHOVER: {
285 auto* This = (G4OpenGLWin32Viewer*)
286 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
287 This->fMouseHovered = true;
288 return 0;
289 }
290
291 case WM_MOUSELEAVE: {
292 auto* This = (G4OpenGLWin32Viewer*)
293 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
294 This->fMouseHovered = false;
295 return 0;
296 }
297
298 case WM_MOUSEMOVE: {
299 auto* This = (G4OpenGLWin32Viewer*)
300 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
301
302 if (!This->fMouseHovered) {
303 // mouse hover/leave tracking
304 TRACKMOUSEEVENT tme;
305 tme.cbSize = sizeof(tme);
306 tme.dwFlags = TME_HOVER | TME_LEAVE;
307 tme.hwndTrack = aWindow;
308 tme.dwHoverTime = HOVER_DEFAULT;
309 ::TrackMouseEvent(&tme);
310 This->fMouseHovered = true;
311 }
312
313 if (This->fMousePressed) {
314 G4int x = (G4int) LOWORD(aLParam);
315 G4int y = (G4int) HIWORD(aLParam);
316 G4int dx = x - This->fMousePressedX;
317 G4int dy = y - This->fMousePressedY;
318 This->fMousePressedX = x;
319 This->fMousePressedY = y;
320
321 if (aWParam == MK_LBUTTON) { // Rotation
322 This->SetRotation(dx, dy);
323 }
324
325 if (aWParam == MK_RBUTTON) { // Shift
326 This->SetShift(dx, dy);
327 }
328
329 This->SetView();
330 This->ClearView();
331 This->DrawView();
332 }
333
334 return 0;
335 }
336
337 case WM_MOUSEWHEEL: {
338 auto* This = (G4OpenGLWin32Viewer*)
339 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
340
341 G4int delta = (short) HIWORD(aWParam);
342
343 This->SetZoom(delta);
344 This->SetView();
345 This->ClearView();
346 This->DrawView();
347 return 0;
348 }
349
350 default:
351 return DefWindowProc(aWindow, aMessage, aWParam, aLParam);
352 }
353// return DefWindowProc(aWindow,aMessage,aWParam,aLParam);
354}
355
356//////////////////////////////////////////////////////////////////////////////
357G4bool G4OpenGLWin32Viewer::SetWindowPixelFormat(
358 HDC aHdc
359)
360//////////////////////////////////////////////////////////////////////////////
361//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
362{
363 // The ungessable...
364
365 PIXELFORMATDESCRIPTOR pfd;
366 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
367 pfd.nVersion = 1;
368 pfd.dwFlags =
369 PFD_DRAW_TO_WINDOW |
370 PFD_SUPPORT_OPENGL |
371 PFD_DOUBLEBUFFER |
372 PFD_STEREO_DONTCARE;
373 pfd.iPixelType = PFD_TYPE_RGBA;
374 pfd.cColorBits = 32;
375 pfd.cRedBits = 8;
376 pfd.cRedShift = 16;
377 pfd.cGreenBits = 8;
378 pfd.cGreenShift = 8;
379 pfd.cBlueBits = 8;
380 pfd.cBlueShift = 0;
381 pfd.cAlphaBits = 0;
382 pfd.cAlphaShift = 0;
383 pfd.cAccumBits = 64;
384 pfd.cAccumRedBits = 16;
385 pfd.cAccumGreenBits = 16;
386 pfd.cAccumBlueBits = 16;
387 pfd.cAccumAlphaBits = 0;
388 pfd.cDepthBits = 32;
389 pfd.cStencilBits = 8;
390 pfd.cAuxBuffers = 0;
391 pfd.iLayerType = PFD_MAIN_PLANE;
392 pfd.bReserved = 0;
393 pfd.dwLayerMask = 0;
394 pfd.dwVisibleMask = 0;
395 pfd.dwDamageMask = 0;
396
397 G4int pixelIndex = ::ChoosePixelFormat(aHdc,&pfd);
398 if (pixelIndex==0) {
399 pixelIndex = 1;
400 if (::DescribePixelFormat(aHdc,
401 pixelIndex,
402 sizeof(PIXELFORMATDESCRIPTOR),
403 &pfd)==0) {
404 return false;
405 }
406 }
407 if (::SetPixelFormat(aHdc,pixelIndex,&pfd)==FALSE) return false;
408 return true;
409}
410
411//////////////////////////////////////////////////////////////////////////////
412void G4OpenGLWin32Viewer::TrackMouse(
413 G4int x
414,G4int y
415)
416//////////////////////////////////////////////////////////////////////////////
417//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
418{
419 fMousePressed = true;
420 fMousePressedX = x;
421 fMousePressedY = y;
422}
423
424//////////////////////////////////////////////////////////////////////////////
425void G4OpenGLWin32Viewer::ReleaseMouse(
426)
427//////////////////////////////////////////////////////////////////////////////
428//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
429{
430 fMousePressed = false;
431 fMousePressedX = 0;
432 fMousePressedY = 0;
433}
434
435//////////////////////////////////////////////////////////////////////////////
436void G4OpenGLWin32Viewer::SetShift(
437 G4int dx
438,G4int dy
439)
440//////////////////////////////////////////////////////////////////////////////
441//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
442{
443 const G4double sceneRadius = GetSceneHandler()->GetScene()
445 const G4double scale = 300; // Roughly pixels per window, empirically chosen
446 const G4double dxScene = dx*sceneRadius/scale;
447 const G4double dyScene = dy*sceneRadius/scale;
448 fVP.IncrementPan(-dxScene,dyScene);
449}
450
451//////////////////////////////////////////////////////////////////////////////
452void G4OpenGLWin32Viewer::SetRotation(
453 G4int dx
454,G4int dy
455)
456//////////////////////////////////////////////////////////////////////////////
457//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
458{
459 // Simple ad-hoc algorithms (borrowed from G4Qt3DViewer)
460 const G4Vector3D& x_prime = fVP.GetViewpointDirection()
461 .cross(fVP.GetUpVector());
462 const G4Vector3D& y_prime = x_prime.cross(fVP.GetViewpointDirection());
463 const G4double scale = 200; // Roughly pixels per window, empirically chosen
464 G4Vector3D newViewpointDirection = fVP.GetViewpointDirection();
465 newViewpointDirection += dx*x_prime/scale;
466 newViewpointDirection += dy*y_prime/scale;
467 fVP.SetViewpointDirection(newViewpointDirection.unit());
468
469 if (fVP.GetRotationStyle() == G4ViewParameters::freeRotation) {
470 G4Vector3D newUpVector = fVP.GetUpVector();
471 newUpVector += dx*x_prime/scale;
472 newUpVector += dy*y_prime/scale;
473 fVP.SetUpVector(newUpVector.unit());
474 }
475}
476
477//////////////////////////////////////////////////////////////////////////////
478void G4OpenGLWin32Viewer::SetZoom(G4int delta)
479//////////////////////////////////////////////////////////////////////////////
480//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
481{
482 POINT mousePos;
483 GetCursorPos(&mousePos);
484 ScreenToClient(fWindow, &mousePos);
485
486 ZoomFromMouseWheel(delta, GetKeyState(VK_SHIFT) & 0x8000, mousePos.x, mousePos.y);
487
488}
489
490G4bool G4OpenGLWin32Viewer::GetWindowSize(unsigned int& a_w, unsigned int& a_h)
491{
492 a_w = fWinSize_x;
493 a_h = fWinSize_y;
494 return true;
495}
496
497G4bool G4OpenGLWin32Viewer::GetRenderAreaSize(unsigned int& a_w, unsigned int& a_h)
498{
499 a_w = fWinSize_x;
500 a_h = fWinSize_y;
501 return true;
502}
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
HepGeom::Vector3D< G4double > G4Vector3D
Definition G4Vector3D.hh:34
virtual void SetView()
unsigned int fWinSize_y
friend class G4OpenGLSceneHandler
unsigned int getWinHeight() const
void ResizeWindow(unsigned int, unsigned int)
unsigned int getWinWidth() const
G4OpenGLViewer(G4OpenGLSceneHandler &scene)
unsigned int fWinSize_x
virtual void CreateMainWindow()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
G4OpenGLWin32Viewer(G4OpenGLSceneHandler &scene)
void ShowView()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
void SetView()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
virtual ~G4OpenGLWin32Viewer()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
void CreateGLWin32Context()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
void GetWin32Connection()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
const G4VisExtent & GetExtent() const
G4Scene * GetScene() const
G4bool fNeedKernelVisit
Definition G4VViewer.hh:280
G4VSceneHandler & fSceneHandler
Definition G4VViewer.hh:268
G4String fName
Definition G4VViewer.hh:270
G4int fViewId
Definition G4VViewer.hh:269
G4ViewParameters fVP
Definition G4VViewer.hh:272
G4VViewer(G4VSceneHandler &, G4int id, const G4String &name="")
Definition G4VViewer.cc:49
G4VSceneHandler * GetSceneHandler() const
void ZoomFromMouseWheel(G4double delta, G4bool shift=false, G4double xPos=0, G4double yPos=0)
Definition G4VViewer.cc:144
G4double GetExtentRadius() const
BasicVector3D< T > cross(const BasicVector3D< T > &v) const
BasicVector3D< T > unit() const
#define TRUE
Definition globals.hh:41
#define FALSE
Definition globals.hh:38
G4bool IsMultithreadedApplication()