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]; }
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; }
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); }
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); } }
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]; }
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; } }
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(); }
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]; } } } }
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(); }
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); }
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); }