Exemple #1
0
 public ShaderProgramInfo GetProgramInfo(Shader vertexShader, Shader pixelShader)
 {
   int key = vertexShader.HashKey | pixelShader.HashKey;
   if (!this._programCache.ContainsKey(key))
     this.Link(vertexShader, pixelShader);
   return this._programCache[key];
 }
Exemple #2
0
        internal EffectPass(    Effect effect, 
                                string name,
                                Shader vertexShader, 
                                Shader pixelShader, 
                                BlendState blendState, 
                                DepthStencilState depthStencilState, 
                                RasterizerState rasterizerState,
                                EffectAnnotationCollection annotations )
        {
            Debug.Assert(effect != null, "Got a null effect!");
            Debug.Assert(annotations != null, "Got a null annotation collection!");

            _effect = effect;

            Name = name;

            _vertexShader = vertexShader;
            _pixelShader = pixelShader;

            _blendState = blendState;
            _depthStencilState = depthStencilState;
            _rasterizerState = rasterizerState;

            Annotations = annotations;
        }
Exemple #3
0
 internal void Apply(Shader shader, IntPtr offset)
 {
   int hashCode = shader.GetHashCode();
   VertexDeclaration.VertexDeclarationAttributeInfo declarationAttributeInfo;
   if (!this.shaderAttributeInfo.TryGetValue(hashCode, out declarationAttributeInfo))
   {
     declarationAttributeInfo = new VertexDeclaration.VertexDeclarationAttributeInfo(this.GraphicsDevice.MaxVertexAttributes);
     foreach (VertexElement element in this._elements)
     {
       int attribLocation = shader.GetAttribLocation(element.VertexElementUsage, element.UsageIndex);
       if (attribLocation >= 0)
       {
         declarationAttributeInfo.Elements.Add(new VertexDeclaration.VertexDeclarationAttributeInfo.Element()
         {
           Offset = element.Offset,
           AttributeLocation = attribLocation,
           NumberOfElements = GraphicsExtensions.OpenGLNumberOfElements(element.VertexElementFormat),
           VertexAttribPointerType = GraphicsExtensions.OpenGLVertexAttribPointerType(element.VertexElementFormat),
           Normalized = GraphicsExtensions.OpenGLVertexAttribNormalized(element)
         });
         declarationAttributeInfo.EnabledAttributes[attribLocation] = true;
       }
     }
     this.shaderAttributeInfo.Add(hashCode, declarationAttributeInfo);
   }
   foreach (VertexDeclaration.VertexDeclarationAttributeInfo.Element element in declarationAttributeInfo.Elements)
     GL.VertexAttribPointer(element.AttributeLocation, element.NumberOfElements, element.VertexAttribPointerType, element.Normalized, this.VertexStride, (IntPtr) (offset.ToInt64() + (long) element.Offset));
   this.GraphicsDevice.SetVertexAttributeArray(declarationAttributeInfo.EnabledAttributes);
 }
        private void Link(Shader vertexShader, Shader pixelShader)
        {
            // NOTE: No need to worry about background threads here
            // as this is only called at draw time when we're in the
            // main drawing thread.
            var program = GL.CreateProgram();
            GraphicsExtensions.CheckGLError();

            GL.AttachShader(program, vertexShader.GetShaderHandle());
            GraphicsExtensions.CheckGLError();

            GL.AttachShader(program, pixelShader.GetShaderHandle());
            GraphicsExtensions.CheckGLError();

            //vertexShader.BindVertexAttributes(program);

            GL.LinkProgram(program);
            GraphicsExtensions.CheckGLError();

            GL.UseProgram(program);
            GraphicsExtensions.CheckGLError();

            vertexShader.GetVertexAttributeLocations(program);

            pixelShader.ApplySamplerTextureUnits(program);

            var linked = 0;

#if GLES
			GL.GetProgram(program, ProgramParameter.LinkStatus, ref linked);
#else
            GL.GetProgram(program, ProgramParameter.LinkStatus, out linked);
#endif
            GraphicsExtensions.LogGLError("VertexShaderCache.Link(), GL.GetProgram");
            if (linked == 0)
            {
#if !GLES
                var log = GL.GetProgramInfoLog(program);
                Console.WriteLine(log);
#endif
                GL.DetachShader(program, vertexShader.GetShaderHandle());
                GL.DetachShader(program, pixelShader.GetShaderHandle());
#if MONOMAC
                GL.DeleteProgram(1, ref program);
#else
                GL.DeleteProgram(program);
#endif
                throw new InvalidOperationException("Unable to link effect program");
            }

            ShaderProgramInfo info;
            info.program = program;
            info.posFixupLoc = GL.GetUniformLocation(program, "posFixup");

            _programCache.Add(vertexShader.HashKey | pixelShader.HashKey, info);             
        }
        private static void SetShaderSamplers(this EffectPass pass, EffectPassProperties props, Shader shader, TextureCollection textures, SamplerStateCollection samplerStates)
        {
            foreach (var sampler in shader.Samplers)
            {
                var param = props.Effect.Parameters[sampler.parameter];
                var texture = param.Data as Texture;

                textures[sampler.textureSlot] = texture;

                // If there is a sampler state set it.
                if (sampler.state != null)
                    samplerStates[sampler.samplerSlot] = sampler.state;
            }
        }
        public ShaderProgram GetProgram(Shader vertexShader, Shader pixelShader)
        {
            // TODO: We should be hashing in the mix of constant 
            // buffers here as well.  This would allow us to optimize
            // setting uniforms to only when a constant buffer changes.

            var key = vertexShader.HashKey | pixelShader.HashKey;
            if (!_programCache.ContainsKey(key))
            {
                // the key does not exist so we need to link the programs
                Link(vertexShader, pixelShader);
            }

            return _programCache[key];
        }        
        internal EffectPass(Effect effect, EffectPass cloneSource)
        {
            Debug.Assert(effect != null, "Got a null effect!");
            Debug.Assert(cloneSource != null, "Got a null cloneSource!");

            _effect = effect;

            // Share all the immutable types.
            Name = cloneSource.Name;
            _blendState = cloneSource._blendState;
            _depthStencilState = cloneSource._depthStencilState;
            _rasterizerState = cloneSource._rasterizerState;
            Annotations = cloneSource.Annotations;
            _vertexShader = cloneSource._vertexShader;
            _pixelShader = cloneSource._pixelShader;
        }
		internal void Apply(Shader shader, IntPtr offset)
		{
            VertexDeclarationAttributeInfo attrInfo;
            int shaderHash = shader.GetHashCode();
            if (!shaderAttributeInfo.TryGetValue(shaderHash, out attrInfo))
            {
                // Get the vertex attribute info and cache it
                attrInfo = new VertexDeclarationAttributeInfo(GraphicsDevice.MaxVertexAttributes);

                foreach (var ve in _elements)
                {
                    var attributeLocation = shader.GetAttribLocation(ve.VertexElementUsage, ve.UsageIndex);
                    // XNA appears to ignore usages it can't find a match for, so we will do the same
                    if (attributeLocation >= 0)
                    {
                        attrInfo.Elements.Add(new VertexDeclarationAttributeInfo.Element()
                        {
                            Offset = ve.Offset,
                            AttributeLocation = attributeLocation,
                            NumberOfElements = ve.VertexElementFormat.OpenGLNumberOfElements(),
                            VertexAttribPointerType = ve.VertexElementFormat.OpenGLVertexAttribPointerType(),
                            Normalized = ve.OpenGLVertexAttribNormalized(),
                        });
                        attrInfo.EnabledAttributes[attributeLocation] = true;
                    }
                }

                shaderAttributeInfo.Add(shaderHash, attrInfo);
            }

            // Apply the vertex attribute info
            foreach (var element in attrInfo.Elements)
            {
                GL.VertexAttribPointer(element.AttributeLocation,
                    element.NumberOfElements,
                    element.VertexAttribPointerType,
                    element.Normalized,
                    this.VertexStride,
                    (IntPtr)(offset.ToInt64() + element.Offset));
                GraphicsExtensions.CheckGLError();
            }
            GraphicsDevice.SetVertexAttributeArray(attrInfo.EnabledAttributes);
		}
Exemple #9
0
 private void Link(Shader vertexShader, Shader pixelShader)
 {
   int program = GL.CreateProgram();
   GL.AttachShader(program, vertexShader.GetShaderHandle());
   GL.AttachShader(program, pixelShader.GetShaderHandle());
   GL.LinkProgram(program);
   GL.UseProgram(program);
   vertexShader.GetVertexAttributeLocations(program);
   pixelShader.ApplySamplerTextureUnits(program);
   int @params = 0;
   GL.GetProgram(program, ProgramParameter.LinkStatus, out @params);
   if (@params == 0)
   {
     Console.WriteLine(GL.GetProgramInfoLog(program));
     throw new InvalidOperationException("Unable to link effect program");
   }
   else
   {
     ShaderProgramInfo shaderProgramInfo;
     shaderProgramInfo.program = program;
     shaderProgramInfo.posFixupLoc = GL.GetUniformLocation(program, "posFixup");
     this._programCache.Add(vertexShader.HashKey | pixelShader.HashKey, shaderProgramInfo);
   }
 }
Exemple #10
0
		private void ReadEffect (BinaryReader reader)
		{
			// Check the header to make sure the file and version is correct!
			var header = new string (reader.ReadChars (MGFXHeader.Length));
			var version = (int)reader.ReadByte ();
			if (header != MGFXHeader)
				throw new Exception ("The MGFX file is corrupt!");
            if (version != MGFXVersion)
                throw new Exception("Wrong MGFX file version!");

			var profile = reader.ReadByte ();
#if DIRECTX
            if (profile != 1)
#else
			if (profile != 0)
#endif
				throw new Exception("The MGFX effect is the wrong profile for this platform!");

			// TODO: Maybe we should be reading in a string 
			// table here to save some bytes in the file.

			// Read in all the constant buffers.
			var buffers = (int)reader.ReadByte ();
			ConstantBuffers = new ConstantBuffer[buffers];
			for (var c = 0; c < buffers; c++) 
            {
				
#if OPENGL
				string name = reader.ReadString ();               
#else
				string name = null;
#endif

				// Create the backing system memory buffer.
				var sizeInBytes = (int)reader.ReadInt16 ();

				// Read the parameter index values.
				var parameters = new int[reader.ReadByte ()];
				var offsets = new int[parameters.Length];
				for (var i = 0; i < parameters.Length; i++) 
                {
					parameters [i] = (int)reader.ReadByte ();
					offsets [i] = (int)reader.ReadUInt16 ();
				}

                var buffer = new ConstantBuffer(GraphicsDevice,
				                                sizeInBytes,
				                                parameters,
				                                offsets,
				                                name);
                ConstantBuffers[c] = buffer;
            }

            // Read in all the shader objects.
            var shaders = (int)reader.ReadByte();
            _shaders = new Shader[shaders];
            for (var s = 0; s < shaders; s++)
                _shaders[s] = new Shader(GraphicsDevice, reader);

            // Read in the parameters.
            Parameters = ReadParameters(reader);

            // Read the techniques.
            var techniqueCount = (int)reader.ReadByte();
            var techniques = new EffectTechnique[techniqueCount];
            for (var t = 0; t < techniqueCount; t++)
            {
                var name = reader.ReadString();

                var annotations = ReadAnnotations(reader);

                var passes = ReadPasses(reader, this, _shaders);

                techniques[t] = new EffectTechnique(this, name, passes, annotations);
            }

            Techniques = new EffectTechniqueCollection(techniques);
            CurrentTechnique = Techniques[0];
        }
Exemple #11
0
        private void SetShaderSamplers(Shader shader, TextureCollection textures, SamplerStateCollection samplerStates)
        {
            foreach (var sampler in shader.Samplers)
            {
                var param = _effect.Parameters[sampler.parameter];
                var texture = param.Data as Texture;

                textures[sampler.textureSlot] = texture;

                // If there is a sampler state set it.
                if (sampler.state != null)
                    samplerStates[sampler.samplerSlot] = sampler.state;
            }
        }
Exemple #12
0
        internal void Apply(Shader shader, IntPtr offset, int divisor = 0)
        {
            List<Element> attrInfo;
            int shaderHash = shader.GetHashCode();
            if (!shaderAttributeInfo.TryGetValue(shaderHash, out attrInfo))
            {
                // Get the vertex attribute info and cache it
                attrInfo = new List<Element>(16); // 16, per XNA4 HiDef spec

                foreach (VertexElement ve in elements)
                {
                    int attributeLocation = shader.GetAttribLocation(ve.VertexElementUsage, ve.UsageIndex);

                    // XNA appears to ignore usages it can't find a match for, so we will do the same
                    if (attributeLocation >= 0)
                    {
                        attrInfo.Add(new Element()
                        {
                            Offset = ve.Offset,
                            AttributeLocation = attributeLocation,
                            NumberOfElements = GetNumberOfElements(ve.VertexElementFormat),
                            VertexAttribPointerType = ve.VertexElementFormat,
                            Normalized = GetVertexAttribNormalized(ve),
                        });
                    }
                }

                shaderAttributeInfo.Add(shaderHash, attrInfo);
            }

            // Apply the vertex attribute info
            foreach (Element element in attrInfo)
            {
                GraphicsDevice.GLDevice.AttributeEnabled[element.AttributeLocation] = true;
                GraphicsDevice.GLDevice.Attributes[element.AttributeLocation].Divisor = divisor;
                GraphicsDevice.GLDevice.VertexAttribPointer(
                    element.AttributeLocation,
                    element.NumberOfElements,
                    element.VertexAttribPointerType,
                    element.Normalized,
                    VertexStride,
                    (IntPtr) (offset.ToInt64() + element.Offset)
                );
            }
        }
		internal void Apply(Shader shader, IntPtr offset)
		{
            throw new NotImplementedException();
		}
Exemple #14
0
        private void RenderFaceWP7(Face face, Shader shader, BasicEffect shaderEffect, GraphicsDevice device, GameTime time)
        {
            foreach (ShaderLayer layer in shader.Layers)
            {
                shaderEffect.Texture = (Texture2D)layer.pTexture.TextureId;

                float[,] tcBackup = null;

                if (layer.TextureCoordModification != ShaderTcMod.None)
                {
                    if ((layer.TextureCoordModification & ShaderTcMod.Rotate) > 0)
                    {
                        float angle = MathHelper.ToRadians((float)(layer.TextureCoordRotateAnglePerSecond * ThW.Utils.Timer.Time));

                        Matrix4x4 tc = Matrix4x4.Rotate(new ThW.Utils.Vector3(0.0f, 0.0f, 1.0f), angle);

                        if (null != tcBackup)
                        {
                            tcBackup = new float[2, face.Vertexes.Length];

                            for (int i = 0; i < face.Vertexes.Length; i++)
                            {
                                tcBackup[0, i] = face.Vertexes[i].TexS;
                                tcBackup[1, i] = face.Vertexes[i].TexT;
                            }
                        }

                        for (int i = 0; i < face.Vertexes.Length; i++)
                        {
                            float[] v1 = new float[4];
                            v1[0] = face.Vertexes[i].TexS - 0.5f;
                            v1[1] = face.Vertexes[i].TexT - 0.5f;
                            v1[2] = 0.0f;
                            v1[3] = 1.0f;

                            v1 = tc * v1;

                            face.Vertexes[i].TexS = v1[0] + 0.5f;
                            face.Vertexes[i].TexT = v1[1] + 0.5f;
                        }
                    }
                }

                foreach (EffectPass pass in shaderEffect.CurrentTechnique.Passes)
                {
                    pass.Apply();

                    device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, face.Vertexes, 0, face.NumVertexes, face.Indices, 0, face.Indices.Length / 3, this.vertexShaderDeclaration);
                }

                if (null != tcBackup)
                {
                    for (int i = 0; i < face.Vertexes.Length; i++)
                    {
                        face.Vertexes[i].TexS = tcBackup[0, i];
                        face.Vertexes[i].TexT = tcBackup[1, i];
                    }
                }
            }
        }
Exemple #15
0
		private void ReadEffect (BinaryReader reader)
		{
			// TODO: Maybe we should be reading in a string 
			// table here to save some bytes in the file.

			// Read in all the constant buffers.
			var buffers = (int)reader.ReadByte ();
			ConstantBuffers = new ConstantBuffer[buffers];
			for (var c = 0; c < buffers; c++) 
            {
				
#if OPENGL
				string name = reader.ReadString ();               
#else
				string name = null;
#endif

				// Create the backing system memory buffer.
				var sizeInBytes = (int)reader.ReadInt16 ();

				// Read the parameter index values.
				var parameters = new int[reader.ReadByte ()];
				var offsets = new int[parameters.Length];
				for (var i = 0; i < parameters.Length; i++) 
                {
					parameters [i] = (int)reader.ReadByte ();
					offsets [i] = (int)reader.ReadUInt16 ();
				}

                var buffer = new ConstantBuffer(GraphicsDevice,
				                                sizeInBytes,
				                                parameters,
				                                offsets,
				                                name);
                ConstantBuffers[c] = buffer;
            }

            // Read in all the shader objects.
            var shaders = (int)reader.ReadByte();
            _shaders = new Shader[shaders];
            for (var s = 0; s < shaders; s++)
                _shaders[s] = new Shader(GraphicsDevice, reader);

            // Read in the parameters.
            Parameters = ReadParameters(reader);

            // Read the techniques.
            var techniqueCount = (int)reader.ReadByte();
            var techniques = new EffectTechnique[techniqueCount];
            for (var t = 0; t < techniqueCount; t++)
            {
                var name = reader.ReadString();

                var annotations = ReadAnnotations(reader);

                var passes = ReadPasses(reader, this, _shaders);

                techniques[t] = new EffectTechnique(this, name, passes, annotations);
            }

            Techniques = new EffectTechniqueCollection(techniques);
            CurrentTechnique = Techniques[0];
        }
            private int[] getParameters(Shader shader)
            {
                
                FieldInfo fieldInfo = typeof(ConstantBuffer).GetField("_parameters", BindingFlags.NonPublic | BindingFlags.Instance);
                List<int> res = new List<int>();

                
                for (var p = 0; p < shader.CBuffers.Length; p++)
                {
                    var c = shader.CBuffers[p];
                    var cb = Effect.ConstantBuffers[c];
                    foreach (int parameter in (int[])fieldInfo.GetValue(cb))
                    {
                        res.Add(parameter);
                    }
                }
                return res.ToArray();
            }
Exemple #17
0
        private static EffectPassCollection ReadPasses(BinaryReader reader, Effect effect, Shader[] shaders)
        {
            var count = (int)reader.ReadByte();
            var passes = new EffectPass[count];

            for (var i = 0; i < count; i++)
            {
                var name = reader.ReadString();
                var annotations = ReadAnnotations(reader);

                // Get the vertex shader.
                Shader vertexShader = null;
                var shaderIndex = (int)reader.ReadByte();
                if (shaderIndex != 255)
                    vertexShader = shaders[shaderIndex];

                // Get the pixel shader.
                Shader pixelShader = null;
                shaderIndex = (int)reader.ReadByte();
                if (shaderIndex != 255)
                    pixelShader = shaders[shaderIndex];

				BlendState blend = null;
				DepthStencilState depth = null;
				RasterizerState raster = null;
				if (reader.ReadBoolean())
				{
					blend = new BlendState
					{
						AlphaBlendFunction = (BlendFunction)reader.ReadByte(),
						AlphaDestinationBlend = (Blend)reader.ReadByte(),
						AlphaSourceBlend = (Blend)reader.ReadByte(),
						BlendFactor = new Color(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()),
						ColorBlendFunction = (BlendFunction)reader.ReadByte(),
						ColorDestinationBlend = (Blend)reader.ReadByte(),
						ColorSourceBlend = (Blend)reader.ReadByte(),
						ColorWriteChannels = (ColorWriteChannels)reader.ReadByte(),
						ColorWriteChannels1 = (ColorWriteChannels)reader.ReadByte(),
						ColorWriteChannels2 = (ColorWriteChannels)reader.ReadByte(),
						ColorWriteChannels3 = (ColorWriteChannels)reader.ReadByte(),
						MultiSampleMask = reader.ReadInt32(),
					};
				}
				if (reader.ReadBoolean())
				{
					depth = new DepthStencilState
					{
						CounterClockwiseStencilDepthBufferFail = (StencilOperation)reader.ReadByte(),
						CounterClockwiseStencilFail = (StencilOperation)reader.ReadByte(),
						CounterClockwiseStencilFunction = (CompareFunction)reader.ReadByte(),
						CounterClockwiseStencilPass = (StencilOperation)reader.ReadByte(),
						DepthBufferEnable = reader.ReadBoolean(),
						DepthBufferFunction = (CompareFunction)reader.ReadByte(),
						DepthBufferWriteEnable = reader.ReadBoolean(),
						ReferenceStencil = reader.ReadInt32(),
						StencilDepthBufferFail = (StencilOperation)reader.ReadByte(),
						StencilEnable = reader.ReadBoolean(),
						StencilFail = (StencilOperation)reader.ReadByte(),
						StencilFunction = (CompareFunction)reader.ReadByte(),
						StencilMask = reader.ReadInt32(),
						StencilPass = (StencilOperation)reader.ReadByte(),
						StencilWriteMask = reader.ReadInt32(),
						TwoSidedStencilMode = reader.ReadBoolean(),
					};
				}
				if (reader.ReadBoolean())
				{
					raster = new RasterizerState
					{
						CullMode = (CullMode)reader.ReadByte(),
						DepthBias = reader.ReadSingle(),
						FillMode = (FillMode)reader.ReadByte(),
						MultiSampleAntiAlias = reader.ReadBoolean(),
						ScissorTestEnable = reader.ReadBoolean(),
						SlopeScaleDepthBias = reader.ReadSingle(),
					};
				}

                passes[i] = new EffectPass(effect, name, vertexShader, pixelShader, blend, depth, raster, annotations);
			}

            return new EffectPassCollection(passes);
		}
Exemple #18
0
        private void Link(Shader vertexShader, Shader pixelShader)
        {
            // NOTE: No need to worry about background threads here
            // as this is only called at draw time when we're in the
            // main drawing thread.
            var program = vertexShader.GraphicsDevice.GLDevice.glCreateProgram();

            vertexShader.GraphicsDevice.GLDevice.glAttachShader(program, vertexShader.GetShaderHandle());

            vertexShader.GraphicsDevice.GLDevice.glAttachShader(program, pixelShader.GetShaderHandle());

            vertexShader.GraphicsDevice.GLDevice.glLinkProgram(program);

            vertexShader.GraphicsDevice.GLDevice.glUseProgram(program);

            vertexShader.GetVertexAttributeLocations(program);

            pixelShader.ApplySamplerTextureUnits(program);

            var linked = 0;
            vertexShader.GraphicsDevice.GLDevice.glGetProgramiv(
                program,
                OpenGLDevice.GLenum.GL_LINK_STATUS,
                out linked
            );
            if (linked == 0)
            {
                Console.WriteLine(
                    vertexShader.GraphicsDevice.GLDevice.glGetProgramInfoLog(program)
                );

                vertexShader.GraphicsDevice.GLDevice.glDetachShader(program, vertexShader.GetShaderHandle());
                vertexShader.GraphicsDevice.GLDevice.glDetachShader(program, pixelShader.GetShaderHandle());

                vertexShader.GraphicsDevice.GLDevice.glDeleteProgram(program);
                throw new InvalidOperationException("Unable to link effect program");
            }

            ShaderProgram shaderProgram = new ShaderProgram(program);

            _programCache.Add(vertexShader.HashKey | pixelShader.HashKey, shaderProgram);
        }