Esempio n. 1
0
        /// <summary>
        /// Gets the stats of the model.
        /// </summary>
        /// <param name="usedVideoMemory">The amount of memory used by this pool.</param>
        /// <param name="renderedTris">The number of Tris rendered by this pool.</param>
        /// <param name="allocatedTris">The number of tris allocated by this pool.</param>
        public void GetStats(ref long usedVideoMemory, ref long renderedTris, ref long allocatedTris)
        {
            // 1 index = 4 byte
            // 1 vertex =
            // - 3 xyz floats  = 12 byte
            // - 2 uv floats   = 8 byte
            // - 4 rgba bytes  = 4 byte
            // - 4 rgba2 bytes = 4 byte
            // - 1 flags int    = 4 byte
            //[ - 1 normals int = 4 byte]
            // - 2 custom floats (uv2)  = 8 byte    when customdata is there

            // Total vertex: 32 bytes or 40 bytes
            // % size normals: 11% or 9%
            // Total index: 4 bytes

            // So 10mil tris => 30mil indices, 30m*0.75=23 mil vertices
            // = 114mb indices, 789mb vertices => 903mb video memory   (no custom floats)
            //                  88mb normals

            long vertexSize = 12 + 8 + 4 + 4 + 4 + (customFloats == null ? 0 : customFloats.InterleaveStride) + (customShorts == null ? 0 : customShorts.InterleaveStride) + (customBytes == null ? 0 : customBytes.InterleaveStride) + (customInts == null ? 0 : customInts.InterleaveStride);

            for (int i = 0; i < pools.Count; i++)
            {
                MeshDataPool pool = pools[i];

                usedVideoMemory += pool.VerticesPoolSize * vertexSize + pool.IndicesPoolSize * 4;
                renderedTris    += pool.RenderedTriangles;
                allocatedTris   += pool.AllocatedTris;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Allocates a new pool for mesh data.
        /// </summary>
        /// <param name="capi">The core client API</param>
        /// <param name="verticesPoolSize">The vertices pool size.</param>
        /// <param name="indicesPoolSize">The index pool size.</param>
        /// <param name="maxPartsPerPool">The maximum parts per pool.</param>
        /// <param name="customFloats">The custom floats of the pool.</param>
        /// <param name="customBytes">The custom bytes of the pool.</param>
        /// <param name="customInts">The custom ints of the pool.</param>
        /// <returns>The resulting mesh data pool.</returns>
        public static MeshDataPool AllocateNewPool(ICoreClientAPI capi, int verticesPoolSize, int indicesPoolSize, int maxPartsPerPool, CustomMeshDataPartFloat customFloats = null, CustomMeshDataPartShort customShorts = null, CustomMeshDataPartByte customBytes = null, CustomMeshDataPartInt customInts = null)
        {
            MeshDataPool pool = new MeshDataPool(verticesPoolSize, indicesPoolSize, maxPartsPerPool);

            if (IntPtr.Size == 8)
            {
                // 64 bit builds require 64 bit memory addresses (should be long[] really, but GL.MultiDrawElements only accepts int[])
                pool.indicesStartsByte = new int[maxPartsPerPool * 2];
            }
            else
            {
                pool.indicesStartsByte = new int[maxPartsPerPool];
            }

            pool.indicesSizes = new int[maxPartsPerPool];

            //MeshData modeldata = new MeshData(verticesPoolSize, indicesPoolSize, false); - wtf?

            // Allocate the right amount of bytes for custom data
            if (customFloats != null)
            {
                customFloats.SetAllocationSize(verticesPoolSize * customFloats.InterleaveStride / 4);
            }
            if (customShorts != null)
            {
                customShorts.SetAllocationSize(verticesPoolSize * customShorts.InterleaveStride / 2);
            }
            if (customBytes != null)
            {
                customBytes.SetAllocationSize(verticesPoolSize * customBytes.InterleaveStride);
            }
            if (customInts != null)
            {
                customInts.SetAllocationSize(verticesPoolSize * customInts.InterleaveStride / 4);
            }

            pool.modelRef = capi.Render.AllocateEmptyMesh(
                MeshData.XyzSize * verticesPoolSize,
                0,
                MeshData.UvSize * verticesPoolSize,
                MeshData.RgbaSize * verticesPoolSize,
                MeshData.FlagsSize * verticesPoolSize,
                MeshData.IndexSize * indicesPoolSize,
                customFloats,
                customShorts,
                customBytes,
                customInts,
                EnumDrawMode.Triangles,
                false
                );


            return(pool);
        }
Esempio n. 3
0
        /// <summary>
        /// Renders the model.
        /// </summary>
        /// <param name="playerpos">The position of the Player</param>
        /// <param name="originUniformName"></param>
        /// <param name="frustumCullMode">The culling mode.  Default is CulHideDelay.</param>
        public void Render(Vec3d playerpos, string originUniformName, EnumFrustumCullMode frustumCullMode = EnumFrustumCullMode.CullNormal)
        {
            for (int i = 0; i < pools.Count; i++)
            {
                MeshDataPool pool = pools[i];
                pool.FrustumCull(frustumCuller, frustumCullMode);

                capi.Render.CurrentActiveShader.Uniform(originUniformName, tmp.Set(
                                                            (float)(pool.poolOrigin.X - playerpos.X),
                                                            (float)(pool.poolOrigin.Y - playerpos.Y),
                                                            (float)(pool.poolOrigin.Z - playerpos.Z)
                                                            ));

                capi.Render.RenderMesh(pool.modelRef, pool.indicesStartsByte, pool.indicesSizes, pool.indicesGroupsCount);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Adds a model to the mesh pool.
        /// </summary>
        /// <param name="modeldata">The model data</param>
        /// <param name="modelOrigin">The origin point of the Model</param>
        /// <param name="frustumCullSphere">The culling sphere.</param>
        /// <returns>The location identifier for the pooled model.</returns>
        public ModelDataPoolLocation AddModel(MeshData modeldata, Vec3i modelOrigin, Sphere frustumCullSphere)
        {
            ModelDataPoolLocation location = null;

            for (int i = 0; i < pools.Count; i++)
            {
                location = pools[i].TryAdd(capi, modeldata, modelOrigin, frustumCullSphere);
                if (location != null)
                {
                    break;
                }
            }

            if (location == null)
            {
                int vertexSize = Math.Max(modeldata.VerticesCount + 1, defaultVertexPoolSize);
                int indexSize  = Math.Max(modeldata.IndicesCount + 1, defaultIndexPoolSize);

                if (vertexSize > defaultIndexPoolSize)
                {
                    capi.World.Logger.Warning("Chunk (or some other mesh source at origin: {0}) exceeds default geometric complexity maximum of {1} vertices and {2} indices. You must be loading some very complex objects (#v = {3}, #i = {4}). Adjusted Pool size accordingly.", modelOrigin, defaultVertexPoolSize, defaultIndexPoolSize, modeldata.VerticesCount, modeldata.IndicesCount);
                }

                MeshDataPool pool = MeshDataPool.AllocateNewPool(capi, vertexSize, indexSize, maxPartsPerPool, customFloats, customShorts, customBytes, customInts);
                pool.poolOrigin = modelOrigin;

                masterPool.AddModelDataPool(pool);
                pools.Add(pool);
                location = pool.TryAdd(capi, modeldata, modelOrigin, frustumCullSphere);
            }

            if (location == null)
            {
                capi.World.Logger.Fatal("Can't add modeldata (probably a tesselated chunk @{0}) to the model data pool list, it exceeds the size of a single empty pool of {1} vertices and {2} indices. You must be loading some very complex objects (#v = {3}, #i = {4}). Try increasing MaxVertexSize and MaxIndexSize. The whole chunk will be invisible.", modelOrigin, defaultVertexPoolSize, defaultIndexPoolSize, modeldata.VerticesCount, modeldata.IndicesCount);

                //location = new ModelDataPoolLocation() { frustumCullSphere = frustumCullSphere };
                //pools[0].poolLocations.Add(location);
            }

            return(location);
        }
Esempio n. 5
0
 /// <summary>
 /// Adds a new pool to the master pool.
 /// </summary>
 /// <param name="pool">The mesh data pool to add.</param>
 public void AddModelDataPool(MeshDataPool pool)
 {
     pool.poolId = modelPools.Count;
     modelPools.Add(pool);
 }