"L. Spiro Engine"
|
00001 00016 #ifndef __LSG_OPENGL_H__ 00017 #define __LSG_OPENGL_H__ 00018 00019 #ifdef LSG_OGL 00020 00021 #include "../Fnd/LSGFndBase.h" 00022 #include "../Fnd/LSGFndConstants.h" 00023 #include "CriticalSection/LSHCriticalSection.h" 00024 #include "Windows/LSSTDWindows.h" 00025 00026 #ifndef APIENTRY 00027 #define APIENTRY 00028 #endif // #ifndef APIENTRY 00029 00030 #ifdef LSE_OSX 00031 #import <OpenGL/gl3.h> 00032 #else 00033 #include <gl/gl.h> 00034 #include "glext.h" 00035 #endif // #ifdef LSE_OSX 00036 00037 00038 #ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT 00039 #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE 00040 #endif // #ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT 00041 #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 00042 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF 00043 #endif // #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 00044 #ifndef GL_GENERATE_MIPMAP_HINT 00045 #define GL_GENERATE_MIPMAP_HINT 0x8192 00046 #endif // #ifndef GL_GENERATE_MIPMAP_HINT 00047 00048 #ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT 00049 #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 00050 #endif // #ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT 00051 #ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 00052 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 00053 #endif // #ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 00054 #ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 00055 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 00056 #endif // #ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 00057 #ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 00058 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 00059 #endif // #ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 00060 00061 00062 #include <cassert> 00063 00064 namespace lsg { 00065 00066 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00067 // CONSTANTS 00068 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00072 enum LSG_BUFFERS { 00073 LSG_B_COLOR_BUFFER = GL_COLOR_BUFFER_BIT, 00074 LSG_B_STENCIL_BUFFER = GL_STENCIL_BUFFER_BIT, 00075 LSG_B_DEPTH_BUFFER = GL_DEPTH_BUFFER_BIT, 00076 LSG_B_ALL = LSG_B_COLOR_BUFFER | LSG_B_STENCIL_BUFFER | LSG_B_DEPTH_BUFFER, 00077 }; 00078 00079 00080 00081 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00082 // TYPES 00083 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00087 typedef class COpenGlShaderManager CShaderManager; 00088 class CShader; 00089 00090 00091 00092 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00093 // INTERFACE 00094 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00101 class COpenGl { 00102 public : 00103 // == Types. 00107 typedef struct LSG_OPENGL_METRICS { 00111 LSUINT32 ui32MaxRenderTargetSize; 00112 00116 LSUINT32 ui32MaxTexture; 00117 00121 LSUINT32 ui32MaxAniso; 00122 } * LPLSG_OPENGL_METRICS, * const LPCLSG_OPENGL_METRICS; 00123 00124 00125 // == Functions. 00131 static LSBOOL LSE_CALL InitOpenGl( LSVOID * _pvParm ); 00132 00136 static LSVOID LSE_CALL PostInitOpenGl(); 00137 00141 static LSVOID LSE_CALL DestroyOpenGl(); 00142 00146 static LSVOID LSE_CALL LoseDevice(); 00147 00153 static LSBOOL LSE_CALL ResetDevice(); 00154 00158 static LSVOID LSE_CALL SetInitialValues(); 00159 00163 static LSVOID LSE_CALL MakeCurrent(); 00164 00168 static LSVOID LSE_CALL FreeTmpResources(); 00169 00183 static CMatrix4x4 LSE_CALL OffsetOrtho( LSREAL _fLeft, LSREAL _fRight, LSREAL _fBottom, LSREAL _fTop, LSREAL _fNear, LSREAL _fFar ); 00184 00185 00186 00187 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00188 // INTERFACE 00189 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00193 static LSE_INLINE LSVOID LSE_FCALL AssertError(); 00194 00201 static LSE_INLINE LSBOOL LSE_FCALL DoNothing(); 00202 00211 static LSBOOL LSE_CALL WarnErrorEx( const LSCHAR * _pcHeader, const LSCHAR * _pcFile, LSUINT32 _ui32Line ); 00212 #ifdef _DEBUG 00213 #define glWarnError( _pcHeader ) COpenGl::WarnErrorEx( _pcHeader, __FILE__, __LINE__ ) 00214 #else 00215 #define glWarnError( _pcHeader ) COpenGl::DoNothing() 00216 #endif // #ifdef _DEBUG 00217 #define glWarnErrorAlways( _pcHeader ) COpenGl::WarnErrorEx( _pcHeader, __FILE__, __LINE__ ) 00218 00222 static LSE_INLINE LSVOID LSE_FCALL Present(); 00223 00229 static LSE_INLINE LSVOID LSE_FCALL Clear( LSUINT32 _ui32Mask ); 00230 00234 static LSE_INLINE LSVOID LSE_FCALL ClearAll(); 00235 00244 static LSVOID LSE_CALL SetClearColor( LSREAL _fR, LSREAL _fG, LSREAL _fB, LSREAL _fA ); 00245 00251 static LSE_INLINE LSVOID LSE_FCALL SetClearDepth( LSREAL _fValue ); 00252 00261 static LSE_INLINE LSVOID LSE_FCALL SetViewport( LSINT32 _i32X, LSINT32 _i32Y, LSINT32 _i32Width, LSINT32 _i32Height ); 00262 00268 static LSE_INLINE LSVOID LSE_FCALL SetDepthTest( LSBOOL _bVal ); 00269 00275 static LSE_INLINE LSVOID LSE_FCALL SetDepthFunc( LSG_DEPTH_TEST _dtFunc ); 00276 00282 static LSE_INLINE LSVOID LSE_FCALL SetDepthWrite( LSBOOL _bVal ); 00283 00289 static LSE_INLINE LSVOID LSE_FCALL SetCulling( LSBOOL _bVal ); 00290 00296 static LSE_INLINE LSVOID LSE_FCALL SetCullMode( LSG_CULL_MODES _cmMode ); 00297 00303 static LSE_INLINE LSG_CULL_MODES LSE_CALL GetCullMode(); 00304 00310 static LSE_INLINE LSVOID LSE_FCALL SetBlendEnabled( LSBOOL _bVal ); 00311 00318 static LSE_INLINE LSVOID LSE_FCALL SetBlendFunc( LSG_BLEND_MODES _bmSrc, LSG_BLEND_MODES _bmDst ); 00319 00325 static LSE_INLINE LSVOID LSE_FCALL SetFillMode( LSG_FILL_MODES _fmMode ); 00326 00332 static LSE_INLINE LSBOOL LSE_FCALL BeginRender(); 00333 00337 static LSE_INLINE LSVOID LSE_FCALL EndRender(); 00338 00344 static LSE_INLINE CShaderManager * LSE_FCALL 00345 GetShaderManager(); 00346 00353 static LSVOID LSE_FCALL SetShader( CShader * _psShader ); 00354 00360 static CShader * LSE_FCALL GetShader(); 00361 00365 static LSVOID LSE_CALL PreRender(); 00366 00372 static LSE_INLINE LSVOID LSE_CALL ActivateTexture( LSUINT32 _ui32Unit ); 00373 00374 00375 00376 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00377 // METRICS 00378 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00384 static LSE_INLINE LSBOOL LSE_CALL NonPo2(); 00385 00391 static LSE_INLINE LSBOOL LSE_CALL FbosSupported(); 00392 00398 static LSE_INLINE LSUINT32 LSE_CALL MaxRenderTargetSize(); 00399 00405 static LSE_INLINE LSUINT32 LSE_CALL MaxTextureSize(); 00406 00407 00408 // == Members. 00412 static PFNGLACTIVETEXTUREPROC glActiveTexture; 00413 00417 static PFNGLDELETESHADERPROC glDeleteShader; 00418 00422 static PFNGLCREATEPROGRAMPROC glCreateProgram; 00423 00427 static PFNGLATTACHSHADERPROC glAttachShader; 00428 00432 static PFNGLLINKPROGRAMPROC glLinkProgram; 00433 00437 static PFNGLGETPROGRAMIVPROC glGetProgramiv; 00438 00442 static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; 00443 00447 static PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; 00448 00452 static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; 00453 00457 static PFNGLUNIFORM1FPROC glUniform1f; 00458 00462 static PFNGLUNIFORM1FVPROC glUniform1fv; 00463 00467 static PFNGLUNIFORM1IPROC glUniform1i; 00468 00472 static PFNGLUNIFORM1IVPROC glUniform1iv; 00473 00477 static PFNGLUNIFORM2FPROC glUniform2f; 00478 00482 static PFNGLUNIFORM2FVPROC glUniform2fv; 00483 00487 static PFNGLUNIFORM2IPROC glUniform2i; 00488 00492 static PFNGLUNIFORM2IVPROC glUniform2iv; 00493 00497 static PFNGLUNIFORM3FPROC glUniform3f; 00498 00502 static PFNGLUNIFORM3FVPROC glUniform3fv; 00503 00507 static PFNGLUNIFORM3IPROC glUniform3i; 00508 00512 static PFNGLUNIFORM3IVPROC glUniform3iv; 00513 00517 static PFNGLUNIFORM4FPROC glUniform4f; 00518 00522 static PFNGLUNIFORM4FVPROC glUniform4fv; 00523 00527 static PFNGLUNIFORM4IPROC glUniform4i; 00528 00532 static PFNGLUNIFORM4IVPROC glUniform4iv; 00533 00537 static PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; 00538 00542 static PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; 00543 00547 static PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; 00548 00552 static PFNGLUSEPROGRAMPROC glUseProgram; 00553 00557 static PFNGLVALIDATEPROGRAMPROC glValidateProgram; 00558 00562 static PFNGLCREATESHADERPROC glCreateShader; 00563 00567 static PFNGLSHADERSOURCEPROC glShaderSource; 00568 00572 static PFNGLCOMPILESHADERPROC glCompileShader; 00573 00577 static PFNGLGETSHADERIVPROC glGetShaderiv; 00578 00582 static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; 00583 00587 static PFNGLGENBUFFERSPROC glGenBuffers; 00588 00592 static PFNGLBINDBUFFERPROC glBindBuffer; 00593 00597 static PFNGLBUFFERDATAPROC glBufferData; 00598 00602 static PFNGLDELETEBUFFERSPROC glDeleteBuffers; 00603 00607 static PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; 00608 00612 static PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; 00613 00617 static PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; 00618 00622 static PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; 00623 00627 static PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; 00628 00632 static PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; 00633 00637 static PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; 00638 00642 static PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; 00643 00647 static PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; 00648 00652 static PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; 00653 00657 static PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; 00658 00662 static PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; 00663 00667 static PFNGLDRAWBUFFERSPROC glDrawBuffers; 00668 00672 static PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; 00673 00677 static PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; 00678 00682 static PFNGLGENERATEMIPMAPPROC glGenerateMipmap; 00683 00687 static CCriticalSection m_csCrit; 00688 00689 protected : 00690 // == Types. 00694 typedef LSVOID * (APIENTRY * wglGetProcAddressLSG)( const char * _pcName ); 00695 00696 00697 // == Members. 00698 #ifdef LSE_WINDOWS 00699 00702 static HDC m_hDc; 00703 00707 static HGLRC m_hgrcContext; 00708 #endif // #ifdef LSE_WINDOWS 00709 00713 static CShaderManager * m_psmShaderMan; 00714 00718 static wglGetProcAddressLSG GetProcAddressLSG; 00719 00723 static LSG_CULL_MODES m_cmCullMode; 00724 00728 static LSUINT32 m_ui32ClearColor; 00729 00733 static GLclampf m_fDepthClear; 00734 00738 static LSBOOL m_bDepthTest; 00739 00743 static LSBOOL m_bCulling; 00744 00748 static LSUINT32 m_ui32LastActiveTexture; 00749 00753 static LSBOOL m_bFbos; 00754 00755 00756 // == Functions. 00763 static LSBOOL LSE_CALL HasExtension( const LSCHAR * _pcExt ); 00764 }; 00765 00766 00767 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00768 // DEFINITIONS 00769 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00773 LSE_INLINE LSVOID LSE_FCALL COpenGl::AssertError() { 00774 #ifdef _DEBUG 00775 assert( !glWarnError( "COpenGl::AssertError()" ) ); 00776 #endif // #ifdef _DEBUG 00777 } 00778 00783 LSE_INLINE LSBOOL LSE_FCALL COpenGl::DoNothing() { 00784 return false; 00785 } 00786 00790 LSE_INLINE LSVOID LSE_FCALL COpenGl::Present() { 00791 #ifdef LSE_WINDOWS 00792 ::SwapBuffers( m_hDc ); 00793 #endif // #ifdef LSE_WINDOWS 00794 } 00795 00801 LSE_INLINE LSVOID LSE_FCALL COpenGl::Clear( LSUINT32 _ui32Mask ) { 00802 ::glClear( _ui32Mask ); 00803 } 00804 00808 LSE_INLINE LSVOID LSE_FCALL COpenGl::ClearAll() { 00809 ::glClear( LSG_B_ALL ); 00810 } 00811 00817 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetClearDepth( LSREAL _fValue ) { 00818 if ( m_fDepthClear != static_cast<GLclampf>(_fValue) ) { 00819 m_fDepthClear = static_cast<GLclampf>(_fValue); 00820 00821 ::glClearDepth( m_fDepthClear ); 00822 } 00823 } 00824 00833 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetViewport( LSINT32 _i32X, LSINT32 _i32Y, LSINT32 _i32Width, LSINT32 _i32Height ) { 00834 ::glViewport( _i32X, _i32Y, _i32Width, _i32Height ); 00835 } 00836 00842 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetDepthTest( LSBOOL _bVal ) { 00843 _bVal = _bVal != false; 00844 if ( m_bDepthTest != _bVal ) { 00845 m_bDepthTest = _bVal; 00846 if ( _bVal ) { ::glEnable( GL_DEPTH_TEST ); } 00847 else { ::glDisable( GL_DEPTH_TEST ); } 00848 } 00849 } 00850 00856 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetDepthFunc( LSG_DEPTH_TEST _dtFunc ) { 00857 if ( CFndBase::m_dtDepthTestFunc != _dtFunc ) { 00858 CFndBase::m_dtDepthTestFunc = _dtFunc; 00859 static const GLenum eFuncs[] = { 00860 GL_NEVER, // LSG_DT_NEVER 00861 GL_ALWAYS, // LSG_DT_ALWAYS 00862 GL_LESS, // LSG_DT_LESS 00863 GL_EQUAL, // LSG_DT_EQUAL 00864 GL_NOTEQUAL, // LSG_DT_NOTEQUAL 00865 GL_LEQUAL, // LSG_DT_LESSEQUAL 00866 GL_GREATER, // LSG_DT_GREATER 00867 GL_GEQUAL, // LSG_DT_GREATEREQUAL 00868 }; 00869 ::glDepthFunc( eFuncs[_dtFunc] ); 00870 } 00871 } 00872 00878 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetDepthWrite( LSBOOL _bVal ) { 00879 _bVal = _bVal != false; 00880 if ( CFndBase::m_bDepthWrite != _bVal ) { 00881 CFndBase::m_bDepthWrite = _bVal; 00882 ::glDepthMask( _bVal ? GL_TRUE : GL_FALSE ); 00883 } 00884 } 00885 00891 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetCulling( LSBOOL _bVal ) { 00892 _bVal = _bVal != false; 00893 if ( m_bCulling != _bVal ) { 00894 m_bCulling = _bVal; 00895 if ( _bVal ) { ::glEnable( GL_CULL_FACE ); } 00896 else { ::glDisable( GL_CULL_FACE ); } 00897 } 00898 } 00899 00905 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetCullMode( LSG_CULL_MODES _cmMode ) { 00906 assert( _cmMode == LSG_CM_CW || _cmMode == LSG_CM_CCW ); 00907 if ( m_cmCullMode != _cmMode ) { 00908 m_cmCullMode = _cmMode; 00909 static const GLenum eModes[] = { 00910 GL_CW, 00911 GL_CCW 00912 }; 00913 ::glFrontFace( eModes[_cmMode] ); 00914 } 00915 } 00916 00922 LSE_INLINE LSG_CULL_MODES LSE_CALL COpenGl::GetCullMode() { 00923 return m_cmCullMode; 00924 } 00925 00931 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetBlendEnabled( LSBOOL _bVal ) { 00932 if ( CFndBase::m_bBlending != (_bVal != false) ) { 00933 CFndBase::m_bBlending = (_bVal != false); 00934 if ( CFndBase::m_bBlending ) { ::glEnable( GL_BLEND ); } 00935 else { ::glDisable( GL_BLEND ); } 00936 } 00937 } 00938 00945 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetBlendFunc( LSG_BLEND_MODES _bmSrc, LSG_BLEND_MODES _bmDst ) { 00946 static const GLenum eModes[] = { 00947 GL_ZERO, // LSG_BM_ZERO 00948 GL_ONE, // LSG_BM_ONE 00949 GL_SRC_COLOR, // LSG_BM_SRC_COLOR 00950 GL_ONE_MINUS_SRC_COLOR, // LSG_BM_INV_SRC_COLOR 00951 GL_DST_COLOR, // LSG_BM_DST_COLOR 00952 GL_ONE_MINUS_DST_COLOR, // LSG_BM_INV_DST_COLOR 00953 GL_SRC_ALPHA, // LSG_BM_SRC_ALPHA 00954 GL_ONE_MINUS_SRC_ALPHA, // LSG_BM_INV_SRC_ALPHA 00955 GL_DST_ALPHA, // LSG_BM_DST_ALPHA 00956 GL_ONE_MINUS_DST_ALPHA, // LSG_BM_INV_DEST_ALPHA 00957 GL_SRC_ALPHA_SATURATE, // LSG_BM_SRC_ALPHA_SAT 00958 }; 00959 00960 if ( CFndBase::m_bmSrcBlend != _bmSrc || CFndBase::m_bmDstBlend != _bmDst ) { 00961 CFndBase::m_bmSrcBlend = _bmSrc; 00962 CFndBase::m_bmDstBlend = _bmDst; 00963 ::glBlendFunc( eModes[_bmSrc], eModes[_bmDst] ); 00964 } 00965 } 00966 00972 LSE_INLINE LSVOID LSE_FCALL COpenGl::SetFillMode( LSG_FILL_MODES _fmMode ) { 00973 static const GLenum eModes[] = { 00974 GL_FILL, 00975 GL_LINE 00976 }; 00977 ::glPolygonMode( GL_FRONT_AND_BACK, eModes[_fmMode] ); 00978 } 00979 00985 LSE_INLINE LSBOOL LSE_FCALL COpenGl::BeginRender() { 00986 return true; 00987 } 00988 00992 LSE_INLINE LSVOID LSE_FCALL COpenGl::EndRender() { 00993 }; 00994 01000 LSE_INLINE CShaderManager * LSE_FCALL COpenGl::GetShaderManager() { 01001 return m_psmShaderMan; 01002 } 01003 01009 LSE_INLINE LSVOID LSE_CALL COpenGl::ActivateTexture( LSUINT32 _ui32Unit ) { 01010 if ( m_ui32LastActiveTexture == _ui32Unit ) { return; } 01011 m_ui32LastActiveTexture = _ui32Unit; 01012 if ( COpenGl::glActiveTexture ) { 01013 COpenGl::glActiveTexture( GL_TEXTURE0 + m_ui32LastActiveTexture ); 01014 } 01015 } 01016 01022 LSE_INLINE LSBOOL LSE_CALL COpenGl::NonPo2() { 01023 return CFndBase::m_mMetrics.bNonPo2; 01024 } 01025 01031 LSE_INLINE LSBOOL LSE_CALL COpenGl::FbosSupported() { 01032 return m_bFbos; 01033 } 01034 01040 LSE_INLINE LSUINT32 LSE_CALL COpenGl::MaxRenderTargetSize() { 01041 return CFndBase::m_mMetrics.ui32MaxRenderTargetSize; 01042 } 01043 01049 LSE_INLINE LSUINT32 LSE_CALL COpenGl::MaxTextureSize() { 01050 return CFndBase::m_mMetrics.ui32MaxTextureHeight; 01051 } 01052 01053 } // namespace lsg 01054 01055 #endif // #ifdef LSG_OGL 01056 01057 #endif // __LSG_OPENGL_H__