public void LoadParameterSet(IRenderContext renderContext, IEffectParameterSet effectParameters, bool skipMatricSync) { if (!skipMatricSync) { if (effectParameters.HasSemantic <IWorldViewProjectionEffectSemantic>()) { var semantic = effectParameters.GetSemantic <IWorldViewProjectionEffectSemantic>(); semantic.World = renderContext.World; semantic.Projection = renderContext.Projection; semantic.View = renderContext.View; } } ((ProtogameParameterSet)effectParameters).Load(renderContext, _targetEffect); }
private IEffectParameterSet GetEffectParameterSet(IMaterial material, ref bool changedRenderRequest, ref string changedRenderRequestBy) { if (_effectUsedForParameterSetCache == _cachedEffect && changedRenderRequest == false && (!_lastDidSetDiffuseTexture || _lastSetDiffuseTexture == _lastCachedDiffuseTexture?.Texture) && (!_lastDidSetNormalMap || _lastSetNormalMap == _lastCachedNormalMapTexture?.Texture) && (!_lastDidSetSpecularPower || _lastSetSpecularPower == _lastCachedSpecularPower) && (!_lastDidSetSpecularColorMap || _lastSetSpecularColorMap == _lastCachedSpecularColorMapTexture?.Texture) && (!_lastDidSetSpecularColor || _lastSetSpecularColor == _lastCachedSpecularColor) && (!_lastDidSetDiffuseColor || _lastSetDiffuseColor == (material.ColorDiffuse ?? Color.Black))) { // Reuse the existing parameter set. return _cachedEffectParameterSet; } changedRenderRequest = true; changedRenderRequestBy += ":parameterset"; // Create a new parameter set and cache it. _cachedEffectParameterSet = _cachedEffect.CreateParameterSet(); _effectUsedForParameterSetCache = _cachedEffect; _lastSetDiffuseTexture = null; _lastSetNormalMap = null; _lastSetSpecularPower = null; _lastSetSpecularColorMap = null; _lastSetSpecularColor = null; _lastSetDiffuseColor = null; _lastDidSetDiffuseTexture = false; _lastDidSetNormalMap = false; _lastDidSetSpecularPower = false; _lastDidSetSpecularColorMap = false; _lastDidSetSpecularColor = false; _lastDidSetDiffuseColor = false; if (_cachedEffectParameterSet.HasSemantic<ITextureEffectSemantic>()) { if (_lastCachedDiffuseTexture?.Texture != null) { _cachedEffectParameterSet.GetSemantic<ITextureEffectSemantic>().Texture = _lastCachedDiffuseTexture.Texture; _lastSetDiffuseTexture = _lastCachedDiffuseTexture.Texture; _lastDidSetDiffuseTexture = true; } } if (_cachedEffectParameterSet.HasSemantic<INormalMapEffectSemantic>()) { if (_lastCachedNormalMapTexture?.Texture != null) { _cachedEffectParameterSet.GetSemantic<INormalMapEffectSemantic>().NormalMap = _lastCachedNormalMapTexture.Texture; _lastSetNormalMap = _lastCachedNormalMapTexture.Texture; _lastDidSetNormalMap = true; } } if (_cachedEffectParameterSet.HasSemantic<ISpecularEffectSemantic>()) { if (_lastCachedSpecularPower != null) { var semantic = _cachedEffectParameterSet.GetSemantic<ISpecularEffectSemantic>(); semantic.SpecularPower = _lastCachedSpecularPower.Value; _lastSetSpecularPower = _lastCachedSpecularPower.Value; _lastDidSetSpecularPower = true; if (_lastCachedSpecularColorMapTexture != null) { semantic.SpecularColorMap = _lastCachedSpecularColorMapTexture.Texture; _lastSetSpecularColorMap = _lastCachedSpecularColorMapTexture.Texture; _lastDidSetSpecularColorMap = true; } else if (_lastCachedSpecularColor != null) { semantic.SpecularColor = _lastCachedSpecularColor.Value; _lastSetSpecularColor = _lastCachedSpecularColor.Value; _lastDidSetSpecularColor = true; } } } if (_cachedEffectParameterSet.HasSemantic<IColorDiffuseEffectSemantic>()) { var v = material.ColorDiffuse ?? Color.Black; _cachedEffectParameterSet.GetSemantic<IColorDiffuseEffectSemantic>().Diffuse = v; _lastSetDiffuseColor = v; _lastDidSetDiffuseColor = true; } return _cachedEffectParameterSet; }
/// <summary> /// Creates a render request for the model using the specified transform. /// </summary> /// <param name="renderContext"> /// The render context. /// </param> /// <param name="effect"></param> /// <param name="effectParameterSet"></param> /// <param name="transform"> /// The transform. /// </param> public IRenderRequest CreateRenderRequest(IRenderContext renderContext, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform) { if (Vertexes.Length == 0 && Indices.Length == 0) { throw new InvalidOperationException( "This model does not have any vertexes or indices. It's most " + "likely been imported from an FBX file that only contains hierarchy, " + "in which case there isn't anything to render."); } LoadBuffers(renderContext.GraphicsDevice); VertexBuffer vertexBuffer; if (_cachedVertexBuffers.ContainsKey(effect)) { vertexBuffer = _cachedVertexBuffers[effect]; } else { // Find the vertex mapping configuration for this model. if (_cachedModelVertexMapping == null) { _cachedModelVertexMapping = _modelRenderConfigurations.Select(x => x.GetVertexMappingToGPU(this, effect)) .FirstOrDefault(x => x != null); if (_cachedModelVertexMapping == null) { throw new InvalidOperationException( "No implementation of IModelRenderConfiguration could provide a vertex " + "mapping for this model. You must implement IModelRenderConfiguration " + "and bind it in the dependency injection system, so that the engine is " + "aware of how to map vertices in models to parameters in effects."); } } var mappedVerticies = Array.CreateInstance(_cachedModelVertexMapping.VertexType, Vertexes.Length); for (var i = 0; i < Vertexes.Length; i++) { var vertex = _cachedModelVertexMapping.MappingFunction(Vertexes[i]); mappedVerticies.SetValue(vertex, i); } float maxX = 0f, maxY = 0f, maxZ = 0f; foreach (var vert in this.Vertexes) { if (vert.Position.HasValue) { if (Math.Abs(vert.Position.Value.X) > maxX) { maxX = Math.Abs(vert.Position.Value.X); } if (Math.Abs(vert.Position.Value.Y) > maxY) { maxY = Math.Abs(vert.Position.Value.Y); } if (Math.Abs(vert.Position.Value.Z) > maxZ) { maxZ = Math.Abs(vert.Position.Value.Z); } } } var radius = new Vector3(maxX, maxY, maxZ).Length() * 2; _localisedBoundingRegion = new LocalisedBoundingRegion(radius); vertexBuffer = new VertexBuffer( renderContext.GraphicsDevice, _cachedModelVertexMapping.VertexDeclaration, Vertexes.Length, BufferUsage.WriteOnly); vertexBuffer.GetType().GetMethods().First(x => x.Name == "SetData" && x.GetParameters().Length == 1).MakeGenericMethod(_cachedModelVertexMapping.VertexType).Invoke( vertexBuffer, new[] { mappedVerticies }); _cachedVertexBuffers[effect] = vertexBuffer; } if (effectParameterSet.HasSemantic <IBonesEffectSemantic>()) { var bonesEffectSemantic = effectParameterSet.GetSemantic <IBonesEffectSemantic>(); foreach (var bone in _flattenedBones) { if (bone.ID == -1) { continue; } bonesEffectSemantic.Bones[bone.ID] = bone.GetFinalMatrix(); } } // Create the render request. return(_renderBatcher.CreateSingleRequestFromState( renderContext, effect, effectParameterSet, vertexBuffer, IndexBuffer, PrimitiveType.TriangleList, renderContext.World * transform, (m, vb, ib) => { var mappedVerticies = Array.CreateInstance(_cachedModelVertexMapping.VertexType, Vertexes.Length * m.Count); var mappedIndicies = new int[Indices.Length * m.Count]; for (var im = 0; im < m.Count; im++) { for (var i = 0; i < Vertexes.Length; i++) { var vertex = _cachedModelVertexMapping.MappingFunction(Vertexes[i].Transform(m[im])); mappedVerticies.SetValue(vertex, im * Vertexes.Length + i); } for (var i = 0; i < Indices.Length; i++) { mappedIndicies[im * Vertexes.Length + i] = Indices[i] + Vertexes.Length * im; } } vb.GetType().GetMethods().First(x => x.Name == "SetData" && x.GetParameters().Length == 1).MakeGenericMethod(_cachedModelVertexMapping.VertexType).Invoke( vb, new[] { mappedVerticies }); ib.SetData(mappedIndicies); }, _localisedBoundingRegion)); }
private IEffectParameterSet GetEffectParameterSet(IMaterial material, ref bool changedRenderRequest, ref string changedRenderRequestBy) { if (_effectUsedForParameterSetCache == _cachedEffect && changedRenderRequest == false && (!_lastDidSetDiffuseTexture || _lastSetDiffuseTexture == _lastCachedDiffuseTexture?.Texture) && (!_lastDidSetNormalMap || _lastSetNormalMap == _lastCachedNormalMapTexture?.Texture) && (!_lastDidSetSpecularPower || _lastSetSpecularPower == _lastCachedSpecularPower) && (!_lastDidSetSpecularColorMap || _lastSetSpecularColorMap == _lastCachedSpecularColorMapTexture?.Texture) && (!_lastDidSetSpecularColor || _lastSetSpecularColor == _lastCachedSpecularColor) && (!_lastDidSetDiffuseColor || _lastSetDiffuseColor == (material.ColorDiffuse ?? Color.Black))) { // Reuse the existing parameter set. return(_cachedEffectParameterSet); } changedRenderRequest = true; changedRenderRequestBy += ":parameterset"; // Create a new parameter set and cache it. _cachedEffectParameterSet = _cachedEffect.CreateParameterSet(); _effectUsedForParameterSetCache = _cachedEffect; _lastSetDiffuseTexture = null; _lastSetNormalMap = null; _lastSetSpecularPower = null; _lastSetSpecularColorMap = null; _lastSetSpecularColor = null; _lastSetDiffuseColor = null; _lastDidSetDiffuseTexture = false; _lastDidSetNormalMap = false; _lastDidSetSpecularPower = false; _lastDidSetSpecularColorMap = false; _lastDidSetSpecularColor = false; _lastDidSetDiffuseColor = false; if (_cachedEffectParameterSet.HasSemantic <ITextureEffectSemantic>()) { if (_lastCachedDiffuseTexture?.Texture != null) { _cachedEffectParameterSet.GetSemantic <ITextureEffectSemantic>().Texture = _lastCachedDiffuseTexture.Texture; _lastSetDiffuseTexture = _lastCachedDiffuseTexture.Texture; _lastDidSetDiffuseTexture = true; } } if (_cachedEffectParameterSet.HasSemantic <INormalMapEffectSemantic>()) { if (_lastCachedNormalMapTexture?.Texture != null) { _cachedEffectParameterSet.GetSemantic <INormalMapEffectSemantic>().NormalMap = _lastCachedNormalMapTexture.Texture; _lastSetNormalMap = _lastCachedNormalMapTexture.Texture; _lastDidSetNormalMap = true; } } if (_cachedEffectParameterSet.HasSemantic <ISpecularEffectSemantic>()) { if (_lastCachedSpecularPower != null) { var semantic = _cachedEffectParameterSet.GetSemantic <ISpecularEffectSemantic>(); semantic.SpecularPower = _lastCachedSpecularPower.Value; _lastSetSpecularPower = _lastCachedSpecularPower.Value; _lastDidSetSpecularPower = true; if (_lastCachedSpecularColorMapTexture != null) { semantic.SpecularColorMap = _lastCachedSpecularColorMapTexture.Texture; _lastSetSpecularColorMap = _lastCachedSpecularColorMapTexture.Texture; _lastDidSetSpecularColorMap = true; } else if (_lastCachedSpecularColor != null) { semantic.SpecularColor = _lastCachedSpecularColor.Value; _lastSetSpecularColor = _lastCachedSpecularColor.Value; _lastDidSetSpecularColor = true; } } } if (_cachedEffectParameterSet.HasSemantic <IColorDiffuseEffectSemantic>()) { var v = material.ColorDiffuse ?? Color.Black; _cachedEffectParameterSet.GetSemantic <IColorDiffuseEffectSemantic>().Diffuse = v; _lastSetDiffuseColor = v; _lastDidSetDiffuseColor = true; } return(_cachedEffectParameterSet); }
/// <summary> /// Creates a render request for the model using the specified transform. /// </summary> /// <param name="renderContext"> /// The render context. /// </param> /// <param name="effect"></param> /// <param name="effectParameterSet"></param> /// <param name="transform"> /// The transform. /// </param> public IRenderRequest CreateRenderRequest(IRenderContext renderContext, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform) { if (Vertexes.Length == 0 && Indices.Length == 0) { throw new InvalidOperationException( "This model does not have any vertexes or indices. It's most " + "likely been imported from an FBX file that only contains hierarchy, " + "in which case there isn't anything to render."); } LoadBuffers(renderContext.GraphicsDevice); VertexBuffer vertexBuffer; if (_cachedVertexBuffers.ContainsKey(effect)) { vertexBuffer = _cachedVertexBuffers[effect]; } else { // Find the vertex mapping configuration for this model. if (_cachedModelVertexMapping == null) { _cachedModelVertexMapping = _modelRenderConfigurations.Select(x => x.GetVertexMappingToGPU(this, effect)) .FirstOrDefault(x => x != null); if (_cachedModelVertexMapping == null) { throw new InvalidOperationException( "No implementation of IModelRenderConfiguration could provide a vertex " + "mapping for this model. You must implement IModelRenderConfiguration " + "and bind it in the dependency injection system, so that the engine is " + "aware of how to map vertices in models to parameters in effects."); } } var mappedVerticies = Array.CreateInstance(_cachedModelVertexMapping.VertexType, Vertexes.Length); for (var i = 0; i < Vertexes.Length; i++) { var vertex = _cachedModelVertexMapping.MappingFunction(Vertexes[i]); mappedVerticies.SetValue(vertex, i); } vertexBuffer = new VertexBuffer( renderContext.GraphicsDevice, _cachedModelVertexMapping.VertexDeclaration, Vertexes.Length, BufferUsage.WriteOnly); vertexBuffer.GetType().GetMethods().First(x => x.Name == "SetData" && x.GetParameters().Length == 1).MakeGenericMethod(_cachedModelVertexMapping.VertexType).Invoke( vertexBuffer, new[] { mappedVerticies }); _cachedVertexBuffers[effect] = vertexBuffer; } if (effectParameterSet.HasSemantic<IBonesEffectSemantic>()) { var bonesEffectSemantic = effectParameterSet.GetSemantic<IBonesEffectSemantic>(); foreach (var bone in _flattenedBones) { if (bone.ID == -1) { continue; } bonesEffectSemantic.Bones[bone.ID] = bone.GetFinalMatrix(); } } // Create the render request. return _renderBatcher.CreateSingleRequestFromState( renderContext, effect, effectParameterSet, vertexBuffer, IndexBuffer, PrimitiveType.TriangleList, renderContext.World*transform, (m, vb, ib) => { var mappedVerticies = Array.CreateInstance(_cachedModelVertexMapping.VertexType, Vertexes.Length * m.Count); var mappedIndicies = new int[Indices.Length*m.Count]; for (var im = 0; im < m.Count; im++) { for (var i = 0; i < Vertexes.Length; i++) { var vertex = _cachedModelVertexMapping.MappingFunction(Vertexes[i].Transform(m[im])); mappedVerticies.SetValue(vertex, im*Vertexes.Length+i); } for (var i = 0; i < Indices.Length; i++) { mappedIndicies[im*Vertexes.Length + i] = Indices[i] + Vertexes.Length*im; } } vb.GetType().GetMethods().First(x => x.Name == "SetData" && x.GetParameters().Length == 1).MakeGenericMethod(_cachedModelVertexMapping.VertexType).Invoke( vb, new[] { mappedVerticies }); ib.SetData(mappedIndicies); }); }