예제 #1
0
        /// <summary>
        /// End() overload without a ref parameter
        /// </summary>
        public void End(BoundingBoxRenderer boxRenderer = null)
        {
            int vertexCount = 0;

            End(ref vertexCount, boxRenderer);
        }
예제 #2
0
        /// <summary>
        /// Cull and draw visible meshes
        /// </summary>
        public void End(ref int vertexCount, BoundingBoxRenderer boxRenderer = null)
        {
            totalVertexCount               = 0;
            graphicsDevice.BlendState      = blendState;
            graphicsDevice.RasterizerState = rasterizerState;

            // Set universal values for effects used by meshes
            effect.Parameters["View"].SetValue(camera.view);
            effect.Parameters["Projection"].SetValue(camera.projection);
            effect.Parameters["camPos"].SetValue(camera.position);

            effect.CurrentTechnique = effect.Techniques["Default"];

            // Loop through each mesh and render it once for each transform
            foreach (KeyValuePair <MeshData, List <Matrix> > meshInstance in meshInstances)
            {
                MeshData      mesh     = meshInstance.Key;
                List <Matrix> matrices = meshInstance.Value;

                // Set the mesh once before setting the transforms
                graphicsDevice.SetVertexBuffer(mesh.vb);
                graphicsDevice.Indices = mesh.ib;

                // Render each instance of this mesh
                foreach (Matrix worldTransform in matrices)
                {
                    if (mesh.ib == null)
                    {
                        continue;
                    }

                    effect.Parameters["World"].SetValue(worldTransform);

                    // Set additional parameters
                    if (mesh.aoTexture != null)
                    {
                        effect.Parameters["aoTexture"].SetValue(mesh.aoTexture);
                    }

                    if (camera.frustum.Contains(mesh.bBox) != ContainmentType.Disjoint ||
                        (mesh.bBox.Max == Vector3.Zero && mesh.bBox.Min == Vector3.Zero))
                    {
                        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                        {
                            pass.Apply();
                            graphicsDevice.DrawIndexedPrimitives(
                                PrimitiveType.TriangleList, 0, 0,
                                mesh.ib.IndexCount, 0, mesh.ib.IndexCount / 3);
                        }

                        // Add total vertices rendered
                        totalVertexCount += mesh.vb.VertexCount;

                        // Draw the bounding box
                        if (boxRenderer != null)
                        {
                            boxRenderer.Draw(graphicsDevice, camera, Matrix.Identity, mesh.bBox, mesh.bBoxColor);
                        }
                    }
                }

                // Done rendering mesh, release item to the cached list
                if (!cachedMeshInstances.ContainsKey(mesh))
                {
                    // Add to cache if not found already
                    cachedMeshInstances.Add(mesh, new List <Matrix>());

                    // Limit cache to batch size if too large, by removing the oldest mesh
                    if (meshQueue.Count == initialBatchSize)
                    {
                        cachedMeshInstances.Remove(meshQueue.Dequeue());
                    }

                    meshQueue.Enqueue(mesh);
                }
            }

            // Remove all current instances
            meshInstances.Clear();
            graphicsDevice.SetRenderTarget(null);

            vertexCount = totalVertexCount;
        }