1
/* -*-c++-*- Producer - Copyright (C) 2001-2004 Don Burns
3
* This library is open source and may be redistributed and/or modified under
4
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5
* (at your option) any later version. The full license is in LICENSE file
6
* included with this distribution, and on the openscenegraph.org website.
8
* This library is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* OpenSceneGraph Public License for more details.
15
#ifndef OSGPRODUCER_RENDER_SURFACE
16
#define OSGPRODUCER_RENDER_SURFACE 1
22
#include <osg/Referenced>
23
#include <osg/ref_ptr>
24
#include "VisualChooser.h"
26
#ifdef _WIN32_IMPLEMENTATION
30
namespace osgProducer {
34
\brief A RenderSurface provides a rendering surface for 3D graphics applications.
36
A RenderSurface creates a window in a windowing system for the purpose of 3D
37
rendering. The focus of a RenderSurface differs from a windowing system window
38
in that it is not a user input/output device, but rather a context and screen area
39
specifically designed for 3D applications. Consequently, a RenderSurface does not
40
provide or impose a requirement on the caller to structure the application around
41
the capturing or handling of events. Further, RenderSurface provides increased
42
control over the quality of pixel formats.
45
class RenderSurface : public osg::Referenced
49
static const unsigned int UnknownDimension;
50
static const unsigned int UnknownAmount;
51
static unsigned int _numScreens;
53
class Callback : public osg::Referenced
57
virtual void operator()( const RenderSurface & ) = 0;
60
virtual ~Callback() {}
66
InputRectangle(): _left(-1.0), _bottom(-1.0), _width(2.0), _height(2.0) {}
67
InputRectangle( float left, float right, float bottom, float top ):
68
_left(left), _bottom(bottom), _width(right-left), _height(top-bottom) {}
69
InputRectangle(const InputRectangle &ir)
76
virtual ~InputRectangle() {}
78
void set( float left, float right, float bottom, float top )
82
_width = right - left;
83
_height = top - bottom;
85
float left() const { return _left; }
86
float bottom() const { return _bottom; }
87
float width() const { return _width; }
88
float height() const { return _height; }
93
float _left, _bottom, _width, _height;
102
RenderSurface( void );
104
static unsigned int getNumberOfScreens(void);
106
void setDrawableType( DrawableType );
107
DrawableType getDrawableType();
108
void setReadDrawable( RenderSurface *);
109
RenderSurface* getReadDrawable() { return _readDrawableRenderSurface; }
111
void setInputRectangle( const InputRectangle &ir );
112
const InputRectangle &getInputRectangle() const;
113
void bindInputRectangleToWindowSize(bool);
116
/** Set the name of the Host the window is to be created on.
118
void setHostName( const std::string & );
121
* Get the name of the Host the window is to be created on.
122
* Ignored on Win32 */
123
const std::string& getHostName( void ) const;
126
* Set the number of the display the render surface is to
127
* be created on. In XWindows, this is the number of the
128
* XServer. Ignored on Win32 */
129
void setDisplayNum( int );
131
/** Get the number of the display the render surface is to
132
* be created on. In XWindows, this is the number of the
133
* XServer. Ignored on Win32 */
134
int getDisplayNum( void ) const;
136
/** Set the number of the screen the render surface is to
137
* be created on. In XWindows, this is the number of the
138
* XServer. Ignored on Win32 */
139
void setScreenNum( int );
141
/** Get the number of the screen the render surface is to
142
* be created on. In XWindows, this is the number of the
143
* XServer. Ignored on Win32 */
144
int getScreenNum( void ) const;
146
/** Get the size of the screen in pixels the render surface
147
* is to be created on. */
148
void getScreenSize( unsigned int &width, unsigned int &height ) const;
151
/** Default window name */
152
static const std::string defaultWindowName;
154
static const std::string &getDefaultWindowName();
156
/** Set the Window system Window name of the Render Surface */
157
void setWindowName( const std::string & );
158
/** Get the Window system Window name of the Render Surface */
159
const std::string& getWindowName( void ) const;
161
/** Set the windowing system rectangle the RenderSurface will
162
* occupy on the screen. The parameters are given as integers
163
* in screen space. x and y determine the lower left hand corner
164
* of the RenderSurface. Width and height are given in screen
166
void setWindowRectangle( int x, int y, unsigned int width, unsigned int height,
168
/** Get the windowing system rectangle the RenderSurface will
169
* occupy on the screen. The parameters are given as integers
170
* in screen space. x and y determine the lower left hand corner
171
* of the RenderSurface. Width and height are given in screen
173
void getWindowRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const;
174
/** Get the X coordinate of the origin of the RenderSurface's window */
175
int getWindowOriginX() const;
177
/** Get the Y coordinate of the origin of the RenderSurface's window */
178
int getWindowOriginY() const;
180
/** Get the width of the RenderSurface in windowing system screen coordinates */
181
unsigned int getWindowWidth() const;
183
/** Get the height of the RenderSurface in windowing system screen coordinates */
184
unsigned int getWindowHeight() const;
187
/** Explicitely set the Display variable before realization. (X11 only). */
188
void setDisplay( Display *dpy );
189
/** Get the Display. (X11 only). */
190
Display* getDisplay( void );
191
/** Get the const Display. (X11 only). */
192
const Display* getDisplay( void ) const;
194
/** Explicitely set the Windowing system window before realization. */
195
void setWindow( const Window win );
196
/** Returns the Windowing system handle to the window */
197
Window getWindow( void ) const;
199
void setGLContext( GLContext );
200
/** Returns the OpenGL context */
201
GLContext getGLContext( void ) const;
203
/** Set the Windowing system's parent window */
204
void setParentWindow( Window parent );
205
/** Get the Windowing system's parent window */
206
Window getParentWindow( void ) const;
210
void setVisualChooser( VisualChooser *vc );
211
VisualChooser *getVisualChooser( void );
212
const VisualChooser *getVisualChooser( void ) const;
215
void setVisualInfo( VisualInfo *vi );
216
VisualInfo *getVisualInfo( void );
217
const VisualInfo *getVisualInfo( void ) const;
219
/** Returns true if the RenderSurface has been realized, false if not. */
220
bool isRealized( void ) const;
223
/** Request the use of a window border. If flag is false, no border will
224
* appear after realization. If flag is true, the windowing system window
225
* will be created in default state. */
226
void useBorder( bool flag );
229
/** Use overrideRedirect (X11 only). This bypasses the window manager
230
* control over the Window. Ignored on Win32 and Mac CGL versions.
231
* This call will only have effect if called before realize(). Calling
232
* it subsequent to realize() will issue a warning. */
233
void useOverrideRedirect(bool);
234
bool usesOverrideRedirect();
236
/** Request whether the window should have a visible cursor. If true, the
237
* windowing system's default cursor will be assigned to the window. If false
238
* the window will not have a visible cursor. */
239
void useCursor( bool flag );
242
/** Set the current window cursor. Producer provides no functionality to create
243
* cursors. It is the application's responsiblity to create a Cursor using the
244
* windowing system of choice. setCursor() will simply set a predefined cursor
245
* as the current Cursor */
246
void setCursor( Cursor );
248
void setCursorToDefault();
250
/** Specify whether the RenderSurface should use a separate thread for
251
* window configuration events. If flag is set to true, then the
252
* RenderSurface will spawn a new thread to manage events caused by
253
* resizing the window, mapping or destroying the window. */
254
void useConfigEventThread(bool flag);
256
/** shareAllGLContexts will share all OpenGL Contexts between render surfaces
257
* upon realize. This must be called before any call to renderSurface::realize().
259
static void shareAllGLContexts(bool);
261
/** Returns true or false indicating the the state flag for sharing contexts
262
* between RenderSurfaces
264
static bool allGLContextsAreShared();
267
/** Realize the RenderSurface. When realized, all components of the RenderSurface
268
* not already configured are configured, a window and a graphics context are
269
* created and made current. If an already existing graphics context is passed
270
* through "sharedGLContext", then the graphics context created will share certain
271
* graphics constructs (such as display lists) with "sharedGLContext". */
272
bool realize( VisualChooser *vc=NULL, GLContext sharedGLContext=0 );
275
void addRealizeCallback( Callback *realizeCB );
276
void setRealizeCallback( Callback *realizeCB ) { addRealizeCallback(realizeCB); }
278
/** Swaps buffers if RenderSurface quality attribute is DoubleBuffered */
279
virtual void swapBuffers(void);
281
/** Makes the graphics context and RenderSurface current for rendering */
282
bool makeCurrent(void) const;
284
/** Where supported, sync() will synchronize with the vertical retrace signal of the
285
* graphics display device. \a divisor specifies the number of vertical retace signals
286
* to allow before returning. */
287
virtual void sync( int divisor=1 );
289
/** Where supported, getRefreshRate() will return the frequency in hz of the vertical
290
* retrace signal of the graphics display device. If getRefreshRate() returns 0, then
291
* the underlying support to get the graphics display device's vertical retrace signal
293
unsigned int getRefreshRate() const;
295
/** Where supported, initThreads will initialize all graphics components for thread
296
* safety. InitThreads() should be called before any other calls to Xlib, or OpenGL
297
* are made, and should always be called when multi-threaded environments are intended. */
298
static void initThreads();
301
* Puts the calling thread to sleep until the RenderSurface is realized. Returns true
302
* if for success and false for failure.
304
bool waitForRealize();
306
/** fullScreen(flag). If flag is true, RenderSurface resizes its window to fill the
307
* entire screen and turns off the border. If false, the window is returned to a size
308
* previously specified. If previous state specified a border around the window, a
309
* the border is replaced
312
/** positionPointer(x,y) places the pointer at window coordinates x, y.
314
void positionPointer( int x, int y );
316
/** set/getUseDefaultEsc is deprecated */
317
void setUseDefaultEsc( bool flag ) {_useDefaultEsc = flag; }
318
bool getUseDefaultEsc() { return _useDefaultEsc; }
320
/** map and unmap the window */
324
void fullScreen( bool flag );
325
/** setCustomFullScreenRencangle(x,y,width,height). Programmer may set a customized
326
* rectangle to be interpreted as "fullscreen" when fullscreen(true) is called. This
327
* allows configurations that have large virtual screens that span more than one monitor
328
* to define a "local" full screen for each monitor.
330
void setCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height );
331
/** useDefaultFullScreenRetangle(). Sets the application back to using the default
332
* screen size as fullscreen rather than the custom full screen rectangle
334
void useDefaultFullScreenRectangle();
336
/** isFullScreen() returns true if the RenderSurface's window fills the entire screen
337
* and has no border. */
338
bool isFullScreen() const { return _isFullScreen; }
340
// TEMPORARY PBUFFER RENDER TO TEXTURE SUPPORT
341
// Temporary PBuffer support for Windows. Somebody got really
342
// confused and mixed up PBuffers with a renderable texture and
343
// caused this messy headache.
344
// These have no meaning in GLX world.....
350
enum RenderToTextureMode {
351
RenderToTextureMode_None,
356
enum RenderToTextureTarget {
362
enum RenderToTextureOptions {
363
RenderToTextureOptions_Default = 0,
364
RequestSpaceForMipMaps = 1,
365
RequestLargestPBuffer = 2
378
* Bind PBuffer content to the currently selected texture.
379
* This method affects PBuffer surfaces only. */
380
void bindPBufferToTexture(BufferType buffer = FrontBuffer) const;
383
* Get the render-to-texture mode (PBuffer drawables only).
384
* This method has no effect if it is called after realize() */
385
RenderToTextureMode getRenderToTextureMode() const;
388
* Set the render-to-texture mode (PBuffer drawables only). You
389
* can pass int values different from the constants defined by
390
* RenderToTextureMode, in which case they will be applied
391
* directly as parameters to the WGL_TEXTURE_FORMAT attribute.
392
* This method has no effect if it is called after realize(). */
393
void setRenderToTextureMode(RenderToTextureMode mode);
396
* Get the render-to-texture target (PBuffer drawables only).
397
* This method has no effect if it is called after realize(). */
398
RenderToTextureTarget getRenderToTextureTarget() const;
401
* Set the render-to-texture target (PBuffer drawables only). You
402
* can pass int values different from the constants defined by
403
* RenderToTextureTarget, in which case they will be applied
404
* directly as parameters to the WGL_TEXTURE_TARGET attribute.
405
* This method has no effect if it is called after realize(). */
406
void setRenderToTextureTarget(RenderToTextureTarget target);
409
* Get the render-to-texture options (PBuffer drawables only).
410
* This method has no effect if it is called after realize(). */
411
RenderToTextureOptions getRenderToTextureOptions() const;
414
* Set the render-to-texture options (PBuffer drawables only).
415
* You can pass any combination of the constants defined in
416
* enum RenderToTextureOptions.
417
* This method has no effect if it is called after realize(). */
418
void setRenderToTextureOptions(RenderToTextureOptions options);
421
* Get which mipmap level on the target texture will be
422
* affected by rendering. */
423
int getRenderToTextureMipMapLevel() const;
426
* Select which mipmap level on the target texture will be
427
* affected by rendering. This method can be called after the
428
* PBuffer has been realized. */
429
void setRenderToTextureMipMapLevel(int level);
432
* Get which face on the target cube map texture will be
433
* affected by rendering. */
434
CubeMapFace getRenderToTextureFace() const;
437
* Select which face on the target cube map texture will be
438
* affected by rendering. This method can be called after the
439
* PBuffer has been realized. */
440
void setRenderToTextureFace(CubeMapFace face);
442
// END TEMPORARY PBUFFER RENDER TO TEXTURE SUPPORT
445
* Get the (const) vector of user-defined PBuffer attributes. */
446
const std::vector<int> &getPBufferUserAttributes() const;
449
* Get the vector of user-defined PBuffer attributes. This
450
* vector will be used to initialize the PBuffer's attribute list.*/
451
std::vector<int> &getPBufferUserAttributes();
454
unsigned int _refreshRate;
455
#ifdef _X11_IMPLEMENTATION
456
int (*__glxGetRefreshRateSGI)(unsigned int *);
457
int (*__glxGetVideoSyncSGI)(unsigned int *);
458
int (*__glxWaitVideoSyncSGI)(int,int,unsigned int *);
459
void testVSync( void );
463
bool _checkEvents( Display *);
464
void _setBorder( bool flag );
465
void _setWindowName( const std::string & );
466
void _useCursor(bool);
467
void _setCursor(Cursor);
468
void _setCursorToDefault();
469
void _positionPointer(int x, int y);
470
void _resizeWindow();
472
bool _overrideRedirectFlag;
475
virtual ~RenderSurface( void );
476
// void _useOverrideRedirect( bool );
478
DrawableType _drawableType;
479
std::string _hostname;
481
float _windowLeft, _windowRight,
482
_windowBottom, _windowTop;
483
int _windowX, _windowY;
484
unsigned int _windowWidth, _windowHeight;
485
unsigned int _screenWidth, _screenHeight;
486
bool _useCustomFullScreen;
487
int _customFullScreenOriginX;
488
int _customFullScreenOriginY;
489
unsigned int _customFullScreenWidth;
490
unsigned int _customFullScreenHeight;
498
RenderSurface *_readDrawableRenderSurface;
499
unsigned int _parentWindowHeight;
501
osg::ref_ptr< VisualChooser > _visualChooser;
503
VisualInfo * _visualInfo;
504
unsigned int _visualID;
505
GLContext _glcontext;
506
GLContext _sharedGLContext;
507
Cursor _currentCursor;
509
Cursor _defaultCursor;
513
std::string _windowName;
514
unsigned int _frameCount;
517
bool _bindInputRectangleToWindowSize;
520
// Temporary "Pbuffer support for Win32
521
RenderToTextureMode _rtt_mode;
522
RenderToTextureTarget _rtt_target;
523
RenderToTextureOptions _rtt_options;
525
CubeMapFace _rtt_face;
526
bool _rtt_dirty_mipmap;
527
bool _rtt_dirty_face;
529
#ifdef _OSX_AGL_IMPLEMENTATION
530
GLContext _windowGlcontext;
531
GLContext _fullscreenGlcontext;
532
CFDictionaryRef _oldDisplayMode;
534
bool _captureDisplayOrWindow();
535
void _releaseDisplayOrWindow();
538
// user-defined PBuffer attributes
539
std::vector<int> _user_pbattr;
542
bool _useConfigEventThread;
543
bool _checkOwnEvents;
546
InputRectangle _inputRectangle;
548
// void _computeScreenSize( unsigned int &width, unsigned int &height ) const;
551
bool _createVisualInfo();
553
virtual bool _init();
554
virtual void _fini();
557
static void _initThreads();
560
#ifdef _WIN32_IMPLEMENTATION
562
class Client : public Producer::Referenced
565
Client(unsigned long mask);
566
unsigned int mask() { return _mask; }
567
EventQueue *getQueue() { return q.get(); }
568
void queue( ref_ptr<Event> ev );
572
Producer::ref_ptr<EventQueue> q;
574
std::vector < Producer::ref_ptr<Client> >clients;
575
void dispatch( ref_ptr<Event> );
578
int _ownVisualChooser;
582
HINSTANCE _hinstance;
584
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag);
587
LONG WINAPI proc( Window, UINT, WPARAM, LPARAM );
588
static LONG WINAPI s_proc( Window, UINT, WPARAM, LPARAM );
589
static std::map <Window, RenderSurface *>registry;
593
unsigned int _mbutton;
598
EventQueue * selectInput( unsigned int mask );
600
// if _parent is set, resize the window to
601
// fill the client area of the parent
602
void resizeToParent();
605
static bool _shareAllGLContexts;