public override RenderSystemCapabilities CreateRenderSystemCapabilities() { var rsc = new RenderSystemCapabilities(); rsc.SetCategoryRelevant(CapabilitiesCategory.GL, true); rsc.DriverVersion = driverVersion; var deviceName = Gl.glGetString(Gl.GL_RENDERER); var vendorName = Gl.glGetString(Gl.GL_VENDOR); rsc.DeviceName = deviceName; rsc.RendersystemName = Name; // determine vendor if (vendorName.Contains("NVIDIA")) { rsc.Vendor = GPUVendor.Nvidia; } else if (vendorName.Contains("ATI")) { rsc.Vendor = GPUVendor.Ati; } else if (vendorName.Contains("Intel")) { rsc.Vendor = GPUVendor.Intel; } else if (vendorName.Contains("S3")) { rsc.Vendor = GPUVendor.S3; } else if (vendorName.Contains("Matrox")) { rsc.Vendor = GPUVendor.Matrox; } else if (vendorName.Contains("3DLabs")) { rsc.Vendor = GPUVendor._3DLabs; } else if (vendorName.Contains("SiS")) { rsc.Vendor = GPUVendor.Sis; } else { rsc.Vendor = GPUVendor.Unknown; } rsc.SetCapability(Graphics.Capabilities.FixedFunction); if (this.GLEW_VERSION_1_4 || this.GLEW_SGIS_generate_mipmap) { var disableAutoMip = false; #if AXIOM_PLATFORM == AXIOM_PLATFORM_APPLE || AXIOM_PLATFORM == AXIOM_PLATFORM_LINUX // Apple & Linux ATI drivers have faults in hardware mipmap generation if (rsc.Vendor == GPUVendor.Ati) { disableAutoMip = true; } #endif // The Intel 915G frequently corrupts textures when using hardware mip generation // I'm not currently sure how many generations of hardware this affects, // so for now, be safe. if (rsc.Vendor == GPUVendor.Intel) { disableAutoMip = true; } // SiS chipsets also seem to have problems with this if (rsc.Vendor == GPUVendor.Sis) { disableAutoMip = true; } if (!disableAutoMip) { rsc.SetCapability(Graphics.Capabilities.HardwareMipMaps); } } // Check for blending support if (this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_env_combine || this.GLEW_EXT_texture_env_combine) { rsc.SetCapability(Graphics.Capabilities.Blending); } // Check for Multitexturing support and set number of texture units if (this.GLEW_VERSION_1_3 || this.GLEW_ARB_multitexture) { int units; Gl.glGetIntegerv(Gl.GL_MAX_TEXTURE_UNITS, out units); if (this.GLEW_ARB_fragment_program) { // Also check GL_MAX_TEXTURE_IMAGE_UNITS_ARB since NV at least // only increased this on the FX/6x00 series int arbUnits; Gl.glGetIntegerv(Gl.GL_MAX_TEXTURE_IMAGE_UNITS_ARB, out arbUnits); if (arbUnits > units) { units = arbUnits; } } rsc.TextureUnitCount = units; } else { // If no multitexture support then set one texture unit rsc.TextureUnitCount = 1; } // Check for Anisotropy support if (this.GLEW_EXT_texture_filter_anisotropic) { rsc.SetCapability(Graphics.Capabilities.AnisotropicFiltering); } // Check for DOT3 support if (this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_env_dot3 || this.GLEW_EXT_texture_env_dot3) { rsc.SetCapability(Graphics.Capabilities.Dot3); } // Check for cube mapping if (this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_cube_map || this.GLEW_EXT_texture_cube_map) { rsc.SetCapability(Graphics.Capabilities.CubeMapping); } // Point sprites if (this.GLEW_VERSION_2_0 || this.GLEW_ARB_point_sprite) { rsc.SetCapability(Graphics.Capabilities.PointSprites); } // Check for point parameters if (this.GLEW_VERSION_1_4) { rsc.SetCapability(Graphics.Capabilities.PointExtendedParameters); } if (this.GLEW_ARB_point_parameters) { rsc.SetCapability(Graphics.Capabilities.PointExtendedParametersARB); } if (this.GLEW_EXT_point_parameters) { rsc.SetCapability(Graphics.Capabilities.PointExtendedParametersEXT); } // Check for hardware stencil support and set bit depth int stencil; Gl.glGetIntegerv(Gl.GL_STENCIL_BITS, out stencil); if (stencil != 0) { rsc.SetCapability(Graphics.Capabilities.StencilBuffer); rsc.StencilBufferBitCount = stencil; } if (this.GLEW_VERSION_1_5 || this.GLEW_ARB_vertex_buffer_object) { if (!this.GLEW_ARB_vertex_buffer_object) { rsc.SetCapability(Graphics.Capabilities.GL15NoVbo); } rsc.SetCapability(Graphics.Capabilities.VertexBuffer); } if (this.GLEW_ARB_vertex_program) { rsc.SetCapability(Graphics.Capabilities.VertexPrograms); // Vertex Program Properties rsc.VertexProgramConstantBoolCount = 0; rsc.VertexProgramConstantIntCount = 0; int floatConstantCount; Gl.glGetProgramivARB(Gl.GL_VERTEX_PROGRAM_ARB, Gl.GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, out floatConstantCount); rsc.VertexProgramConstantFloatCount = floatConstantCount; rsc.AddShaderProfile("arbvp1"); if (this.GLEW_NV_vertex_program2_option) { rsc.AddShaderProfile("vp30"); } if (this.GLEW_NV_vertex_program3) { rsc.AddShaderProfile("vp40"); } if (this.GLEW_NV_vertex_program4) { rsc.AddShaderProfile("gp4vp"); rsc.AddShaderProfile("gpu_vp"); } } if (this.GLEW_NV_register_combiners2 && this.GLEW_NV_texture_shader) { rsc.SetCapability(Graphics.Capabilities.FragmentPrograms); rsc.AddShaderProfile("fp20"); } // NFZ - check for ATI fragment shader support if (this.GLEW_ATI_fragment_shader) { rsc.SetCapability(Graphics.Capabilities.FragmentPrograms); // no boolean params allowed rsc.FragmentProgramConstantBoolCount = 0; // no integer params allowed rsc.FragmentProgramConstantIntCount = 0; // only 8 Vector4 constant floats supported rsc.FragmentProgramConstantFloatCount = 8; rsc.AddShaderProfile("ps_1_4"); rsc.AddShaderProfile("ps_1_3"); rsc.AddShaderProfile("ps_1_2"); rsc.AddShaderProfile("ps_1_1"); } if (this.GLEW_ARB_fragment_program) { rsc.SetCapability(Graphics.Capabilities.FragmentPrograms); // Fragment Program Properties rsc.FragmentProgramConstantBoolCount = 0; rsc.FragmentProgramConstantIntCount = 0; int floatConstantCount; Gl.glGetProgramivARB(Gl.GL_FRAGMENT_PROGRAM_ARB, Gl.GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, out floatConstantCount); rsc.FragmentProgramConstantFloatCount = floatConstantCount; rsc.AddShaderProfile("arbfp1"); if (this.GLEW_NV_fragment_program_option) { rsc.AddShaderProfile("fp30"); } if (this.GLEW_NV_fragment_program2) { rsc.AddShaderProfile("fp40"); } } // NFZ - Check if GLSL is supported if (this.GLEW_VERSION_2_0 || (this.GLEW_ARB_shading_language_100 && this.GLEW_ARB_shader_objects && this.GLEW_ARB_fragment_shader && this.GLEW_ARB_vertex_shader)) { rsc.AddShaderProfile("glsl"); } // Check if geometry shaders are supported if (this.GLEW_VERSION_2_0 && this.GLEW_EXT_geometry_shader4) { rsc.SetCapability(Graphics.Capabilities.GeometryPrograms); rsc.AddShaderProfile("nvgp4"); //Also add the CG profiles rsc.AddShaderProfile("gpu_gp"); rsc.AddShaderProfile("gp4gp"); rsc.GeometryProgramConstantBoolCount = 0; rsc.GeometryProgramConstantIntCount = 0; int floatConstantCount; Gl.glGetProgramivARB(Gl.GL_GEOMETRY_PROGRAM_NV, Gl.GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, out floatConstantCount); rsc.GeometryProgramConstantFloatCount = floatConstantCount; int maxOutputVertices; Gl.glGetIntegerv(Gl.GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, out maxOutputVertices); rsc.GeometryProgramNumOutputVertices = maxOutputVertices; } if (this._glSupport.CheckExtension("GL_ARB_get_program_binary")) { // states 3.0 here: http://developer.download.nvidia.com/opengl/specs/GL_ARB_get_program_binary.txt // but not here: http://www.opengl.org/sdk/docs/man4/xhtml/glGetProgramBinary.xml // and here states 4.1: http://www.geeks3d.com/20100727/opengl-4-1-allows-the-use-of-binary-shaders/ rsc.SetCapability(Graphics.Capabilities.CanGetCompiledShaderBuffer); } if (this.GLEW_VERSION_3_3) { // states 3.3 here: http://www.opengl.org/sdk/docs/man3/xhtml/glVertexAttribDivisor.xml rsc.SetCapability(Graphics.Capabilities.VertexBufferInstanceData); } //Check if render to vertex buffer (transform feedback in OpenGL) if (this.GLEW_VERSION_2_0 && this.GLEW_NV_transform_feedback) { rsc.SetCapability(Graphics.Capabilities.HardwareRenderToTexture); } // Check for texture compression if (this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_compression) { rsc.SetCapability(Graphics.Capabilities.TextureCompression); // Check for dxt compression if (this.GLEW_EXT_texture_compression_s3tc) { #if __APPLE__ && __PPC__ // Apple on ATI & PPC has errors in DXT if (_glSupport.Vendor.Contains("ATI") == false) #endif rsc.SetCapability(Graphics.Capabilities.TextureCompressionDXT); } // Check for vtc compression if (this.GLEW_NV_texture_compression_vtc) { rsc.SetCapability(Graphics.Capabilities.TextureCompressionVTC); } } // Scissor test is standard in GL 1.2 (is it emulated on some cards though?) rsc.SetCapability(Graphics.Capabilities.ScissorTest); // As are user clipping planes rsc.SetCapability(Graphics.Capabilities.UserClipPlanes); // 2-sided stencil? if (this.GLEW_VERSION_2_0 || this.GLEW_EXT_stencil_two_side) { rsc.SetCapability(Graphics.Capabilities.TwoSidedStencil); } // stencil wrapping? if (this.GLEW_VERSION_1_4 || this.GLEW_EXT_stencil_wrap) { rsc.SetCapability(Graphics.Capabilities.StencilWrap); } // Check for hardware occlusion support if (this.GLEW_VERSION_1_5 || this.GLEW_ARB_occlusion_query) { // Some buggy driver claim that it is GL 1.5 compliant and // not support ARB_occlusion_query if (!this.GLEW_ARB_occlusion_query) { rsc.SetCapability(Graphics.Capabilities.GL15NoHardwareOcclusion); } rsc.SetCapability(Graphics.Capabilities.HardwareOcculusion); } else if (this.GLEW_NV_occlusion_query) { // Support NV extension too for old hardware rsc.SetCapability(Graphics.Capabilities.HardwareOcculusion); } // UBYTE4 always supported rsc.SetCapability(Graphics.Capabilities.VertexFormatUByte4); // Infinite far plane always supported rsc.SetCapability(Graphics.Capabilities.InfiniteFarPlane); // Check for non-power-of-2 texture support if (this.GLEW_ARB_texture_non_power_of_two) { rsc.SetCapability(Graphics.Capabilities.NonPowerOf2Textures); } // Check for Float textures if (this.GLEW_ATI_texture_float || this.GLEW_ARB_texture_float) { rsc.SetCapability(Graphics.Capabilities.TextureFloat); } // 3D textures should be supported by GL 1.2, which is our minimum version rsc.SetCapability(Graphics.Capabilities.Texture3D); // Check for framebuffer object extension if (this.GLEW_EXT_framebuffer_object) { // Probe number of draw buffers // Only makes sense with FBO support, so probe here if (this.GLEW_VERSION_2_0 || this.GLEW_ARB_draw_buffers || this.GLEW_ATI_draw_buffers) { int buffers; Gl.glGetIntegerv(Gl.GL_MAX_DRAW_BUFFERS_ARB, out buffers); rsc.MultiRenderTargetCount = Utility.Min(buffers, Config.MaxMultipleRenderTargets); rsc.SetCapability(Graphics.Capabilities.MRTDifferentBitDepths); if (!this.GLEW_VERSION_2_0) { // Before GL version 2.0, we need to get one of the extensions if (this.GLEW_ARB_draw_buffers) { rsc.SetCapability(Graphics.Capabilities.FrameBufferObjectsARB); } if (this.GLEW_ATI_draw_buffers) { rsc.SetCapability(Graphics.Capabilities.FrameBufferObjectsATI); } } // Set FBO flag for all 3 'subtypes' rsc.SetCapability(Graphics.Capabilities.FrameBufferObjects); } rsc.SetCapability(Graphics.Capabilities.HardwareRenderToTexture); } // Check GLSupport for PBuffer support if (this._glSupport.SupportsPBuffers) { // Use PBuffers rsc.SetCapability(Graphics.Capabilities.HardwareRenderToTexture); rsc.SetCapability(Graphics.Capabilities.PBuffer); } // Point size if (this.GLEW_VERSION_1_4) { float ps; Gl.glGetFloatv(Gl.GL_POINT_SIZE_MAX, out ps); rsc.MaxPointSize = ps; } else { var vSize = new int[2]; Gl.glGetIntegerv(Gl.GL_POINT_SIZE_RANGE, vSize); rsc.MaxPointSize = vSize[1]; } // Vertex texture fetching if (this._glSupport.CheckExtension("GL_ARB_vertex_shader")) { int vUnits; Gl.glGetIntegerv(Gl.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, out vUnits); rsc.VertexTextureUnitCount = vUnits; if (vUnits > 0) { rsc.SetCapability(Graphics.Capabilities.VertexTextureFetch); } // GL always shares vertex and fragment texture units (for now?) rsc.VertexTextureUnitsShared = true; } // Mipmap LOD biasing? if (this.GLEW_VERSION_1_4 || this.GLEW_EXT_texture_lod_bias) { rsc.SetCapability(Graphics.Capabilities.MipmapLODBias); } // Alpha to coverage? if (this._glSupport.CheckExtension("GL_ARB_multisample")) { // Alpha to coverage always 'supported' when MSAA is available // although card may ignore it if it doesn't specifically support A2C rsc.SetCapability(Graphics.Capabilities.AlphaToCoverage); } // Advanced blending operations if (this.GLEW_VERSION_2_0) { rsc.SetCapability(Graphics.Capabilities.AdvancedBlendOperations); } return(rsc); }
private void _convertVertexShaderCaps( RenderSystemCapabilities rsc ) { var major = 0xFF; var minor = 0xFF; var minVsCaps = new D3D9.Capabilities(); // Find the device with the lowest vertex shader caps. foreach ( var pCurDriver in this._driverList ) { var rkCurCaps = pCurDriver.D3D9DeviceCaps; var currMajor = rkCurCaps.VertexShaderVersion.Major; var currMinor = rkCurCaps.VertexShaderVersion.Minor; if ( currMajor < major ) { major = currMajor; minor = currMinor; minVsCaps = rkCurCaps; } else if ( currMajor == major && currMinor < minor ) { minor = currMinor; minVsCaps = rkCurCaps; } } var vs2x = false; var vs2a = false; // Special case detection for vs_2_x/a support if ( major >= 2 ) { if ( ( minVsCaps.VS20Caps.Caps & D3D9.VertexShaderCaps.Predication ) != 0 && ( minVsCaps.VS20Caps.DynamicFlowControlDepth > 0 ) && ( minVsCaps.VS20Caps.TempCount >= 12 ) ) { vs2x = true; } if ( ( minVsCaps.VS20Caps.Caps & D3D9.VertexShaderCaps.Predication ) != 0 && ( minVsCaps.VS20Caps.DynamicFlowControlDepth > 0 ) && ( minVsCaps.VS20Caps.TempCount >= 13 ) ) { vs2a = true; } } // Populate max param count switch ( major ) { case 1: // No boolean params allowed rsc.VertexProgramConstantBoolCount = 0; // No integer params allowed rsc.VertexProgramConstantIntCount = 0; // float params, always 4D rsc.VertexProgramConstantFloatCount = minVsCaps.MaxVertexShaderConst; break; case 2: // 16 boolean params allowed rsc.VertexProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.VertexProgramConstantIntCount = 16; // float params, always 4D rsc.VertexProgramConstantFloatCount = minVsCaps.MaxVertexShaderConst; break; case 3: // 16 boolean params allowed rsc.VertexProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.VertexProgramConstantIntCount = 16; // float params, always 4D rsc.VertexProgramConstantFloatCount = minVsCaps.MaxVertexShaderConst; break; } // populate syntax codes in program manager (no breaks in this one so it falls through) switch ( major ) { case 3: rsc.AddShaderProfile( "vs_3_0" ); goto case 2; case 2: if ( vs2x ) { rsc.AddShaderProfile( "vs_2_x" ); } if ( vs2a ) { rsc.AddShaderProfile( "vs_2_a" ); } rsc.AddShaderProfile( "vs_2_0" ); goto case 1; case 1: rsc.AddShaderProfile( "vs_1_1" ); rsc.SetCapability( Graphics.Capabilities.VertexPrograms ); break; } }
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 this._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 ( this._fixedFunctionTextureUnits > maxTexCoords ) { this._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 ) ) { this._hardwareBufferManager = new GLHardwareBufferManager(); } else { this._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 this.gpuProgramMgr = new GLGpuProgramManager(); if ( caps.HasCapability( Graphics.Capabilities.VertexPrograms ) ) { if ( caps.IsShaderProfileSupported( "arbvp1" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "arbvp1", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "vp30" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "vp30", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "vp40" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "vp40", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "gp4vp" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "gp4vp", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "gpu_vp" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "gpu_vp", new ARBGpuProgramFactory() ); } } if ( caps.HasCapability( Graphics.Capabilities.GeometryPrograms ) ) { //TODO : Should these be createGLArbGpuProgram or createGLGpuNVparseProgram? if ( caps.IsShaderProfileSupported( "nvgp4" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "nvgp4", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "gp4gp" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "gp4gp", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "gpu_gp" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "gpu_gp", new ARBGpuProgramFactory() ); } } if ( caps.HasCapability( Graphics.Capabilities.FragmentPrograms ) ) { if ( caps.IsShaderProfileSupported( "fp20" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "fp20", new Nvidia.NvparseProgramFactory() ); } if ( caps.IsShaderProfileSupported( "ps_1_4" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "ps_1_4", new ATI.ATIFragmentShaderFactory() ); } if ( caps.IsShaderProfileSupported( "ps_1_3" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "ps_1_3", new ATI.ATIFragmentShaderFactory() ); } if ( caps.IsShaderProfileSupported( "ps_1_2" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "ps_1_2", new ATI.ATIFragmentShaderFactory() ); } if ( caps.IsShaderProfileSupported( "ps_1_1" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "ps_1_1", new ATI.ATIFragmentShaderFactory() ); } if ( caps.IsShaderProfileSupported( "arbfp1" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "arbfp1", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "fp40" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "fp40", new ARBGpuProgramFactory() ); } if ( caps.IsShaderProfileSupported( "fp30" ) ) { this.gpuProgramMgr.RegisterProgramFactory( "fp30", new ARBGpuProgramFactory() ); } } if ( caps.IsShaderProfileSupported( "glsl" ) ) { // NFZ - check for GLSL vertex and fragment shader support successful this._GLSLProgramFactory = new GLSL.GLSLProgramFactory(); HighLevelGpuProgramManager.Instance.AddFactory( this._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)" ); this.rttManager = new GLFBORTTManager( this._glSupport, false ); caps.SetCapability( Graphics.Capabilities.RTTSeperateDepthBuffer ); //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 this.rttManager = new GLPBRTTManager( this._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 this.rttManager = new GLCopyingRTTManager( this._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( this._glSupport ); this._glInitialised = true; }
public override RenderSystemCapabilities CreateRenderSystemCapabilities() { var rsc = new RenderSystemCapabilities(); rsc.SetCategoryRelevant( CapabilitiesCategory.GL, true ); rsc.DriverVersion = driverVersion; var deviceName = Gl.glGetString( Gl.GL_RENDERER ); var vendorName = Gl.glGetString( Gl.GL_VENDOR ); rsc.DeviceName = deviceName; rsc.RendersystemName = Name; // determine vendor if ( vendorName.Contains( "NVIDIA" ) ) { rsc.Vendor = GPUVendor.Nvidia; } else if ( vendorName.Contains( "ATI" ) ) { rsc.Vendor = GPUVendor.Ati; } else if ( vendorName.Contains( "Intel" ) ) { rsc.Vendor = GPUVendor.Intel; } else if ( vendorName.Contains( "S3" ) ) { rsc.Vendor = GPUVendor.S3; } else if ( vendorName.Contains( "Matrox" ) ) { rsc.Vendor = GPUVendor.Matrox; } else if ( vendorName.Contains( "3DLabs" ) ) { rsc.Vendor = GPUVendor._3DLabs; } else if ( vendorName.Contains( "SiS" ) ) { rsc.Vendor = GPUVendor.Sis; } else { rsc.Vendor = GPUVendor.Unknown; } rsc.SetCapability( Graphics.Capabilities.FixedFunction ); if ( this.GLEW_VERSION_1_4 || this.GLEW_SGIS_generate_mipmap ) { var disableAutoMip = false; #if AXIOM_PLATFORM == AXIOM_PLATFORM_APPLE || AXIOM_PLATFORM == AXIOM_PLATFORM_LINUX // Apple & Linux ATI drivers have faults in hardware mipmap generation if ( rsc.Vendor == GPUVendor.Ati ) { disableAutoMip = true; } #endif // The Intel 915G frequently corrupts textures when using hardware mip generation // I'm not currently sure how many generations of hardware this affects, // so for now, be safe. if ( rsc.Vendor == GPUVendor.Intel ) { disableAutoMip = true; } // SiS chipsets also seem to have problems with this if ( rsc.Vendor == GPUVendor.Sis ) { disableAutoMip = true; } if ( !disableAutoMip ) { rsc.SetCapability( Graphics.Capabilities.HardwareMipMaps ); } } // Check for blending support if ( this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_env_combine || this.GLEW_EXT_texture_env_combine ) { rsc.SetCapability( Graphics.Capabilities.Blending ); } // Check for Multitexturing support and set number of texture units if ( this.GLEW_VERSION_1_3 || this.GLEW_ARB_multitexture ) { int units; Gl.glGetIntegerv( Gl.GL_MAX_TEXTURE_UNITS, out units ); if ( this.GLEW_ARB_fragment_program ) { // Also check GL_MAX_TEXTURE_IMAGE_UNITS_ARB since NV at least // only increased this on the FX/6x00 series int arbUnits; Gl.glGetIntegerv( Gl.GL_MAX_TEXTURE_IMAGE_UNITS_ARB, out arbUnits ); if ( arbUnits > units ) { units = arbUnits; } } rsc.TextureUnitCount = units; } else { // If no multitexture support then set one texture unit rsc.TextureUnitCount = 1; } // Check for Anisotropy support if ( this.GLEW_EXT_texture_filter_anisotropic ) { rsc.SetCapability( Graphics.Capabilities.AnisotropicFiltering ); } // Check for DOT3 support if ( this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_env_dot3 || this.GLEW_EXT_texture_env_dot3 ) { rsc.SetCapability( Graphics.Capabilities.Dot3 ); } // Check for cube mapping if ( this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_cube_map || this.GLEW_EXT_texture_cube_map ) { rsc.SetCapability( Graphics.Capabilities.CubeMapping ); } // Point sprites if ( this.GLEW_VERSION_2_0 || this.GLEW_ARB_point_sprite ) { rsc.SetCapability( Graphics.Capabilities.PointSprites ); } // Check for point parameters if ( this.GLEW_VERSION_1_4 ) { rsc.SetCapability( Graphics.Capabilities.PointExtendedParameters ); } if ( this.GLEW_ARB_point_parameters ) { rsc.SetCapability( Graphics.Capabilities.PointExtendedParametersARB ); } if ( this.GLEW_EXT_point_parameters ) { rsc.SetCapability( Graphics.Capabilities.PointExtendedParametersEXT ); } // Check for hardware stencil support and set bit depth int stencil; Gl.glGetIntegerv( Gl.GL_STENCIL_BITS, out stencil ); if ( stencil != 0 ) { rsc.SetCapability( Graphics.Capabilities.StencilBuffer ); rsc.StencilBufferBitCount = stencil; } if ( this.GLEW_VERSION_1_5 || this.GLEW_ARB_vertex_buffer_object ) { if ( !this.GLEW_ARB_vertex_buffer_object ) { rsc.SetCapability( Graphics.Capabilities.GL15NoVbo ); } rsc.SetCapability( Graphics.Capabilities.VertexBuffer ); } if ( this.GLEW_ARB_vertex_program ) { rsc.SetCapability( Graphics.Capabilities.VertexPrograms ); // Vertex Program Properties rsc.VertexProgramConstantBoolCount = 0; rsc.VertexProgramConstantIntCount = 0; int floatConstantCount; Gl.glGetProgramivARB( Gl.GL_VERTEX_PROGRAM_ARB, Gl.GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, out floatConstantCount ); rsc.VertexProgramConstantFloatCount = floatConstantCount; rsc.AddShaderProfile( "arbvp1" ); if ( this.GLEW_NV_vertex_program2_option ) { rsc.AddShaderProfile( "vp30" ); } if ( this.GLEW_NV_vertex_program3 ) { rsc.AddShaderProfile( "vp40" ); } if ( this.GLEW_NV_vertex_program4 ) { rsc.AddShaderProfile( "gp4vp" ); rsc.AddShaderProfile( "gpu_vp" ); } } if ( this.GLEW_NV_register_combiners2 && this.GLEW_NV_texture_shader ) { rsc.SetCapability( Graphics.Capabilities.FragmentPrograms ); rsc.AddShaderProfile( "fp20" ); } // NFZ - check for ATI fragment shader support if ( this.GLEW_ATI_fragment_shader ) { rsc.SetCapability( Graphics.Capabilities.FragmentPrograms ); // no boolean params allowed rsc.FragmentProgramConstantBoolCount = 0; // no integer params allowed rsc.FragmentProgramConstantIntCount = 0; // only 8 Vector4 constant floats supported rsc.FragmentProgramConstantFloatCount = 8; rsc.AddShaderProfile( "ps_1_4" ); rsc.AddShaderProfile( "ps_1_3" ); rsc.AddShaderProfile( "ps_1_2" ); rsc.AddShaderProfile( "ps_1_1" ); } if ( this.GLEW_ARB_fragment_program ) { rsc.SetCapability( Graphics.Capabilities.FragmentPrograms ); // Fragment Program Properties rsc.FragmentProgramConstantBoolCount = 0; rsc.FragmentProgramConstantIntCount = 0; int floatConstantCount; Gl.glGetProgramivARB( Gl.GL_FRAGMENT_PROGRAM_ARB, Gl.GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, out floatConstantCount ); rsc.FragmentProgramConstantFloatCount = floatConstantCount; rsc.AddShaderProfile( "arbfp1" ); if ( this.GLEW_NV_fragment_program_option ) { rsc.AddShaderProfile( "fp30" ); } if ( this.GLEW_NV_fragment_program2 ) { rsc.AddShaderProfile( "fp40" ); } } // NFZ - Check if GLSL is supported if ( this.GLEW_VERSION_2_0 || ( this.GLEW_ARB_shading_language_100 && this.GLEW_ARB_shader_objects && this.GLEW_ARB_fragment_shader && this.GLEW_ARB_vertex_shader ) ) { rsc.AddShaderProfile( "glsl" ); } // Check if geometry shaders are supported if ( this.GLEW_VERSION_2_0 && this.GLEW_EXT_geometry_shader4 ) { rsc.SetCapability( Graphics.Capabilities.GeometryPrograms ); rsc.AddShaderProfile( "nvgp4" ); //Also add the CG profiles rsc.AddShaderProfile( "gpu_gp" ); rsc.AddShaderProfile( "gp4gp" ); rsc.GeometryProgramConstantBoolCount = 0; rsc.GeometryProgramConstantIntCount = 0; int floatConstantCount; Gl.glGetProgramivARB( Gl.GL_GEOMETRY_PROGRAM_NV, Gl.GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, out floatConstantCount ); rsc.GeometryProgramConstantFloatCount = floatConstantCount; int maxOutputVertices; Gl.glGetIntegerv( Gl.GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, out maxOutputVertices ); rsc.GeometryProgramNumOutputVertices = maxOutputVertices; } if ( this._glSupport.CheckExtension( "GL_ARB_get_program_binary" ) ) { // states 3.0 here: http://developer.download.nvidia.com/opengl/specs/GL_ARB_get_program_binary.txt // but not here: http://www.opengl.org/sdk/docs/man4/xhtml/glGetProgramBinary.xml // and here states 4.1: http://www.geeks3d.com/20100727/opengl-4-1-allows-the-use-of-binary-shaders/ rsc.SetCapability( Graphics.Capabilities.CanGetCompiledShaderBuffer ); } if ( this.GLEW_VERSION_3_3 ) { // states 3.3 here: http://www.opengl.org/sdk/docs/man3/xhtml/glVertexAttribDivisor.xml rsc.SetCapability( Graphics.Capabilities.VertexBufferInstanceData ); } //Check if render to vertex buffer (transform feedback in OpenGL) if ( this.GLEW_VERSION_2_0 && this.GLEW_NV_transform_feedback ) { rsc.SetCapability( Graphics.Capabilities.HardwareRenderToTexture ); } // Check for texture compression if ( this.GLEW_VERSION_1_3 || this.GLEW_ARB_texture_compression ) { rsc.SetCapability( Graphics.Capabilities.TextureCompression ); // Check for dxt compression if ( this.GLEW_EXT_texture_compression_s3tc ) { #if __APPLE__ && __PPC__ // Apple on ATI & PPC has errors in DXT if (_glSupport.Vendor.Contains("ATI") == false) #endif rsc.SetCapability( Graphics.Capabilities.TextureCompressionDXT ); } // Check for vtc compression if ( this.GLEW_NV_texture_compression_vtc ) { rsc.SetCapability( Graphics.Capabilities.TextureCompressionVTC ); } } // Scissor test is standard in GL 1.2 (is it emulated on some cards though?) rsc.SetCapability( Graphics.Capabilities.ScissorTest ); // As are user clipping planes rsc.SetCapability( Graphics.Capabilities.UserClipPlanes ); // 2-sided stencil? if ( this.GLEW_VERSION_2_0 || this.GLEW_EXT_stencil_two_side ) { rsc.SetCapability( Graphics.Capabilities.TwoSidedStencil ); } // stencil wrapping? if ( this.GLEW_VERSION_1_4 || this.GLEW_EXT_stencil_wrap ) { rsc.SetCapability( Graphics.Capabilities.StencilWrap ); } // Check for hardware occlusion support if ( this.GLEW_VERSION_1_5 || this.GLEW_ARB_occlusion_query ) { // Some buggy driver claim that it is GL 1.5 compliant and // not support ARB_occlusion_query if ( !this.GLEW_ARB_occlusion_query ) { rsc.SetCapability( Graphics.Capabilities.GL15NoHardwareOcclusion ); } rsc.SetCapability( Graphics.Capabilities.HardwareOcculusion ); } else if ( this.GLEW_NV_occlusion_query ) { // Support NV extension too for old hardware rsc.SetCapability( Graphics.Capabilities.HardwareOcculusion ); } // UBYTE4 always supported rsc.SetCapability( Graphics.Capabilities.VertexFormatUByte4 ); // Infinite far plane always supported rsc.SetCapability( Graphics.Capabilities.InfiniteFarPlane ); // Check for non-power-of-2 texture support if ( this.GLEW_ARB_texture_non_power_of_two ) { rsc.SetCapability( Graphics.Capabilities.NonPowerOf2Textures ); } // Check for Float textures if ( this.GLEW_ATI_texture_float || this.GLEW_ARB_texture_float ) { rsc.SetCapability( Graphics.Capabilities.TextureFloat ); } // 3D textures should be supported by GL 1.2, which is our minimum version rsc.SetCapability( Graphics.Capabilities.Texture3D ); // Check for framebuffer object extension if ( this.GLEW_EXT_framebuffer_object ) { // Probe number of draw buffers // Only makes sense with FBO support, so probe here if ( this.GLEW_VERSION_2_0 || this.GLEW_ARB_draw_buffers || this.GLEW_ATI_draw_buffers ) { int buffers; Gl.glGetIntegerv( Gl.GL_MAX_DRAW_BUFFERS_ARB, out buffers ); rsc.MultiRenderTargetCount = Utility.Min( buffers, Config.MaxMultipleRenderTargets ); rsc.SetCapability( Graphics.Capabilities.MRTDifferentBitDepths ); if ( !this.GLEW_VERSION_2_0 ) { // Before GL version 2.0, we need to get one of the extensions if ( this.GLEW_ARB_draw_buffers ) { rsc.SetCapability( Graphics.Capabilities.FrameBufferObjectsARB ); } if ( this.GLEW_ATI_draw_buffers ) { rsc.SetCapability( Graphics.Capabilities.FrameBufferObjectsATI ); } } // Set FBO flag for all 3 'subtypes' rsc.SetCapability( Graphics.Capabilities.FrameBufferObjects ); } rsc.SetCapability( Graphics.Capabilities.HardwareRenderToTexture ); } // Check GLSupport for PBuffer support if ( this._glSupport.SupportsPBuffers ) { // Use PBuffers rsc.SetCapability( Graphics.Capabilities.HardwareRenderToTexture ); rsc.SetCapability( Graphics.Capabilities.PBuffer ); } // Point size if ( this.GLEW_VERSION_1_4 ) { float ps; Gl.glGetFloatv( Gl.GL_POINT_SIZE_MAX, out ps ); rsc.MaxPointSize = ps; } else { var vSize = new int[2]; Gl.glGetIntegerv( Gl.GL_POINT_SIZE_RANGE, vSize ); rsc.MaxPointSize = vSize[ 1 ]; } // Vertex texture fetching if ( this._glSupport.CheckExtension( "GL_ARB_vertex_shader" ) ) { int vUnits; Gl.glGetIntegerv( Gl.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, out vUnits ); rsc.VertexTextureUnitCount = vUnits; if ( vUnits > 0 ) { rsc.SetCapability( Graphics.Capabilities.VertexTextureFetch ); } // GL always shares vertex and fragment texture units (for now?) rsc.VertexTextureUnitsShared = true; } // Mipmap LOD biasing? if ( this.GLEW_VERSION_1_4 || this.GLEW_EXT_texture_lod_bias ) { rsc.SetCapability( Graphics.Capabilities.MipmapLODBias ); } // Alpha to coverage? if ( this._glSupport.CheckExtension( "GL_ARB_multisample" ) ) { // Alpha to coverage always 'supported' when MSAA is available // although card may ignore it if it doesn't specifically support A2C rsc.SetCapability( Graphics.Capabilities.AlphaToCoverage ); } // Advanced blending operations if ( this.GLEW_VERSION_2_0 ) { rsc.SetCapability( Graphics.Capabilities.AdvancedBlendOperations ); } return rsc; }
private void _convertPixelShaderCaps( RenderSystemCapabilities rsc ) { var major = 0xFF; var minor = 0xFF; var minPsCaps = new D3D9.Capabilities(); // Find the device with the lowest vertex shader caps. foreach ( var pCurDriver in this._driverList ) { var currCaps = pCurDriver.D3D9DeviceCaps; var currMajor = currCaps.PixelShaderVersion.Major; var currMinor = currCaps.PixelShaderVersion.Minor; if ( currMajor < major ) { major = currMajor; minor = currMinor; minPsCaps = currCaps; } else if ( currMajor == major && currMinor < minor ) { minor = currMinor; minPsCaps = currCaps; } } var ps2a = false; var ps2b = false; var ps2x = false; // Special case detection for ps_2_x/a/b support if ( major >= 2 ) { if ( ( minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.NoTextureInstructionLimit ) != 0 && ( minPsCaps.PS20Caps.TempCount >= 32 ) ) { ps2b = true; } if ( ( minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.NoTextureInstructionLimit ) != 0 && ( minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.NoDependentReadLimit ) != 0 && ( minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.ArbitrarySwizzle ) != 0 && ( minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.GradientInstructions ) != 0 && ( minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.Predication ) != 0 && ( minPsCaps.PS20Caps.TempCount >= 22 ) ) { ps2a = true; } // Does this enough? if ( ps2a || ps2b ) { ps2x = true; } } switch ( major ) { case 1: // no boolean params allowed rsc.FragmentProgramConstantBoolCount = 0; // no integer params allowed rsc.FragmentProgramConstantIntCount = 0; // float params, always 4D // NB in ps_1_x these are actually stored as fixed point values, // but they are entered as floats rsc.FragmentProgramConstantFloatCount = 8; break; case 2: // 16 boolean params allowed rsc.FragmentProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.FragmentProgramConstantIntCount = 16; // float params, always 4D rsc.FragmentProgramConstantFloatCount = 32; break; case 3: // 16 boolean params allowed rsc.FragmentProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.FragmentProgramConstantIntCount = 16; // float params, always 4D rsc.FragmentProgramConstantFloatCount = 224; break; } // populate syntax codes in program manager (no breaks in this one so it falls through) switch ( major ) { case 3: if ( minor > 0 ) { rsc.AddShaderProfile( "ps_3_x" ); } rsc.AddShaderProfile( "ps_3_0" ); goto case 2; case 2: if ( ps2x ) { rsc.AddShaderProfile( "ps_2_x" ); } if ( ps2a ) { rsc.AddShaderProfile( "ps_2_a" ); } if ( ps2b ) { rsc.AddShaderProfile( "ps_2_b" ); } rsc.AddShaderProfile( "ps_2_0" ); goto case 1; case 1: if ( major > 1 || minor >= 4 ) { rsc.AddShaderProfile( "ps_1_4" ); } if ( major > 1 || minor >= 3 ) { rsc.AddShaderProfile( "ps_1_3" ); } if ( major > 1 || minor >= 2 ) { rsc.AddShaderProfile( "ps_1_2" ); } rsc.AddShaderProfile( "ps_1_1" ); rsc.SetCapability( Graphics.Capabilities.FragmentPrograms ); break; } }
public override RenderSystemCapabilities CreateRenderSystemCapabilities() { var rsc = new RenderSystemCapabilities(); rsc.SetCategoryRelevant( CapabilitiesCategory.GL, true ); rsc.DriverVersion = driverVersion; string deviceName = GL.GetString( All.Renderer ); GLES2Config.GlCheckError( this ); string vendorName = GL.GetString( All.Vendor ); GLES2Config.GlCheckError( this ); deviceName = deviceName ?? string.Empty; vendorName = vendorName ?? string.Empty; if ( !string.IsNullOrEmpty( deviceName ) ) { rsc.DeviceName = deviceName; } rsc.RendersystemName = this.Name; //Determine vendor if ( vendorName.Contains( "Imagination Technologies" ) ) { rsc.Vendor = GPUVendor.ImaginationTechnologies; } else if ( vendorName.Contains( "Apple Computer, Inc." ) ) { rsc.Vendor = GPUVendor.Apple; // iOS Simulator } else if ( vendorName.Contains( "NVIDIA" ) ) { rsc.Vendor = GPUVendor.Nvidia; } else { rsc.Vendor = GPUVendor.Unknown; } //Multitexturing support and set number of texture units; int units = 0; GL.GetInteger( All.MaxTextureImageUnits, ref units ); GLES2Config.GlCheckError( this ); rsc.TextureUnitCount = units; //check hardware stenicl support and set bit depth int stencil = -1; GL.GetInteger( All.StencilBits, ref stencil ); GLES2Config.GlCheckError( this ); if ( stencil != -1 ) { rsc.SetCapability( Graphics.Capabilities.StencilBuffer ); rsc.SetCapability( Graphics.Capabilities.TwoSidedStencil ); rsc.StencilBufferBitCount = stencil; } // Scissor test is standard rsc.SetCapability( Graphics.Capabilities.ScissorTest ); //Vertex buffer objects are always supported by OpenGL ES /*Port notes: Ogre sets capability as VBO, or Vertex Buffer Objects. VertexBuffer is closest */ rsc.SetCapability( Graphics.Capabilities.VertexBuffer ); //Check for hardware occlusion support if ( this.glSupport.CheckExtension( "GL_EXT_occlusion_query_boolean" ) ) { ; rsc.SetCapability( Graphics.Capabilities.HardwareOcculusion ); } // OpenGL ES - Check for these extensions too // For 2.0, http://www.khronos.org/registry/gles/api/2.0/gl2ext.h if ( this.glSupport.CheckExtension( "GL_IMG_texture_compression_pvrtc" ) || this.glSupport.CheckExtension( "GL_EXT_texture_compression_dxt1" ) || this.glSupport.CheckExtension( "GL_EXT_texture_compression_s3tc" ) ) { rsc.SetCapability( Graphics.Capabilities.TextureCompression ); if ( this.glSupport.CheckExtension( "GL_IMG_texture_compression_pvrtc" ) ) { rsc.SetCapability( Graphics.Capabilities.TextureCompressionPVRTC ); } if ( this.glSupport.CheckExtension( "GL_EXT_texture_compression_dxt1" ) && this.glSupport.CheckExtension( "GL_EXT_texture_compression_s3tc" ) ) { rsc.SetCapability( Graphics.Capabilities.TextureCompressionDXT ); } } if ( this.glSupport.CheckExtension( "GL_EXT_texture_filter_anisotropic" ) ) { rsc.SetCapability( Graphics.Capabilities.AnisotropicFiltering ); } rsc.SetCapability( Graphics.Capabilities.FrameBufferObjects ); rsc.SetCapability( Graphics.Capabilities.HardwareRenderToTexture ); rsc.MultiRenderTargetCount = 1; //Cube map rsc.SetCapability( Graphics.Capabilities.CubeMapping ); //Stencil wrapping rsc.SetCapability( Graphics.Capabilities.StencilWrap ); //GL always shares vertex and fragment texture units (for now?) rsc.VertexTextureUnitsShared = true; //Hardware support mipmapping //rsc.SetCapability(Graphics.Capabilities.AutoMipMap); //Blending support rsc.SetCapability( Graphics.Capabilities.Blending ); rsc.SetCapability( Graphics.Capabilities.AdvancedBlendOperations ); //DOT3 support is standard rsc.SetCapability( Graphics.Capabilities.Dot3 ); //Point size var psRange = new float[ 2 ] { 0.0f, 0.0f }; GL.GetFloat( All.AliasedPointSizeRange, psRange ); GLES2Config.GlCheckError( this ); rsc.MaxPointSize = psRange[ 1 ]; //Point sprites rsc.SetCapability( Graphics.Capabilities.PointSprites ); rsc.SetCapability( Graphics.Capabilities.PointExtendedParameters ); // GLSL ES is always supported in GL ES 2 rsc.AddShaderProfile( "glsles" ); LogManager.Instance.Write( "GLSL ES support detected" ); //todo: OGRE has a #if here checking for cg support //I believe Android supports cg, but not iPhone? rsc.AddShaderProfile( "cg" ); rsc.AddShaderProfile( "ps_2_0" ); rsc.AddShaderProfile( "vs_2_0" ); //UBYTE4 is always supported rsc.SetCapability( Graphics.Capabilities.VertexFormatUByte4 ); //Infinite far plane always supported rsc.SetCapability( Graphics.Capabilities.InfiniteFarPlane ); //Vertex/Fragment programs rsc.SetCapability( Graphics.Capabilities.VertexPrograms ); rsc.SetCapability( Graphics.Capabilities.FragmentPrograms ); //Sepearte shader objects if ( glSupport.CheckExtension( "GL_EXT_seperate_shader_objects" ) ) rsc.SetCapability( Graphics.Capabilities.SeperateShaderObjects ); float floatConstantCount = 0; GL.GetFloat( All.MaxVertexUniformVectors, ref floatConstantCount ); GLES2Config.GlCheckError( this ); rsc.VertexProgramConstantFloatCount = (int) floatConstantCount; rsc.VertexProgramConstantBoolCount = (int) floatConstantCount; rsc.VertexProgramConstantIntCount = (int) floatConstantCount; //Fragment Program Properties floatConstantCount = 0; GL.GetFloat( All.MaxFragmentUniformVectors, ref floatConstantCount ); GLES2Config.GlCheckError( this ); rsc.FragmentProgramConstantFloatCount = (int) floatConstantCount; rsc.FragmentProgramConstantBoolCount = (int) floatConstantCount; rsc.FragmentProgramConstantIntCount = (int) floatConstantCount; //Geometry programs are not supported, report 0 rsc.GeometryProgramConstantFloatCount = 0; rsc.GeometryProgramConstantBoolCount = 0; rsc.GeometryProgramConstantIntCount = 0; //Check for Float textures rsc.SetCapability( Graphics.Capabilities.TextureFloat ); //Alpha to coverate always 'supported' when MSAA is availalbe //although card may ignore it if it doesn't specifically support A2C rsc.SetCapability( Graphics.Capabilities.AlphaToCoverage ); //No point sprites, so no size rsc.MaxPointSize = 0; if ( this.glSupport.CheckExtension( "GL_OES_get_program_binary" ) ) { // http://www.khronos.org/registry/gles/extensions/OES/OES_get_program_binary.txt rsc.SetCapability( Graphics.Capabilities.CanGetCompiledShaderBuffer ); } return rsc; }
public override void InitializeFromRenderSystemCapabilities( RenderSystemCapabilities caps, RenderTarget primary ) { if ( caps.RendersystemName != this.Name ) { throw new AxiomException( "Trying to initialize GLES2RenderSystem from RenderSystemCapabilities that do not support OpenGL ES" ); } this.gpuProgramManager = new GLES2GpuProgramManager(); this.glslESProgramFactory = new GLSLES.GLSLESProgramFactory(); HighLevelGpuProgramManager.Instance.AddFactory( this.glslESProgramFactory ); //todo: check what can/can't support cg this.glslESCgProgramFactory = new GLSLES.GLSLESCgProgramFactory(); HighLevelGpuProgramManager.Instance.AddFactory( this.glslESCgProgramFactory ); //Set texture the number of texture units this.fixedFunctionTextureUnits = caps.TextureUnitCount; //Use VBO's by default this.hardwareBufferManager = new GLES2HardwareBufferManager(); //Create FBO manager LogManager.Instance.Write( "GL ES 2: Using FBOs for rendering to textures" ); this.rttManager = new GLES2FBOManager(); caps.SetCapability( Graphics.Capabilities.RTTSerperateDepthBuffer ); Log defaultLog = LogManager.Instance.DefaultLog; if ( defaultLog != null ) { caps.Log( defaultLog ); } textureManager = new GLES2TextureManager( this.glSupport ); this.glInitialized = true; }
private void _convertPixelShaderCaps(RenderSystemCapabilities rsc) { var major = 0xFF; var minor = 0xFF; var minPsCaps = new D3D9.Capabilities(); // Find the device with the lowest vertex shader caps. foreach (var pCurDriver in this._driverList) { var currCaps = pCurDriver.D3D9DeviceCaps; var currMajor = currCaps.PixelShaderVersion.Major; var currMinor = currCaps.PixelShaderVersion.Minor; if (currMajor < major) { major = currMajor; minor = currMinor; minPsCaps = currCaps; } else if (currMajor == major && currMinor < minor) { minor = currMinor; minPsCaps = currCaps; } } var ps2a = false; var ps2b = false; var ps2x = false; // Special case detection for ps_2_x/a/b support if (major >= 2) { if ((minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.NoTextureInstructionLimit) != 0 && (minPsCaps.PS20Caps.TempCount >= 32)) { ps2b = true; } if ((minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.NoTextureInstructionLimit) != 0 && (minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.NoDependentReadLimit) != 0 && (minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.ArbitrarySwizzle) != 0 && (minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.GradientInstructions) != 0 && (minPsCaps.PS20Caps.Caps & D3D9.PixelShaderCaps.Predication) != 0 && (minPsCaps.PS20Caps.TempCount >= 22)) { ps2a = true; } // Does this enough? if (ps2a || ps2b) { ps2x = true; } } switch (major) { case 1: // no boolean params allowed rsc.FragmentProgramConstantBoolCount = 0; // no integer params allowed rsc.FragmentProgramConstantIntCount = 0; // float params, always 4D // NB in ps_1_x these are actually stored as fixed point values, // but they are entered as floats rsc.FragmentProgramConstantFloatCount = 8; break; case 2: // 16 boolean params allowed rsc.FragmentProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.FragmentProgramConstantIntCount = 16; // float params, always 4D rsc.FragmentProgramConstantFloatCount = 32; break; case 3: // 16 boolean params allowed rsc.FragmentProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.FragmentProgramConstantIntCount = 16; // float params, always 4D rsc.FragmentProgramConstantFloatCount = 224; break; } // populate syntax codes in program manager (no breaks in this one so it falls through) switch (major) { case 3: if (minor > 0) { rsc.AddShaderProfile("ps_3_x"); } rsc.AddShaderProfile("ps_3_0"); goto case 2; case 2: if (ps2x) { rsc.AddShaderProfile("ps_2_x"); } if (ps2a) { rsc.AddShaderProfile("ps_2_a"); } if (ps2b) { rsc.AddShaderProfile("ps_2_b"); } rsc.AddShaderProfile("ps_2_0"); goto case 1; case 1: if (major > 1 || minor >= 4) { rsc.AddShaderProfile("ps_1_4"); } if (major > 1 || minor >= 3) { rsc.AddShaderProfile("ps_1_3"); } if (major > 1 || minor >= 2) { rsc.AddShaderProfile("ps_1_2"); } rsc.AddShaderProfile("ps_1_1"); rsc.SetCapability(Graphics.Capabilities.FragmentPrograms); break; } }
private void _convertVertexShaderCaps(RenderSystemCapabilities rsc) { var major = 0xFF; var minor = 0xFF; var minVsCaps = new D3D9.Capabilities(); // Find the device with the lowest vertex shader caps. foreach (var pCurDriver in this._driverList) { var rkCurCaps = pCurDriver.D3D9DeviceCaps; var currMajor = rkCurCaps.VertexShaderVersion.Major; var currMinor = rkCurCaps.VertexShaderVersion.Minor; if (currMajor < major) { major = currMajor; minor = currMinor; minVsCaps = rkCurCaps; } else if (currMajor == major && currMinor < minor) { minor = currMinor; minVsCaps = rkCurCaps; } } var vs2x = false; var vs2a = false; // Special case detection for vs_2_x/a support if (major >= 2) { if ((minVsCaps.VS20Caps.Caps & D3D9.VertexShaderCaps.Predication) != 0 && (minVsCaps.VS20Caps.DynamicFlowControlDepth > 0) && (minVsCaps.VS20Caps.TempCount >= 12)) { vs2x = true; } if ((minVsCaps.VS20Caps.Caps & D3D9.VertexShaderCaps.Predication) != 0 && (minVsCaps.VS20Caps.DynamicFlowControlDepth > 0) && (minVsCaps.VS20Caps.TempCount >= 13)) { vs2a = true; } } // Populate max param count switch (major) { case 1: // No boolean params allowed rsc.VertexProgramConstantBoolCount = 0; // No integer params allowed rsc.VertexProgramConstantIntCount = 0; // float params, always 4D rsc.VertexProgramConstantFloatCount = minVsCaps.MaxVertexShaderConst; break; case 2: // 16 boolean params allowed rsc.VertexProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.VertexProgramConstantIntCount = 16; // float params, always 4D rsc.VertexProgramConstantFloatCount = minVsCaps.MaxVertexShaderConst; break; case 3: // 16 boolean params allowed rsc.VertexProgramConstantBoolCount = 16; // 16 integer params allowed, 4D rsc.VertexProgramConstantIntCount = 16; // float params, always 4D rsc.VertexProgramConstantFloatCount = minVsCaps.MaxVertexShaderConst; break; } // populate syntax codes in program manager (no breaks in this one so it falls through) switch (major) { case 3: rsc.AddShaderProfile("vs_3_0"); goto case 2; case 2: if (vs2x) { rsc.AddShaderProfile("vs_2_x"); } if (vs2a) { rsc.AddShaderProfile("vs_2_a"); } rsc.AddShaderProfile("vs_2_0"); goto case 1; case 1: rsc.AddShaderProfile("vs_1_1"); rsc.SetCapability(Graphics.Capabilities.VertexPrograms); break; } }
private void _setCapabilitiesForReachProfile( ref RenderSystemCapabilities rsc ) { // Fill in the Reach profile requirements. // Texture Compression // We always support compression, Xna will decompress if device does not support rsc.SetCapability( Graphics.Capabilities.TextureCompression ); rsc.SetCapability( Graphics.Capabilities.TextureCompressionDXT ); // Xna uses vertex buffers for everything rsc.SetCapability( Graphics.Capabilities.VertexBuffer ); //VertexShaderVersion = 0x200; rsc.SetCapability( Graphics.Capabilities.VertexPrograms ); rsc.MaxVertexProgramVersion = "vs_2_0"; rsc.VertexProgramConstantIntCount = 16 * 4; rsc.VertexProgramConstantFloatCount = 256; rsc.AddShaderProfile( "vs_1_1" ); rsc.AddShaderProfile( "vs_2_0" ); //PixelShaderVersion = 0x200; rsc.SetCapability( Graphics.Capabilities.FragmentPrograms ); rsc.MaxFragmentProgramVersion = "ps_2_0"; rsc.FragmentProgramConstantIntCount = 0; rsc.FragmentProgramConstantFloatCount = 32; rsc.AddShaderProfile( "ps_1_1" ); rsc.AddShaderProfile( "ps_1_2" ); rsc.AddShaderProfile( "ps_1_3" ); rsc.AddShaderProfile( "ps_1_4" ); rsc.AddShaderProfile( "ps_2_0" ); //SeparateAlphaBlend = false; //DestBlendSrcAlphaSat = false; //MaxPrimitiveCount = 65535; //IndexElementSize32 = false; //MaxVertexStreams = 16; //MaxStreamStride = 255; //MaxTextureSize = 2048; //MaxCubeSize = 512; //MaxVolumeExtent = 0; //MaxTextureAspectRatio = 2048; //MaxVertexSamplers = 0; //MaxRenderTargets = 1; rsc.TextureUnitCount = 16; rsc.MultiRenderTargetCount = 1; //NonPow2Unconditional = false; //NonPow2Cube = false; //NonPow2Volume = false; //ValidTextureFormats = MakeList(STANDARD_TEXTURE_FORMATS, COMPRESSED_TEXTURE_FORMATS, SIGNED_TEXTURE_FORMATS); //ValidCubeFormats = MakeList(STANDARD_TEXTURE_FORMATS, COMPRESSED_TEXTURE_FORMATS); //ValidVolumeFormats = MakeList<SurfaceFormat>(); //ValidVertexTextureFormats = MakeList<SurfaceFormat>(); //InvalidFilterFormats = MakeList<SurfaceFormat>(); //InvalidBlendFormats = MakeList<SurfaceFormat>(); //ValidVertexFormats = MakeList(STANDARD_VERTEX_FORMATS); }
private void _setCapabilitiesForHiDefProfile( ref RenderSystemCapabilities rsc ) { // Fill in the HiDef profile requirements. rsc.SetCapability( Graphics.Capabilities.HardwareOcculusion ); //VertexShaderVersion = 0x300; rsc.SetCapability( Graphics.Capabilities.VertexPrograms ); rsc.MaxVertexProgramVersion = "vs_3_0"; rsc.VertexProgramConstantIntCount = 16 * 4; rsc.VertexProgramConstantFloatCount = 256; rsc.AddShaderProfile( "vs_1_1" ); rsc.AddShaderProfile( "vs_2_0" ); rsc.AddShaderProfile( "vs_2_x" ); rsc.AddShaderProfile( "vs_3_0" ); //PixelShaderVersion = 0x300; rsc.SetCapability( Graphics.Capabilities.FragmentPrograms ); rsc.MaxFragmentProgramVersion = "ps_3_0"; rsc.FragmentProgramConstantIntCount = 16; rsc.FragmentProgramConstantFloatCount = 224; rsc.AddShaderProfile( "ps_1_1" ); rsc.AddShaderProfile( "ps_1_2" ); rsc.AddShaderProfile( "ps_1_3" ); rsc.AddShaderProfile( "ps_1_4" ); rsc.AddShaderProfile( "ps_2_0" ); rsc.AddShaderProfile( "ps_3_0" ); //SeparateAlphaBlend = true; rsc.SetCapability( Graphics.Capabilities.AdvancedBlendOperations ); //DestBlendSrcAlphaSat = true; //MaxPrimitiveCount = 1048575; //IndexElementSize32 = true; //MaxVertexStreams = 16; //MaxStreamStride = 255; //MaxTextureSize = 4096; //MaxCubeSize = 4096; //MaxVolumeExtent = 256; //MaxTextureAspectRatio = 2048; //MaxVertexSamplers = 4; //MaxRenderTargets = 4; rsc.TextureUnitCount = 16; rsc.MultiRenderTargetCount = 4; //NonPow2Unconditional = true; //NonPow2Cube = true; //NonPow2Volume = true; //ValidTextureFormats = MakeList(STANDARD_TEXTURE_FORMATS, COMPRESSED_TEXTURE_FORMATS, SIGNED_TEXTURE_FORMATS, HIDEF_TEXTURE_FORMATS, FLOAT_TEXTURE_FORMATS); //ValidCubeFormats = MakeList(STANDARD_TEXTURE_FORMATS, COMPRESSED_TEXTURE_FORMATS, HIDEF_TEXTURE_FORMATS, FLOAT_TEXTURE_FORMATS); //ValidVolumeFormats = MakeList(STANDARD_TEXTURE_FORMATS, HIDEF_TEXTURE_FORMATS, FLOAT_TEXTURE_FORMATS); //ValidVertexTextureFormats = MakeList(FLOAT_TEXTURE_FORMATS); //InvalidFilterFormats = MakeList(FLOAT_TEXTURE_FORMATS); //InvalidBlendFormats = MakeList(STANDARD_FLOAT_TEXTURE_FORMATS); //ValidVertexFormats = MakeList(STANDARD_VERTEX_FORMATS, HIDEF_VERTEX_FORMATS); }
private void _setCapabilitiesForAllProfiles( ref RenderSystemCapabilities rsc ) { //TODO Should we add an XNA capabilities category? //rsc.SetCategoryRelevant( CapabilitiesCategory.D3D9, true ); rsc.DriverVersion = driverVersion; rsc.DeviceName = _activeDriver.Description; rsc.RendersystemName = Name; // determine vendor // Full list of vendors here: http://www.pcidatabase.com/vendors.php?sort=id #if SILVERLIGHT var vendorId = 0x0000; #else var vendorId = _device.Adapter.VendorId; #endif switch (vendorId) { case 0x10DE: rsc.Vendor = GPUVendor.Nvidia; break; case 0x1002: rsc.Vendor = GPUVendor.Ati; break; case 0x163C: case 0x8086: rsc.Vendor = GPUVendor.Intel; break; case 0x5333: rsc.Vendor = GPUVendor.S3; break; case 0x3D3D: rsc.Vendor = GPUVendor._3DLabs; break; case 0x102B: rsc.Vendor = GPUVendor.Matrox; break; case 0x1039: rsc.Vendor = GPUVendor.Sis; break; default: rsc.Vendor = GPUVendor.Unknown; break; } // Texture Compression // We always support compression, Xna will decompress if device does not support rsc.SetCapability( Graphics.Capabilities.TextureCompression ); rsc.SetCapability( Graphics.Capabilities.TextureCompressionDXT ); // Xna uses vertex buffers for everything rsc.SetCapability( Graphics.Capabilities.VertexBuffer ); // blending between stages is definitely supported rsc.SetCapability(Graphics.Capabilities.TextureBlending); rsc.SetCapability(Graphics.Capabilities.MultiTexturing); }
/// <summary> /// /// </summary> /// <param name="primary"></param> private void CheckCaps( RenderTarget primary ) { _rsCapabilities = new RenderSystemCapabilities(); _rsCapabilities.DeviceName = OpenTK.Graphics.ES11.GL.GetString( All.Renderer ); _rsCapabilities.VendorName = OpenTK.Graphics.ES11.GL.GetString( All.Vendor ); _rsCapabilities.RendersystemName = Name; // GL ES 1.x is fixed function only _rsCapabilities.SetCapability( Capabilities.FixedFunction ); // Multitexturing support and set number of texture units int units = 0; OpenGL.GetInteger( All.MaxTextureUnits, ref units ); _rsCapabilities.TextureUnitCount = units; // Check for hardware stencil support and set bit depth int stencil = 0; OpenGL.GetInteger( All.StencilBits, ref stencil ); GLESConfig.GlCheckError( this ); if ( stencil != 0 ) { _rsCapabilities.SetCapability( Capabilities.StencilBuffer ); _rsCapabilities.StencilBufferBitCount = stencil; } // Scissor test is standard _rsCapabilities.SetCapability( Capabilities.ScissorTest ); // Vertex Buffer Objects are always supported by OpenGL ES _rsCapabilities.SetCapability( Capabilities.VertexBuffer ); // OpenGL ES - Check for these extensions too // For 1.1, http://www.khronos.org/registry/gles/api/1.1/glext.h // For 2.0, http://www.khronos.org/registry/gles/api/2.0/gl2ext.h if ( _glSupport.CheckExtension( "GL_IMG_texture_compression_pvrtc" ) || _glSupport.CheckExtension( "GL_AMD_compressed_3DC_texture" ) || _glSupport.CheckExtension( "GL_AMD_compressed_ATC_texture" ) || _glSupport.CheckExtension( "GL_OES_compressed_ETC1_RGB8_texture" ) || _glSupport.CheckExtension( "GL_OES_compressed_paletted_texture" ) ) { // TODO: Add support for compression types other than pvrtc _rsCapabilities.SetCapability( Capabilities.TextureCompression ); if ( _glSupport.CheckExtension( "GL_IMG_texture_compression_pvrtc" ) ) _rsCapabilities.SetCapability( Capabilities.TextureCompressionPVRTC ); } if ( _glSupport.CheckExtension( "GL_EXT_texture_filter_anisotropic" ) ) _rsCapabilities.SetCapability( Capabilities.AnisotropicFiltering ); if ( _glSupport.CheckExtension( "GL_OES_framebuffer_object" ) ) { LogManager.Instance.Write( "[GLES] Framebuffers are supported." ); _rsCapabilities.SetCapability( Capabilities.FrameBufferObjects ); _rsCapabilities.SetCapability( Capabilities.HardwareRenderToTexture ); } else { _rsCapabilities.SetCapability( Capabilities.PBuffer ); _rsCapabilities.SetCapability( Capabilities.HardwareRenderToTexture ); } // Cube map if ( _glSupport.CheckExtension( "GL_OES_texture_cube_map" ) ) _rsCapabilities.SetCapability( Capabilities.CubeMapping ); if ( _glSupport.CheckExtension( "GL_OES_stencil_wrap" ) ) _rsCapabilities.SetCapability( Capabilities.StencilWrap ); if ( _glSupport.CheckExtension( "GL_OES_blend_subtract" ) ) _rsCapabilities.SetCapability( Capabilities.AdvancedBlendOperations ); if ( _glSupport.CheckExtension( "GL_ANDROID_user_clip_plane" ) ) _rsCapabilities.SetCapability( Capabilities.UserClipPlanes ); if ( _glSupport.CheckExtension( "GL_OES_texture3D" ) ) _rsCapabilities.SetCapability( Capabilities.Texture3D ); // GL always shares vertex and fragment texture units (for now?) _rsCapabilities.VertexTextureUnitsShared = true; // Hardware support mipmapping _rsCapabilities.SetCapability( Capabilities.Automipmap ); if ( _glSupport.CheckExtension( "GL_EXT_texture_lod_bias" ) ) _rsCapabilities.SetCapability( Capabilities.MipmapLODBias ); //blending support _rsCapabilities.SetCapability( Capabilities.TextureBlending ); // DOT3 support is standard _rsCapabilities.SetCapability( Capabilities.Dot3 ); if ( _rsCapabilities.HasCapability( Capabilities.VertexBuffer ) ) { hardwareBufferManager = new GLESHardwareBufferManager(); } else { hardwareBufferManager = new GLESDefaultHardwareBufferManager(); } /// Do this after extension function pointers are initialised as the extension /// is used to probe further capabilities. int rttMode = 0; if ( ConfigOptions.ContainsKey( "RTT Preferred Mode" ) ) { ConfigOption opt = ConfigOptions[ "RTT Preferred Mode" ]; // RTT Mode: 0 use whatever available, 1 use PBuffers, 2 force use copying if ( opt.Value == "PBuffer" ) { rttMode = 1; } else if ( opt.Value == "Copy" ) { rttMode = 2; } } LogManager.Instance.Write( "[GLES] 'RTT Preferred Mode' = {0}", rttMode ); // Check for framebuffer object extension if ( _rsCapabilities.HasCapability( Capabilities.FrameBufferObjects ) && ( rttMode < 1 ) ) { if ( _rsCapabilities.HasCapability( Capabilities.HardwareRenderToTexture ) ) { // Create FBO manager LogManager.Instance.Write( "[GLES] Using GL_OES_framebuffer_object for rendering to textures (best)" ); _rttManager = new GLESFBORTTManager(); } } else { // Check GLSupport for PBuffer support if ( _rsCapabilities.HasCapability( Capabilities.PBuffer ) && rttMode < 2 ) { if ( _rsCapabilities.HasCapability( Capabilities.HardwareRenderToTexture ) ) { // Use PBuffers _rttManager = new GLESPBRTTManager(); LogManager.Instance.Write( "[GLES] Using PBuffers for rendering to textures" ); } } else { // No pbuffer support either -- fallback to simplest copying from framebuffer _rttManager = new GLESCopyingRTTManager(); LogManager.Instance.Write( "[GLES] Using framebuffer copy for rendering to textures (worst)" ); LogManager.Instance.Write( "[GLES] Warning: RenderTexture size is restricted to size of framebuffer." ); } _rsCapabilities.MultiRenderTargetCount = 1; } // Point size float ps = 0; OpenGL.GetFloat( All.PointSizeMax, ref ps ); GLESConfig.GlCheckError( this ); _rsCapabilities.MaxPointSize = ps; // Point sprites if ( _glSupport.CheckExtension( "GL_OES_point_sprite" ) ) _rsCapabilities.SetCapability( Capabilities.PointSprites ); _rsCapabilities.SetCapability( Capabilities.PointExtendedParameters ); // UBYTE4 always supported _rsCapabilities.SetCapability( Capabilities.VertexFormatUByte4 ); // Infinite far plane always supported _rsCapabilities.SetCapability( Capabilities.InfiniteFarPlane ); // hardware occlusion support _rsCapabilities.SetCapability( Capabilities.HardwareOcculusion ); //// Check for Float textures if ( _glSupport.CheckExtension( "GL_OES_texture_half_float" ) ) _rsCapabilities.SetCapability( Capabilities.TextureFloat ); // Alpha to coverage always 'supported' when MSAA is available // although card may ignore it if it doesn't specifically support A2C _rsCapabilities.SetCapability( Capabilities.AlphaToCoverage ); }
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 this._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 (this._fixedFunctionTextureUnits > maxTexCoords) { this._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)) { this._hardwareBufferManager = new GLHardwareBufferManager(); } else { this._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 this.gpuProgramMgr = new GLGpuProgramManager(); if (caps.HasCapability(Graphics.Capabilities.VertexPrograms)) { if (caps.IsShaderProfileSupported("arbvp1")) { this.gpuProgramMgr.RegisterProgramFactory("arbvp1", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("vp30")) { this.gpuProgramMgr.RegisterProgramFactory("vp30", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("vp40")) { this.gpuProgramMgr.RegisterProgramFactory("vp40", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("gp4vp")) { this.gpuProgramMgr.RegisterProgramFactory("gp4vp", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("gpu_vp")) { this.gpuProgramMgr.RegisterProgramFactory("gpu_vp", new ARBGpuProgramFactory()); } } if (caps.HasCapability(Graphics.Capabilities.GeometryPrograms)) { //TODO : Should these be createGLArbGpuProgram or createGLGpuNVparseProgram? if (caps.IsShaderProfileSupported("nvgp4")) { this.gpuProgramMgr.RegisterProgramFactory("nvgp4", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("gp4gp")) { this.gpuProgramMgr.RegisterProgramFactory("gp4gp", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("gpu_gp")) { this.gpuProgramMgr.RegisterProgramFactory("gpu_gp", new ARBGpuProgramFactory()); } } if (caps.HasCapability(Graphics.Capabilities.FragmentPrograms)) { if (caps.IsShaderProfileSupported("fp20")) { this.gpuProgramMgr.RegisterProgramFactory("fp20", new Nvidia.NvparseProgramFactory()); } if (caps.IsShaderProfileSupported("ps_1_4")) { this.gpuProgramMgr.RegisterProgramFactory("ps_1_4", new ATI.ATIFragmentShaderFactory()); } if (caps.IsShaderProfileSupported("ps_1_3")) { this.gpuProgramMgr.RegisterProgramFactory("ps_1_3", new ATI.ATIFragmentShaderFactory()); } if (caps.IsShaderProfileSupported("ps_1_2")) { this.gpuProgramMgr.RegisterProgramFactory("ps_1_2", new ATI.ATIFragmentShaderFactory()); } if (caps.IsShaderProfileSupported("ps_1_1")) { this.gpuProgramMgr.RegisterProgramFactory("ps_1_1", new ATI.ATIFragmentShaderFactory()); } if (caps.IsShaderProfileSupported("arbfp1")) { this.gpuProgramMgr.RegisterProgramFactory("arbfp1", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("fp40")) { this.gpuProgramMgr.RegisterProgramFactory("fp40", new ARBGpuProgramFactory()); } if (caps.IsShaderProfileSupported("fp30")) { this.gpuProgramMgr.RegisterProgramFactory("fp30", new ARBGpuProgramFactory()); } } if (caps.IsShaderProfileSupported("glsl")) { // NFZ - check for GLSL vertex and fragment shader support successful this._GLSLProgramFactory = new GLSL.GLSLProgramFactory(); HighLevelGpuProgramManager.Instance.AddFactory(this._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)"); this.rttManager = new GLFBORTTManager(this._glSupport, false); caps.SetCapability(Graphics.Capabilities.RTTSeperateDepthBuffer); //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 this.rttManager = new GLPBRTTManager(this._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 this.rttManager = new GLCopyingRTTManager(this._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(this._glSupport); this._glInitialised = true; }