Esempio n. 1
0
        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;
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 5
0
        /// <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);
                });
        }