Logo ROOT  
Reference Guide
TGWin32GL.cxx
Go to the documentation of this file.
1// @(#)root/win32gdk:$Id$
2// Author: Valeriy Onuchin(TGWin32GL)/ Timur Pocheptsov (TGWin32GLManager)
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TGWin32GL
13\ingroup win32
14
15The TGWin32GL is win32gdk implementation of TVirtualGLImp class.
16*/
17
18#include <deque>
19
20#include "TGWin32GL.h"
22#include "TVirtualViewer3D.h"
23#include "TVirtualX.h"
24#include "TError.h"
25#include "TROOT.h"
26#include "TList.h"
27
28#include "Windows4Root.h"
29#include "gdk/gdk.h"
30#include "gdk/win32/gdkwin32.h"
31
32#include <GL/gl.h>
33#include <GL/glu.h>
34
35
36// Win32 GL Manager's stuff
37
41 //
42 HDC fDC;
43 HBITMAP fHBitmap;
45 //
48 //
51 //
53 //
55 //
57 //
59};
60
61namespace {
62
63 //RAII class for HDC, returned by CreateCompatibleDC
64 class CDCGuard {
65 private:
66 HDC fHDC;
67
68 CDCGuard(const CDCGuard &);
69 CDCGuard &operator = (const CDCGuard &);
70
71 public:
72 explicit CDCGuard(HDC hDC) : fHDC(hDC)
73 {}
74 ~CDCGuard()
75 {
76 if (fHDC)
77 DeleteDC(fHDC);
78 }
79 void Stop()
80 {
81 fHDC = 0;
82 }
83 };
84
85 //RAII class for HDC, returned by GetWindowDC
86 class WDCGuard {
87 private:
88 HDC fHDC;
89 Window_t fWinID;
90
91 WDCGuard(const WDCGuard &);
92 WDCGuard &operator = (const WDCGuard &);
93
94 public:
95 WDCGuard(HDC hDC, Window_t winID) : fHDC(hDC), fWinID(winID)
96 {}
97 ~WDCGuard()
98 {
99 if (fHDC)
100 ReleaseDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)fWinID), fHDC);
101 }
102 void Stop()
103 {
104 fHDC = 0;
105 }
106 };
107
108 //RAII class for HBITMAP
109 class BMPGuard {
110 private:
111 HBITMAP fBMP;
112
113 BMPGuard(const BMPGuard &);
114 BMPGuard &operator = (const BMPGuard &);
115
116 public:
117 explicit BMPGuard(HBITMAP bmp) : fBMP(bmp)
118 {}
119 ~BMPGuard()
120 {
121 if (fBMP)
122 DeleteObject(fBMP);
123 }
124 void Stop()
125 {
126 fBMP = 0;
127 }
128 };
129
130 //RAII class for HGLRC
131 class WGLGuard {
132 private:
133 HGLRC fCtx;
134
135 WGLGuard(const WGLGuard &);
136 WGLGuard &operator = (const WGLGuard &);
137
138 public:
139 explicit WGLGuard(HGLRC glrc) : fCtx(glrc)
140 {}
141 ~WGLGuard()
142 {
143 if (fCtx)
144 wglDeleteContext(fCtx);
145 }
146 void Stop()
147 {
148 fCtx = 0;
149 }
150 };
151}
152
153const PIXELFORMATDESCRIPTOR
155 sizeof doubleBufferDesc, // size of this pfd
156 1, // version number
157 PFD_DRAW_TO_WINDOW | // support window
158 PFD_SUPPORT_OPENGL | // support OpenGL
159 PFD_DOUBLEBUFFER, // double buffered
160 PFD_TYPE_RGBA, // RGBA type
161 24, // 24-bit color depth
162 0, 0, 0, 0, 0, 0, // color bits ignored
163 0, // no alpha buffer
164 0, // shift bit ignored
165 0, // no accumulation buffer
166 0, 0, 0, 0, // accum bits ignored
167 32, // 32-bit z-buffer
168 8, // stencil buffer depth
169 0, // no auxiliary buffer
170 PFD_MAIN_PLANE // main layer
171};
172
173const PIXELFORMATDESCRIPTOR
175 sizeof singleScreenDesc, // size of this pfd
176 1, // version number
177 PFD_DRAW_TO_BITMAP | // draw into bitmap
178 PFD_SUPPORT_OPENGL, // support OpenGL
179 PFD_TYPE_RGBA, // RGBA type
180 24, // 24-bit color depth
181 0, 0, 0, 0, 0, 0, // color bits ignored
182 0, // no alpha buffer
183 0, // shift bit ignored
184 0, // no accumulation buffer
185 0, 0, 0, 0, // accum bits ignored
186 32, // 32-bit z-buffer
187 8, // stencil buffer depth
188 0, // no auxiliary buffer
189 PFD_MAIN_PLANE // main layer
190};
191
193public:
195 {}
197 std::deque<TGLContext> fGLContexts;
199};
200
202{
203 //all devices should be destroyed at this moment
204 std::deque<TGLContext>::size_type i = 0;
205
206 for (; i < fGLContexts.size(); ++i) {
207 TGLContext &ctx = fGLContexts[i];
208
209 if (ctx.fGLContext) {
210 //gl context (+DIB, if exists) must be destroyed from outside, by pad.
211 ::Warning("TGWin32GLManager::~TGLWin32GLManager", "You forget to destroy gl-context %d\n", i);
212 //destroy hdc and glrc, pixmap will be destroyed by TVirtualX
213 if (ctx.fPixmapIndex != -1) {
214 gVirtualX->SelectWindow(ctx.fPixmapIndex);
215 gVirtualX->ClosePixmap();
216 }
217
218 wglDeleteContext(ctx.fGLContext);
219 ReleaseDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)gVirtualX->GetWindowID(ctx.fWindowIndex)),
220 ctx.fDC);
221 }
222 }
223}
224
226
227////////////////////////////////////////////////////////////////////////////////
228
230{
232 gROOT->GetListOfSpecials()->AddLast(this);
233 gGLManager = this;
234}
235
236////////////////////////////////////////////////////////////////////////////////
237
239{
240 delete fPimpl;
241}
242
243////////////////////////////////////////////////////////////////////////////////
244
246{
247 return gVirtualX->InitWindow(winID);
248}
249
250////////////////////////////////////////////////////////////////////////////////
251///winInd is TGWin32 index, returned by previous call gGLManager->InitGLWindow
252///returns descripto (index) of gl context or -1 if failed
253
255{
256 Window_t winID = gVirtualX->GetWindowID(winInd);
257 HDC hDC = GetWindowDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)winID));
258
259 if (!hDC) {
260 Error("CreateGLContext", "GetWindowDC failed\n");
261 return -1;
262 }
263
264 WDCGuard dcGuard(hDC, winID);
265
266 if (Int_t pixFormat = ChoosePixelFormat(hDC, &doubleBufferDesc)) {
267 if (SetPixelFormat(hDC, pixFormat, &doubleBufferDesc)) {
268 HGLRC glCtx = wglCreateContext(hDC);
269
270 if (!glCtx) {
271 Error("CreateGLContext", "wglCreateContext failed\n");
272 return -1;
273 }
274
275 TGLContext newDevice = {winInd, -1, hDC, 0, glCtx};
276 PIXELFORMATDESCRIPTOR testFormat = {};
277 DescribePixelFormat(hDC, pixFormat, sizeof testFormat, &testFormat);
278 newDevice.fHighColor = testFormat.cColorBits < 24 ? kTRUE : kFALSE;
279
280 if (TGLContext *ctx = fPimpl->fNextFreeContext) {
281 Int_t ind = ctx->fWindowIndex;
283 *ctx = newDevice;
284 dcGuard.Stop();
285 return ind;
286 } else {
287 WGLGuard wglGuard(glCtx);
288 fPimpl->fGLContexts.push_back(newDevice);
289 wglGuard.Stop();
290 dcGuard.Stop();
291 return fPimpl->fGLContexts.size() - 1;
292 }
293 } else
294 Error("CreateGLContext", "SetPixelFormat failed\n");
295 } else
296 Error("CreateGLContext", "ChoosePixelFormat failed\n");
297
298 return -1;
299}
300
301////////////////////////////////////////////////////////////////////////////////
302///Create DIB section to read GL buffer into
303
305{
306 HDC dibDC = CreateCompatibleDC(0);
307
308 if (!dibDC) {
309 Error("CreateDIB", "CreateCompatibleDC failed\n");
310 return kFALSE;
311 }
312
313 CDCGuard dcGuard(dibDC);
314
315 BITMAPINFOHEADER bmpHeader = {sizeof bmpHeader, (LONG) ctx.fW, (LONG) ctx.fH, 1, 32, BI_RGB};
316 void *bmpCnt = nullptr;
317 HBITMAP hDIB = CreateDIBSection(dibDC, (BITMAPINFO*)&bmpHeader, DIB_RGB_COLORS, &bmpCnt, 0, 0);
318
319 if (!hDIB) {
320 Error("CreateDIB", "CreateDIBSection failed\n");
321 return kFALSE;
322 }
323
324 BMPGuard bmpGuard(hDIB);
325
326 ctx.fPixmapIndex = gVirtualX->AddPixmap((Handle_t)hDIB, ctx.fW, ctx.fH);
327 ctx.fHBitmap = hDIB;
328 ctx.fDIBData = static_cast<UChar_t *>(bmpCnt);
329
330 bmpGuard.Stop();
331
332 return kTRUE;
333}
334
335////////////////////////////////////////////////////////////////////////////////
336
338{
339 TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
340 TGLContext newCtx = {ctx.fWindowIndex, -1, ctx.fDC, 0, ctx.fGLContext, w, h, x, y, ctx.fHighColor};
341
342 if (CreateDIB(newCtx)) {
343 ctx = newCtx;
344 return kTRUE;
345 }
346
347 return kFALSE;
348}
349
350////////////////////////////////////////////////////////////////////////////////
351///Create new DIB if needed
352
354{
355 TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
356
357 if (ctx.fPixmapIndex != -1)
358 if (TMath::Abs(Int_t(w) - Int_t(ctx.fW)) > 1 || TMath::Abs(Int_t(h) - Int_t(ctx.fH)) > 1) {
359 TGLContext newCtx = {ctx.fWindowIndex, -1, ctx.fDC, 0, ctx.fGLContext, w, h, x, y, ctx.fHighColor};
360 if (CreateDIB(newCtx)) {
361 //new DIB created
362 gVirtualX->SelectWindow(ctx.fPixmapIndex);
363 gVirtualX->ClosePixmap();
364 ctx = newCtx;
365 } else {
366 Error("ResizeOffScreenDevice", "Error trying to create new DIB\n");
367 return kFALSE;
368 }
369 } else {
370 ctx.fX = x;
371 ctx.fY = y;
372 }
373
374 return kTRUE;
375}
376
377////////////////////////////////////////////////////////////////////////////////
378
380{
381 gVirtualX->SelectWindow(fPimpl->fGLContexts[ctxInd].fPixmapIndex);
382}
383
384////////////////////////////////////////////////////////////////////////////////
385
387{
388 if (fPimpl->fGLContexts[pixInd].fPixmapIndex != -1)
389 fPimpl->fGLContexts[pixInd].fDirect = isDirect;
390}
391
392////////////////////////////////////////////////////////////////////////////////
393
395{
396 TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
397
398 if (ctx.fPixmapIndex != -1) {
399 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
400 glReadBuffer(GL_BACK);
401 glReadPixels(0, 0, ctx.fW, ctx.fH, GL_BGRA_EXT, GL_UNSIGNED_BYTE, ctx.fDIBData);
402 }
403}
404
405////////////////////////////////////////////////////////////////////////////////
406
408{
409 return fPimpl->fGLContexts[ctxInd].fPixmapIndex;
410}
411
412////////////////////////////////////////////////////////////////////////////////
413
415{
416 TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
417 return (Bool_t)wglMakeCurrent(ctx.fDC, ctx.fGLContext);
418}
419
420////////////////////////////////////////////////////////////////////////////////
421
423{
424 TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
425
426 if (ctx.fPixmapIndex == -1) {
427 //doube-buffered OpenGL
428 wglSwapLayerBuffers(ctx.fDC, WGL_SWAP_MAIN_PLANE);
429 } else if (ctx.fDirect) {
430 //DIB is flushed by viewer directly
431 HDC hDC = CreateCompatibleDC(0);
432
433 if (!hDC) {
434 Error("Flush", "CreateCompatibleDC failed\n");
435 return;
436 }
437
438 HBITMAP oldDIB = (HBITMAP)SelectObject(hDC, ctx.fHBitmap);
439
440 if (!BitBlt(ctx.fDC, ctx.fX, ctx.fY, ctx.fW, ctx.fH, hDC, 0, 0, SRCCOPY))
441 ctx.fDirect = kFALSE;
442
443 SelectObject(hDC, oldDIB);
444 DeleteDC(hDC);
445 }
446 //do nothing for non-direct off-screen device
447}
448
449////////////////////////////////////////////////////////////////////////////////
450
452{
453 TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
454
455 if (ctx.fPixmapIndex != -1) {
456 gVirtualX->SelectWindow(ctx.fPixmapIndex);
457 gVirtualX->ClosePixmap();
458 ctx.fPixmapIndex = -1;
459 }
460
461 wglDeleteContext(ctx.fGLContext);
462 ctx.fGLContext = 0;
463 ReleaseDC((HWND)GDK_DRAWABLE_XID((GdkWindow *)gVirtualX->GetWindowID(ctx.fWindowIndex)),
464 ctx.fDC);
465 //now, save its own index before putting into list of free devices
466 ctx.fWindowIndex = ctxInd;
468 fPimpl->fNextFreeContext = &ctx;
469}
470
471////////////////////////////////////////////////////////////////////////////////
472
474{
475 TGLContext &ctx = fPimpl->fGLContexts[ctxInd];
476
477 if (ctx.fPixmapIndex != -1) {
478 viewport[0] = 0;
479 viewport[1] = 0;
480 viewport[2] = ctx.fW;
481 viewport[3] = ctx.fH;
482 }
483}
484
485////////////////////////////////////////////////////////////////////////////////
486
488{
489 p->Paint();
490}
491
492////////////////////////////////////////////////////////////////////////////////
493
495{
496 vv->PrintObjects();
497}
498
499////////////////////////////////////////////////////////////////////////////////
500
501Bool_t TGWin32GLManager::SelectManip(TVirtualGLManip *manip, const TGLCamera * camera, const TGLRect * rect, const TGLBoundingBox * sceneBox)
502{
503 return manip->Select(*camera, *rect, *sceneBox);
504}
505
506////////////////////////////////////////////////////////////////////////////////
507
509{
510 return o->Pan(x, y);
511}
512
513////////////////////////////////////////////////////////////////////////////////
514
516{
517 return plot->PlotSelected(px, py);
518}
519
520////////////////////////////////////////////////////////////////////////////////
521
523{
524 return plot->GetPlotInfo(px, py);
525}
526
527////////////////////////////////////////////////////////////////////////////////
528
530{
531 if (ctxInd == -1)
532 return kFALSE;
533
534 return fPimpl->fGLContexts[ctxInd].fHighColor;
535}
Handle_t Window_t
Window handle.
Definition: GuiTypes.h:29
ULongptr_t Handle_t
Generic resource handle.
Definition: GuiTypes.h:26
#define h(i)
Definition: RSha256.hxx:106
int Int_t
Definition: RtypesCore.h:45
unsigned char UChar_t
Definition: RtypesCore.h:38
unsigned int UInt_t
Definition: RtypesCore.h:46
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
const PIXELFORMATDESCRIPTOR doubleBufferDesc
Definition: TGWin32GL.cxx:154
const PIXELFORMATDESCRIPTOR singleScreenDesc
Definition: TGWin32GL.cxx:174
Binding & operator=(OUT(*fun)(void))
#define gROOT
Definition: TROOT.h:404
#define gGLManager
Definition: TVirtualGL.h:162
R__EXTERN TGLManager *(* gPtr2GLManager)()
Definition: TVirtualGL.h:163
#define gVirtualX
Definition: TVirtualX.h:338
Concrete class describing an orientated (free) or axis aligned box of 8 vertices.
Abstract base camera class - concrete classes for orthographic and perspective cameras derive from it...
Definition: TGLCamera.h:44
Viewport (pixel base) 2D rectangle class.
Definition: TGLUtil.h:422
static TGLManager * ProxyObject()
std::deque< TGLContext > fGLContexts
Definition: TGWin32GL.cxx:197
Int_t InitGLWindow(Window_t winID)
Definition: TGWin32GL.cxx:245
Int_t CreateGLContext(Int_t winInd)
winInd is TGWin32 index, returned by previous call gGLManager->InitGLWindow returns descripto (index)...
Definition: TGWin32GL.cxx:254
Bool_t ResizeOffScreenDevice(Int_t devInd, Int_t x, Int_t y, UInt_t w, UInt_t h)
Create new DIB if needed.
Definition: TGWin32GL.cxx:353
void Flush(Int_t ctxInd)
Definition: TGWin32GL.cxx:422
Bool_t PlotSelected(TVirtualGLPainter *plot, Int_t px, Int_t py)
Definition: TGWin32GL.cxx:515
void PaintSingleObject(TVirtualGLPainter *)
Definition: TGWin32GL.cxx:487
void PrintViewer(TVirtualViewer3D *vv)
Definition: TGWin32GL.cxx:494
Bool_t CreateDIB(TGLContext &ctx) const
Create DIB section to read GL buffer into.
Definition: TGWin32GL.cxx:304
Int_t GetVirtualXInd(Int_t devInd)
Definition: TGWin32GL.cxx:407
void PanObject(TVirtualGLPainter *o, Int_t x, Int_t y)
Definition: TGWin32GL.cxx:508
void DeleteGLContext(Int_t devInd)
Definition: TGWin32GL.cxx:451
void ExtractViewport(Int_t devInd, Int_t *vp)
Definition: TGWin32GL.cxx:473
void SelectOffScreenDevice(Int_t devInd)
Definition: TGWin32GL.cxx:379
TGWin32GLImpl * fPimpl
Definition: TGWin32GL.h:22
void MarkForDirectCopy(Int_t devInd, Bool_t)
Definition: TGWin32GL.cxx:386
Bool_t MakeCurrent(Int_t devInd)
Definition: TGWin32GL.cxx:414
void ReadGLBuffer(Int_t devInd)
Definition: TGWin32GL.cxx:394
Bool_t AttachOffScreenDevice(Int_t ctxInd, Int_t x, Int_t y, UInt_t w, UInt_t h)
Definition: TGWin32GL.cxx:337
Bool_t HighColorFormat(Int_t ctx)
Definition: TGWin32GL.cxx:529
char * GetPlotInfo(TVirtualGLPainter *plot, Int_t px, Int_t py)
Definition: TGWin32GL.cxx:522
Bool_t SelectManip(TVirtualGLManip *manip, const TGLCamera *camera, const TGLRect *rect, const TGLBoundingBox *sceneBox)
Definition: TGWin32GL.cxx:501
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:879
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
virtual Bool_t Select(const TGLCamera &camera, const TGLRect &rect, const TGLBoundingBox &sceneBox)=0
virtual Bool_t PlotSelected(Int_t px, Int_t py)=0
virtual char * GetPlotInfo(Int_t px, Int_t py)=0
virtual void Pan(Int_t px, Int_t py)=0
virtual void Paint()=0
Abstract 3D shapes viewer.
virtual void PrintObjects()
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
Short_t Abs(Short_t d)
Definition: TMathBase.h:120