Factory class for GLSL programs.
Inheritance: HighLevelGpuProgramFactory
Esempio n. 1
0
		public override void Shutdown()
		{
			// call base Shutdown implementation
			base.Shutdown();

            // Deleting the GLSL program factory
		    if (_GLSLProgramFactory != null)
		    {
		        // Remove from manager safely
		        if ( HighLevelGpuProgramManager.Instance != null )
                    HighLevelGpuProgramManager.Instance.RemoveFactory(_GLSLProgramFactory);
		        _GLSLProgramFactory.Dispose();
		        _GLSLProgramFactory = null;
		    }

            if ( gpuProgramMgr != null )
			{
				gpuProgramMgr.Dispose();
			}

			if ( _hardwareBufferManager != null )
			{
				_hardwareBufferManager.Dispose();
			}

			if ( rttManager != null )
			{
				rttManager.Dispose();
			}

            // Delete extra threads contexts
            foreach (var curContext in _backgroundContextList)
            {
                curContext.ReleaseContext();
                curContext.Dispose();
            }
            _backgroundContextList.Clear();

			_glSupport.Stop();
			_stopRendering = true;

			if ( textureManager != null )
			{
				textureManager.Dispose();
			}

			// There will be a new initial window and so forth, thus any call to test
			//  some params will access an invalid pointer, so it is best to reset
			//  the whole state.
            _glInitialised = false;
		}
        public override void InitializeFromRenderSystemCapabilities(
            RenderSystemCapabilities caps, RenderTarget primary )
        {
            if ( caps.RendersystemName != Name )
            {
                throw new AxiomException(
                    "Trying to initialize GLRenderSystem from RenderSystemCapabilities that do not support OpenGL" );
            }

            // set texture the number of texture units
            _fixedFunctionTextureUnits = caps.TextureUnitCount;

            //In GL there can be less fixed function texture units than general
            //texture units. Get the minimum of the two.
            if ( caps.HasCapability( Graphics.Capabilities.FragmentPrograms ) )
            {
                int maxTexCoords;
                Gl.glGetIntegerv( Gl.GL_MAX_TEXTURE_COORDS_ARB, out maxTexCoords );
                if ( _fixedFunctionTextureUnits > maxTexCoords )
                {
                    _fixedFunctionTextureUnits = maxTexCoords;
                }
            }

            /* Axiom: assume that OpenTK/Tao does this already
             * otherwise we will need to use delegates for these gl calls ..
             * 
            if (caps.HasCapability(Graphics.Capabilities.GL15NoVbo))
            {
                // Assign ARB functions same to GL 1.5 version since
                // interface identical

                Gl.glBindBufferARB = Gl.glBindBuffer;
                Gl.glBufferDataARB = Gl.glBufferData;
                Gl.glBufferSubDataARB = Gl.glBufferSubData;
                Gl.glDeleteBuffersARB = Gl.glDeleteBuffers;
                Gl.glGenBuffersARB = Gl.glGenBuffers;
                Gl.glGetBufferParameterivARB = Gl.glGetBufferParameteriv;
                Gl.glGetBufferPointervARB = Gl.glGetBufferPointerv;
                Gl.glGetBufferSubDataARB = Gl.glGetBufferSubData;
                Gl.glIsBufferARB = Gl.glIsBuffer;
                Gl.glMapBufferARB = Gl.glMapBuffer;
                Gl.glUnmapBufferARB = Gl.glUnmapBuffer;
            }
             */

            if ( caps.HasCapability( Graphics.Capabilities.VertexBuffer ) )
            {

                _hardwareBufferManager = new GLHardwareBufferManager();
            }
            else
            {
                _hardwareBufferManager = new GLDefaultHardwareBufferManager();
            }

            // XXX Need to check for nv2 support and make a program manager for it
            // XXX Probably nv1 as well for older cards
            // GPU Program Manager setup
            gpuProgramMgr = new GLGpuProgramManager();

            if ( caps.HasCapability( Graphics.Capabilities.VertexPrograms ) )
            {
                if ( caps.IsShaderProfileSupported( "arbvp1" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "arbvp1", new ARBGpuProgramFactory() );
                }

                if ( caps.IsShaderProfileSupported( "vp30" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "vp30", new ARBGpuProgramFactory() );
                }

                if ( caps.IsShaderProfileSupported( "vp40" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "vp40", new ARBGpuProgramFactory() );
                }

                if ( caps.IsShaderProfileSupported( "gp4vp" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "gp4vp", new ARBGpuProgramFactory() );
                }

                if ( caps.IsShaderProfileSupported( "gpu_vp" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "gpu_vp", new ARBGpuProgramFactory() );
                }
            }

            if ( caps.HasCapability( Graphics.Capabilities.GeometryPrograms ) )
            {
                //TODO : Should these be createGLArbGpuProgram or createGLGpuNVparseProgram?
                if ( caps.IsShaderProfileSupported( "nvgp4" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "nvgp4", new ARBGpuProgramFactory() );
                }
                if ( caps.IsShaderProfileSupported( "gp4gp" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "gp4gp", new ARBGpuProgramFactory() );
                }
                if ( caps.IsShaderProfileSupported( "gpu_gp" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "gpu_gp", new ARBGpuProgramFactory() );
                }
            }

            if ( caps.HasCapability( Graphics.Capabilities.FragmentPrograms ) )
            {

                if ( caps.IsShaderProfileSupported( "fp20" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "fp20", new Nvidia.NvparseProgramFactory() );
                }

                if ( caps.IsShaderProfileSupported( "ps_1_4" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "ps_1_4", new ATI.ATIFragmentShaderFactory() );
                }

                if ( caps.IsShaderProfileSupported( "ps_1_3" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "ps_1_3", new ATI.ATIFragmentShaderFactory() );
                }

                if ( caps.IsShaderProfileSupported( "ps_1_2" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "ps_1_2", new ATI.ATIFragmentShaderFactory() );
                }

                if ( caps.IsShaderProfileSupported( "ps_1_1" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "ps_1_1", new ATI.ATIFragmentShaderFactory() );
                }

                if ( caps.IsShaderProfileSupported( "arbfp1" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "arbfp1", new ARBGpuProgramFactory() );
                }

                if ( caps.IsShaderProfileSupported( "fp40" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "fp40", new ARBGpuProgramFactory() );
                }

                if ( caps.IsShaderProfileSupported( "fp30" ) )
                {
                    gpuProgramMgr.RegisterProgramFactory( "fp30", new ARBGpuProgramFactory() );
                }

            }

            if ( caps.IsShaderProfileSupported( "glsl" ) )
            {
                // NFZ - check for GLSL vertex and fragment shader support successful
                _GLSLProgramFactory = new GLSL.GLSLProgramFactory();
                HighLevelGpuProgramManager.Instance.AddFactory( _GLSLProgramFactory );
                LogManager.Instance.Write( "GLSL support detected" );
            }

            /* Axiom: assume that OpenTK/Tao does this already
             * otherwise we will need to use delegates for these gl calls ..
             * 
            if ( caps.HasCapability( Graphics.Capabilities.HardwareOcculusion ) )
            {
                if ( caps.HasCapability( Graphics.Capabilities.GL15NoHardwareOcclusion ) )
                {
                    // Assign ARB functions same to GL 1.5 version since
                    // interface identical
                    Gl.glBeginQueryARB = Gl.glBeginQuery;
                    Gl.glDeleteQueriesARB = Gl.glDeleteQueries;
                    Gl.glEndQueryARB = Gl.glEndQuery;
                    Gl.glGenQueriesARB = Gl.glGenQueries;
                    Gl.glGetQueryObjectivARB = Gl.glGetQueryObjectiv;
                    Gl.glGetQueryObjectuivARB = Gl.glGetQueryObjectuiv;
                    Gl.glGetQueryivARB = Gl.glGetQueryiv;
                    Gl.glIsQueryARB = Gl.glIsQuery;
                }
            }
             */

            // Do this after extension function pointers are initialised as the extension
            // is used to probe further capabilities.
            ConfigOption cfi;
            var rttMode = 0;
            if ( ConfigOptions.TryGetValue( "RTT Preferred Mode", out cfi ) )
            {
                if ( cfi.Value == "PBuffer" )
                {
                    rttMode = 1;
                }
                else if ( cfi.Value == "Copy" )
                {
                    rttMode = 2;
                }
            }


            // Check for framebuffer object extension
		    if(caps.HasCapability(Graphics.Capabilities.FrameBufferObjects) && rttMode < 1)
		    {
			    // Before GL version 2.0, we need to get one of the extensions
			    //if(caps.HasCapability(Graphics.Capabilities.FrameBufferObjectsARB))
				//    GLEW_GET_FUN(__glewDrawBuffers) = Gl.glDrawBuffersARB;
			    //else if(caps.HasCapability(Graphics.Capabilities.FrameBufferObjectsATI))
				//    GLEW_GET_FUN(__glewDrawBuffers) = Gl.glDrawBuffersATI;

			    if(caps.HasCapability(Graphics.Capabilities.HardwareRenderToTexture))
			    {
				    // Create FBO manager
				    LogManager.Instance.Write("GL: Using GL_EXT_framebuffer_object for rendering to textures (best)");
				    rttManager = new GLFBORTTManager(_glSupport, false);
				    caps.SetCapability(Graphics.Capabilities.RTTSerperateDepthBuffer);

				    //TODO: Check if we're using OpenGL 3.0 and add RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL flag
			    }
		    } 
            else
		    {
		        // Check GLSupport for PBuffer support
		        if ( caps.HasCapability( Graphics.Capabilities.PBuffer ) && rttMode < 2 )
		        {
		            if ( caps.HasCapability( Graphics.Capabilities.HardwareRenderToTexture ) )
		            {
		                // Use PBuffers
		                rttManager = new GLPBRTTManager( _glSupport, primary );
		                LogManager.Instance.Write( "GL: Using PBuffers for rendering to textures" );

		                //TODO: Depth buffer sharing in pbuffer is left unsupported
		            }
		        }
		        else
		        {
		            // No pbuffer support either -- fallback to simplest copying from framebuffer
		            rttManager = new GLCopyingRTTManager(_glSupport);
		            LogManager.Instance.Write( "GL: Using framebuffer copy for rendering to textures (worst)" );
		            LogManager.Instance.Write(
		                "GL: Warning: RenderTexture size is restricted to size of framebuffer. If you are on Linux, consider using GLX instead of SDL." );

		            //Copy method uses the main depth buffer but no other depth buffer
		            caps.SetCapability( Graphics.Capabilities.RTTMainDepthbufferAttachable );
		            caps.SetCapability( Graphics.Capabilities.RTTDepthbufferResolutionLessEqual );
		        }

		        // Downgrade number of simultaneous targets
		        caps.MultiRenderTargetCount = 1;
		    }

            var defaultLog = LogManager.Instance.DefaultLog;
		    if (defaultLog != null)
		    {
			    caps.Log(defaultLog);
		    }

		    // Create the texture manager        
		    textureManager = new GLTextureManager(_glSupport); 

		    _glInitialised = true;
        }