1 /* -*-c++-*- Producer - Copyright (C) 2001-2004 Don Burns
2 *
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.
7 *
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.
12 */
13
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "RenderSurface.h"
18
19 using namespace std;
20 using namespace osgProducer;
21
22 const std::string RenderSurface::defaultWindowName = std::string(" *** Producer::RenderSurface *** ");
23
24 const unsigned int RenderSurface::UnknownDimension = 0xFFFFFFFF;
25 const unsigned int RenderSurface::UnknownAmount = 0xFFFFFFFF;
26 unsigned int RenderSurface::_numScreens = RenderSurface::UnknownAmount;
27
28 bool RenderSurface::_shareAllGLContexts = false;
29 //GLContext RenderSurface::_globallySharedGLContext = 0L;
30
shareAllGLContexts(bool flag)31 void RenderSurface::shareAllGLContexts(bool flag)
32 {
33 _shareAllGLContexts = flag;
34 }
35
allGLContextsAreShared()36 bool RenderSurface::allGLContextsAreShared()
37 {
38 return _shareAllGLContexts;
39 }
40
41
getDefaultWindowName()42 const std::string &RenderSurface::getDefaultWindowName()
43 {
44 return defaultWindowName;
45 }
46
RenderSurface(void)47 RenderSurface::RenderSurface( void )
48 {
49 _drawableType = DrawableType_Window;
50 _hostname = "";
51 _displayNum = 0;
52 _screen = 0;
53 _mayFullScreen = true;
54 _isFullScreen = true;
55
56 // This used to be #ifdefed for the X11 implementation
57 // but the code is pure C++ and should compile anywhere
58 // The _dislayNum variable is used by CGL as well.
59 char *envptr = getenv( "DISPLAY" );
60 if( envptr != NULL && *envptr != 0 )
61 {
62 size_t p0 = 0;
63 size_t p1 = string(envptr).find(":", p0);
64 _hostname = string(envptr).substr(p0,p1);
65 p0 = p1+1;
66 p1 = string(envptr).find(".", p0);
67
68 if( p1 > 0 )
69 {
70 _displayNum = atoi((string(envptr).substr(p0,p1)).c_str());
71 p0 = p1+1;
72 p1 = string(envptr).length() - p0;
73 if( p1 > 0 )
74 _screen = atoi((string(envptr).substr(p0,p1)).c_str());
75 }
76 else if( p1 < string(envptr).length() )
77 {
78 p1 = string(envptr).length();
79 _displayNum = atoi((string(envptr).substr(p0,p1)).c_str());
80 _screen = 0;
81 }
82 }
83
84 _windowLeft = 0;
85 _windowRight = 1;
86 _windowBottom = 0;
87 _windowTop = 1;
88 _windowX = 0;
89 _windowY = 0;
90 _windowWidth = UnknownDimension;
91 _windowHeight = UnknownDimension;
92 _screenWidth = UnknownDimension;
93 _screenHeight = UnknownDimension;
94 _customFullScreenOriginX = 0;
95 _customFullScreenOriginY = 0;
96 _customFullScreenWidth = UnknownDimension;
97 _customFullScreenHeight = UnknownDimension;
98 _useCustomFullScreen = false;
99
100 _readDrawableRenderSurface = 0L;
101 _windowName = defaultWindowName;
102 _realized = false;
103 _useConfigEventThread = true;
104 _overrideRedirectFlag = false;
105
106 char *override_envptr = getenv( "PRODUCER_OVERRIDE_REDIRECT" );
107 if( override_envptr != NULL && *override_envptr != 0 )
108 {
109 if (strcmp(override_envptr,"true")==0 || strcmp(override_envptr,"True")==0 || strcmp(override_envptr,"TRUE")==0)
110 {
111 _overrideRedirectFlag = true;
112 }
113 else
114 {
115 _overrideRedirectFlag = false;
116 }
117 }
118
119 _decorations = true;
120 _useCursorFlag = true;
121
122
123
124
125 _useDefaultEsc = true;
126 _checkOwnEvents = true;
127 _inputRectangle.set( -1.0, 1.0, -1.0, 1.0 );
128 _bindInputRectangleToWindowSize = false;
129
130
131 _rtt_mode = RenderToTextureMode_None;
132 //_rtt_mode = RenderToRGBTexture;
133 _rtt_target = Texture2D;
134 _rtt_options = RenderToTextureOptions_Default;
135 _rtt_mipmap = 0;
136 _rtt_face = PositiveX;
137 _rtt_dirty_mipmap = true;
138 _rtt_dirty_face = true;
139
140
141 #ifdef _WIN32_IMPLEMENTATION
142 _ownWindow = true;
143 _ownVisualChooser = true;
144 _ownVisualInfo = true;
145 _hinstance = NULL;
146 _glcontext = NULL;
147 _mx = 0;
148 _my = 0;
149 _mbutton = 0;
150 #endif
151 }
152
~RenderSurface(void)153 RenderSurface::~RenderSurface( void )
154 {
155 }
156
157
setDrawableType(RenderSurface::DrawableType drawableType)158 void RenderSurface::setDrawableType( RenderSurface::DrawableType drawableType )
159 {
160 if( _realized )
161 {
162 std::cerr << "Warning: RenderSurface::setDrawableType() "
163 "has no effect after RenderSurface has been realized\n";
164 return;
165 }
166 _drawableType = drawableType;
167 }
168
getDrawableType()169 RenderSurface::DrawableType RenderSurface::getDrawableType()
170 {
171 return _drawableType;
172 }
173
setReadDrawable(osgProducer::RenderSurface * rs)174 void RenderSurface::setReadDrawable( osgProducer::RenderSurface *rs )
175 {
176 _readDrawableRenderSurface = rs;
177 #if 0
178 if( _realized )
179 makeCurrent();
180 #endif
181 }
182
183 #if 0
184 void RenderSurface::setParentWindow( Window parent )
185 {
186 _parent = parent;
187 }
188
189 Producer::Window RenderSurface::getParentWindow( void ) const
190 {
191 return _parent;
192 }
193 #endif
194
setWindowName(const std::string & name)195 void RenderSurface::setWindowName( const std::string &name )
196 {
197 // _setWindowName( name );
198 _windowName = name;
199 }
200
getWindowName(void) const201 const std::string &RenderSurface::getWindowName( void ) const
202 {
203 return _windowName;
204 }
205
setHostName(const std::string & name)206 void RenderSurface::setHostName( const std::string &name )
207 {
208 _hostname = name;
209 }
210
getHostName(void) const211 const std::string &RenderSurface::getHostName( void ) const
212 {
213 return _hostname;
214 }
215
216 #if 0
217 void RenderSurface::setDisplay( Display *dpy )
218 {
219 _dpy = dpy;
220 }
221
222 Producer::Display *RenderSurface::getDisplay()
223 {
224 #ifdef WIN32
225 return &_hdc;
226 #else
227 return _dpy;
228 #endif
229 }
230
231 const Producer::Display *RenderSurface::getDisplay() const
232 {
233 #ifdef WIN32
234 return &_hdc;
235 #else
236 return _dpy;
237 #endif
238 }
239 #endif
240
setDisplayNum(int num)241 void RenderSurface::setDisplayNum( int num )
242 {
243 _displayNum = num;
244 }
245
getDisplayNum(void) const246 int RenderSurface::getDisplayNum( void ) const
247 {
248 return _displayNum;
249 }
250
setScreenNum(int num)251 void RenderSurface::setScreenNum( int num )
252 {
253 _screen = num;
254 }
255
getScreenNum(void) const256 int RenderSurface::getScreenNum( void ) const
257 {
258 return _screen;
259 }
260
setWindowRectangle(int x,int y,unsigned int width,unsigned int height,bool)261 void RenderSurface::setWindowRectangle( int x, int y, unsigned int width, unsigned int height, bool /*resize*/)
262 {
263 if( _useCustomFullScreen )
264 {
265 _windowX = x + _customFullScreenOriginX;
266 _windowY = y + _customFullScreenOriginY;
267 }
268 else
269 {
270 _windowX = x;
271 _windowY = y;
272 }
273 _windowWidth = width;
274 _windowHeight = height;
275 #ifdef _OSX_AGL_IMPLEMENTATION
276 fullScreen(false); // STH: this may break other implementations, but it is necessary for OSX
277 #else
278 _isFullScreen = false;
279 #endif
280 #if 0
281 if( _realized && resize )
282 _resizeWindow();
283 else
284 #endif
285 if( _bindInputRectangleToWindowSize == true )
286 _inputRectangle.set( 0.0, _windowWidth, 0.0, _windowHeight );
287 }
288
getWindowRectangle(int & x,int & y,unsigned int & width,unsigned int & height) const289 void RenderSurface::getWindowRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const
290 {
291 if( _isFullScreen )
292 {
293 x = 0;
294 y = 0;
295 if( _useCustomFullScreen == true )
296 {
297 width = _customFullScreenWidth;
298 height = _customFullScreenHeight;
299 }
300 else
301 {
302 width = _screenWidth;
303 height = _screenHeight;
304 }
305 }
306 else
307 {
308 x = _windowX;
309 y = _windowY;
310 width = _windowWidth;
311 height = _windowHeight;
312 }
313 }
314
useDefaultFullScreenRectangle()315 void RenderSurface::useDefaultFullScreenRectangle()
316 {
317 _useCustomFullScreen = false;
318 }
319
setCustomFullScreenRectangle(int x,int y,unsigned int width,unsigned int height)320 void RenderSurface::setCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height )
321 {
322 _customFullScreenOriginX = x;
323 _customFullScreenOriginY = y;
324 _customFullScreenWidth = width;
325 _customFullScreenHeight = height;
326 _useCustomFullScreen = true;
327
328 _windowX += _customFullScreenOriginX;
329 _windowY += _customFullScreenOriginY;
330 }
331
getWindowOriginX() const332 int RenderSurface::getWindowOriginX() const
333 {
334 if( _isFullScreen )
335 {
336 if( _useCustomFullScreen == true )
337 return _customFullScreenOriginX;
338 else
339 return 0;
340 }
341 return _windowX;
342 }
343
getWindowOriginY() const344 int RenderSurface::getWindowOriginY() const
345 {
346 if( _isFullScreen )
347 {
348 if( _useCustomFullScreen == true )
349 return _customFullScreenOriginY;
350 else
351 return 0;
352 }
353 return _windowY;
354 }
355
getWindowWidth() const356 unsigned int RenderSurface::getWindowWidth() const
357 {
358 if( _isFullScreen )
359 {
360 if( _useCustomFullScreen == true )
361 return _customFullScreenWidth;
362 else
363 return _screenWidth;
364 }
365 return _windowWidth;
366 }
367
getWindowHeight() const368 unsigned int RenderSurface::getWindowHeight() const
369 {
370 if( _isFullScreen )
371 {
372 if( _useCustomFullScreen == true )
373 return _customFullScreenHeight;
374 else
375 return _screenHeight;
376 }
377 return _windowHeight;
378 }
379
setInputRectangle(const InputRectangle & inputRectangle)380 void RenderSurface::setInputRectangle( const InputRectangle &inputRectangle )
381 {
382 _inputRectangle = inputRectangle;
383 }
384
getInputRectangle() const385 const RenderSurface::InputRectangle &RenderSurface::getInputRectangle() const
386 {
387 return _inputRectangle;
388 }
389
bindInputRectangleToWindowSize(bool flag)390 void RenderSurface::bindInputRectangleToWindowSize( bool flag)
391 {
392 _bindInputRectangleToWindowSize = flag;
393 if( _bindInputRectangleToWindowSize == true )
394 _inputRectangle.set( 0.0, float(_windowWidth), 0.0, float(_windowHeight) );
395 else
396 _inputRectangle.set( -1.0, 1.0, -1.0, 1.0 );
397 }
398
399
useBorder(bool flag)400 void RenderSurface::useBorder( bool flag )
401 {
402 _decorations = flag;
403 #if 0
404 if( _realized )
405 _setBorder(_decorations);
406 #endif
407 }
408
usesBorder()409 bool RenderSurface::usesBorder()
410 {
411 return _decorations;
412 }
413
414 #if 0
415 void RenderSurface::useCursor( bool flag )
416 {
417 _useCursor(flag);
418 }
419
420 void RenderSurface::setCursor( Cursor cursor )
421 {
422 _setCursor(cursor);
423 }
424
425 void RenderSurface::setCursorToDefault()
426 {
427 _setCursorToDefault();
428 }
429 void RenderSurface::setWindow( const Window win )
430 {
431 if( _realized )
432 {
433 std::cerr << "RenderSurface::setWindow() - cannot set window after RenderSurface has been realized\n";
434 return;
435 }
436 _win = win;
437 #ifdef WIN32
438 _ownWindow = false;
439 #endif
440 }
441
442 Producer::Window RenderSurface::getWindow( void ) const
443 {
444 return _win;
445 }
446
447 GLContext RenderSurface::getGLContext( void) const
448 {
449 return _glcontext;
450 }
451
452 void RenderSurface::setGLContext( GLContext glContext )
453 {
454 if( _realized )
455 {
456 std::cerr << "RenderSurface::setGLContext() - Warning: Must be set before realize()." << std::endl;
457 return;
458 }
459
460 _glcontext = glContext;
461 }
462
463
464 bool RenderSurface::isRealized() const
465 {
466 return _realized;
467 }
468
469 void RenderSurface::setVisualInfo( VisualInfo *vi )
470 {
471 if( _realized )
472 {
473 std::cerr << "RenderSurface::setVisualInfo():Warning - has no effect after RenderSurface has been realized\n";
474 return;
475 }
476 _visualInfo = vi;
477 #ifdef _WIN32_IMPLEMENTATION
478 _ownVisualInfo = false;
479 #endif
480 }
481
482 VisualInfo *RenderSurface::getVisualInfo( void )
483 {
484 return _visualInfo;
485 }
486
487 const VisualInfo *RenderSurface::getVisualInfo( void ) const
488 {
489 return _visualInfo;
490 }
491
492 #endif
493
setVisualChooser(VisualChooser * vc)494 void RenderSurface::setVisualChooser( VisualChooser *vc )
495 {
496 if( _realized )
497 {
498 std::cerr << "RenderSurface::setVisualChooser():Warning - has no effect after RenderSurface has been realized\n";
499 return;
500 }
501 _visualChooser = vc;
502
503 #ifdef _WIN32_IMPLEMENTATION
504 _ownVisualChooser = false;
505 #endif
506 }
507
getVisualChooser(void)508 VisualChooser *RenderSurface::getVisualChooser( void )
509 {
510 return _visualChooser.get();
511 }
512
getVisualChooser(void) const513 const VisualChooser *RenderSurface::getVisualChooser( void ) const
514 {
515 return _visualChooser.get();
516 }
517
518
519 #if 0
520 void RenderSurface::getScreenSize( unsigned int &width, unsigned int &height ) const
521 {
522 if( _realized )
523 {
524 if( _useCustomFullScreen == true )
525 {
526 width = _customFullScreenWidth;
527 height = _customFullScreenHeight;
528 }
529 else
530 {
531 width = _screenWidth;
532 height = _screenHeight;
533 }
534 }
535 else
536 {
537 _computeScreenSize(width, height);
538 }
539 }
540 #endif
541
542 #if 0
543 void RenderSurface::useConfigEventThread( bool flag )
544 {
545 if( _realized )
546 {
547 // This message is annoying. Cameras that share a render surface will call this after the
548 // render surface has been realized, which is valid.
549 //std::cerr << "RenderSurface::useConfigEventThread():Warning - has no effect after RenderSurface has been realized\n";
550 return;
551 }
552 _useConfigEventThread = flag;
553 }
554
555 unsigned int RenderSurface::getRefreshRate() const
556 {
557 if( !_realized ) return 0;
558 return _refreshRate;
559 }
560
561 void RenderSurface::addRealizeCallback( Callback *realizeCB )
562 {
563 if( _realized )
564 {
565 std::cerr << "RenderSurface::addRealizeCallback() : Warning. RenderSurface is already realized. ignored.\n";
566 return;
567 }
568 _realizeCallbacks.push_back( realizeCB );
569 }
570
571 bool RenderSurface::waitForRealize()
572 {
573 if( _realized ) return true;
574 while( _realized == false )
575 _realizeBlock->block();
576 return true;
577 }
578
579 void RenderSurface::positionPointer( int x, int y )
580 {
581 _positionPointer(x,y);
582 }
583
584 void RenderSurface::initThreads()
585 {
586 _initThreads();
587 }
588 #endif
589
getRenderToTextureMode() const590 RenderSurface::RenderToTextureMode RenderSurface::getRenderToTextureMode() const
591 {
592 return _rtt_mode;
593 }
594
595
setRenderToTextureMode(RenderToTextureMode mode)596 void RenderSurface::setRenderToTextureMode(RenderToTextureMode mode)
597 {
598 _rtt_mode = mode;
599 }
600
601
getRenderToTextureTarget() const602 RenderSurface::RenderToTextureTarget RenderSurface::getRenderToTextureTarget() const
603 {
604 return _rtt_target;
605 }
606
607
setRenderToTextureTarget(RenderToTextureTarget target)608 void RenderSurface::setRenderToTextureTarget(RenderToTextureTarget target)
609 {
610 _rtt_target = target;
611 }
612
613
getRenderToTextureOptions() const614 RenderSurface::RenderToTextureOptions RenderSurface::getRenderToTextureOptions() const
615 {
616 return _rtt_options;
617 }
618
619
setRenderToTextureOptions(RenderToTextureOptions options)620 void RenderSurface::setRenderToTextureOptions(RenderToTextureOptions options)
621 {
622 _rtt_options = options;
623 }
624
getRenderToTextureMipMapLevel() const625 int RenderSurface::getRenderToTextureMipMapLevel() const
626 {
627 return _rtt_mipmap;
628 }
629
630
setRenderToTextureMipMapLevel(int level)631 void RenderSurface::setRenderToTextureMipMapLevel(int level)
632 {
633 _rtt_mipmap = level;
634 _rtt_dirty_mipmap = true;
635 }
636
getRenderToTextureFace() const637 RenderSurface::CubeMapFace RenderSurface::getRenderToTextureFace() const
638 {
639 return _rtt_face;
640 }
641
642
setRenderToTextureFace(CubeMapFace face)643 void RenderSurface::setRenderToTextureFace(CubeMapFace face)
644 {
645 _rtt_face = face;
646 _rtt_dirty_face = true;
647 }
648
getPBufferUserAttributes() const649 const std::vector<int> &RenderSurface::getPBufferUserAttributes() const
650 {
651 return _user_pbattr;
652 }
653
getPBufferUserAttributes()654 std::vector<int> &RenderSurface::getPBufferUserAttributes()
655 {
656 return _user_pbattr;
657 }
658
659
660
useOverrideRedirect(bool flag)661 void RenderSurface::useOverrideRedirect(bool flag)
662 {
663 _overrideRedirectFlag = flag;
664 }
665
usesOverrideRedirect()666 bool RenderSurface::usesOverrideRedirect()
667 {
668 return _overrideRedirectFlag;
669 }
670
671