X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Frenderstate.cpp;h=f714fc7eb2dd16712ae6486829ae7d81ea8965c0;hb=f80fb44b67d748419a38cb864eeb615ed83f6963;hp=9dc8e2de0a2136076eea4e0789036b1e2b437d78;hpb=18d60f90d7603cb420150739251cf98519c57406;p=xonotic%2Fnetradiant.git diff --git a/radiant/renderstate.cpp b/radiant/renderstate.cpp index 9dc8e2de..f714fc7e 100644 --- a/radiant/renderstate.cpp +++ b/radiant/renderstate.cpp @@ -54,7 +54,6 @@ #include "xywindow.h" - #define DEBUG_RENDER 0 inline void debug_string( const char* string ){ @@ -225,10 +224,10 @@ void create(){ // create shader { StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glsl"; + filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_vp.glsl"; createShader( m_program, filename.c_str(), GL_VERTEX_SHADER_ARB ); filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glsl"; + filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_fp.glsl"; createShader( m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB ); } @@ -334,10 +333,10 @@ void create(){ // create shader { StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glsl"; + filename << GlobalRadiant().getDataPath() << "gl/zfill_vp.glsl"; createShader( m_program, filename.c_str(), GL_VERTEX_SHADER_ARB ); filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glsl"; + filename << GlobalRadiant().getDataPath() << "gl/zfill_fp.glsl"; createShader( m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB ); } @@ -351,12 +350,14 @@ void destroy(){ glDeleteObjectARB( m_program ); m_program = 0; } + void enable(){ glUseProgramObjectARB( m_program ); GlobalOpenGL_debugAssertNoErrors(); debug_string( "enable depthfill" ); g_depthfillPass_enabled = true; } + void disable(){ glUseProgramObjectARB( 0 ); GlobalOpenGL_debugAssertNoErrors(); @@ -406,13 +407,13 @@ void create(){ glGenProgramsARB( 1, &m_vertex_program ); glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program ); StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glp"; + filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_vp.glp"; createProgram( filename.c_str(), GL_VERTEX_PROGRAM_ARB ); glGenProgramsARB( 1, &m_fragment_program ); glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program ); filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glp"; + filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_fp.glp"; createProgram( filename.c_str(), GL_FRAGMENT_PROGRAM_ARB ); } @@ -508,13 +509,13 @@ void create(){ glGenProgramsARB( 1, &m_vertex_program ); glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program ); StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glp"; + filename << GlobalRadiant().getDataPath() << "gl/zfill_vp.glp"; createProgram( filename.c_str(), GL_VERTEX_PROGRAM_ARB ); glGenProgramsARB( 1, &m_fragment_program ); glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program ); filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glp"; + filename << GlobalRadiant().getDataPath() << "gl/zfill_fp.glp"; createProgram( filename.c_str(), GL_FRAGMENT_PROGRAM_ARB ); } @@ -589,13 +590,13 @@ void createVertexProgram(){ glGenProgramsNV( 1, &m_vertex_program ); glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program ); StringOutputStream filename( 256 ); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.nv30"; + filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_vp.nv30"; createProgram( m_vertex_program, filename.c_str(), GL_VERTEX_PROGRAM_NV ); glGenProgramsNV( 1, &m_fragment_program ); glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program ); filename.clear(); - filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.nv30"; + filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_fp.nv30"; createProgram( m_fragment_program, filename.c_str(), GL_FRAGMENT_PROGRAM_NV ); } @@ -844,8 +845,6 @@ void OpenGLState_constructDefault( OpenGLState& state ){ } - - /// \brief A container of Renderable references. /// May contain the same Renderable multiple times, with different transforms. class OpenGLStateBucket @@ -872,6 +871,7 @@ Renderables m_renderables; public: OpenGLStateBucket(){ } + void addRenderable( const OpenGLRenderable& renderable, const Matrix4& modelview, const RendererLight* light = 0 ){ m_renderables.push_back( RenderTransform( renderable, modelview, light ) ); } @@ -913,6 +913,7 @@ using func = void(const RendererLight&); OpenGLStateBucketAdd( OpenGLStateBucket& bucket, const OpenGLRenderable& renderable, const Matrix4& modelview ) : m_bucket( bucket ), m_renderable( renderable ), m_modelview( modelview ){ } + void operator()( const RendererLight& light ){ m_bucket.addRenderable( m_renderable, m_modelview, &light ); } @@ -926,9 +927,11 @@ using func = void(RendererLight&); CountLights() : m_count( 0 ){ } + void operator()( const RendererLight& light ){ ++m_count; } + std::size_t count() const { return m_count; } @@ -944,9 +947,12 @@ ModuleObservers m_observers; public: OpenGLShader() : m_shader( 0 ), m_used( 0 ){ } + ~OpenGLShader(){ } + void construct( const char* name ); + void destroy(){ if ( m_shader ) { m_shader->DecRef(); @@ -959,6 +965,7 @@ void destroy(){ } m_passes.clear(); } + void addRenderable( const OpenGLRenderable& renderable, const Matrix4& modelview, const LightList* lights ){ for ( Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i ) { @@ -989,31 +996,37 @@ void addRenderable( const OpenGLRenderable& renderable, const Matrix4& modelview } } } + void incrementUsed(){ if ( ++m_used == 1 && m_shader != 0 ) { m_shader->SetInUse( true ); } } + void decrementUsed(){ if ( --m_used == 0 && m_shader != 0 ) { m_shader->SetInUse( false ); } } + bool realised() const { return m_shader != 0; } + void attach( ModuleObserver& observer ){ if ( realised() ) { observer.realise(); } m_observers.attach( observer ); } + void detach( ModuleObserver& observer ){ if ( realised() ) { observer.unrealise(); } m_observers.detach( observer ); } + void realise( const CopiedString& name ){ construct( name.c_str() ); @@ -1028,6 +1041,7 @@ void realise( const CopiedString& name ){ m_observers.realise(); } + void unrealise(){ m_observers.unrealise(); @@ -1038,18 +1052,22 @@ void unrealise(){ destroy(); } + qtexture_t& getTexture() const { ASSERT_NOTNULL( m_shader ); return *m_shader->getTexture(); } + unsigned int getFlags() const { ASSERT_NOTNULL( m_shader ); return m_shader->getFlags(); } + IShader& getShader() const { ASSERT_NOTNULL( m_shader ); return *m_shader; } + OpenGLState& appendDefaultPass(){ m_passes.push_back( new OpenGLStateBucket ); OpenGLState& state = m_passes.back()->state(); @@ -1081,6 +1099,7 @@ LinearLightList( LightCullable& cullable, RendererLights& lights, const Callback m_cullable( cullable ), m_allLights( lights ), m_evaluateChanged( evaluateChanged ){ m_lightsChanged = true; } + void evaluateLights() const { m_evaluateChanged(); if ( m_lightsChanged ) { @@ -1114,6 +1133,7 @@ void evaluateLights() const { } #endif } + void forEachLight( const RendererLightCallback& callback ) const { evaluateLights(); @@ -1122,6 +1142,7 @@ void forEachLight( const RendererLightCallback& callback ) const { callback( *( *i ) ); } } + void lightsChanged() const { m_lightsChanged = true; } @@ -1147,6 +1168,7 @@ public: explicit CreateOpenGLShader( OpenGLShaderCache* cache = 0 ) : m_cache( cache ){ } + OpenGLShader* construct( const CopiedString& name ){ OpenGLShader* shader = new OpenGLShader; if ( m_cache->realised() ) { @@ -1154,6 +1176,7 @@ OpenGLShader* construct( const CopiedString& name ){ } return shader; } + void destroy( OpenGLShader* shader ){ if ( m_cache->realised() ) { shader->unrealise(); @@ -1180,12 +1203,14 @@ OpenGLShaderCache() m_lightsChanged( true ), m_traverseRenderablesMutex( false ){ } + ~OpenGLShaderCache(){ for ( Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i ) { globalOutputStream() << "leaked shader: " << makeQuoted( ( *i ).key.c_str() ) << "\n"; } } + Shader* capture( const char* name ){ ASSERT_MESSAGE( name[0] == '$' || *name == '[' @@ -1197,6 +1222,7 @@ Shader* capture( const char* name ){ #endif return m_shaders.capture( name ).get(); } + void release( const char *name ){ #if DEBUG_SHADERS globalOutputStream() << "shaders release: " << makeQuoted( name ) << '\n'; @@ -1311,6 +1337,7 @@ void render( RenderStateFlags globalstate, const Matrix4& modelview, const Matri } debug_string( "end rendering" ); } + void realise(){ if ( --m_unrealised == 0 ) { if ( lightingSupported() && lightingEnabled() ) { @@ -1333,6 +1360,7 @@ void realise(){ } } } + void unrealise(){ if ( ++m_unrealised == 1 ) { for ( Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i ) @@ -1354,6 +1382,7 @@ void unrealise(){ } } } + bool realised(){ return m_unrealised == 0; } @@ -1362,12 +1391,15 @@ bool realised(){ bool lightingEnabled() const { return m_lightingEnabled; } + bool lightingSupported() const { return m_lightingSupported; } + bool useShaderLanguage() const { return m_useShaderLanguage; } + void setLighting( bool supported, bool enabled ){ bool refresh = ( m_lightingSupported && m_lightingEnabled ) != ( supported && enabled ); @@ -1383,6 +1415,7 @@ void setLighting( bool supported, bool enabled ){ realise(); } } + void extensionsInitialised(){ setLighting( GlobalOpenGL().GL_1_3() && GlobalOpenGL().ARB_vertex_program() @@ -1419,6 +1452,7 @@ void extensionsInitialised(){ } } } + void setLightingEnabled( bool enabled ){ setLighting( m_lightingSupported, enabled ); } @@ -1433,27 +1467,33 @@ LightLists m_lightLists; const LightList& attach( LightCullable& cullable ){ return ( *m_lightLists.insert( LightLists::value_type( &cullable, LinearLightList( cullable, m_lights, EvaluateChangedCaller( *this ) ) ) ).first ).second; } + void detach( LightCullable& cullable ){ m_lightLists.erase( &cullable ); } + void changed( LightCullable& cullable ){ LightLists::iterator i = m_lightLists.find( &cullable ); ASSERT_MESSAGE( i != m_lightLists.end(), "cullable not attached" ); ( *i ).second.lightsChanged(); } + void attach( RendererLight& light ){ ASSERT_MESSAGE( m_lights.find( &light ) == m_lights.end(), "light could not be attached" ); m_lights.insert( &light ); changed( light ); } + void detach( RendererLight& light ){ ASSERT_MESSAGE( m_lights.find( &light ) != m_lights.end(), "light could not be detached" ); m_lights.erase( &light ); changed( light ); } + void changed( RendererLight& light ){ m_lightsChanged = true; } + void evaluateChanged(){ if ( m_lightsChanged ) { m_lightsChanged = false; @@ -1463,6 +1503,7 @@ void evaluateChanged(){ } } } + typedef MemberCaller EvaluateChangedCaller; typedef std::set Renderables; @@ -1475,11 +1516,13 @@ void attachRenderable( const Renderable& renderable ){ ASSERT_MESSAGE( m_renderables.find( &renderable ) == m_renderables.end(), "renderable could not be attached" ); m_renderables.insert( &renderable ); } + void detachRenderable( const Renderable& renderable ){ ASSERT_MESSAGE( !m_traverseRenderablesMutex, "detaching renderable during traversal" ); ASSERT_MESSAGE( m_renderables.find( &renderable ) != m_renderables.end(), "renderable could not be detached" ); m_renderables.erase( &renderable ); } + void forEachRenderable( const RenderableCallback& callback ) const { ASSERT_MESSAGE( !m_traverseRenderablesMutex, "for-each during traversal" ); m_traverseRenderablesMutex = true; @@ -2018,9 +2061,11 @@ public: } typedef States::iterator iterator; + iterator begin(){ return m_states.begin(); } + iterator end(){ return m_states.end(); } @@ -2033,6 +2078,7 @@ void insert( const char* name, const OpenGLState& state ){ bool inserted = m_states.insert( States::value_type( name, state ) ).second; ASSERT_MESSAGE( inserted, "OpenGLStateMap::insert: " << name << " already exists" ); } + void erase( const char* name ){ std::size_t count = m_states.erase( name ); ASSERT_MESSAGE( count == 1, "OpenGLStateMap::erase: " << name << " does not exist" ); @@ -2341,16 +2387,22 @@ void OpenGLShader::construct( const char* name ){ { case IShader::eAlways: state.m_alphafunc = GL_ALWAYS; + break; case IShader::eEqual: state.m_alphafunc = GL_EQUAL; + break; case IShader::eLess: state.m_alphafunc = GL_LESS; + break; case IShader::eGreater: state.m_alphafunc = GL_GREATER; + break; case IShader::eLEqual: state.m_alphafunc = GL_LEQUAL; + break; case IShader::eGEqual: state.m_alphafunc = GL_GEQUAL; + break; } } reinterpret_cast( state.m_colour ) = m_shader->getTexture()->color; @@ -2385,14 +2437,17 @@ class OpenGLStateLibraryAPI OpenGLStateMap m_stateMap; public: typedef OpenGLStateLibrary Type; + STRING_CONSTANT( Name, "*" ); OpenGLStateLibraryAPI(){ g_openglStates = &m_stateMap; } + ~OpenGLStateLibraryAPI(){ g_openglStates = 0; } + OpenGLStateLibrary* getTable(){ return &m_stateMap; } @@ -2415,6 +2470,7 @@ class ShaderCacheAPI ShaderCache* m_shaderCache; public: typedef ShaderCache Type; + STRING_CONSTANT( Name, "*" ); ShaderCacheAPI(){ @@ -2422,9 +2478,11 @@ ShaderCacheAPI(){ m_shaderCache = GetShaderCache(); } + ~ShaderCacheAPI(){ ShaderCache_Destroy(); } + ShaderCache* getTable(){ return m_shaderCache; }