Files
OpenSceneGraph/src/osgPlugins/cfg/RenderSurface.h

614 lines
23 KiB
C++

/* -*-c++-*- Producer - Copyright (C) 2001-2004 Don Burns
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGPRODUCER_RENDER_SURFACE
#define OSGPRODUCER_RENDER_SURFACE 1
#include <map>
#include <string>
#include <iostream>
#include <osg/Referenced>
#include <osg/ref_ptr>
#include "VisualChooser.h"
#ifdef _WIN32_IMPLEMENTATION
#include <vector>
#endif
namespace osgProducer {
/**
\class RenderSurface
\brief A RenderSurface provides a rendering surface for 3D graphics applications.
A RenderSurface creates a window in a windowing system for the purpose of 3D
rendering. The focus of a RenderSurface differs from a windowing system window
in that it is not a user input/output device, but rather a context and screen area
specifically designed for 3D applications. Consequently, a RenderSurface does not
provide or impose a requirement on the caller to structure the application around
the capturing or handling of events. Further, RenderSurface provides increased
control over the quality of pixel formats.
*/
class RenderSurface : public osg::Referenced
{
public :
static const unsigned int UnknownDimension;
static const unsigned int UnknownAmount;
static unsigned int _numScreens;
class Callback : public osg::Referenced
{
public:
Callback() {}
virtual void operator()( const RenderSurface & ) = 0;
protected:
virtual ~Callback() {}
};
struct InputRectangle
{
public:
InputRectangle(): _left(-1.0), _bottom(-1.0), _width(2.0), _height(2.0) {}
InputRectangle( float left, float right, float bottom, float top ):
_left(left), _bottom(bottom), _width(right-left), _height(top-bottom) {}
InputRectangle(const InputRectangle &ir)
{
_left = ir._left;
_bottom = ir._bottom;
_width = ir._width;
_height = ir._height;
}
virtual ~InputRectangle() {}
void set( float left, float right, float bottom, float top )
{
_left = left;
_bottom = bottom;
_width = right - left;
_height = top - bottom;
}
float left() const { return _left; }
float bottom() const { return _bottom; }
float width() const { return _width; }
float height() const { return _height; }
protected:
private:
float _left, _bottom, _width, _height;
};
enum DrawableType {
DrawableType_Window,
DrawableType_PBuffer
};
RenderSurface( void );
static unsigned int getNumberOfScreens(void);
void setDrawableType( DrawableType );
DrawableType getDrawableType();
void setReadDrawable( RenderSurface *);
RenderSurface* getReadDrawable() { return _readDrawableRenderSurface; }
void setInputRectangle( const InputRectangle &ir );
const InputRectangle &getInputRectangle() const;
void bindInputRectangleToWindowSize(bool);
/** Set the name of the Host the window is to be created on.
Ignored on Win32*/
void setHostName( const std::string & );
/**
* Get the name of the Host the window is to be created on.
* Ignored on Win32 */
const std::string& getHostName( void ) const;
/**
* Set the number of the display the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
void setDisplayNum( int );
/** Get the number of the display the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
int getDisplayNum( void ) const;
/** Set the number of the screen the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
void setScreenNum( int );
/** Get the number of the screen the render surface is to
* be created on. In XWindows, this is the number of the
* XServer. Ignored on Win32 */
int getScreenNum( void ) const;
/** Get the size of the screen in pixels the render surface
* is to be created on. */
void getScreenSize( unsigned int &width, unsigned int &height ) const;
/** Default window name */
static const std::string defaultWindowName;
static const std::string &getDefaultWindowName();
/** Set the Window system Window name of the Render Surface */
void setWindowName( const std::string & );
/** Get the Window system Window name of the Render Surface */
const std::string& getWindowName( void ) const;
/** Set the windowing system rectangle the RenderSurface will
* occupy on the screen. The parameters are given as integers
* in screen space. x and y determine the lower left hand corner
* of the RenderSurface. Width and height are given in screen
* coordinates */
void setWindowRectangle( int x, int y, unsigned int width, unsigned int height,
bool resize=true );
/** Get the windowing system rectangle the RenderSurface will
* occupy on the screen. The parameters are given as integers
* in screen space. x and y determine the lower left hand corner
* of the RenderSurface. Width and height are given in screen
* coordinates */
void getWindowRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const;
/** Get the X coordinate of the origin of the RenderSurface's window */
int getWindowOriginX() const;
/** Get the Y coordinate of the origin of the RenderSurface's window */
int getWindowOriginY() const;
/** Get the width of the RenderSurface in windowing system screen coordinates */
unsigned int getWindowWidth() const;
/** Get the height of the RenderSurface in windowing system screen coordinates */
unsigned int getWindowHeight() const;
#if 0
/** Explicitely set the Display variable before realization. (X11 only). */
void setDisplay( Display *dpy );
/** Get the Display. (X11 only). */
Display* getDisplay( void );
/** Get the const Display. (X11 only). */
const Display* getDisplay( void ) const;
/** Explicitely set the Windowing system window before realization. */
void setWindow( const Window win );
/** Returns the Windowing system handle to the window */
Window getWindow( void ) const;
void setGLContext( GLContext );
/** Returns the OpenGL context */
GLContext getGLContext( void ) const;
/** Set the Windowing system's parent window */
void setParentWindow( Window parent );
/** Get the Windowing system's parent window */
Window getParentWindow( void ) const;
#endif
void setVisualChooser( VisualChooser *vc );
VisualChooser *getVisualChooser( void );
const VisualChooser *getVisualChooser( void ) const;
#if 0
void setVisualInfo( VisualInfo *vi );
VisualInfo *getVisualInfo( void );
const VisualInfo *getVisualInfo( void ) const;
/** Returns true if the RenderSurface has been realized, false if not. */
bool isRealized( void ) const;
#endif
/** Request the use of a window border. If flag is false, no border will
* appear after realization. If flag is true, the windowing system window
* will be created in default state. */
void useBorder( bool flag );
bool usesBorder();
/** Use overrideRedirect (X11 only). This bypasses the window manager
* control over the Window. Ignored on Win32 and Mac CGL versions.
* This call will only have effect if called before realize(). Calling
* it subsequent to realize() will issue a warning. */
void useOverrideRedirect(bool);
bool usesOverrideRedirect();
/** Request whether the window should have a visible cursor. If true, the
* windowing system's default cursor will be assigned to the window. If false
* the window will not have a visible cursor. */
void useCursor( bool flag );
#if 0
/** Set the current window cursor. Producer provides no functionality to create
* cursors. It is the application's responsiblity to create a Cursor using the
* windowing system of choice. setCursor() will simply set a predefined cursor
* as the current Cursor */
void setCursor( Cursor );
#endif
void setCursorToDefault();
/** Specify whether the RenderSurface should use a separate thread for
* window configuration events. If flag is set to true, then the
* RenderSurface will spawn a new thread to manage events caused by
* resizing the window, mapping or destroying the window. */
void useConfigEventThread(bool flag);
/** shareAllGLContexts will share all OpenGL Contexts between render surfaces
* upon realize. This must be called before any call to renderSurface::realize().
*/
static void shareAllGLContexts(bool);
/** Returns true or false indicating the the state flag for sharing contexts
* between RenderSurfaces
*/
static bool allGLContextsAreShared();
#if 0
/** Realize the RenderSurface. When realized, all components of the RenderSurface
* not already configured are configured, a window and a graphics context are
* created and made current. If an already existing graphics context is passed
* through "sharedGLContext", then the graphics context created will share certain
* graphics constructs (such as display lists) with "sharedGLContext". */
bool realize( VisualChooser *vc=NULL, GLContext sharedGLContext=0 );
void addRealizeCallback( Callback *realizeCB );
void setRealizeCallback( Callback *realizeCB ) { addRealizeCallback(realizeCB); }
/** Swaps buffers if RenderSurface quality attribute is DoubleBuffered */
virtual void swapBuffers(void);
/** Makes the graphics context and RenderSurface current for rendering */
bool makeCurrent(void) const;
/** Where supported, sync() will synchronize with the vertical retrace signal of the
* graphics display device. \a divisor specifies the number of vertical retace signals
* to allow before returning. */
virtual void sync( int divisor=1 );
/** Where supported, getRefreshRate() will return the frequency in hz of the vertical
* retrace signal of the graphics display device. If getRefreshRate() returns 0, then
* the underlying support to get the graphics display device's vertical retrace signal
* is not present. */
unsigned int getRefreshRate() const;
/** Where supported, initThreads will initialize all graphics components for thread
* safety. InitThreads() should be called before any other calls to Xlib, or OpenGL
* are made, and should always be called when multi-threaded environments are intended. */
static void initThreads();
/**
* Puts the calling thread to sleep until the RenderSurface is realized. Returns true
* if for success and false for failure.
* */
bool waitForRealize();
/** fullScreen(flag). If flag is true, RenderSurface resizes its window to fill the
* entire screen and turns off the border. If false, the window is returned to a size
* previously specified. If previous state specified a border around the window, a
* the border is replaced
* */
/** positionPointer(x,y) places the pointer at window coordinates x, y.
*/
void positionPointer( int x, int y );
/** set/getUseDefaultEsc is deprecated */
void setUseDefaultEsc( bool flag ) {_useDefaultEsc = flag; }
bool getUseDefaultEsc() { return _useDefaultEsc; }
/** map and unmap the window */
void mapWindow();
void unmapWindow();
#endif
void fullScreen( bool flag );
/** setCustomFullScreenRencangle(x,y,width,height). Programmer may set a customized
* rectangle to be interpreted as "fullscreen" when fullscreen(true) is called. This
* allows configurations that have large virtual screens that span more than one monitor
* to define a "local" full screen for each monitor.
*/
void setCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height );
/** useDefaultFullScreenRetangle(). Sets the application back to using the default
* screen size as fullscreen rather than the custom full screen rectangle
*/
void useDefaultFullScreenRectangle();
/** isFullScreen() returns true if the RenderSurface's window fills the entire screen
* and has no border. */
bool isFullScreen() const { return _isFullScreen; }
// TEMPORARY PBUFFER RENDER TO TEXTURE SUPPORT
// Temporary PBuffer support for Windows. Somebody got really
// confused and mixed up PBuffers with a renderable texture and
// caused this messy headache.
// These have no meaning in GLX world.....
enum BufferType {
FrontBuffer,
BackBuffer
};
enum RenderToTextureMode {
RenderToTextureMode_None,
RenderToRGBTexture,
RenderToRGBATexture
};
enum RenderToTextureTarget {
Texture1D,
Texture2D,
TextureCUBE
};
enum RenderToTextureOptions {
RenderToTextureOptions_Default = 0,
RequestSpaceForMipMaps = 1,
RequestLargestPBuffer = 2
};
enum CubeMapFace {
PositiveX = 0,
NegativeX = 1,
PositiveY = 2,
NegativeY = 3,
PositiveZ = 4,
NegativeZ = 5
};
/**
* Bind PBuffer content to the currently selected texture.
* This method affects PBuffer surfaces only. */
void bindPBufferToTexture(BufferType buffer = FrontBuffer) const;
/**
* Get the render-to-texture mode (PBuffer drawables only).
* This method has no effect if it is called after realize() */
RenderToTextureMode getRenderToTextureMode() const;
/**
* Set the render-to-texture mode (PBuffer drawables only). You
* can pass int values different from the constants defined by
* RenderToTextureMode, in which case they will be applied
* directly as parameters to the WGL_TEXTURE_FORMAT attribute.
* This method has no effect if it is called after realize(). */
void setRenderToTextureMode(RenderToTextureMode mode);
/**
* Get the render-to-texture target (PBuffer drawables only).
* This method has no effect if it is called after realize(). */
RenderToTextureTarget getRenderToTextureTarget() const;
/**
* Set the render-to-texture target (PBuffer drawables only). You
* can pass int values different from the constants defined by
* RenderToTextureTarget, in which case they will be applied
* directly as parameters to the WGL_TEXTURE_TARGET attribute.
* This method has no effect if it is called after realize(). */
void setRenderToTextureTarget(RenderToTextureTarget target);
/**
* Get the render-to-texture options (PBuffer drawables only).
* This method has no effect if it is called after realize(). */
RenderToTextureOptions getRenderToTextureOptions() const;
/**
* Set the render-to-texture options (PBuffer drawables only).
* You can pass any combination of the constants defined in
* enum RenderToTextureOptions.
* This method has no effect if it is called after realize(). */
void setRenderToTextureOptions(RenderToTextureOptions options);
/**
* Get which mipmap level on the target texture will be
* affected by rendering. */
int getRenderToTextureMipMapLevel() const;
/**
* Select which mipmap level on the target texture will be
* affected by rendering. This method can be called after the
* PBuffer has been realized. */
void setRenderToTextureMipMapLevel(int level);
/**
* Get which face on the target cube map texture will be
* affected by rendering. */
CubeMapFace getRenderToTextureFace() const;
/**
* Select which face on the target cube map texture will be
* affected by rendering. This method can be called after the
* PBuffer has been realized. */
void setRenderToTextureFace(CubeMapFace face);
// END TEMPORARY PBUFFER RENDER TO TEXTURE SUPPORT
/**
* Get the (const) vector of user-defined PBuffer attributes. */
const std::vector<int> &getPBufferUserAttributes() const;
/**
* Get the vector of user-defined PBuffer attributes. This
* vector will be used to initialize the PBuffer's attribute list.*/
std::vector<int> &getPBufferUserAttributes();
private :
unsigned int _refreshRate;
#ifdef _X11_IMPLEMENTATION
int (*__glxGetRefreshRateSGI)(unsigned int *);
int (*__glxGetVideoSyncSGI)(unsigned int *);
int (*__glxWaitVideoSyncSGI)(int,int,unsigned int *);
void testVSync( void );
#endif
#if 0
bool _checkEvents( Display *);
void _setBorder( bool flag );
void _setWindowName( const std::string & );
void _useCursor(bool);
void _setCursor(Cursor);
void _setCursorToDefault();
void _positionPointer(int x, int y);
void _resizeWindow();
#endif
bool _overrideRedirectFlag;
protected :
virtual ~RenderSurface( void );
// void _useOverrideRedirect( bool );
DrawableType _drawableType;
std::string _hostname;
int _displayNum;
float _windowLeft, _windowRight,
_windowBottom, _windowTop;
int _windowX, _windowY;
unsigned int _windowWidth, _windowHeight;
unsigned int _screenWidth, _screenHeight;
bool _useCustomFullScreen;
int _customFullScreenOriginX;
int _customFullScreenOriginY;
unsigned int _customFullScreenWidth;
unsigned int _customFullScreenHeight;
int _screen;
#if 0
Display * _dpy;
Window _win;
Window _parent;
#endif
RenderSurface *_readDrawableRenderSurface;
unsigned int _parentWindowHeight;
bool _realized;
osg::ref_ptr< VisualChooser > _visualChooser;
#if 0
VisualInfo * _visualInfo;
unsigned int _visualID;
GLContext _glcontext;
GLContext _sharedGLContext;
Cursor _currentCursor;
Cursor _nullCursor;
Cursor _defaultCursor;
#endif
bool _decorations;
bool _useCursorFlag;
std::string _windowName;
unsigned int _frameCount;
bool _mayFullScreen;
bool _isFullScreen;
bool _bindInputRectangleToWindowSize;
// Temporary "Pbuffer support for Win32
RenderToTextureMode _rtt_mode;
RenderToTextureTarget _rtt_target;
RenderToTextureOptions _rtt_options;
int _rtt_mipmap;
CubeMapFace _rtt_face;
bool _rtt_dirty_mipmap;
bool _rtt_dirty_face;
#ifdef _OSX_AGL_IMPLEMENTATION
GLContext _windowGlcontext;
GLContext _fullscreenGlcontext;
CFDictionaryRef _oldDisplayMode;
bool _captureDisplayOrWindow();
void _releaseDisplayOrWindow();
#endif
// user-defined PBuffer attributes
std::vector<int> _user_pbattr;
bool _useConfigEventThread;
bool _checkOwnEvents;
bool _useDefaultEsc;
InputRectangle _inputRectangle;
// void _computeScreenSize( unsigned int &width, unsigned int &height ) const;
#if 0
bool _createVisualInfo();
virtual bool _init();
virtual void _fini();
virtual void run();
static void _initThreads();
#endif
#ifdef _WIN32_IMPLEMENTATION
class Client : public Producer::Referenced
{
public:
Client(unsigned long mask);
unsigned int mask() { return _mask; }
EventQueue *getQueue() { return q.get(); }
void queue( ref_ptr<Event> ev );
private :
unsigned int _mask;
Producer::ref_ptr<EventQueue> q;
};
std::vector < Producer::ref_ptr<Client> >clients;
void dispatch( ref_ptr<Event> );
int _ownWindow;
int _ownVisualChooser;
int _ownVisualInfo;
HDC _hdc;
HINSTANCE _hinstance;
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag);
void KillGLWindow();
LONG WINAPI proc( Window, UINT, WPARAM, LPARAM );
static LONG WINAPI s_proc( Window, UINT, WPARAM, LPARAM );
static std::map <Window, RenderSurface *>registry;
/* mouse things */
int _mx, _my;
unsigned int _mbutton;
WNDPROC _oldWndProc;
public:
EventQueue * selectInput( unsigned int mask );
// if _parent is set, resize the window to
// fill the client area of the parent
void resizeToParent();
#endif
static bool _shareAllGLContexts;
};
}
#endif