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