Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
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
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
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
220 ctx.fDC);
221 }
222 }
223}
224
225
226////////////////////////////////////////////////////////////////////////////////
227
229{
231 gROOT->GetListOfSpecials()->AddLast(this);
232 gGLManager = this;
233}
234
235////////////////////////////////////////////////////////////////////////////////
236
241
242////////////////////////////////////////////////////////////////////////////////
243
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);
257
258 if (!hDC) {
259 Error("CreateGLContext", "GetWindowDC failed\n");
260 return -1;
261 }
262
263 WDCGuard dcGuard(hDC, winID);
264
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};
277 newDevice.fHighColor = testFormat.cColorBits < 24 ? kTRUE : kFALSE;
278
279 if (TGLContext *ctx = fPimpl->fNextFreeContext) {
280 Int_t ind = ctx->fWindowIndex;
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;
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((Handle_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{
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{
355
356 if (ctx.fPixmapIndex != -1)
357 if (std::abs(Int_t(w) - Int_t(ctx.fW)) > 1 || std::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
390
391////////////////////////////////////////////////////////////////////////////////
392
403
404////////////////////////////////////////////////////////////////////////////////
405
410
411////////////////////////////////////////////////////////////////////////////////
412
418
419////////////////////////////////////////////////////////////////////////////////
420
422{
424
425 if (ctx.fPixmapIndex == -1) {
426 //doube-buffered OpenGL
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{
453
454 if (ctx.fPixmapIndex != -1) {
455 gVirtualX->SelectWindow(ctx.fPixmapIndex);
456 gVirtualX->ClosePixmap();
457 ctx.fPixmapIndex = -1;
458 }
459
461 ctx.fGLContext = 0;
463 ctx.fDC);
464 //now, save its own index before putting into list of free devices
465 ctx.fWindowIndex = ctxInd;
467 fPimpl->fNextFreeContext = &ctx;
468}
469
470////////////////////////////////////////////////////////////////////////////////
471
473{
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
490
491////////////////////////////////////////////////////////////////////////////////
492
494{
495 vv->PrintObjects();
496}
497
498////////////////////////////////////////////////////////////////////////////////
499
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
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
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:52
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
const PIXELFORMATDESCRIPTOR doubleBufferDesc
const PIXELFORMATDESCRIPTOR singleScreenDesc
winID h pixInd
winID winInd
winID h TVirtualViewer3D TVirtualGLPainter p
winID h TVirtualViewer3D vv
winID h TVirtualViewer3D TVirtualGLPainter char TVirtualGLPainter plot
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t rect
Binding & operator=(OUT(*fun)(void))
#define gROOT
Definition TROOT.h:411
#define gGLManager
Definition TVirtualGL.h:159
R__EXTERN TGLManager *(* gPtr2GLManager)()
Definition TVirtualGL.h:160
#define gVirtualX
Definition TVirtualX.h:337
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
void DeleteGLContext(Int_t devInd) override
Bool_t HighColorFormat(Int_t ctx) override
void ExtractViewport(Int_t devInd, Int_t *vp) override
Bool_t ResizeOffScreenDevice(Int_t devInd, Int_t x, Int_t y, UInt_t w, UInt_t h) override
Create new DIB if needed.
Int_t CreateGLContext(Int_t winInd) override
winInd is TGWin32 index, returned by previous call gGLManager->InitGLWindow returns descripto (index)...
Bool_t CreateDIB(TGLContext &ctx) const
Create DIB section to read GL buffer into.
char * GetPlotInfo(TVirtualGLPainter *plot, Int_t px, Int_t py) override
void PaintSingleObject(TVirtualGLPainter *) override
void PanObject(TVirtualGLPainter *o, Int_t x, Int_t y) override
Bool_t PlotSelected(TVirtualGLPainter *plot, Int_t px, Int_t py) override
Int_t GetVirtualXInd(Int_t devInd) override
Bool_t SelectManip(TVirtualGLManip *manip, const TGLCamera *camera, const TGLRect *rect, const TGLBoundingBox *sceneBox) override
void ReadGLBuffer(Int_t devInd) override
void Flush(Int_t ctxInd) override
Bool_t AttachOffScreenDevice(Int_t ctxInd, Int_t x, Int_t y, UInt_t w, UInt_t h) override
void PrintViewer(TVirtualViewer3D *vv) override
Int_t InitGLWindow(Window_t winID) override
TGWin32GLImpl * fPimpl
Definition TGWin32GL.h:23
void SelectOffScreenDevice(Int_t devInd) override
~TGWin32GLManager() override
Bool_t MakeCurrent(Int_t devInd) override
void MarkForDirectCopy(Int_t devInd, Bool_t) override
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Pan(Int_t px, Int_t py)=0
Abstract 3D shapes viewer.
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17