public override PixelFormat GetNativeFormat(TextureType ttype, PixelFormat format, TextureUsage usage) { // Adjust requested parameters to capabilities RenderSystemCapabilities caps = Root.Instance.RenderSystem.Capabilities; // Check compressed texture support // if a compressed format not supported, revert to PF_A8R8G8B8 if (PixelUtil.IsCompressed(format) && !caps.HasCapability(Capabilities.TextureCompressionDXT)) { return(PixelFormat.A8R8G8B8); } // if floating point textures not supported, revert to PF_A8R8G8B8 if (PixelUtil.IsFloatingPoint(format) && !caps.HasCapability(Capabilities.TextureFloat)) { return(PixelFormat.A8R8G8B8); } // Check if this is a valid rendertarget format if ((usage & TextureUsage.RenderTarget) != 0) { /// Get closest supported alternative /// If mFormat is supported it's returned return(GLRTTManager.Instance.GetSupportedAlternative(format)); } // Supported return(format); }
/// <summary> /// </summary> /// <param name="ttype"> </param> /// <param name="format"> </param> /// <param name="usage"> </param> /// <returns> </returns> public override Media.PixelFormat GetNativeFormat(TextureType ttype, Media.PixelFormat format, TextureUsage usage) { // Adjust requested parameters to capabilities RenderSystemCapabilities caps = Root.Instance.RenderSystem.HardwareCapabilities; #warning check TextureCompressionVTC == RSC_TEXTURE_COMPRESSION_PVRTC // Check compressed texture support // if a compressed format not supported, revert to A8R8G8B8 if (PixelUtil.IsCompressed(format) && !caps.HasCapability(Capabilities.TextureCompressionDXT) && !caps.HasCapability(Capabilities.TextureCompressionVTC)) { return(Media.PixelFormat.A8R8G8B8); } // if floating point textures not supported, revert to A8R8G8B8 if (PixelUtil.IsFloatingPoint(format) && !caps.HasCapability(Capabilities.TextureFloat)) { return(Media.PixelFormat.A8R8G8B8); } // Check if this is a valid rendertarget format if ((usage & TextureUsage.RenderTarget) != 0) { /// Get closest supported alternative /// If format is supported it's returned return(GLESRTTManager.Instance.GetSupportedAlternative(format)); } // Supported return(format); }
public override void CreateScene() { // Check capabilities RenderSystemCapabilities caps = Root.Singleton.RenderSystem.Capabilities; if (!caps.HasCapability(Mogre.Capabilities.RSC_VERTEX_PROGRAM) || !(caps.HasCapability(Mogre.Capabilities.RSC_FRAGMENT_PROGRAM))) { MessageBox.Show("Your card does not support vertex and fragment programs, so cannot run this demo. Sorry! CelShading::createScene"); } // Create a point light Light l = sceneMgr.CreateLight("MainLight"); // Accept default settings: point light, white diffuse, just set position // Add light to the scene node rootNode = sceneMgr.RootSceneNode.CreateChildSceneNode(); rootNode.CreateChildSceneNode(new Vector3(20, 40, 50)).AttachObject(l); Entity ent = sceneMgr.CreateEntity("head", "ogrehead.mesh"); camera.Position = new Vector3(20, 0, 100); camera.LookAt(new Vector3(0, 0, 0)); // Set common material, but define custom parameters to change colours // See Example-Advanced.material for how these are finally bound to GPU parameters SubEntity sub; // eyes sub = ent.GetSubEntity(0); sub.SetMaterialName("Examples/CelShading"); sub.SetCustomParameter(CUSTOM_SHININESS, new Vector4(35.0f, 0.0f, 0.0f, 0.0f)); sub.SetCustomParameter(CUSTOM_DIFFUSE, new Vector4(1.0f, 0.3f, 0.3f, 1.0f)); sub.SetCustomParameter(CUSTOM_SPECULAR, new Vector4(1.0f, 0.6f, 0.6f, 1.0f)); // skin sub = ent.GetSubEntity(1); sub.SetMaterialName("Examples/CelShading"); sub.SetCustomParameter(CUSTOM_SHININESS, new Vector4(10.0f, 0.0f, 0.0f, 0.0f)); sub.SetCustomParameter(CUSTOM_DIFFUSE, new Vector4(0.0f, 0.5f, 0.0f, 1.0f)); sub.SetCustomParameter(CUSTOM_SPECULAR, new Vector4(0.3f, 0.5f, 0.3f, 1.0f)); // earring sub = ent.GetSubEntity(2); sub.SetMaterialName("Examples/CelShading"); sub.SetCustomParameter(CUSTOM_SHININESS, new Vector4(25.0f, 0.0f, 0.0f, 0.0f)); sub.SetCustomParameter(CUSTOM_DIFFUSE, new Vector4(1.0f, 1.0f, 0.0f, 1.0f)); sub.SetCustomParameter(CUSTOM_SPECULAR, new Vector4(1.0f, 1.0f, 0.7f, 1.0f)); // teeth sub = ent.GetSubEntity(3); sub.SetMaterialName("Examples/CelShading"); sub.SetCustomParameter(CUSTOM_SHININESS, new Vector4(20.0f, 0.0f, 0.0f, 0.0f)); sub.SetCustomParameter(CUSTOM_DIFFUSE, new Vector4(1.0f, 1.0f, 0.7f, 1.0f)); sub.SetCustomParameter(CUSTOM_SPECULAR, new Vector4(1.0f, 1.0f, 1.0f, 1.0f)); // Add entity to the root scene node sceneMgr.RootSceneNode.CreateChildSceneNode().AttachObject(ent); window.GetViewport(0).BackgroundColour = (Mogre.ColourValue.White); }
public override void TestCapabilities(RenderSystemCapabilities capabilities) { if (!capabilities.HasCapability(Capabilities.VertexPrograms) || !capabilities.HasCapability(Capabilities.FragmentPrograms)) { throw new AxiomException( "Your graphics card does not support vertex or fragment shaders, so you cannot run this sample. Sorry!"); } }
/// <summary> /// /// </summary> /// <param name="capabilities"></param> public override void TestCapabilities( RenderSystemCapabilities capabilities ) { if ( !capabilities.HasCapability( Capabilities.Texture3D ) ) { throw new AxiomException( "Your card does not support 3D textures, so cannot run this demo. Sorry!" ); } }
/// <summary> /// /// </summary> /// <param name="capabilities"></param> public override void TestCapabilities(RenderSystemCapabilities capabilities) { if (!capabilities.HasCapability(Capabilities.Texture3D)) { throw new AxiomException("Your card does not support 3D textures, so cannot run this demo. Sorry!"); } }
protected override void TestCapabilities(RenderSystemCapabilities caps) { if (!caps.HasCapability(Capabilities.RSC_CUBEMAPPING)) { throw new InvalidOperationException("Your graphics card does not support cube mapping, so you cannot run this sample. Sorry!"); } }
/// <summary> /// Returns next power-of-two size if required by render system, in case /// RSC_NON_POWER_OF_2_TEXTURES is supported it returns value as-is. /// </summary> /// <param name="value"></param> /// <returns></returns> public static int OptionalPO2(int value) { RenderSystemCapabilities caps = Root.Instance.RenderSystem.Capabilities; if (caps.HasCapability(Capabilities.NonPowerOf2Textures)) { return(value); } else { return((int)Bitwise.FirstPO2From((uint)value)); } }
/// <summary> /// /// </summary> /// <param name="geom"></param> public override void Init(PagedGeometry geom) { mSceneMgr = geom.SceneManager; mBatch = new BatchedGeometry(mSceneMgr, geom.SceneNode); mFadeEnabled = false; RenderSystemCapabilities caps = Root.Singleton.RenderSystem.Capabilities; if (caps.HasCapability(Capabilities.VertexPrograms)) { mShadersSupported = true; } else { mShadersSupported = false; } ++mRefCount; }
/// <summary> /// Returns next power-of-two size if required by render system, in case RSC_NON_POWER_OF_2_TEXTURES is supported it returns value as-is. /// </summary> /// <param name="value"> </param> /// <returns> </returns> public static int OptionalPO2(int value) { RenderSystemCapabilities caps = Root.Instance.RenderSystem.HardwareCapabilities; if (caps.HasCapability(Capabilities.NonPowerOf2Textures)) { return(value); } else { var n = (uint)value; --n; n |= n >> 16; n |= n >> 8; n |= n >> 4; n |= n >> 2; n |= n >> 1; ++n; return((int)n); } }
/// <summary> /// /// </summary> internal void UpdateShaders() { if (mShaderNeedsUpdate) { mShaderNeedsUpdate = false; //Proceed only if there is no custom vertex shader and the user's computer supports vertex shaders RenderSystemCapabilities caps = Root.Singleton.RenderSystem.Capabilities; if (caps.HasCapability(Capabilities.VertexPrograms)) { //Generate a string ID that identifies the current set of vertex shader options string tmpName = string.Empty; tmpName += "GrassVS_"; if (mAnimate) { tmpName += "anim_"; } if (mBlend) { tmpName += "blend_"; } tmpName += mRenderTechnique.ToString() + "_"; tmpName += mFadeTechnique.ToString() + "_"; if (mFadeTechnique == FadeTechnique.Grow || mFadeTechnique == FadeTechnique.AlphaGrow) { tmpName += mMaxHeight + "_"; } tmpName += "vp"; string vsName = tmpName; //Generate a string ID that identifies the material combined with the vertex shader string matName = mMaterial.Name + "_" + vsName; //Check if the desired material already exists (if not, create it) Material tmpMat = (Material)MaterialManager.Instance.GetByName(matName); if (tmpMat == null) { //Clone the original material tmpMat = mMaterial.Clone(matName); //Disable lighting tmpMat.Lighting = false; //Check if the desired shader already exists (if not, compile it) HighLevelGpuProgram vertexShader = (HighLevelGpuProgram)HighLevelGpuProgramManager.Instance.GetByName(vsName); if (vertexShader == null) { //Generate the grass shader string vertexProgSource = string.Empty; vertexProgSource += "void main( \n" + " float4 iPosition : POSITION, \n"+ " float4 iColor : COLOR, \n"+ " float2 iUV : TEXCOORD0, \n"+ " out float4 oPosition : POSITION, \n"+ " out float4 oColor : COLOR, \n"+ " out float2 oUV : TEXCOORD0, \n"; if (mAnimate) { vertexProgSource += " uniform float time, \n"+ " uniform float frequency, \n"+ " uniform float4 direction, \n"; } if (mFadeTechnique == FadeTechnique.Grow || mFadeTechnique == FadeTechnique.AlphaGrow) { vertexProgSource += " uniform float grassHeight, \n"; } if (mRenderTechnique == GrassTechnique.Sprite) { vertexProgSource += " float4 iNormal : NORMAL, \n"; } vertexProgSource += " uniform float4x4 worldViewProj, \n"+ " uniform float3 camPos, \n"+ " uniform float fadeRange ) \n"+ "{ \n"+ " oColor.rgb = iColor.rgb; \n"+ " float4 position = iPosition; \n"+ " float dist = distance(camPos.xz, position.xz); \n"; if (mFadeTechnique == FadeTechnique.Alpha || mFadeTechnique == FadeTechnique.AlphaGrow) { vertexProgSource += //Fade out in the distance " oColor.a = 2.0f - (2.0f * dist / fadeRange); \n"; } else { vertexProgSource += " oColor.a = 1.0f; \n"; } vertexProgSource += " float oldposx = position.x; \n"; if (mRenderTechnique == GrassTechnique.Sprite) { vertexProgSource += //Face the camera " float3 dirVec = (float3)position - (float3)camPos; \n"+ " float3 p = normalize(cross(float4(0,1,0,0), dirVec)); \n"+ " position += float4(p.x * iNormal.x, iNormal.y, p.z * iNormal.x, 0); \n"; } if (mAnimate) { vertexProgSource += " if (iUV.y == 0.0f){ \n"+ //Wave grass in breeze " float offset = sin(time + oldposx * frequency); \n"+ " position += direction * offset; \n"+ " } \n"; } if (mBlend && mAnimate) { vertexProgSource += " else { \n"; } else if (mBlend) { vertexProgSource += " if (iUV.y != 0.0f){ \n"; } if (mBlend) { vertexProgSource += //Blend the base of nearby grass into the terrain " if (oColor.a >= 1.0f) \n"+ " oColor.a = 4.0f * ((dist / fadeRange) - 0.1f); \n"+ " } \n"; } if (mFadeTechnique == FadeTechnique.Grow || mFadeTechnique == FadeTechnique.AlphaGrow) { vertexProgSource += " float offset = (2.0f * dist / fadeRange) - 1.0f; \n"+ " position.y -= grassHeight * clamp(offset, 0, 1); "; } vertexProgSource += " oPosition = mul(worldViewProj, position); \n"; vertexProgSource += " oUV = iUV;\n"+ "}"; vertexShader = HighLevelGpuProgramManager.Instance.CreateProgram( vsName, ResourceGroupManager.DefaultResourceGroupName, "cg", GpuProgramType.Vertex); vertexShader.Source = vertexProgSource; vertexShader.SetParam("profiles", "vs_1_1 arbvp1"); vertexShader.SetParam("entry_point", "main"); vertexShader.Load(); } //Now the vertex shader (vertexShader) has either been found or just generated //(depending on whether or not it was already generated). //Apply the shader to the material Pass pass = tmpMat.GetTechnique(0).GetPass(0); pass.VertexProgramName = vsName; GpuProgramParameters gparams = pass.VertexProgramParameters; gparams.SetNamedAutoConstant("worldViewProj", GpuProgramParameters.AutoConstantType.WorldViewProjMatrix, 0); gparams.SetNamedAutoConstant("camPos", GpuProgramParameters.AutoConstantType.CameraPositionObjectSpace, 0); gparams.SetNamedAutoConstant("fadeRange", GpuProgramParameters.AutoConstantType.Custom, 1); if (mAnimate) { gparams.SetNamedAutoConstant("time", GpuProgramParameters.AutoConstantType.Custom, 1); gparams.SetNamedAutoConstant("frequency", GpuProgramParameters.AutoConstantType.Custom, 1); gparams.SetNamedAutoConstant("direction", GpuProgramParameters.AutoConstantType.Custom, 4); } if (mFadeTechnique == FadeTechnique.Grow || mFadeTechnique == FadeTechnique.AlphaGrow) { gparams.SetNamedAutoConstant("grassHeight", GpuProgramParameters.AutoConstantType.Custom, 1); gparams.SetNamedConstant("grassHeight", mMaxHeight * 1.05f); } float farViewDist = mGeom.DetailLevels[0].FarRange; pass.VertexProgramParameters.SetNamedConstant("fadeRange", farViewDist / 1.225f); //Note: 1.225 ~= sqrt(1.5), which is necessary since the far view distance is measured from the centers //of pages, while the vertex shader needs to fade grass completely out (including the closest corner) //before the page center is out of range. } //Now the material (tmpMat) has either been found or just created (depending on whether or not it was already //created). The appropriate vertex shader should be applied and the material is ready for use. //Apply the new material mMaterial = tmpMat; } } }
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 void TestCapabilities( RenderSystemCapabilities capabilities ) { if ( !capabilities.HasCapability( Capabilities.VertexPrograms ) || !capabilities.HasCapability( Capabilities.FragmentPrograms ) ) { throw new AxiomException( "Your graphics card does not support vertex or fragment shaders, so you cannot run this sample. Sorry!" ); } }
/// <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; }
public override void CreateScene() { //init spline array for (int i = 0; i < NUM_FISH; i++) { fishSplines[i] = new SimpleSpline(); } // Check prerequisites first RenderSystemCapabilities caps = Root.Singleton.RenderSystem.Capabilities; if (!caps.HasCapability(Capabilities.RSC_VERTEX_PROGRAM) || !(caps.HasCapability(Capabilities.RSC_FRAGMENT_PROGRAM))) { throw new System.Exception("Your card does not support vertex and fragment programs, so cannot run this demo. Sorry!"); } else { if (!GpuProgramManager.Singleton.IsSyntaxSupported("arbfp1") && !GpuProgramManager.Singleton.IsSyntaxSupported("ps_2_0") && !GpuProgramManager.Singleton.IsSyntaxSupported("ps_1_4") ) { throw new System.Exception("Your card does not support advanced fragment programs, so cannot run this demo. Sorry!"); } } camera.SetPosition(-50, 125, 760); camera.SetDirection(0, 0, -1); // Set ambient light sceneMgr.AmbientLight = new ColourValue(0.5f, 0.5f, 0.5f); // Create a point light Light l = sceneMgr.CreateLight("MainLight"); l.Type = Light.LightTypes.LT_DIRECTIONAL; l.Direction = -Vector3.UNIT_Y; Entity pEnt; TexturePtr mTexture = TextureManager.Singleton.CreateManual("Refraction", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, TextureType.TEX_TYPE_2D, 512, 512, 0, PixelFormat.PF_R8G8B8, (int)TextureUsage.TU_RENDERTARGET); //RenderTexture* rttTex = mRoot.getRenderSystem().createRenderTexture( "Refraction", 512, 512 ); RenderTarget rttTex = mTexture.GetBuffer().GetRenderTarget(); { Viewport v = rttTex.AddViewport(camera); MaterialPtr mat = MaterialManager.Singleton.GetByName("Examples/FresnelReflectionRefraction"); mat.GetTechnique(0).GetPass(0).GetTextureUnitState(2).SetTextureName("Refraction"); v.OverlaysEnabled = false; rttTex.PreRenderTargetUpdate += new RenderTargetListener.PreRenderTargetUpdateHandler(Refraction_PreRenderTargetUpdate); rttTex.PostRenderTargetUpdate += new RenderTargetListener.PostRenderTargetUpdateHandler(Refraction_PostRenderTargetUpdate); } mTexture = TextureManager.Singleton.CreateManual("Reflection", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, TextureType.TEX_TYPE_2D, 512, 512, 0, PixelFormat.PF_R8G8B8, (int)TextureUsage.TU_RENDERTARGET); //rttTex = mRoot.getRenderSystem().createRenderTexture( "Reflection", 512, 512 ); rttTex = mTexture.GetBuffer().GetRenderTarget(); { Viewport v = rttTex.AddViewport(camera); MaterialPtr mat = MaterialManager.Singleton.GetByName("Examples/FresnelReflectionRefraction"); mat.GetTechnique(0).GetPass(0).GetTextureUnitState(1).SetTextureName("Reflection"); v.OverlaysEnabled = false; rttTex.PreRenderTargetUpdate += new RenderTargetListener.PreRenderTargetUpdateHandler(Reflection_PreRenderTargetUpdate); rttTex.PostRenderTargetUpdate += new RenderTargetListener.PostRenderTargetUpdateHandler(Reflection_PostRenderTargetUpdate); } // Define a floor plane mesh reflectionPlane.normal = Vector3.UNIT_Y; reflectionPlane.d = 0; MeshManager.Singleton.CreatePlane("ReflectPlane", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, reflectionPlane, 1500, 1500, 10, 10, true, 1, 5, 5, Vector3.UNIT_Z); pPlaneEnt = sceneMgr.CreateEntity("plane", "ReflectPlane"); pPlaneEnt.SetMaterialName("Examples/FresnelReflectionRefraction"); sceneMgr.RootSceneNode.CreateChildSceneNode().AttachObject(pPlaneEnt); sceneMgr.SetSkyBox(true, "Examples/CloudyNoonSkyBox"); // My node to which all objects will be attached SceneNode myRootNode = sceneMgr.RootSceneNode.CreateChildSceneNode(); // above water entities pEnt = sceneMgr.CreateEntity("RomanBathUpper", "RomanBathUpper.mesh"); myRootNode.AttachObject(pEnt); aboveWaterEnts.Add(pEnt); pEnt = sceneMgr.CreateEntity("Columns", "Columns.mesh"); myRootNode.AttachObject(pEnt); aboveWaterEnts.Add(pEnt); SceneNode headNode = myRootNode.CreateChildSceneNode(); pEnt = sceneMgr.CreateEntity("OgreHead", "ogrehead.mesh"); pEnt.SetMaterialName("RomanBath/OgreStone"); headNode.AttachObject(pEnt); headNode.SetPosition(-350, 55, 130); headNode.Rotate(Vector3.UNIT_Y, new Degree(90)); aboveWaterEnts.Add(pEnt); // below water entities pEnt = sceneMgr.CreateEntity("RomanBathLower", "RomanBathLower.mesh"); myRootNode.AttachObject(pEnt); belowWaterEnts.Add(pEnt); for (int fishNo = 0; fishNo < NUM_FISH; ++fishNo) { pEnt = sceneMgr.CreateEntity("fish" + fishNo, "fish.mesh"); fishNodes[fishNo] = myRootNode.CreateChildSceneNode(); fishAnimations[fishNo] = pEnt.GetAnimationState("swim"); fishAnimations[fishNo].Enabled = true; fishNodes[fishNo].AttachObject(pEnt); belowWaterEnts.Add(pEnt); // Generate a random selection of points for the fish to swim to fishSplines[fishNo].SetAutoCalculate(false); Vector3 lastPos = new Vector3(); for (int waypoint = 0; waypoint < NUM_FISH_WAYPOINTS; ++waypoint) { Vector3 pos = new Vector3( Mogre.Math.SymmetricRandom() * 270, -10, Mogre.Math.SymmetricRandom() * 700); if (waypoint > 0) { // check this waypoint isn't too far, we don't want turbo-fish ;) // since the waypoints are achieved every 5 seconds, half the length // of the pond is ok while ((lastPos - pos).Length > 750) { pos = new Vector3( Mogre.Math.SymmetricRandom() * 270, -10, Mogre.Math.SymmetricRandom() * 700); } } fishSplines[fishNo].AddPoint(pos); lastPos = pos; } // close the spline fishSplines[fishNo].AddPoint(fishSplines[fishNo].GetPoint(0)); // recalc fishSplines[fishNo].RecalcTangents(); } }
/// <summary> /// /// </summary> /// <param name="mgr"></param> /// <param name="rootSceneNode"></param> /// <param name="method"></param> public StaticBillboardSet(SceneManager mgr, SceneNode rootSceneNode, BillboardMethod method) { mSceneMgr = mgr; mRenderMethod = method; mVisible = true; mFadeEnabled = false; mBBOrigin = BillboardOrigin.Center; //Fall back to Compatible if vertex shaders are not available if (mRenderMethod == BillboardMethod.Accelerated) { RenderSystemCapabilities caps = Root.Singleton.RenderSystem.Capabilities; if (!caps.HasCapability(Capabilities.VertexPrograms)) { mRenderMethod = BillboardMethod.Compatible; } } mNode = rootSceneNode.CreateChildSceneNode(); mEntityName = GetUniqueID("SBSEntity"); if (mRenderMethod == BillboardMethod.Accelerated) { //Accelerated billboard method mEntity = null; mUFactor = 1.0f; mVFactor = 1.0f; //Load vertex shader to align billboards to face the camera (if not loaded already) if (++mSelfInstances == 1) { //First shader, simple camera-alignment HighLevelGpuProgram vertexShader = (HighLevelGpuProgram)HighLevelGpuProgramManager.Instance.GetByName("Sprite_vp"); if (vertexShader == null) { string vertexProg = string.Empty; vertexProg = "void Sprite_vp( \n"+ " float4 position : POSITION, \n"+ " float3 normal : NORMAL, \n"+ " float4 color : COLOR, \n"+ " float2 uv : TEXCOORD0, \n"+ " out float4 oPosition : POSITION, \n"+ " out float2 oUv : TEXCOORD0, \n"+ " out float4 oColor : COLOR, \n"+ " out float4 oFog : FOG, \n"+ " uniform float4x4 worldViewProj, \n"+ " uniform float uScroll, \n"+ " uniform float vScroll, \n"+ " uniform float4 preRotatedQuad[4] ) \n"+ "{ \n"+ //Face the camera " float4 vCenter = float4( position.x, position.y, position.z, 1.0f ); \n"+ " float4 vScale = float4( normal.x, normal.y, normal.x, 1.0f ); \n"+ " oPosition = mul( worldViewProj, vCenter + (preRotatedQuad[normal.z] * vScale) ); \n"+ //Color " oColor = color; \n"+ //UV Scroll " oUv = uv; \n"+ " oUv.x += uScroll; \n"+ " oUv.y += vScroll; \n"+ //Fog " oFog.x = oPosition.z; \n"+ "}"; vertexShader = HighLevelGpuProgramManager.Instance.CreateProgram( "Sprite_vp", ResourceGroupManager.DefaultResourceGroupName, "cg", GpuProgramType.Vertex); vertexShader.Source = vertexProg; vertexShader.SetParam("profiles", "vs_1_1 arbvp1"); vertexShader.SetParam("entry_point", "Sprite_vp"); vertexShader.Load(); } //Second shader, camera alignment and distance based fading HighLevelGpuProgram vertexShader2 = (HighLevelGpuProgram)HighLevelGpuProgramManager.Instance.GetByName("SpriteFade_vp"); if (vertexShader2 == null) { string vertexProg2 = string.Empty; vertexProg2 = "void SpriteFade_vp( \n"+ " float4 position : POSITION, \n"+ " float3 normal : NORMAL, \n"+ " float4 color : COLOR, \n"+ " float2 uv : TEXCOORD0, \n"+ " out float4 oPosition : POSITION, \n"+ " out float2 oUv : TEXCOORD0, \n"+ " out float4 oColor : COLOR, \n"+ " out float4 oFog : FOG, \n"+ " uniform float4x4 worldViewProj, \n"+ " uniform float3 camPos, \n"+ " uniform float fadeGap, \n"+ " uniform float invisibleDist, \n" + " uniform float uScroll, \n"+ " uniform float vScroll, \n"+ " uniform float4 preRotatedQuad[4] ) \n"+ "{ \n"+ //Face the camera " float4 vCenter = float4( position.x, position.y, position.z, 1.0f ); \n"+ " float4 vScale = float4( normal.x, normal.y, normal.x, 1.0f ); \n"+ " oPosition = mul( worldViewProj, vCenter + (preRotatedQuad[normal.z] * vScale) ); \n"+ " oColor.rgb = color.rgb; \n"+ //Fade out in the distance " float dist = distance(camPos.xz, position.xz); \n"+ " oColor.a = (invisibleDist - dist) / fadeGap; \n"+ //UV scroll " oUv = uv; \n"+ " oUv.x += uScroll; \n"+ " oUv.y += vScroll; \n"+ //Fog " oFog.x = oPosition.z; \n"+ "}"; vertexShader2 = HighLevelGpuProgramManager.Instance.CreateProgram( "SpriteFade_vp", ResourceGroupManager.DefaultResourceGroupName, "cg", GpuProgramType.Vertex); vertexShader2.Source = vertexProg2; vertexShader2.SetParam("profiles", "vs_1_1 arbvp1"); vertexShader2.SetParam("entry_point", "SpriteFade_vp"); vertexShader2.Load(); } } } else { //Compatible billboard method mFallbackSet = mSceneMgr.CreateBillboardSet(GetUniqueID("SBS"), 100); mNode.AttachObject(mFallbackSet); } }