Ejemplo n.º 1
0
 public bool DeleteFromRegistry(ModelMeshPart mesh, TransformMatrix worldMatrix)
 {
     for (var i = 0; i < Index; i++)
     {
         MeshLibrary meshLib = _meshLib[i];
         if (meshLib.HasMesh(mesh))
         {
             if (meshLib.DeleteFromRegistry(worldMatrix)) //if true, we can delete it from registry
             {
                 for (var j = i; j < Index - 1; j++)
                 {
                     //slide down one
                     _meshLib[j] = _meshLib[j + 1];
                 }
                 Index--;
             }
             break;
         }
     }
     if (Index <= 0)
     {
         return(true);            //this material is no longer needed.
     }
     return(false);
 }
Ejemplo n.º 2
0
        public void Register(ModelMeshPart mesh, TransformMatrix worldMatrix, BoundingSphere boundingSphere)
        {
            bool found = false;

            //Check if we already have a model like that, if yes put it in there!
            for (var i = 0; i < Index; i++)
            {
                MeshLibrary meshLib = _meshLib[i];
                if (meshLib.HasMesh(mesh))
                {
                    meshLib.Register(worldMatrix);
                    found = true;
                    break;
                }
            }

            //We have no Lib yet, make a new one.
            if (!found)
            {
                _meshLib[Index] = new MeshLibrary();
                _meshLib[Index].SetMesh(mesh);
                _meshLib[Index].SetBoundingSphere(boundingSphere);
                _meshLib[Index].Register(worldMatrix);
                Index++;
            }

            //If we exceeded our array length, make the array bigger.
            if (Index >= _meshLib.Length)
            {
                MeshLibrary[] tempLib = new MeshLibrary[Index + 1];
                _meshLib.CopyTo(tempLib, 0);
                _meshLib = tempLib;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Checks whether or not anything has moved, if no then we ignore the frame
        /// </summary>
        /// <param name="lightViewPointChanged"></param>
        /// <param name="hasAnyObjectMoved"></param>
        /// <returns></returns>
        private bool CheckShadowMapUpdateNeeds(bool lightViewPointChanged, bool hasAnyObjectMoved)
        {
            if (lightViewPointChanged || hasAnyObjectMoved)
            {
                bool discardFrame = true;

                for (int index1 = 0; index1 < Index; index1++)
                {
                    MaterialLibrary matLib = MaterialLib[index1];

                    //We determined beforehand whether something changed this frame
                    if (matLib.HasChangedThisFrame)
                    {
                        for (int i = 0; i < matLib.Index; i++)
                        {
                            //Now we have to check whether we have a rendered thing in here
                            MeshLibrary meshLib = matLib.GetMeshLibrary()[i];
                            for (int index = 0; index < meshLib.Index; index++)
                            {
                                //If it's set to "not rendered" skip
                                for (int j = 0; j < meshLib.Rendered.Length; j++)
                                {
                                    if (meshLib.Rendered[j])
                                    {
                                        discardFrame = false;
                                        break;
                                    }
                                }

                                if (!discardFrame)
                                {
                                    break;
                                }
                            }
                        }
                        if (!discardFrame)
                        {
                            break;
                        }
                    }
                }

                if (discardFrame)
                {
                    return(false);
                }

                graphicsDevice.DepthStencilState = _depthWrite;
                ClearFrame(graphicsDevice);
                graphicsDevice.DepthStencilState = DepthStencilState.Default;
            }

            GameStats.activeShadowMaps++;

            return(true);
        }
Ejemplo n.º 4
0
        private bool ApplyShaders(RenderType renderType, IRenderModule renderModule, Matrix localWorldMatrix, Matrix?view, Matrix viewProjection, MeshLibrary meshLib, int index, int outlineId, bool outlined)
        {
            if (renderType == RenderType.Opaque ||
                renderType == RenderType.ShadowLinear ||
                renderType == RenderType.ShadowOmnidirectional ||
                renderType == RenderType.SubsurfaceScattering ||
                renderType == RenderType.Forward)
            {
                renderModule.Apply(localWorldMatrix, view, viewProjection);
            }
            else if (renderType == RenderType.Hologram)
            {
                Shaders.HologramEffectParameter_World.SetValue(localWorldMatrix);
                Shaders.HologramEffectParameter_WorldViewProj.SetValue(localWorldMatrix * viewProjection);

                Shaders.HologramEffect.CurrentTechnique.Passes[0].Apply();
            }
            else if (renderType == RenderType.IdRender || renderType == RenderType.IdOutline)
            {
                Shaders.IdRenderEffectParameterWorldViewProj.SetValue(localWorldMatrix * viewProjection);

                int id = meshLib.GetWorldMatrices()[index].Id;

                if (renderType == RenderType.IdRender)
                {
                    Shaders.IdRenderEffectParameterColorId.SetValue(IdGenerator.GetColorFromId(id).ToVector4());

                    Shaders.IdRenderEffectDrawId.Apply();
                }
                if (renderType == RenderType.IdOutline)
                {
                    //Is this the Id we want to outline?
                    if (id == outlineId)
                    {
                        graphicsDevice.RasterizerState = RasterizerState.CullNone;

                        Shaders.IdRenderEffectParameterWorld.SetValue(localWorldMatrix);

                        if (outlined)
                        {
                            Shaders.IdRenderEffectDrawOutline.Apply();
                        }
                        else
                        {
                            Shaders.IdRenderEffectDrawId.Apply();
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 5
0
        public void Draw(RenderType renderType, Matrix viewProjection, bool lightViewPointChanged = false, bool hasAnyObjectMoved = false, bool outlined = false, int outlineId = 0, Matrix?view = null, IRenderModule renderModule = null)
        {
            SetBlendAndRasterizerState(renderType);

            if (renderType == RenderType.ShadowLinear || renderType == RenderType.ShadowOmnidirectional)
            {
                //For shadowmaps we need to find out whether any object has moved and if so if it is rendered. If yes, redraw the whole frame, if no don't do anything
                if (!CheckShadowMapUpdateNeeds(lightViewPointChanged, hasAnyObjectMoved))
                {
                    return;
                }
            }

            for (int index1 = 0; index1 < Index; index1++)
            {
                MaterialLibrary matLib = MaterialLib[index1];

                if (matLib.Index < 1)
                {
                    continue;
                }

                //if none of this materialtype is drawn continue too!
                bool isUsed = false;

                for (int i = 0; i < matLib.Index; i++)
                {
                    MeshLibrary meshLib = matLib.GetMeshLibrary()[i];

                    //If it's set to "not rendered" skip
                    for (int j = 0; j < meshLib.Rendered.Length; j++)
                    {
                        if (meshLib.Rendered[j])
                        {
                            isUsed = true;
                            //if (meshLib.GetWorldMatrices()[j].HasChanged)
                            //    hasAnyObjectMoved = true;
                        }

                        if (isUsed)    // && hasAnyObjectMoved)
                        {
                            break;
                        }
                    }
                }

                if (!isUsed)
                {
                    continue;
                }

                //Count the draws of different materials!

                MaterialEffect material = matLib.GetMaterial();

                //Check if alpha or opaque!
                if (renderType == RenderType.Opaque && material.IsTransparent || renderType == RenderType.Opaque && material.Type == MaterialEffect.MaterialTypes.ForwardShaded)
                {
                    continue;
                }
                if (renderType == RenderType.Hologram && material.Type != MaterialEffect.MaterialTypes.Hologram)
                {
                    continue;
                }
                if (renderType != RenderType.Hologram && material.Type == MaterialEffect.MaterialTypes.Hologram)
                {
                    continue;
                }

                if (renderType == RenderType.SubsurfaceScattering &&
                    material.Type != MaterialEffect.MaterialTypes.SubsurfaceScattering)
                {
                    continue;
                }

                if (renderType == RenderType.Forward &&
                    material.Type != MaterialEffect.MaterialTypes.ForwardShaded)
                {
                    continue;
                }

                //Set the appropriate Shader for the material
                if (renderType == RenderType.ShadowOmnidirectional || renderType == RenderType.ShadowLinear)
                {
                    if (!material.HasShadow)
                    {
                        continue;
                    }
                }

                if (renderType != RenderType.IdRender && renderType != RenderType.IdOutline)
                {
                    GameStats.MaterialDraws++;
                }

                PerMaterialSettings(renderType, material, renderModule);

                for (int i = 0; i < matLib.Index; i++)
                {
                    MeshLibrary meshLib = matLib.GetMeshLibrary()[i];

                    //Initialize the mesh VB and IB
                    graphicsDevice.SetVertexBuffer(meshLib.GetMesh().VertexBuffer);
                    graphicsDevice.Indices = (meshLib.GetMesh().IndexBuffer);
                    int primitiveCount = meshLib.GetMesh().PrimitiveCount;
                    int vertexOffset   = meshLib.GetMesh().VertexOffset;
                    //int vCount = meshLib.GetMesh().NumVertices;
                    int startIndex = meshLib.GetMesh().StartIndex;

                    //Now draw the local meshes!
                    for (int index = 0; index < meshLib.Index; index++)
                    {
                        //If it's set to "not rendered" skip
                        //if (!meshLib.GetWorldMatrices()[index].Rendered) continue;
                        if (!meshLib.Rendered[index])
                        {
                            continue;
                        }

                        Matrix localWorldMatrix = meshLib.GetWorldMatrices()[index].World;

                        if (!ApplyShaders(renderType, renderModule, localWorldMatrix, view, viewProjection, meshLib, index,
                                          outlineId, outlined))
                        {
                            continue;
                        }
                        GameStats.MeshDraws++;

                        graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, vertexOffset, startIndex,
                                                             primitiveCount);
                    }
                }

                //Reset to
                if (material.RenderCClockwise)
                {
                    graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Update whether or not Objects are in the viewFrustumEx and need to be rendered or not.
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="boundingFrustrum"></param>
        /// <param name="hasCameraChanged"></param>
        public bool FrustumCulling(List <BasicEntity> entities, BoundingFrustum boundingFrustrum, bool hasCameraChanged, Vector3 cameraPosition)
        {
            //Check if the culling mode has changed
            if (_previousMode != GameSettings.g_cpuculling)
            {
                if (_previousMode)
                {
                    //If we previously did cull and now don't we need to set all the submeshes to render
                    for (int index1 = 0; index1 < Index; index1++)
                    {
                        MaterialLibrary matLib = MaterialLib[index1];
                        for (int i = 0; i < matLib.Index; i++)
                        {
                            MeshLibrary meshLib = matLib.GetMeshLibrary()[i];
                            for (int j = 0; j < meshLib.Rendered.Length; j++)
                            {
                                meshLib.Rendered[j] = _previousMode;
                            }
                        }
                    }
                }
                _previousMode = GameSettings.g_cpuculling;
            }

            if (!GameSettings.g_cpuculling)
            {
                return(false);
            }

            for (int index1 = 0; index1 < entities.Count; index1++)
            {
                BasicEntity entity = entities[index1];

                if (!hasCameraChanged && !entity.WorldTransform.HasChanged)// && entity.DynamicPhysicsObject == null)
                {
                    continue;
                }

                if (entity.WorldTransform.HasChanged)// || entity.DynamicPhysicsObject != null)
                {
                    entity.ApplyTransformation();
                }
            }

            bool hasAnythingChanged = false;

            //Ok we applied the transformation to all the entities, now update the submesh boundingboxes!
            // Parallel.For(0, Index, index1 =>
            for (int index1 = 0; index1 < Index; index1++)
            {
                float distance = 0;
                int   counter  = 0;


                MaterialLibrary matLib = GameSettings.g_cpusort
                        ? MaterialLib[MaterialLibPointer[index1]]
                        : MaterialLib[index1];
                for (int i = 0; i < matLib.Index; i++)
                {
                    MeshLibrary meshLib    = matLib.GetMeshLibrary()[i];
                    float?      distanceSq = meshLib.UpdatePositionAndCheckRender(hasCameraChanged, boundingFrustrum,
                                                                                  cameraPosition, _defaultBoundingSphere);

                    //If we get a new distance, apply it to the material
                    if (distanceSq != null)
                    {
                        distance += (float)distanceSq;
                        counter++;
                        hasAnythingChanged = true;
                    }
                }

                if (Math.Abs(distance) > 0.00001f)
                {
                    distance /= counter;
                    matLib.DistanceSquared     = distance;
                    matLib.HasChangedThisFrame = true;
                }
            }    //);

            //finally sort the materials by distance. Bubble sort should in theory be fast here since little changes.
            if (hasAnythingChanged)
            {
                SortByDistance();
            }

            return(hasAnythingChanged);
        }