00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "OSDLOpenGL.h"
00028
00029 #include "OSDLVideo.h"
00030 #include "OSDLGLTexture.h"
00031 #include "OSDLUtils.h"
00032
00033
00034
00035
00036 #include "Ceylan.h"
00037
00038
00039 #ifdef OSDL_USES_CONFIG_H
00040 #include <OSDLConfig.h>
00041 #endif // OSDL_USES_CONFIG_H
00042
00043 #ifdef OSDL_HAVE_OPENGL
00044 #include "SDL_opengl.h"
00045 #endif // OSDL_HAVE_OPENGL
00046
00047
00048 #if OSDL_USES_SDL
00049 #include "SDL.h"
00050 #endif // OSDL_USES_SDL
00051
00052
00053
00054 #ifdef OSDL_RUNS_ON_WINDOWS
00055
00056
00057
00058 #ifdef near
00059 #undef near
00060 #endif // near
00061
00062 #ifdef far
00063 #undef far
00064 #endif // far
00065
00066 #endif // OSDL_RUNS_ON_WINDOWS
00067
00068
00069
00070 using std::string ;
00071
00072 #include <list>
00073 using std::list ;
00074
00075 using namespace OSDL::Video ;
00076 using namespace OSDL::Video::OpenGL ;
00077 using namespace OSDL::Video::OpenGL::GLU ;
00078
00079 using namespace Ceylan::Log ;
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #if CEYLAN_DETECTED_LITTLE_ENDIAN
00128
00129 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::RedMask = 0x000000ff ;
00130 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::GreenMask = 0x0000ff00 ;
00131 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::BlueMask = 0x00ff0000 ;
00132 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::AlphaMask = 0xff000000 ;
00133
00134
00135 #else // CEYLAN_DETECTED_LITTLE_ENDIAN
00136
00137 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::RedMask = 0xff000000 ;
00138 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::GreenMask = 0x00ff0000 ;
00139 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::BlueMask = 0x0000ff00 ;
00140 OSDL::Video::Pixels::ColorMask OSDL::Video::OpenGL::AlphaMask = 0x000000ff ;
00141
00142 #endif // CEYLAN_DETECTED_LITTLE_ENDIAN
00143
00144
00145
00146
00147
00148 OpenGLException::OpenGLException( const std::string & reason ):
00149 VideoException( reason )
00150 {
00151
00152 }
00153
00154
00155 OpenGLException::~OpenGLException() throw()
00156 {
00157
00158 }
00159
00160
00161
00162 const bool OpenGLContext::ContextCanBeLost =
00163 Ceylan::System::openGLContextsCanBeLost() ;
00164
00165
00166 const bool OpenGLContext::ContextIsLostOnResize =
00167 Ceylan::System::openGLContextsLostOnResize() ;
00168
00169
00170 const bool OpenGLContext::ContextIsLostOnApplicationSwitch =
00171 Ceylan::System::openGLContextsLostOnApplicationSwitch() ;
00172
00173
00174 const bool OpenGLContext::ContextIsLostOnColorDepthChange =
00175 Ceylan::System::openGLContextsLostOnColorDepthChange() ;
00176
00177
00178
00179 const GLLength OpenGLContext::DefaultOrthographicWidth = 1000.0f ;
00180
00181 const GLCoordinate OpenGLContext::DefaultNearClippingPlaneFor2D = -1.0f ;
00182 const GLCoordinate OpenGLContext::DefaultFarClippingPlaneFor2D = 1.0f ;
00183
00184 const GLCoordinate OpenGLContext::DefaultNearClippingPlaneFor3D = 1.0f ;
00185 const GLCoordinate OpenGLContext::DefaultFarClippingPlaneFor3D = 100000.0f ;
00186
00187
00188
00189
00190 OpenGLContext::OpenGLContext( OpenGL::Flavour flavour, BitsPerPixel plannedBpp,
00191 Length viewportWidth, Length viewportHeight ) :
00192 _flavour( OpenGL::None ),
00193 _redSize( 0 ),
00194 _greenSize( 0 ),
00195 _blueSize( 0 ),
00196 _alphaSize( 0 ),
00197 _viewportWidth( viewportWidth ),
00198 _viewportHeight( viewportHeight ),
00199 _projectionMode( Orthographic ),
00200 _projectionWidth( DefaultOrthographicWidth ),
00201 _nearClippingPlane( DefaultNearClippingPlaneFor2D ),
00202 _farClippingPlane( DefaultFarClippingPlaneFor2D ),
00203 _clearColor()
00204 {
00205
00206 #if OSDL_USES_OPENGL
00207
00208
00209
00210 LogPlug::trace( "OpenGLContext constructor" ) ;
00211
00212 selectFlavour( flavour ) ;
00213
00214 setClearColor( Pixels::Black ) ;
00215 clearViewport() ;
00216
00217 #else // OSDL_USES_OPENGL
00218
00219 throw OpenGLException( "OpenGLContext constructor failed: "
00220 "OpenGL support not available." ) ;
00221
00222 #endif // OSDL_USES_OPENGL
00223
00224 }
00225
00226
00227
00228 OpenGLContext::~OpenGLContext() throw()
00229 {
00230
00231 LogPlug::trace( "OpenGLContext destructor" ) ;
00232
00233 }
00234
00235
00236
00237
00238 void OpenGLContext::selectFlavour( Flavour flavour )
00239 {
00240
00241 LogPlug::trace( "OpenGLContext::selectFlavour" ) ;
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 switch( flavour )
00254 {
00255
00256 case None:
00257 _flavour = None ;
00258
00259 return ;
00260 break ;
00261
00262 case OpenGLFor2D:
00263
00264 set2DFlavour() ;
00265 break ;
00266
00267 case OpenGLFor3D:
00268
00269 set3DFlavour() ;
00270 return ;
00271 break ;
00272
00273 case Reload:
00274
00275 reload() ;
00276 return ;
00277 break ;
00278
00279 default:
00280 throw OpenGLException( "OpenGLContext:selectFlavour: "
00281 "unknown flavour selected." ) ;
00282 break ;
00283
00284 }
00285
00286
00287
00288
00289
00290
00291 setViewPort( _viewportWidth, _viewportHeight ) ;
00292
00293 }
00294
00295
00296
00297 void OpenGLContext::set2DFlavour()
00298 {
00299
00300 #if OSDL_USES_OPENGL
00301
00302 LogPlug::trace( "OpenGLContext::set2DFlavour" ) ;
00303
00304 _flavour = OpenGLFor2D ;
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 setDepthBufferStatus( false ) ;
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 OpenGLContext::DisableFeature( CullPolygons ) ;
00332
00333 setShadingModel( Flat ) ;
00334
00335
00336
00337
00338
00339
00340
00341 OpenGLContext::EnableFeature( Alphablending ) ;
00342
00343
00344
00345
00346
00347
00348 setBlendingFunction( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
00349
00350 GLTexture::SetTextureFlavour( GLTexture::For2D ) ;
00351
00352
00353
00354 glMatrixMode( GL_MODELVIEW ) ;
00355
00356
00357 glLoadIdentity() ;
00358
00359
00360
00361
00362
00363
00364 glTranslatef( 0.375, 0.375, 0.0 ) ;
00365
00366
00367
00368
00369 #endif // OSDL_USES_OPENGL
00370
00371 }
00372
00373
00374
00375 void OpenGLContext::set3DFlavour()
00376 {
00377
00378 #if OSDL_USES_OPENGL
00379
00380 LogPlug::trace( "OpenGLContext::set3DFlavour" ) ;
00381
00382 _flavour = OpenGLFor3D ;
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 EnableFeature( DepthTests ) ;
00395
00396 setShadingModel( Smooth ) ;
00397
00398
00399
00400
00401
00402
00403 EnableFeature( Alphablending ) ;
00404
00405
00406
00407
00408
00409
00410 setBlendingFunction( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
00411
00412 GLTexture::SetTextureFlavour( GLTexture::For3D ) ;
00413
00414 glMatrixMode( GL_PROJECTION ) ;
00415
00416 glLoadIdentity() ;
00417
00418 gluPerspective( 45.0f,
00419 static_cast<GLfloat>( _viewportWidth ) /
00420 static_cast<GLfloat>( _viewportHeight ),
00421 1.0f,
00422 100 ) ;
00423
00424
00425 glMatrixMode( GL_MODELVIEW ) ;
00426
00427
00428 glLoadIdentity() ;
00429
00430 #endif // OSDL_USES_OPENGL
00431
00432 }
00433
00434
00435
00436 void OpenGLContext::blank()
00437 {
00438
00439 LogPlug::warning( "OpenGLContext::blank not implemented yet." ) ;
00440
00441 }
00442
00443
00444
00445 void OpenGLContext::reload()
00446 {
00447
00448 setClearColor( _clearColor ) ;
00449 clearViewport() ;
00450
00451 updateProjection() ;
00452
00453 LogPlug::warning( "OpenGLContext::reload not fully implemented yet." ) ;
00454
00455 }
00456
00457
00458
00459 void OpenGLContext::setBlendingFunction( GLEnumeration sourceFactor,
00460 GLEnumeration destinationFactor )
00461 {
00462
00463 #if OSDL_USES_OPENGL
00464
00465 glBlendFunc( sourceFactor, destinationFactor ) ;
00466
00467 #if OSDL_CHECK_OPENGL_CALLS
00468
00469 switch ( glGetError() )
00470 {
00471
00472 case GL_NO_ERROR:
00473 break ;
00474
00475 case GL_INVALID_ENUM:
00476 throw OpenGLException( "OpenGLContext::setBlendingFunction: "
00477 "a factor is not an accepted value." ) ;
00478 break ;
00479
00480 case GL_INVALID_OPERATION:
00481 throw OpenGLException( "OpenGLContext::setBlendingFunction: "
00482 "incorrectly executed between the execution of glBegin and "
00483 "the corresponding execution of glEnd." ) ;
00484 break ;
00485
00486 default:
00487 throw OpenGLException( "OpenGLContext::setBlendingFunction: "
00488 "unexpected error reported." ) ;
00489 break ;
00490
00491 }
00492
00493 #endif // OSDL_CHECK_OPENGL_CALLS
00494
00495
00496 #else // OSDL_USES_OPENGL
00497
00498 throw OpenGLException( "OpenGLContext::setBlendingFunction failed: "
00499 "no OpenGL support available" ) ;
00500
00501 #endif // OSDL_USES_OPENGL
00502
00503 }
00504
00505
00506
00507 void OpenGLContext::setShadingModel( ShadingModel newShadingModel )
00508 {
00509
00510 #if OSDL_USES_OPENGL
00511
00512 #if OSDL_USES_SDL
00513
00514 switch( newShadingModel )
00515 {
00516
00517 case Flat:
00518 glShadeModel( GL_FLAT ) ;
00519 break ;
00520
00521 case Smooth:
00522 glShadeModel( GL_SMOOTH ) ;
00523 break ;
00524
00525 default:
00526 throw OpenGLException( "OpenGLContext::setShadingModel: "
00527 "unknown shading model specified." ) ;
00528 break ;
00529
00530 }
00531
00532 #if OSDL_CHECK_OPENGL_CALLS
00533
00534 switch ( glGetError() )
00535 {
00536
00537 case GL_NO_ERROR:
00538 break ;
00539
00540 case GL_INVALID_ENUM:
00541 throw OpenGLException( "OpenGLContext::setShadingModel: "
00542 "unexpected value for shading model." ) ;
00543 break ;
00544
00545 case GL_INVALID_OPERATION:
00546 throw OpenGLException( "OpenGLContext::setShadingModel: "
00547 "incorrectly executed between the execution of glBegin and "
00548 "the corresponding execution of glEnd." ) ;
00549 break ;
00550
00551 default:
00552 throw OpenGLException( "OpenGLContext::setShadingModel: "
00553 "unexpected error reported." ) ;
00554 break ;
00555
00556 }
00557
00558 #endif // OSDL_CHECK_OPENGL_CALLS
00559
00560
00561 #else // OSDL_USES_SDL
00562
00563 throw OpenGLException( "OpenGLContext::setShadingModel failed: "
00564 "no SDL support available" ) ;
00565
00566 #endif // OSDL_USES_SDL
00567
00568 #else // OSDL_USES_OPENGL
00569
00570 throw OpenGLException( "OpenGLContext::setShadingModel failed: "
00571 "no OpenGL support available" ) ;
00572
00573 #endif // OSDL_USES_OPENGL
00574
00575 }
00576
00577
00578
00579 void OpenGLContext::setCullingStatus( bool newStatus )
00580 {
00581
00582 #if OSDL_USES_OPENGL
00583
00584 #if OSDL_USES_SDL
00585
00586 if ( newStatus )
00587 EnableFeature( CullPolygons ) ;
00588 else
00589 DisableFeature( CullPolygons ) ;
00590
00591 #else // OSDL_USES_SDL
00592
00593 throw OpenGLException( "OpenGLContext::setCullingStatus failed: "
00594 "no SDL support available" ) ;
00595
00596 #endif // OSDL_USES_SDL
00597
00598 #else // OSDL_USES_OPENGL
00599
00600 throw OpenGLException( "OpenGLContext::setCullingStatus failed: "
00601 "no OpenGL support available" ) ;
00602
00603 #endif // OSDL_USES_OPENGL
00604
00605 }
00606
00607
00608
00609 void OpenGLContext::setCulling( CulledFacet culledFacet,
00610 FrontOrientation frontOrientation, bool autoEnable )
00611 {
00612
00613 #if OSDL_USES_OPENGL
00614
00615 switch( culledFacet )
00616 {
00617
00618 case Front:
00619 glCullFace( GL_FRONT ) ;
00620 break ;
00621
00622 case Back:
00623 glCullFace( GL_BACK ) ;
00624 break ;
00625
00626 case FrontAndBack:
00627 glCullFace( GL_FRONT_AND_BACK ) ;
00628 break ;
00629 }
00630
00631
00632 #if OSDL_CHECK_OPENGL_CALLS
00633
00634 switch ( glGetError() )
00635 {
00636
00637 case GL_NO_ERROR:
00638 break ;
00639
00640 case GL_INVALID_ENUM:
00641 throw OpenGLException( "OpenGLContext::setCulling (facet): "
00642 "unexpected culled facet selection." ) ;
00643 break ;
00644
00645 case GL_INVALID_OPERATION:
00646 throw OpenGLException( "OpenGLContext::setCulling (facet): "
00647 "incorrectly executed between the execution of glBegin and "
00648 "the corresponding execution of glEnd." ) ;
00649 break ;
00650
00651 default:
00652 throw OpenGLException( "OpenGLContext::setCulling (facet): "
00653 "unexpected error reported." ) ;
00654 break ;
00655
00656 }
00657
00658 #endif // OSDL_CHECK_OPENGL_CALLS
00659
00660
00661 switch( frontOrientation )
00662 {
00663
00664 case Clockwise:
00665 glFrontFace( GL_CW ) ;
00666 break ;
00667
00668 case CounterClockwise:
00669 glFrontFace( GL_CCW ) ;
00670 break ;
00671
00672 }
00673
00674
00675 #if OSDL_CHECK_OPENGL_CALLS
00676
00677 switch ( glGetError() )
00678 {
00679
00680 case GL_NO_ERROR:
00681 break ;
00682
00683 case GL_INVALID_ENUM:
00684 throw OpenGLException( "OpenGLContext::setCulling: (orientation)"
00685 "unexpected front orientation selection." ) ;
00686 break ;
00687
00688 case GL_INVALID_OPERATION:
00689 throw OpenGLException( "OpenGLContext::setCulling: (orientation)"
00690 "incorrectly executed between the execution of glBegin and "
00691 "the corresponding execution of glEnd." ) ;
00692 break ;
00693
00694 default:
00695 throw OpenGLException( "OpenGLContext::setCulling (orientation): "
00696 "unexpected error reported." ) ;
00697 break ;
00698
00699 }
00700
00701 #endif // OSDL_CHECK_OPENGL_CALLS
00702
00703
00704 if ( autoEnable )
00705 setCullingStatus( true ) ;
00706
00707 #else // OSDL_USES_OPENGL
00708
00709 throw OpenGLException( "OpenGLContext::setCulling failed: "
00710 "no OpenGL support available" ) ;
00711
00712 #endif // OSDL_USES_OPENGL
00713
00714 }
00715
00716
00717
00718 void OpenGLContext::setDepthBufferStatus( bool newStatus )
00719 {
00720
00721
00722
00723 #if OSDL_USES_OPENGL
00724
00725 if ( newStatus )
00726 {
00727 EnableFeature( DepthTests ) ;
00728 clearDepthBuffer() ;
00729 }
00730 else
00731 {
00732 DisableFeature( DepthTests ) ;
00733 }
00734
00735 #else // OSDL_USES_OPENGL
00736
00737 throw OpenGLException(
00738 "OpenGLContext::setDepthBufferStatus failed: "
00739 "no OpenGL support available" ) ;
00740
00741 #endif // OSDL_USES_OPENGL
00742
00743 }
00744
00745
00746
00747 void OpenGLContext::setViewPort( Length width, Length height,
00748 const TwoDimensional::Point2D & lowerLeftCorner )
00749 {
00750
00751 #if OSDL_USES_OPENGL
00752
00753 LogPlug::trace( "OpenGLContext::setViewPort called for "
00754 + Ceylan::toString( width ) + "x" + Ceylan::toString( height )
00755 + " from lower left corner" + lowerLeftCorner.toString() ) ;
00756
00757 _viewportWidth = width ;
00758 _viewportHeight = height ;
00759
00760 glViewport( lowerLeftCorner.getX(), lowerLeftCorner.getY(),
00761 width, height ) ;
00762
00763
00764 #if OSDL_CHECK_OPENGL_CALLS
00765
00766 switch ( glGetError() )
00767 {
00768
00769 case GL_NO_ERROR:
00770 break ;
00771
00772 case GL_INVALID_VALUE:
00773 throw OpenGLException( "OpenGLContext::setViewPort: "
00774 "either width or height is negative." ) ;
00775 break ;
00776
00777 case GL_INVALID_OPERATION:
00778 throw OpenGLException( "OpenGLContext::setViewPort: "
00779 "incorrectly executed between the execution of glBegin and "
00780 "the corresponding execution of glEnd." ) ;
00781 break ;
00782
00783 default:
00784 throw OpenGLException( "OpenGLContext::setViewPort: "
00785 "unexpected error reported." ) ;
00786 break ;
00787
00788 }
00789
00790 #endif // OSDL_CHECK_OPENGL_CALLS
00791
00792
00793
00794 updateProjection() ;
00795
00796
00797 #else // OSDL_USES_OPENGL
00798
00799 throw OpenGLException( "OpenGLContext::setViewPort failed: "
00800 "no OpenGL support available" ) ;
00801
00802 #endif // OSDL_USES_OPENGL
00803
00804 }
00805
00806
00807
00808 void OpenGLContext::setOrthographicProjection( GLLength width,
00809 GLCoordinate near, GLCoordinate far )
00810 {
00811
00812 #if OSDL_USES_OPENGL
00813
00814 LogPlug::trace( "OpenGLContext::setOrthographicProjection" ) ;
00815
00816 _projectionMode = Orthographic ;
00817 _projectionWidth = width ;
00818
00819 glMatrixMode( GL_PROJECTION ) ;
00820 glPushMatrix() ;
00821 glLoadIdentity() ;
00822
00823
00824
00825 GLCoordinate right = width / 2 ;
00826
00827
00828 GLCoordinate top = ( width * _viewportHeight ) / ( 2 * _viewportWidth ) ;
00829
00830 glOrtho( -right, right,
00831 -top, top,
00832 near, far ) ;
00833
00834
00835 #if OSDL_CHECK_OPENGL_CALLS
00836
00837 switch ( glGetError() )
00838 {
00839
00840 case GL_NO_ERROR:
00841 break ;
00842
00843 case GL_INVALID_OPERATION:
00844 throw OpenGLException( "OpenGLContext::setOrthographicProjection: "
00845 "incorrectly executed between the execution of glBegin and "
00846 "the corresponding execution of glEnd." ) ;
00847 break ;
00848
00849 default:
00850 LogPlug::warning( "OpenGLContext::setOrthographicProjection: "
00851 "unexpected error reported." ) ;
00852 break ;
00853
00854 }
00855
00856 #endif // OSDL_CHECK_OPENGL_CALLS
00857
00858 #else // OSDL_USES_OPENGL
00859
00860 throw OpenGLException( "OpenGLContext::setOrthographicProjection failed: "
00861 "no OpenGL support available" ) ;
00862
00863 #endif // OSDL_USES_OPENGL
00864
00865 }
00866
00867
00868
00869 void OpenGLContext::setOrthographicProjectionFor2D(
00870 GLLength width, GLLength height )
00871 {
00872
00873 #if OSDL_USES_OPENGL
00874
00875 LogPlug::trace( "OpenGLContext::setOrthographicProjectionFor2D" ) ;
00876
00877 _projectionMode = Orthographic ;
00878 _projectionWidth = width ;
00879
00880 glMatrixMode( GL_PROJECTION ) ;
00881
00882
00883 glLoadIdentity() ;
00884
00885
00886
00887
00888
00889
00890
00891
00892 glOrtho( 0, width,
00893 height, 0,
00894 DefaultNearClippingPlaneFor2D,
00895 DefaultFarClippingPlaneFor2D ) ;
00896
00897
00898 #if OSDL_CHECK_OPENGL_CALLS
00899
00900 switch ( glGetError() )
00901 {
00902
00903 case GL_NO_ERROR:
00904 break ;
00905
00906 case GL_INVALID_OPERATION:
00907 throw OpenGLException(
00908 "OpenGLContext::setOrthographicProjectionFor2D: "
00909 "incorrectly executed between the execution of glBegin and "
00910 "the corresponding execution of glEnd." ) ;
00911 break ;
00912
00913 default:
00914 throw OpenGLException(
00915 "OpenGLContext::setOrthographicProjectionFor2D: "
00916 "unexpected error reported." ) ;
00917 break ;
00918
00919 }
00920
00921 #endif // OSDL_CHECK_OPENGL_CALLS
00922
00923
00924 #else // OSDL_USES_OPENGL
00925
00926 throw OpenGLException(
00927 "OpenGLContext::setOrthographicProjectionFor2D failed: "
00928 "no OpenGL support available" ) ;
00929
00930 #endif // OSDL_USES_OPENGL
00931
00932 }
00933
00934
00935
00936 void OpenGLContext::setClearColor( const Pixels::ColorDefinition & color )
00937 {
00938
00939 #if OSDL_USES_OPENGL
00940
00941 _clearColor = color ;
00942
00943 glClearColor( static_cast<GLclampf>( color.r/255.0 ),
00944 static_cast<GLclampf>( color.g/255.0 ),
00945 static_cast<GLclampf>( color.b/255.0 ),
00946 static_cast<GLclampf>( color.unused/255.0 ) ) ;
00947
00948 #if OSDL_CHECK_OPENGL_CALLS
00949
00950 switch ( glGetError() )
00951 {
00952
00953 case GL_NO_ERROR:
00954 break ;
00955
00956 case GL_INVALID_OPERATION:
00957 throw OpenGLException( "OpenGLContext::setClearColor: "
00958 "incorrectly executed between the execution of glBegin and "
00959 "the corresponding execution of glEnd." ) ;
00960 break ;
00961
00962 default:
00963 LogPlug::warning( "OpenGLContext::setClearColor: "
00964 "unexpected error reported." ) ;
00965 break ;
00966
00967 }
00968
00969 #endif // OSDL_CHECK_OPENGL_CALLS
00970
00971 #else // OSDL_USES_OPENGL
00972
00973 throw OpenGLException( "OpenGLContext::setClearColor failed: "
00974 "no OpenGL support available" ) ;
00975
00976 #endif // OSDL_USES_OPENGL
00977
00978 }
00979
00980
00981
00982 void OpenGLContext::clearViewport()
00983 {
00984
00985 #if OSDL_USES_OPENGL
00986
00987 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
00988
00989 #if OSDL_CHECK_OPENGL_CALLS
00990
00991 switch ( glGetError() )
00992 {
00993
00994 case GL_NO_ERROR:
00995 break ;
00996
00997 case GL_INVALID_VALUE:
00998 throw OpenGLException( "OpenGLContext::clearViewport: "
00999 "invalid bit in specified clear mask." ) ;
01000 break ;
01001
01002 case GL_INVALID_OPERATION:
01003 throw OpenGLException( "OpenGLContext::clearViewport: "
01004 "incorrectly executed between the execution of glBegin and "
01005 "the corresponding execution of glEnd." ) ;
01006 break ;
01007
01008 default:
01009 LogPlug::warning( "OpenGLContext::clearViewport: "
01010 "unexpected error reported." ) ;
01011 break ;
01012
01013 }
01014
01015 #endif // OSDL_CHECK_OPENGL_CALLS
01016
01017
01018 #else // OSDL_USES_OPENGL
01019
01020 throw OpenGLException( "OpenGLContext::clearViewport failed: "
01021 "no OpenGL support available" ) ;
01022
01023 #endif // OSDL_USES_OPENGL
01024
01025 }
01026
01027
01028
01029 void OpenGLContext::clearDepthBuffer()
01030 {
01031
01032 #if OSDL_USES_OPENGL
01033
01034 glClear( GL_DEPTH_BUFFER_BIT ) ;
01035
01036
01037 #if OSDL_CHECK_OPENGL_CALLS
01038
01039 switch ( glGetError() )
01040 {
01041 case GL_NO_ERROR:
01042 break ;
01043
01044 case GL_INVALID_VALUE:
01045 throw OpenGLException( "OpenGLContext::clearDepthBuffer: "
01046 "invalid bit in specified clear mask." ) ;
01047 break ;
01048
01049 case GL_INVALID_OPERATION:
01050 throw OpenGLException( "OpenGLContext::clearDepthBuffer: "
01051 "incorrectly executed between the execution of glBegin and "
01052 "the corresponding execution of glEnd." ) ;
01053 break ;
01054
01055 default:
01056 LogPlug::warning( "OpenGLContext::clearDepthBuffer: "
01057 "unexpected error reported." ) ;
01058 break ;
01059
01060 }
01061
01062 #endif // OSDL_CHECK_OPENGL_CALLS
01063
01064
01065 #else // OSDL_USES_OPENGL
01066
01067 throw OpenGLException( "OpenGLContext::clearDepthBuffer failed: "
01068 "no OpenGL support available" ) ;
01069
01070 #endif // OSDL_USES_OPENGL
01071
01072 }
01073
01074
01075
01076 void OpenGLContext::pushAttribute( GLBitField attributeField )
01077 {
01078
01079 #if OSDL_USES_OPENGL
01080
01081 glPushAttrib( attributeField ) ;
01082
01083 #if OSDL_CHECK_OPENGL_CALLS
01084
01085 switch ( glGetError() )
01086 {
01087
01088 case GL_NO_ERROR:
01089 break ;
01090
01091 case GL_STACK_OVERFLOW:
01092 throw OpenGLException( "OpenGLContext::pushAttribute: "
01093 "attribute stack is full." ) ;
01094 break ;
01095
01096 case GL_INVALID_OPERATION:
01097 throw OpenGLException( "OpenGLContext::pushAttribute: "
01098 "incorrectly executed between the execution of glBegin and "
01099 "the corresponding execution of glEnd." ) ;
01100 break ;
01101
01102 default:
01103 throw OpenGLException( "OpenGLContext::pushAttribute: "
01104 "unexpected error reported." ) ;
01105 break ;
01106
01107 }
01108
01109 #endif // OSDL_CHECK_OPENGL_CALLS
01110
01111
01112 #else // OSDL_USES_OPENGL
01113
01114 throw OpenGLException( "OpenGLContext::pushAttribute failed: "
01115 "no OpenGL support available" ) ;
01116
01117 #endif // OSDL_USES_OPENGL
01118
01119 }
01120
01121
01122
01123 void OpenGLContext::popAttribute()
01124 {
01125
01126 #if OSDL_USES_OPENGL
01127
01128 glPopAttrib() ;
01129
01130 #if OSDL_CHECK_OPENGL_CALLS
01131
01132 switch ( glGetError() )
01133 {
01134
01135 case GL_NO_ERROR:
01136 break ;
01137
01138 case GL_STACK_UNDERFLOW:
01139 throw OpenGLException( "OpenGLContext::popAttribute: "
01140 "attribute stack is empty." ) ;
01141 break ;
01142
01143 case GL_INVALID_OPERATION:
01144 throw OpenGLException( "OpenGLContext::popAttribute: "
01145 "incorrectly executed between the execution of glBegin and "
01146 "the corresponding execution of glEnd." ) ;
01147 break ;
01148
01149 default:
01150 throw OpenGLException( "OpenGLContext::popAttribute: "
01151 "unexpected error reported." ) ;
01152 break ;
01153
01154 }
01155
01156 #endif // OSDL_CHECK_OPENGL_CALLS
01157
01158
01159 #else // OSDL_USES_OPENGL
01160
01161 throw OpenGLException( "OpenGLContext::popAttribute failed: "
01162 "no OpenGL support available" ) ;
01163
01164 #endif // OSDL_USES_OPENGL
01165
01166 }
01167
01168
01169
01170
01171
01172 const string OpenGLContext::toString( Ceylan::VerbosityLevels level ) const
01173 {
01174
01175 std::list<string> res ;
01176
01177 res.push_back( "OpenGL context whose current selected flavour is "
01178 + ToString( _flavour ) + "." ) ;
01179
01180 OSDL::Video::BitsPerPixel redSize, greenSize, blueSize, alphaSize ;
01181
01182 BitsPerPixel bpp = GetColorDepth( redSize, greenSize, blueSize,
01183 alphaSize ) ;
01184
01185 res.push_back( "Overall bit per pixel is "
01186 + Ceylan::toNumericalString( bpp ) + "." ) ;
01187
01188 res.push_back( "Red component size: "
01189 + Ceylan::toNumericalString( redSize ) + " bits." ) ;
01190
01191 res.push_back( "Green component size: "
01192 + Ceylan::toNumericalString( greenSize ) + " bits." ) ;
01193
01194 res.push_back( "Blue component size: "
01195 + Ceylan::toNumericalString( blueSize ) + " bits." ) ;
01196
01197 res.push_back( "Alpha component size: "
01198 + Ceylan::toNumericalString( alphaSize ) + " bits." ) ;
01199
01200 return "Current OpenGL state is:" + Ceylan::formatStringList( res ) ;
01201
01202 }
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212 void OpenGLContext::SetUpForFlavour( OpenGL::Flavour flavour, bool safest )
01213 {
01214
01215 #if OSDL_USES_OPENGL
01216
01217
01218
01219 switch( flavour )
01220 {
01221
01222 case None:
01223
01224 break ;
01225
01226 case OpenGLFor2D:
01227 SetDoubleBufferStatus( true ) ;
01228
01229
01230 SetHardwareAccelerationStatus( true ) ;
01231 TrySettingVerticalBlankSynchronizationStatus( true ) ;
01232
01233 break ;
01234
01235 case OpenGLFor3D:
01236 SetDoubleBufferStatus( true ) ;
01237 SetDepthBufferSize( 16 ) ;
01238
01239 if ( ! safest )
01240 {
01241
01242 SetFullScreenAntialiasingStatus( true,
01243 4 ) ;
01244
01245 }
01246 else
01247 {
01248
01249 SetFullScreenAntialiasingStatus( false ) ;
01250
01251 }
01252 SetHardwareAccelerationStatus( true ) ;
01253 TrySettingVerticalBlankSynchronizationStatus( true ) ;
01254
01255 break ;
01256
01257 case Reload:
01258
01259 break ;
01260
01261 default:
01262 throw OpenGLException( "OpenGLContext::SetUpForFlavour failed: "
01263 "unknown flavour (" + Ceylan::toString( flavour )
01264 + "), which is abnormal." ) ;
01265 break ;
01266 }
01267
01268
01269 #else // OSDL_USES_OPENGL
01270
01271 throw OpenGLException( "OpenGLContext::SetUpForFlavour failed: "
01272 "no OpenGL support available" ) ;
01273
01274 #endif // OSDL_USES_OPENGL
01275
01276
01277 }
01278
01279
01280
01281 void OpenGLContext::EnableFeature( OpenGL::Feature feature )
01282 {
01283
01284 #if OSDL_USES_OPENGL
01285
01286 #if OSDL_CHECK_OPENGL_CALLS
01287
01288 switch( feature )
01289 {
01290
01291 case Alphablending:
01292 case TwoDimensionalTexturing:
01293 case CullPolygons:
01294 case DepthTests:
01295 case Lighting:
01296 case Light_1:
01297 case Light_2:
01298 case Light_3:
01299 case Light_4:
01300 case Light_5:
01301 case Light_6:
01302 case Light_7:
01303 case Light_8:
01304 break ;
01305
01306 default:
01307 throw OpenGLException( "OpenGLContext::EnableFeature: "
01308 "unexpected feature requested ("
01309 + Ceylan::toString( feature ) + ")." ) ;
01310
01311 }
01312
01313 #endif // OSDL_CHECK_OPENGL_CALLS
01314
01315 glEnable( feature ) ;
01316
01317 #if OSDL_CHECK_OPENGL_CALLS
01318
01319 switch ( glGetError() )
01320 {
01321
01322 case GL_NO_ERROR:
01323 break ;
01324
01325 case GL_INVALID_ENUM:
01326 throw OpenGLException( "OpenGLContext::EnableFeature: "
01327 "invalid enumeration." ) ;
01328 break ;
01329
01330 case GL_INVALID_OPERATION:
01331 throw OpenGLException( "OpenGLContext::EnableFeature: "
01332 "incorrectly executed between the execution of glBegin and "
01333 "the corresponding execution of glEnd." ) ;
01334 break ;
01335
01336 default:
01337 throw OpenGLException( "OpenGLContext::EnableFeature: "
01338 "unexpected error reported." ) ;
01339 break ;
01340
01341 }
01342
01343 #endif // OSDL_CHECK_OPENGL_CALLS
01344
01345
01346 #else // OSDL_USES_OPENGL
01347
01348 throw OpenGLException( "OpenGLContext::EnableFeature failed: "
01349 "no OpenGL support available" ) ;
01350
01351 #endif // OSDL_USES_OPENGL
01352
01353 }
01354
01355
01356
01357 void OpenGLContext::DisableFeature( Feature feature )
01358 {
01359
01360 #if OSDL_CHECK_OPENGL_CALLS
01361
01362 switch( feature )
01363 {
01364
01365 case Alphablending:
01366 case TwoDimensionalTexturing:
01367 case CullPolygons:
01368 case DepthTests:
01369 case Lighting:
01370 case Light_1:
01371 case Light_2:
01372 case Light_3:
01373 case Light_4:
01374 case Light_5:
01375 case Light_6:
01376 case Light_7:
01377 case Light_8:
01378 break ;
01379
01380 default:
01381 throw OpenGLException( "OpenGLContext::DisableFeature: "
01382 "unexpected feature specified ("
01383 + Ceylan::toString( feature ) + ")." ) ;
01384
01385 }
01386
01387 #endif // OSDL_CHECK_OPENGL_CALLS
01388
01389 #if OSDL_USES_OPENGL
01390
01391 glDisable( feature ) ;
01392
01393 #if OSDL_CHECK_OPENGL_CALLS
01394
01395 switch ( glGetError() )
01396 {
01397
01398 case GL_NO_ERROR:
01399 break ;
01400
01401 case GL_INVALID_ENUM:
01402 throw OpenGLException( "OpenGLContext::DisableFeature: "
01403 "invalid enumeration." ) ;
01404 break ;
01405
01406 case GL_INVALID_OPERATION:
01407 throw OpenGLException( "OpenGLContext::DisableFeature: "
01408 "incorrectly executed between the execution of glBegin and "
01409 "the corresponding execution of glEnd." ) ;
01410 break ;
01411
01412 default:
01413 throw OpenGLException( "OpenGLContext::DisableFeature: "
01414 "unexpected error reported." ) ;
01415 break ;
01416
01417 }
01418
01419 #endif // OSDL_CHECK_OPENGL_CALLS
01420
01421
01422 #else // OSDL_USES_OPENGL
01423
01424 throw OpenGLException( "OpenGLContext::DisableFeature failed: "
01425 "no OpenGL support available" ) ;
01426
01427 #endif // OSDL_USES_OPENGL
01428
01429 }
01430
01431
01432
01433 bool OpenGLContext::GetDoubleBufferStatus()
01434 {
01435
01436 return ( GetGLAttribute( SDL_GL_DOUBLEBUFFER ) == 1 ) ;
01437
01438 }
01439
01440
01441
01442 void OpenGLContext::SetDoubleBufferStatus( bool newStatus )
01443 {
01444
01445 #if OSDL_USES_OPENGL
01446
01447 #if OSDL_USES_SDL
01448
01449
01450
01451
01452
01453
01454 SetGLAttribute( SDL_GL_DOUBLEBUFFER, newStatus ? 1 : 0 ) ;
01455
01456 #else // OSDL_USES_SDL
01457
01458 throw OpenGLException( "OpenGLContext::SetDoubleBufferStatus failed: "
01459 "no SDL support available" ) ;
01460
01461 #endif // OSDL_USES_SDL
01462
01463 #else // OSDL_USES_OPENGL
01464
01465 throw OpenGLException( "OpenGLContext::SetDoubleBufferStatus failed: "
01466 "no OpenGL support available" ) ;
01467
01468 #endif // OSDL_USES_OPENGL
01469
01470 }
01471
01472
01473
01474 Ceylan::Uint8 OpenGLContext::GetDepthBufferSize()
01475 {
01476
01477 return static_cast<Ceylan::Uint8>( GetGLAttribute( SDL_GL_DEPTH_SIZE ) ) ;
01478
01479 }
01480
01481
01482
01483 void OpenGLContext::SetDepthBufferSize( Ceylan::Uint8 bitsNumber )
01484 {
01485
01486 #if OSDL_USES_OPENGL
01487
01488 #if OSDL_USES_SDL
01489
01490
01491
01492
01493
01494
01495 SetGLAttribute( SDL_GL_DEPTH_SIZE, bitsNumber ) ;
01496
01497 #else // OSDL_USES_SDL
01498
01499 throw OpenGLException( "OpenGLContext::SetDepthBufferSize failed: "
01500 "no SDL support available" ) ;
01501
01502 #endif // OSDL_USES_SDL
01503
01504 #else // OSDL_USES_OPENGL
01505
01506 throw OpenGLException( "OpenGLContext::SetDepthBufferSize failed: "
01507 "no OpenGL support available" ) ;
01508
01509 #endif // OSDL_USES_OPENGL
01510
01511 }
01512
01513
01514
01515 Ceylan::Uint8 OpenGLContext::GetFullScreenAntialiasingStatus()
01516 {
01517
01518
01519
01520
01521
01522
01523
01524 if ( GetGLAttribute( SDL_GL_MULTISAMPLEBUFFERS ) == 0 )
01525 return 0 ;
01526
01527 return static_cast<Ceylan::Uint8>(
01528 GetGLAttribute( SDL_GL_MULTISAMPLESAMPLES ) ) ;
01529
01530 }
01531
01532
01533
01534 void OpenGLContext::SetFullScreenAntialiasingStatus( bool newStatus,
01535 Ceylan::Uint8 samplesPerPixelNumber )
01536 {
01537
01538 #if OSDL_USES_OPENGL
01539
01540 #if OSDL_USES_SDL
01541
01542
01543
01544
01545
01546
01547
01548 if ( newStatus )
01549 {
01550
01551 SetGLAttribute( SDL_GL_MULTISAMPLEBUFFERS,
01552 1 ) ;
01553
01554 SetGLAttribute( SDL_GL_MULTISAMPLESAMPLES, samplesPerPixelNumber ) ;
01555
01556 }
01557 else
01558 {
01559
01560 SetGLAttribute( SDL_GL_MULTISAMPLEBUFFERS,
01561 0 ) ;
01562
01563 SetGLAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 ) ;
01564
01565 }
01566
01567 #else // OSDL_USES_SDL
01568
01569 throw OpenGLException(
01570 "OpenGLContext::SetFullScreenAntialiasingStatus failed: "
01571 "no SDL support available" ) ;
01572
01573 #endif // OSDL_USES_SDL
01574
01575 #else // OSDL_USES_OPENGL
01576
01577 throw OpenGLException(
01578 "OpenGLContext::SetFullScreenAntialiasingStatus failed: "
01579 "no OpenGL support available" ) ;
01580
01581 #endif // OSDL_USES_OPENGL
01582
01583 }
01584
01585
01586
01587 bool OpenGLContext::GetHardwareAccelerationStatus()
01588 {
01589
01590
01591
01592
01593
01594
01595
01596 return ( GetGLAttribute( SDL_GL_ACCELERATED_VISUAL ) == 1 ) ;
01597
01598 }
01599
01600
01601
01602 void OpenGLContext::SetHardwareAccelerationStatus( bool newStatus )
01603 {
01604
01605 #if OSDL_USES_OPENGL
01606
01607 #if OSDL_USES_SDL
01608
01609
01610
01611
01612
01613
01614 SetGLAttribute( SDL_GL_ACCELERATED_VISUAL, newStatus ? 1 : 0 ) ;
01615
01616 #else // OSDL_USES_SDL
01617
01618 throw OpenGLException(
01619 "OpenGLContext::SetHardwareAccelerationStatus failed: "
01620 "no SDL support available" ) ;
01621
01622 #endif // OSDL_USES_SDL
01623
01624 #else // OSDL_USES_OPENGL
01625
01626 throw OpenGLException(
01627 "OpenGLContext::SetHardwareAccelerationStatus failed: "
01628 "no OpenGL support available" ) ;
01629
01630 #endif // OSDL_USES_OPENGL
01631
01632 }
01633
01634
01635
01636 bool OpenGLContext::GetVerticalBlankSynchronizationStatus()
01637 {
01638
01639
01640
01641
01642
01643
01644
01645 return ( GetGLAttribute( SDL_GL_SWAP_CONTROL ) == 1 ) ;
01646
01647 }
01648
01649
01650
01651 void OpenGLContext::SetVerticalBlankSynchronizationStatus( bool newStatus )
01652 {
01653
01654 #if OSDL_USES_OPENGL
01655
01656 #if OSDL_USES_SDL
01657
01658
01659
01660
01661
01662
01663 SetGLAttribute( SDL_GL_SWAP_CONTROL, newStatus ? 1 : 0 ) ;
01664
01665 #else // OSDL_USES_SDL
01666
01667 throw OpenGLException(
01668 "OpenGLContext::SetVerticalBlankSynchronizationStatus failed: "
01669 "no SDL support available" ) ;
01670
01671 #endif // OSDL_USES_SDL
01672
01673 #else // OSDL_USES_OPENGL
01674
01675 throw OpenGLException(
01676 "OpenGLContext::SetVerticalBlankSynchronizationStatus failed: "
01677 "no OpenGL support available" ) ;
01678
01679 #endif // OSDL_USES_OPENGL
01680
01681 }
01682
01683
01684
01685 bool OpenGLContext::TrySettingVerticalBlankSynchronizationStatus(
01686 bool newStatus )
01687 {
01688
01689 #if OSDL_USES_OPENGL
01690
01691 #if OSDL_USES_SDL
01692
01693
01694
01695
01696
01697
01698 return TrySettingGLAttribute( SDL_GL_SWAP_CONTROL, newStatus ? 1 : 0 ) ;
01699
01700 #else // OSDL_USES_SDL
01701
01702 throw OpenGLException(
01703 "OpenGLContext::TrySettingVerticalBlankSynchronizationStatus failed: "
01704 "no SDL support available" ) ;
01705
01706 #endif // OSDL_USES_SDL
01707
01708 #else // OSDL_USES_OPENGL
01709
01710 throw OpenGLException(
01711 "OpenGLContext::TrySettingVerticalBlankSynchronizationStatus failed: "
01712 "no OpenGL support available" ) ;
01713
01714 #endif // OSDL_USES_OPENGL
01715
01716 }
01717
01718
01719
01720 Ceylan::Uint8 OpenGLContext::GetColorDepth(
01721 OSDL::Video::BitsPerPixel & redSize,
01722 OSDL::Video::BitsPerPixel & greenSize,
01723 OSDL::Video::BitsPerPixel & blueSize,
01724 OSDL::Video::BitsPerPixel & alphaSize )
01725 {
01726
01727 #if OSDL_USES_OPENGL
01728
01729 #if OSDL_USES_SDL
01730
01731
01732 redSize = static_cast<OSDL::Video::BitsPerPixel>(
01733 GetGLAttribute( SDL_GL_RED_SIZE ) ) ;
01734
01735 greenSize = static_cast<OSDL::Video::BitsPerPixel>(
01736 GetGLAttribute( SDL_GL_GREEN_SIZE ) ) ;
01737
01738 blueSize = static_cast<OSDL::Video::BitsPerPixel>(
01739 GetGLAttribute( SDL_GL_BLUE_SIZE ) ) ;
01740
01741 alphaSize = static_cast<OSDL::Video::BitsPerPixel>(
01742 GetGLAttribute( SDL_GL_ALPHA_SIZE ) ) ;
01743
01744
01745 return redSize + greenSize + blueSize ;
01746
01747
01748 #else // OSDL_USES_SDL
01749
01750 throw OpenGLException( "OpenGLContext::GetColorDepth failed: "
01751 "no SDL support available" ) ;
01752
01753 #endif // OSDL_USES_SDL
01754
01755 #else // OSDL_USES_OPENGL
01756
01757 throw OpenGLException( "OpenGLContext::GetColorDepth failed: "
01758 "no OpenGL support available" ) ;
01759
01760 #endif // OSDL_USES_OPENGL
01761
01762 }
01763
01764
01765
01766 void OpenGLContext::SetColorDepth( BitsPerPixel plannedBpp )
01767 {
01768
01769 #if OSDL_USES_OPENGL
01770
01771 #if OSDL_USES_SDL
01772
01773
01774
01775 int rgbSize[ 3 ] ;
01776
01777 switch( plannedBpp )
01778 {
01779
01780 case 8:
01781 rgbSize[0] = 3 ;
01782 rgbSize[1] = 3 ;
01783 rgbSize[2] = 2 ;
01784 break ;
01785
01786 case 15:
01787 case 16:
01788 rgbSize[0] = 5 ;
01789 rgbSize[1] = 5 ;
01790 rgbSize[2] = 5 ;
01791 break ;
01792
01793 case 32:
01794 rgbSize[0] = 8 ;
01795 rgbSize[1] = 8 ;
01796 rgbSize[2] = 8 ;
01797 break ;
01798
01799 default:
01800 throw OpenGLException( "OpenGLContext::SetColorDepth failed: "
01801 "unsupported color depth ("
01802 + Ceylan::toNumericalString(plannedBpp)
01803 + " bits per pixel)" ) ;
01804 break ;
01805 }
01806
01807
01808
01809
01810
01811
01812
01813 SetGLAttribute( SDL_GL_RED_SIZE, rgbSize[0] ) ;
01814 SetGLAttribute( SDL_GL_GREEN_SIZE, rgbSize[1] ) ;
01815 SetGLAttribute( SDL_GL_BLUE_SIZE, rgbSize[2] ) ;
01816
01817
01818
01819
01820 #else // OSDL_USES_SDL
01821
01822 throw OpenGLException( "OpenGLContext::SetColorDepth failed: "
01823 "no SDL support available" ) ;
01824
01825 #endif // OSDL_USES_SDL
01826
01827 #else // OSDL_USES_OPENGL
01828
01829 throw OpenGLException( "OpenGLContext::SetColorDepth failed: "
01830 "no OpenGL support available" ) ;
01831
01832 #endif // OSDL_USES_OPENGL
01833
01834 }
01835
01836
01837
01838 void OpenGLContext::SetColorDepth(
01839 OSDL::Video::BitsPerPixel redSize,
01840 OSDL::Video::BitsPerPixel greenSize,
01841 OSDL::Video::BitsPerPixel blueSize )
01842 {
01843
01844 #if OSDL_USES_OPENGL
01845
01846 #if OSDL_USES_SDL
01847
01848
01849
01850
01851
01852
01853 SetGLAttribute( SDL_GL_RED_SIZE, redSize ) ;
01854 SetGLAttribute( SDL_GL_GREEN_SIZE, greenSize ) ;
01855 SetGLAttribute( SDL_GL_BLUE_SIZE, blueSize ) ;
01856
01857
01858
01859 #else // OSDL_USES_SDL
01860
01861 throw OpenGLException( "OpenGLContext::SetColorDepth failed: "
01862 "no SDL support available" ) ;
01863
01864 #endif // OSDL_USES_SDL
01865
01866 #else // OSDL_USES_OPENGL
01867
01868 throw OpenGLException( "OpenGLContext::SetColorDepth failed: "
01869 "no OpenGL support available" ) ;
01870
01871 #endif // OSDL_USES_OPENGL
01872
01873 }
01874
01875
01876
01877 std::string OpenGLContext::InterpretFeatureAvailability()
01878 {
01879
01880 #if OSDL_USES_OPENGL
01881
01882 #if OSDL_USES_SDL
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894 std::list<string> res ;
01895
01896 if ( HasGLAttribute( SDL_GL_DOUBLEBUFFER ) )
01897 {
01898
01899 if ( GetDoubleBufferStatus() )
01900 res.push_back( "OpenGL double-buffering available." ) ;
01901 else
01902 res.push_back( "OpenGL double-buffering not available." ) ;
01903
01904 }
01905 else
01906 res.push_back( "No OpenGL double-buffering attribute defined." ) ;
01907
01908
01909 if ( HasGLAttribute( SDL_GL_DEPTH_SIZE ) )
01910 res.push_back( "OpenGL depth buffer size: "
01911 + Ceylan::toNumericalString( GetDepthBufferSize() ) + " bits." ) ;
01912 else
01913 res.push_back( "No OpenGL depth buffer size attribute defined." ) ;
01914
01915
01916 if ( HasGLAttribute( SDL_GL_MULTISAMPLEBUFFERS ) )
01917 {
01918
01919 Ceylan::Uint8 samples = GetFullScreenAntialiasingStatus() ;
01920
01921 if ( samples == 0 )
01922 res.push_back( "OpenGL Fullscreen antialiasing not available." ) ;
01923 else
01924 res.push_back( Ceylan::toNumericalString( samples )
01925 + "x fullscreen antialiasing available." ) ;
01926 }
01927 else
01928 {
01929
01930 res.push_back( "No OpenGL multisample buffer attribute defined." ) ;
01931
01932 }
01933
01934
01935 if ( HasGLAttribute( SDL_GL_ACCELERATED_VISUAL ) )
01936 {
01937
01938 if ( GetHardwareAccelerationStatus() )
01939 res.push_back( "OpenGL hardware acceleration available." ) ;
01940 else
01941 res.push_back( "OpenGL hardware acceleration not available." ) ;
01942
01943 }
01944 else
01945 {
01946
01947 res.push_back( "No OpenGL hardware acceleration attribute defined." ) ;
01948
01949 }
01950
01951
01952 if ( HasGLAttribute( SDL_GL_SWAP_CONTROL ) )
01953 {
01954
01955 if ( GetVerticalBlankSynchronizationStatus() )
01956 res.push_back(
01957 "OpenGL vertical blank synchronization (VSYNC) available." ) ;
01958 else
01959 res.push_back(
01960 "OpenGL vertical blank synchronization (VSYNC) not available."
01961 ) ;
01962 }
01963 else
01964 {
01965
01966 res.push_back( "No OpenGL vertical blank synchronization (VSYNC) "
01967 "attribute defined." ) ;
01968
01969 }
01970
01971
01972 if ( HasGLAttribute( SDL_GL_RED_SIZE )
01973 && HasGLAttribute( SDL_GL_GREEN_SIZE )
01974 && HasGLAttribute( SDL_GL_BLUE_SIZE )
01975 && HasGLAttribute( SDL_GL_ALPHA_SIZE ) )
01976 {
01977
01978 OSDL::Video::BitsPerPixel redSize, greenSize, blueSize, alphaSize,
01979 total ;
01980
01981 total = GetColorDepth( redSize, greenSize, blueSize, alphaSize ) ;
01982
01983 res.push_back( "OpenGL Color depths: "
01984 + Ceylan::toNumericalString( total )
01985 + " color bits per pixel, with "
01986 + Ceylan::toNumericalString( redSize ) + " bits for red, "
01987 + Ceylan::toNumericalString( greenSize ) + " bits for green, "
01988 + Ceylan::toNumericalString( blueSize ) + " bits for blue, and "
01989 + Ceylan::toNumericalString( alphaSize ) + " bits for alpha" ) ;
01990
01991 }
01992 else
01993 {
01994
01995 res.push_back( "OpenGL color depth component attributes "
01996 "are not all defined." ) ;
01997
01998 }
01999
02000 return "Summary of the currently available OpenGL features: "
02001 + Ceylan::formatStringList( res ) ;
02002
02003
02004 #else // OSDL_USES_SDL
02005
02006 throw OpenGLException(
02007 "OpenGLContext::InterpretFeatureAvailability failed: "
02008 "no SDL support available" ) ;
02009
02010 #endif // OSDL_USES_SDL
02011
02012 #else // OSDL_USES_OPENGL
02013
02014 throw OpenGLException(
02015 "OpenGLContext::InterpretFeatureAvailability failed: "
02016 "no OpenGL support available" ) ;
02017
02018 #endif // OSDL_USES_OPENGL
02019
02020 }
02021
02022
02023
02024 string OpenGLContext::ToString( OpenGL::Flavour flavour )
02025 {
02026
02027 switch( flavour )
02028 {
02029
02030 case OpenGL::None:
02031 return "no OpenGL" ;
02032 break ;
02033
02034 case OpenGL::OpenGLFor2D:
02035 return "OpenGL for 2D" ;
02036 break ;
02037
02038 case OpenGL::OpenGLFor3D:
02039 return "OpenGL for 3D" ;
02040 break ;
02041
02042 case OpenGL::Reload:
02043 return "reload OpenGL context" ;
02044 break ;
02045
02046 default:
02047 return "unknown flavour (" + Ceylan::toString( flavour )
02048 + "), which is abnormal" ;
02049 break ;
02050
02051 }
02052
02053 }
02054
02055
02056
02057
02058
02059
02060
02061
02062 void OpenGLContext::updateProjection()
02063 {
02064
02065 LogPlug::trace( "OpenGLContext::updateProjection" ) ;
02066
02067 switch( _flavour )
02068 {
02069
02070 case OpenGLFor2D:
02071
02072 setOrthographicProjectionFor2D( _viewportWidth, _viewportHeight ) ;
02073 return ;
02074 break ;
02075
02076 case OpenGLFor3D:
02077
02078
02079 return ;
02080 break ;
02081
02082 default:
02083 LogPlug::warning( "OpenGLContext::updateProjection: "
02084 "not managed currently for that flavour." ) ;
02085 return ;
02086 break ;
02087
02088 }
02089
02090
02091 }
02092
02093
02094
02095 bool OpenGLContext::HasGLAttribute( GLAttribute attribute )
02096 {
02097
02098 #if OSDL_USES_OPENGL
02099
02100 #if OSDL_USES_SDL
02101
02102
02103
02104
02105
02106
02107
02108 int value ;
02109
02110 return ( SDL_GL_GetAttribute( attribute, & value ) != -1 ) ;
02111
02112 #else // OSDL_USES_SDL
02113
02114 throw OpenGLException( "OpenGLContext::HasGLAttribute failed: "
02115 "no SDL support available" ) ;
02116
02117 #endif // OSDL_USES_SDL
02118
02119 #else // OSDL_USES_OPENGL
02120
02121 throw OpenGLException( "OpenGLContext::HasGLAttribute failed: "
02122 "no OpenGL support available" ) ;
02123
02124 #endif // OSDL_USES_OPENGL
02125
02126 }
02127
02128
02129
02130 int OpenGLContext::GetGLAttribute( GLAttribute attribute )
02131 {
02132
02133 #if OSDL_USES_OPENGL
02134
02135 #if OSDL_USES_SDL
02136
02137
02138
02139
02140
02141
02142
02143 int value ;
02144
02145 if ( SDL_GL_GetAttribute( attribute, & value ) == -1 )
02146 throw OpenGLException(
02147 "OpenGLContext::GetGLAttribute of attribute corresponding to "
02148 + GLAttributeToString( attribute ) + " failed: "
02149 + Utils::getBackendLastError() ) ;
02150
02151 return value ;
02152
02153 #else // OSDL_USES_SDL
02154
02155 throw OpenGLException( "OpenGLContext::GetGLAttribute failed: "
02156 "no SDL support available" ) ;
02157
02158 #endif // OSDL_USES_SDL
02159
02160 #else // OSDL_USES_OPENGL
02161
02162 throw OpenGLException( "OpenGLContext::GetGLAttribute failed: "
02163 "no OpenGL support available" ) ;
02164
02165 #endif // OSDL_USES_OPENGL
02166
02167 }
02168
02169
02170
02171 void OpenGLContext::SetGLAttribute( GLAttribute attribute, int value )
02172 {
02173
02174 #if OSDL_USES_OPENGL
02175
02176 #if OSDL_USES_SDL
02177
02178
02179
02180
02181
02182
02183
02184 if ( SDL_GL_SetAttribute( attribute, value ) == -1 )
02185 throw OpenGLException(
02186 "OpenGLContext::SetGLAttribute of attribute corresponding to "
02187 + GLAttributeToString( attribute ) + " to value "
02188 + Ceylan::toString( value ) + " failed: "
02189 + Utils::getBackendLastError() ) ;
02190
02191 #else // OSDL_USES_SDL
02192
02193 throw OpenGLException( "OpenGLContext::SetGLAttribute failed: "
02194 "no SDL support available" ) ;
02195
02196 #endif // OSDL_USES_SDL
02197
02198 #else // OSDL_USES_OPENGL
02199
02200 throw OpenGLException( "OpenGLContext::SetGLAttribute failed: "
02201 "no OpenGL support available" ) ;
02202
02203 #endif // OSDL_USES_OPENGL
02204
02205 }
02206
02207
02208
02209 bool OpenGLContext::TrySettingGLAttribute( GLAttribute attribute, int value )
02210 {
02211
02212 #if OSDL_USES_OPENGL
02213
02214 #if OSDL_USES_SDL
02215
02216
02217
02218
02219
02220
02221
02222 if ( SDL_GL_SetAttribute( attribute, value ) == -1 )
02223 {
02224
02225 LogPlug::warning( "OpenGLContext::TrySettingGLAttribute "
02226 "of attribute corresponding to "
02227 + GLAttributeToString( attribute ) + " to value "
02228 + Ceylan::toString( value ) + " failed: "
02229 + Utils::getBackendLastError() ) ;
02230
02231 return false ;
02232
02233 }
02234 else
02235 {
02236
02237 int newValue ;
02238
02239 try
02240 {
02241
02242 newValue = GetGLAttribute( attribute ) ;
02243
02244 if ( newValue != value )
02245 {
02246
02247 LogPlug::warning( "OpenGLContext::TrySettingGLAttribute "
02248 "of attribute corresponding to "
02249 + GLAttributeToString( attribute ) + " to value "
02250 + Ceylan::toString( value ) + " did not fail, "
02251 "but re-reading the set attribute results in the value "
02252 + Ceylan::toString( newValue ) + " instead." ) ;
02253
02254 return false ;
02255
02256 }
02257
02258 }
02259 catch( const OpenGLException & e )
02260 {
02261
02262 LogPlug::warning( "OpenGLContext::TrySettingGLAttribute "
02263 "of attribute corresponding to "
02264 + GLAttributeToString( attribute ) + " to value "
02265 + Ceylan::toString( value )
02266 + " failed: when trying to read back that value, got: "
02267 + e.toString() ) ;
02268
02269 return false ;
02270
02271 }
02272
02273
02274 return true ;
02275
02276 }
02277
02278
02279 #else // OSDL_USES_SDL
02280
02281 throw OpenGLException( "OpenGLContext::TrySettingGLAttribute failed: "
02282 "no SDL support available" ) ;
02283
02284 #endif // OSDL_USES_SDL
02285
02286 #else // OSDL_USES_OPENGL
02287
02288 throw OpenGLException( "OpenGLContext::TrySettingGLAttribute failed: "
02289 "no OpenGL support available" ) ;
02290
02291 #endif // OSDL_USES_OPENGL
02292
02293 }
02294
02295
02296
02297 std::string OpenGLContext::GLAttributeToString( GLAttribute attribute )
02298 {
02299
02300 #if OSDL_USES_OPENGL
02301
02302 #if OSDL_USES_SDL
02303
02304 string res ;
02305
02306
02307
02308
02309
02310
02311 switch( attribute )
02312 {
02313
02314 case SDL_GL_RED_SIZE:
02315 res = "minimum depth, in bits, of OpenGL red component" ;
02316 break ;
02317
02318 case SDL_GL_GREEN_SIZE:
02319 res = "minimum depth, in bits, of OpenGL green component" ;
02320 break ;
02321
02322 case SDL_GL_BLUE_SIZE:
02323 res = "minimum depth, in bits, of OpenGL blue component" ;
02324 break ;
02325
02326 case SDL_GL_ALPHA_SIZE:
02327 res = "minimum depth, in bits, of alpha component" ;
02328 break ;
02329
02330 case SDL_GL_BUFFER_SIZE:
02331 res = "minimum depth, in bits, of the OpenGL framebuffer" ;
02332 break ;
02333
02334 case SDL_GL_DOUBLEBUFFER:
02335 res = "OpenGL double-buffering" ;
02336 break ;
02337
02338 case SDL_GL_DEPTH_SIZE:
02339 res = "minimum depth, in bits, of the OpenGL depth buffer" ;
02340 break ;
02341
02342 case SDL_GL_STENCIL_SIZE:
02343 res = "minimum depth, in bits, of the OpenGL stencil buffer" ;
02344 break ;
02345
02346 case SDL_GL_ACCUM_RED_SIZE:
02347 res = "minimum depth, in bits, of the red component "
02348 "in OpenGL accumulation buffer" ;
02349 break ;
02350
02351 case SDL_GL_ACCUM_GREEN_SIZE:
02352 res = "minimum depth, in bits, of the green component "
02353 "in OpenGL accumulation buffer" ;
02354 break ;
02355
02356 case SDL_GL_ACCUM_BLUE_SIZE:
02357 res = "size of OpenGL accumulation blue component" ;
02358 break ;
02359
02360 case SDL_GL_ACCUM_ALPHA_SIZE:
02361 res = "minimum depth, in bits, of the alpha component "
02362 "in OpenGL accumulation buffer" ;
02363 break ;
02364
02365 case SDL_GL_STEREO:
02366 res = "OpenGL stereo (left and right) rendering" ;
02367 break ;
02368
02369 case SDL_GL_MULTISAMPLEBUFFERS:
02370 res = "OpenGL full screen anti-aliasing (FSAA)" ;
02371 break ;
02372
02373 case SDL_GL_MULTISAMPLESAMPLES:
02374 res = "number of samples per pixel "
02375 "in the OpenGL multisample buffer" ;
02376 break ;
02377
02378 case SDL_GL_ACCELERATED_VISUAL:
02379 res = "OpenGL support for accelerated visuals" ;
02380 break ;
02381
02382 case SDL_GL_SWAP_CONTROL:
02383 res = "OpenGL vertical synchronization (v-sync)" ;
02384 break ;
02385
02386 default:
02387 res = "unknown OpenGL attribute (abnormal)" ;
02388 break ;
02389
02390 }
02391
02392 return res ;
02393
02394 #else // OSDL_USES_SDL
02395
02396 throw OpenGLException( "OpenGLContext::GLAttributeToString failed: "
02397 "no SDL support available" ) ;
02398
02399 #endif // OSDL_USES_SDL
02400
02401 #else // OSDL_USES_OPENGL
02402
02403 throw OpenGLException( "OpenGLContext::GLAttributeToString failed: "
02404 "no OpenGL support available" ) ;
02405
02406 #endif // OSDL_USES_OPENGL
02407
02408 }
02409