Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
74//////////////////////////////////////////////////////////////////////////////
76)
77//////////////////////////////////////////////////////////////////////////////
78//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
79{
80}
81
82//////////////////////////////////////////////////////////////////////////////
84)
85//////////////////////////////////////////////////////////////////////////////
86//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
87{
88}
89
90//////////////////////////////////////////////////////////////////////////////
92)
93//////////////////////////////////////////////////////////////////////////////
94//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
95{
96 if(fWindow) return; //Done.
97
98 // Bill Gates stuff...
99 static const char className[] = "G4OpenGLWin32";
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_APPLICATION);
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
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,fName.c_str(),
124 WS_OVERLAPPEDWINDOW,
125 //WS_CHILD | WS_VISIBLE,
126 // 0,0,
130 NULL, NULL,
131 ::GetModuleHandle(NULL),
132 NULL);
133 if(!fWindow) return;
134
135 ::SetWindowLongPtr(fWindow,GWLP_USERDATA,LONG_PTR(this));
136
137 // initialize OpenGL rendering :
138 fHDC = ::GetDC(fWindow);
139 if( fHDC && (SetWindowPixelFormat(fHDC)==TRUE) ) {
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]/This->DrawView()
149 // from this method. Else we have crash.
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//////////////////////////////////////////////////////////////////////////////
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//////////////////////////////////////////////////////////////////////////////
181)
182//////////////////////////////////////////////////////////////////////////////
183//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
184{
185 // This is the end (Jim Morisson).
186 if (fViewId >= 0) {
187 if(wglGetCurrentContext()!=NULL) wglMakeCurrent(NULL,NULL);
188 if(fHGLRC) {
189 wglDeleteContext(fHGLRC);
190 fHGLRC = NULL;
191 }
192
193 if(fWindow) {
194 ::SetWindowLongPtr(fWindow,GWLP_USERDATA,LONG(NULL));
195 if(fHDC) ::ReleaseDC(fWindow,fHDC);
196 ::DestroyWindow(fWindow);
197 }
198 }
199}
200
201//////////////////////////////////////////////////////////////////////////////
202LRESULT CALLBACK G4OpenGLWin32Viewer::WindowProc(
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.es, 2021/02/23)
215 auto* This = (G4OpenGLWin32Viewer*)
216 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
217 if (This) {
218 This->fWinSize_x = (G4int) LOWORD(aLParam);
219 This->fWinSize_y = (G4int) HIWORD(aLParam);
220 if (!This->fInCreateWindow) {
221 This->SetView();
222 glViewport(0, 0, This->fWinSize_x, This->fWinSize_y);
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, GWLP_USERDATA);
234 if (This) {
235 //FIXME : To have an automatic refresh someone have to redraw here.
236 // Seems to be done (ovidio.pena AT upm.es, 2021/02/23)
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, GWLP_USERDATA);
250 This->TrackMouse(LOWORD(aLParam), HIWORD(aLParam));
251 return 0;
252 }
253
254 case WM_RBUTTONDOWN: {
255 auto* This = (G4OpenGLWin32Viewer*)
256 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
257 This->TrackMouse(LOWORD(aLParam), HIWORD(aLParam));
258 return 0;
259 }
260
261 case WM_LBUTTONUP: {
262 auto* This = (G4OpenGLWin32Viewer*)
263 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
264 This->ReleaseMouse();
265 return 0;
266 }
267
268 case WM_RBUTTONUP: {
269 auto* This = (G4OpenGLWin32Viewer*)
270 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
271 This->ReleaseMouse();
272 return 0;
273 }
274
275 case WM_MOUSEHOVER: {
276 auto* This = (G4OpenGLWin32Viewer*)
277 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
278 This->fMouseHovered = true;
279 return 0;
280 }
281
282 case WM_MOUSELEAVE: {
283 auto* This = (G4OpenGLWin32Viewer*)
284 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
285 This->fMouseHovered = false;
286 return 0;
287 }
288
289 case WM_MOUSEMOVE: {
290 auto* This = (G4OpenGLWin32Viewer*)
291 ::GetWindowLongPtr(aWindow, GWLP_USERDATA);
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) { // Rotation
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, GWLP_USERDATA);
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, aWParam, aLParam);
344 }
345// return DefWindowProc(aWindow,aMessage,aWParam,aLParam);
346}
347
348//////////////////////////////////////////////////////////////////////////////
349G4bool G4OpenGLWin32Viewer::SetWindowPixelFormat(
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,&pfd);
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)==FALSE) return false;
400 return true;
401}
402
403//////////////////////////////////////////////////////////////////////////////
404void G4OpenGLWin32Viewer::TrackMouse(
405 G4int x
406,G4int y
407)
408//////////////////////////////////////////////////////////////////////////////
409//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
410{
411 fMousePressed = true;
412 fMousePressedX = x;
413 fMousePressedY = y;
414}
415
416//////////////////////////////////////////////////////////////////////////////
417void G4OpenGLWin32Viewer::ReleaseMouse(
418)
419//////////////////////////////////////////////////////////////////////////////
420//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
421{
422 fMousePressed = false;
423 fMousePressedX = 0;
424 fMousePressedY = 0;
425}
426
427//////////////////////////////////////////////////////////////////////////////
428void G4OpenGLWin32Viewer::SetShift(
429 G4int dx
430,G4int dy
431)
432//////////////////////////////////////////////////////////////////////////////
433//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
434{
435 const G4double sceneRadius = GetSceneHandler()->GetScene()
437 const G4double scale = 300; // Roughly pixels per window, empirically chosen
438 const G4double dxScene = dx*sceneRadius/scale;
439 const G4double dyScene = dy*sceneRadius/scale;
440 fVP.IncrementPan(-dxScene,dyScene);
441}
442
443//////////////////////////////////////////////////////////////////////////////
444void G4OpenGLWin32Viewer::SetRotation(
445 G4int dx
446,G4int dy
447)
448//////////////////////////////////////////////////////////////////////////////
449//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
450{
451 // Simple ad-hoc algorithms (borrowed from G4Qt3DViewer)
452 const G4Vector3D& x_prime = fVP.GetViewpointDirection()
454 const G4Vector3D& y_prime = x_prime.cross(fVP.GetViewpointDirection());
455 const G4double scale = 200; // Roughly pixels per window, empirically chosen
456 G4Vector3D newViewpointDirection = fVP.GetViewpointDirection();
457 newViewpointDirection += dx*x_prime/scale;
458 newViewpointDirection += dy*y_prime/scale;
459 fVP.SetViewpointDirection(newViewpointDirection.unit());
460
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//////////////////////////////////////////////////////////////////////////////
470void G4OpenGLWin32Viewer::SetZoom(
471 G4int delta
472)
473//////////////////////////////////////////////////////////////////////////////
474//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
475{
476 if (fVP.GetFieldHalfAngle() == 0.) { // Orthographic projection
477 const G4double scale = 500; // Empirically chosen
478 fVP.MultiplyZoomFactor(1. + delta/scale);
479 } else { // Perspective projection
480 const G4double scale = fVP.GetFieldHalfAngle()/(10.*deg); // Empirical
481 fVP.SetDolly(fVP.GetDolly() + delta/scale);
482 }
483}
484
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
unsigned int getWinHeight() const
void ResizeWindow(unsigned int, unsigned int)
unsigned int getWinWidth() const
virtual void CreateMainWindow()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
G4OpenGLWin32Viewer(G4OpenGLSceneHandler &scene)
void ShowView()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
void SetView()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
virtual ~G4OpenGLWin32Viewer()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
void CreateGLWin32Context()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
void GetWin32Connection()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
const G4VisExtent & GetExtent() const
G4Scene * GetScene() const
G4String fName
Definition: G4VViewer.hh:218
G4int fViewId
Definition: G4VViewer.hh:217
G4ViewParameters fVP
Definition: G4VViewer.hh:220
G4VSceneHandler * GetSceneHandler() const
void SetViewpointDirection(const G4Vector3D &viewpointDirection)
G4int GetWindowAbsoluteLocationHintY(G4int) const
unsigned int GetWindowSizeHintX() const
const G4Vector3D & GetViewpointDirection() const
G4double GetFieldHalfAngle() const
void SetDolly(G4double dolly)
G4int GetWindowAbsoluteLocationHintX(G4int) const
void IncrementPan(G4double right, G4double up)
const G4Vector3D & GetUpVector() const
void SetUpVector(const G4Vector3D &upVector)
RotationStyle GetRotationStyle() const
void MultiplyZoomFactor(G4double zoomFactorMultiplier)
unsigned int GetWindowSizeHintY() const
G4double GetDolly() const
G4double GetExtentRadius() const
Definition: G4VisExtent.cc:75
BasicVector3D< T > cross(const BasicVector3D< T > &v) const
BasicVector3D< T > unit() const
#define TRUE
Definition: globals.hh:41
#define FALSE
Definition: globals.hh:38