1
/**************************************************************************\
3
* This file is part of the Coin 3D visualization library.
4
* Copyright (C) 1998-2005 by Systems in Motion. All rights reserved.
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* ("GPL") version 2 as published by the Free Software Foundation.
9
* See the file LICENSE.GPL at the root directory of this source
10
* distribution for additional information about the GNU GPL.
12
* For using Coin with software that can not be combined with the GNU
13
* GPL, and for taking advantage of the additional benefits of our
14
* support services, please contact Systems in Motion about acquiring
15
* a Coin Professional Edition License.
17
* See <URL:http://www.coin3d.org/> for more information.
19
* Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
20
* <URL:http://www.sim.no/>.
22
\**************************************************************************/
24
// src/Inventor/Qt/SoQtGLWidgetCommon.cpp. Generated from SoGuiGLWidgetCommon.cpp.in by configure.
26
#define PRIVATE(obj) ((SoGuiGLWidgetP *)(obj->pimpl))
28
// *************************************************************************
31
\class SoQtGLWidget SoQtGLWidget.h Inventor/Qt/SoQtGLWidget.h
32
\brief The SoQtGLWidget class manages OpenGL contexts.
35
This is the basic, abstract component class which sets up an OpenGL
36
canvas for its subclasses.
38
Application programmers will normally not use this class directly,
39
but rather through the interface of either its direct descendent;
40
SoQtRenderArea, or through one of the "rapid application
41
development"-style viewer subclasses.
45
An important thing to know about embedding SoQtGLWidget derived
46
components into other Qt widgets is that you need to set up
47
"focus proxying" to have events still be sent to the OpenGL canvas
48
widget. This is true for both the SoQtRenderArea aswell as all
49
the viewer components (like SoQtExaminerViewer,
52
As an example, if you embed an SoQtExaminerViewer inside a QFrame
56
QMainWindow * toplevel = new QMainWindow;
57
QFrame * frame = new QFrame(toplevel);
58
SoQtExaminerViewer * viewer = new SoQtExaminerViewer(toplevel);
61
...events from the keyboard will not always automatically be
62
forwarded to the viewer OpenGL canvas. This is the code you need to
66
toplevel->setFocusProxy(viewer->getWidget());
73
For debugging purposes, SoWinGLWidget provides the
74
OIV_FORCE_PIXEL_FORMAT environment variable to make it possible to
75
override the pixel format chosen by the internal attribute match
81
// *************************************************************************
85
#endif // HAVE_CONFIG_H
87
#include <Inventor/Qt/common/gl.h>
88
#include <Inventor/Qt/SoQtGLWidget.h>
89
#include <Inventor/Qt/SoQtGLWidgetP.h>
91
// *************************************************************************
93
// All shared documentation for functions with specific
94
// implementations in the individual toolkits.
97
\fn SoQtGLWidget::SoQtGLWidget(QWidget * const parent, const char * const name, const SbBool embed, const int glmodes, const SbBool build)
99
The constructor is protected, as this is an abstract class to only
100
be used by it's subclasses.
104
\fn SoQtGLWidget::~SoQtGLWidget()
106
Clean up all use of internal resources.
108
The destructor is protected, as this is an abstract class to only be
109
used by it's subclasses.
113
\fn void SoQtGLWidget::setBorder(const SbBool enable)
115
Specify whether or not there should be a border framing the OpenGL
116
canvas. The border will be 2 pixels wide.
118
The default is to display the OpenGL canvas with no border.
124
\fn SbBool SoQtGLWidget::isBorder(void) const
126
Returns whether or not there's a border framing the OpenGL canvas.
132
\fn void SoQtGLWidget::setOverlayRender(const SbBool onoff)
134
Turn on or off the use of overlay planes.
136
\sa isOverlayRender()
140
\fn SbBool SoQtGLWidget::isOverlayRender(void) const
142
Returns a flag indicating whether or not overplay planes are
145
\sa setOverlayRender()
149
\fn void SoQtGLWidget::setDoubleBuffer(const SbBool enable)
151
Switch between single and double buffer mode for the OpenGL canvas.
152
The default is to use a single buffer canvas.
158
\fn SbBool SoQtGLWidget::isDoubleBuffer(void) const
160
Returns the status of the buffer mode.
162
\sa setDoubleBuffer()
166
\fn void SoQtGLWidget::setQuadBufferStereo(const SbBool enable)
168
Enables or disables OpenGL quad buffer stereo.
172
\fn SbBool SoQtGLWidget::isQuadBufferStereo(void) const
174
Returns \c TRUE if quad buffer stereo is enabled for this widget.
178
\fn void SoQtGLWidget::setAccumulationBuffer(const SbBool enable)
180
Enables/disables the OpenGL accumulation buffer.
182
For general information about accumulation buffers, confer with your
183
OpenGL reference documentation.
185
By default, the accumulation buffer will be attempted disabled.
186
Whether or not it will \e actually be disabled depends on what
187
OpenGL contexts are available on the system. It is perfectly
188
possible that the only usable contexts with regard to the other
189
settings (like double buffering and RGBA mode versus color index
190
mode) causes the context selection to choose an OpenGL format that
191
contains an accumulation buffer, even though it was not
194
Vice versa, one is not guaranteed to get accumulation buffers even
195
when requested through this function, either because they are not
196
available, or because they are only available in combination with
197
other OpenGL context settings that are not wanted (like single
198
buffers, non-accellerated rendering, etc).
200
If you try to enable accumulation buffers by using this function,
201
you should therefore in succession use the
202
SoQtGLWidget::getAccumulationBuffer() to query whether or not an
203
accumulation buffer could actually be set up.
205
\sa SoQtRenderArea::setAntiAliasing()
209
\fn SbBool SoQtGLWidget::getAccumulationBuffer(void) const
211
Returns whether the OpenGL accumulation buffer is enabled.
213
The returned flag will indicate whether or not accumulation buffers
214
are \e actually present, and not just parrot the input value to
215
SoQtGLWidget::setAccumulationBuffer(). See documentation of that
216
function for more information.
220
\fn void SoQtGLWidget::setStencilBuffer(const SbBool enable)
222
Enables/disables the OpenGL stencil buffer.
224
For general information about stencil buffers, confer with your
225
OpenGL reference documentation.
227
By default, the stencil buffer will be attempted disabled, but the
228
same notes apply for stencil buffers as for accumulation
229
buffers. For an explanation on the issue of stencil and accumulation
230
buffer availability, see the function documentation of
231
SoQtGLWidget::setAccumulationBuffer().
235
\fn SbBool SoQtGLWidget::getStencilBuffer(void) const
237
Returns whether the OpenGL stencil buffer is enabled.
239
The returned flag will indicate whether or not stencil buffers are
240
\e actually present, in the same manner as for
241
SoQtGLWidget::getAccumulationBuffer(). See documentation of
242
SoQtGLWidget::setStencilBuffer().
246
\fn void SoQtGLWidget::setAlphaChannel(const SbBool enable)
248
Enables/disables the alpha channel for the OpenGL context.
252
\fn SbBool SoQtGLWidget::getAlphaChannel(void) const
254
Returns whether the alpha channel is enabled for the OpenGL context.
258
\fn void SoQtGLWidget::setDrawToFrontBufferEnable(const SbBool enable)
260
If this is set to \c TRUE, rendering will happen in the front buffer
261
even if the current rendering mode is double buffered.
265
\fn SbBool SoQtGLWidget::isDrawToFrontBufferEnable(void) const
266
\sa setDrawToFrontBufferEnable()
270
\fn QWidget * SoQtGLWidget::buildWidget(QWidget * parent)
272
This method builds the component contents in the given \a parent
273
widget. For subclasses adding new user interface items, this method
274
is typically overridden in the following manner:
277
QWidget * MyOwnViewer::buildWidget(QWidget * parent)
279
QWidget * superw = <superclass>::buildWidget(parent);
280
// [then move superw within MyOwnViewer framework and add own
281
// user interface components]
287
\fn virtual void SoQtGLWidget::redraw(void)
289
This method is invoked when the GL buffer needs to be redrawn.
293
\var SbBool SoQtGLWidget::waitForExpose
295
If this is \c TRUE, rendering should not be done yet. Upon the first
296
expose event of a newly created OpenGL widget, this variable will
301
\var SbBool SoQtGLWidget::drawToFrontBuffer
303
If this is \c TRUE, rendering will happen in the front buffer even
304
if the current rendering mode is double buffered.
308
\fn QWidget * SoQtGLWidget::getNormalWidget(void) const
311
For SoQt, this returns the same widget pointer as that of
312
SoQtGLWidget::getGLWidget().
317
\fn QWidget * SoQtGLWidget::getOverlayWidget(void) const
319
Returns widget associated with overlay planes, or \c NULL if no
320
overlay planes are available.
323
For the Qt toolkit, overlay planes is a feature of the QGLWidget,
324
and not seen at a separate widget entity. So this call will just
325
return the same widget reference as the SoQt::getGLWidget() call (if
326
overlay planes are supported).
331
\fn void SoQtGLWidget::setGLSize(const SbVec2s size)
332
Sets the size of the GL canvas.
336
\fn SbVec2s SoQtGLWidget::getGLSize(void) const
338
Return the dimensions of the OpenGL canvas.
342
\fn float SoQtGLWidget::getGLAspectRatio(void) const
344
Return the aspect ratio of the OpenGL canvas.
348
\fn void SoQtGLWidget::setGlxSize(const SbVec2s size)
349
This function has been renamed to the more appropriate setGLSize.
354
\fn SbVec2s SoQtGLWidget::getGlxSize(void) const
355
This function has been renamed to the more appropriate getGLSize.
360
\fn float SoQtGLWidget::getGlxAspectRatio(void) const
361
This function has been renamed to the more appropriate getGLAspectRatio.
366
\fn QWidget * SoQtGLWidget::getGLWidget(void) const
368
Returns a pointer to the toolkit-native GL widget.
372
\fn void SoQtGLWidget::widgetChanged(QWidget * w)
374
This is the method which gets called whenever we change which OpenGL
377
Should be overridden in subclasses which directly or indirectly
378
store the return value from the SoQtGLWidget::getGLWidget()
385
\fn void SoQtGLWidget::processEvent(QEvent * anyevent)
387
Any events from the native window system that goes to the OpenGL
388
canvas gets piped through this method.
390
It is overridden in the subclasses to catch user interaction with
391
the render canvas in the viewers, aswell as forwarding relevant
392
events to the scenegraph.
396
\fn void SoQtGLWidget::glLockNormal(void)
398
This method calls make-current on the correct context and ups the
403
\fn void SoQtGLWidget::glUnlockNormal(void)
405
This method drops the lock level.
409
\fn void SoQtGLWidget::glSwapBuffers(void)
410
Swap back buffer to front and vice versa.
414
\fn void SoQtGLWidget::glFlushBuffer(void)
416
Flush the current GL buffer. Simply calls glFlush().
420
\fn void SoQtGLWidget::glLockOverlay(void)
422
This method calls make-current on the correct context and ups the
427
\fn void SoQtGLWidget::glUnlockOverlay(void)
429
This method drops the lock level.
433
\fn unsigned long SoQtGLWidget::getOverlayTransparentPixel(void)
434
Returns the overlay transparent pixel.
438
\fn SbBool SoQtGLWidget::isRGBMode(void)
440
Returns \c TRUE if the normal GL context is in RGBA mode.
441
Return \c FALSE if color index mode is used.
445
\fn void SoQtGLWidget::redrawOverlay(void)
447
Renders the overlay scene graph. Default method is empty. Subclasses
448
should override this method.
452
\fn SbBool SoQtGLWidget::hasNormalGLArea(void) const
454
Will return \c TRUE if a normal GL drawing area exists.
458
\fn SbBool SoQtGLWidget::hasOverlayGLArea(void) const
460
Will return \c TRUE if an overlay GL drawing area exists.
464
\fn void SoQtGLWidget::initGraphic(void)
466
Will be called when GL widget should initialize graphic, after
467
the widget has been created. Default method enabled GL_DEPTH_TEST.
471
\fn void SoQtGLWidget::initOverlayGraphic(void)
473
Will be called after the overlay widget has been created, and subclasses
474
should override this to initialize overlay stuff.
476
Default method does nothing.
480
\fn SbBool SoQtGLWidget::glScheduleRedraw(void)
482
Will be called whenever scene graph needs to be redrawn. If this
483
method return \c FALSE, redraw() will be called immediately.
485
Default method simply returns \c FALSE. Override this method to
486
schedule a redraw and return \c TRUE if you're trying to do The
491
\fn void SoQtGLWidget::setStealFocus(SbBool enable)
493
Sets whether the GL widget should steal keyboard focus when the
494
mouse is over the GL view.
503
\fn SbBool SoQtGLWidget::isStealFocus(void) const
505
Returns whether focus stealing policy is on (\c TRUE) or off (\c
514
// Documented in common/SoGuiGLWidgetCommon.cpp.in.
516
SoQtGLWidget::setStealFocus(SbBool enable)
518
PRIVATE(this)->stealFocus = enable;
521
// Documented in common/SoGuiGLWidgetCommon.cpp.in.
523
SoQtGLWidget::isStealFocus(void) const
525
return PRIVATE(this)->stealFocus;
528
// *************************************************************************
531
This function is provided as a convenience for the application
532
programmer to help with acquiring the OpenGL implementation limits
533
for rendering points.
535
For robust application code, one needs to consider the range limits
536
when setting the SoDrawStyle::pointSize field.
539
SoQtGLWidget::getPointSizeLimits(SbVec2f & range, float & granularity)
541
this->glLockNormal();
544
glGetFloatv(GL_POINT_SIZE_RANGE, vals);
546
// Matthias Koenig reported on coin-discuss that the OpenGL
547
// implementation on SGI Onyx 2 InfiniteReality returns 0 for the
548
// lowest pointsize, but it will still set the return value of
549
// glGetError() to GL_INVALID_VALUE if this size is attempted
550
// used. So the boundary range fix in the next line of code is a
551
// workaround for that OpenGL implementation bug.
553
// 0.0f and lower values are explicitly disallowed, according to
554
// the OpenGL 1.3 specification, Chapter 3.3.
556
if (vals[0] <= 0.0f) { vals[0] = SoQtMin(1.0f, vals[1]); }
558
range.setValue(vals[0], vals[1]);
561
glGetFloatv(GL_POINT_SIZE_GRANULARITY, gran);
562
granularity = gran[0];
564
this->glUnlockNormal();
568
This function is provided as a convenience for the application
569
programmer to help with acquiring the OpenGL implementation limits
572
For robust application code, one needs to consider the range limits
573
when setting the SoDrawStyle::lineWidth field.
576
SoQtGLWidget::getLineWidthLimits(SbVec2f & range, float & granularity)
578
this->glLockNormal();
581
glGetFloatv(GL_LINE_WIDTH_RANGE, vals);
583
// Matthias Koenig reported on coin-discuss that the OpenGL
584
// implementation on SGI Onyx 2 InfiniteReality returns 0 for the
585
// lowest linewidth, but it will still set the return value of
586
// glGetError() to GL_INVALID_VALUE if this size is attempted
587
// used. This is a workaround for what looks like an OpenGL bug.
589
if (vals[0] <= 0.0f) { vals[0] = SoQtMin(1.0f, vals[1]); }
591
range.setValue(vals[0], vals[1]);
594
glGetFloatv(GL_LINE_WIDTH_GRANULARITY, gran);
595
granularity = gran[0];
597
this->glUnlockNormal();
600
// FIXME: other implementation specifics to check are
602
// * maximum stack depths (attribute, modelview matrix, name,
603
// projection matrix, texture matrix)
605
// * max display list nesting
607
// * max nr of clipplanes
609
// * max nr of light sources
611
// * max 3D texture size (needs specific extension?)
616
Sets whether OpenGL stereo buffers (quad buffer stereo) should be
620
SoQtGLWidget::setStereoBuffer(SbBool flag)
622
// FIXME: is this really correct? 20011012 mortene.
623
this->setQuadBufferStereo(flag);
627
Returns whether OpenGL stereo buffers are being used.
630
SoQtGLWidget::isStereoBuffer(void) const
632
// FIXME: is this really correct? 20011012 mortene.
633
return this->isQuadBufferStereo();
636
// *************************************************************************
638
#ifndef DOXYGEN_SKIP_THIS
640
// Remaining code is for the SoGuiGLWidgetP "private implementation"
644
SoGuiGLWidgetP::SoGuiGLWidgetP(SoQtGLWidget * publ)
647
this->stealFocus = TRUE;
650
SoGuiGLWidgetP::~SoGuiGLWidgetP()
654
// Just forward from a static function, so we can find out from
655
// anywhere within the library -- without exposing the API for the app
658
SoGuiGLWidgetP::isDirectRendering(SoQtGLWidget * w)
660
return ((SoGuiGLWidgetP *)(w->pimpl))->isDirectRendering();
664
#endif // DOXYGEN_SKIP_THIS
666
// *************************************************************************