Esempio n. 1
0
        public void RemoveVBO(Stack <VBOStorageInformation> vbos)
        {
            //only delete if its not the node farthes in the hierarchy
            if (leaf == null)
            {
                //if leaf not null remove the VBO that is at this level and delete it from GPU memory
                VBOStorageInformation thisLevelVBO = vbos.Pop();
                bool removed = serverBufferIds.Remove(thisLevelVBO);

                if (removed)
                {
                    VBOUtils.DeleteFromGPU(thisLevelVBO);
                }
            }

            if (ParentNodeID != null)
            {
                ParentNodeID.RemoveVBO(vbos);
            }
        }
Esempio n. 2
0
        public static void DeleteFromGPU(VBOStorageInformation serverBufferIds)
        {
            //free memory on server
            if (serverBufferIds.NumberOfPoints == 0)
            {
                return;
            }
            int[] buffersToDelete = new int[3];
            buffersToDelete[0] = serverBufferIds.VertexVBO;
            buffersToDelete[1] = serverBufferIds.NormalVBO;
            buffersToDelete[2] = serverBufferIds.ColorVBO;
            Gl.glDeleteBuffers(buffersToDelete.Length, buffersToDelete);

            LasMetrics.GetInstance().bytesCurrentlyOnGPURAM -= serverBufferIds.NumberOfPoints * 3 * 4; //3=every point has color, position and normal; 4=every value has 4 bytes
            LasMetrics.GetInstance().numberOfExistingVBOs--;
            LasMetrics.GetInstance().numberOfPointsLoadedIntoExistingVBOs -= serverBufferIds.NumberOfPoints;

            serverBufferIds.ColorVBO       = serverBufferIds.NormalVBO = serverBufferIds.VertexVBO = 0;
            serverBufferIds.NumberOfPoints = 0;
        }
Esempio n. 3
0
        /// <summary>
        /// called from the child leaf or node. loads a subset of passed points into its VBOs and passes the rest upward
        ///
        /// </summary>
        public void AddVBO(Stack <VBOStorageInformation> vbos)
        {
            if (serverBufferIds == null)
            {
                serverBufferIds = new List <VBOStorageInformation>();
            }

            //only insert if the node does not contain a leaf
            if (leaf == null)
            {
                VBOStorageInformation vbo = vbos.Pop();
                serverBufferIds.Add(vbo);
            }

            //top most node finishes it
            if (ParentNodeID != null)
            {
                ParentNodeID.AddVBO(vbos);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// copies points into the VBOs. returns number of points that were copied
        /// </summary>
        /// <param name="nbrPts"></param>
        /// <param name="vertices"></param>
        /// <param name="normals"></param>
        /// <param name="colors"></param>
        /// <param name="serverBufferIds"></param>
        /// <returns></returns>
        unsafe public static void CopyPointsToVBOs(float[] interleavedData, VBOStorageInformation serverBufferIds)
        {
            //create and initialize vertexbuffer
            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, serverBufferIds.InterleavedVBO);
            VBOUtils.CheckGlError("Tried first binding of interleaved VBO during glBegin() and glEnd()");

            long bytesCopied = 0;
            int  size        = 0;

            fixed(float *vptr = interleavedData)
            {
                size         = (sizeof(float) * interleavedData.Length);
                bytesCopied += size;
                Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)size, (IntPtr)vptr, Gl.GL_STATIC_DRAW);
            }

            VBOUtils.CheckGlError("Error copying interleaved data to VBO");

            LasMetrics.GetInstance().bytesTransferedToGPU += bytesCopied;
            LasMetrics.GetInstance().numberOfPointsLoadedIntoExistingVBOs += serverBufferIds.NumberOfPoints;
        }
Esempio n. 5
0
        public static void RenderVBOsFastSecondPass()
        {
            if (LasMetrics.GetInstance().renderToggle == false || secondPassVBOs.Count == 0)
            {
                return;
            }

            int numVBOSIs             = secondPassVBOs.Count;
            VBOStorageInformation vbo = null;

            int stride = 40;

            for (int i = 0; i < numVBOSIs; i++)
            {
                vbo = secondPassVBOs[i];
                Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo.InterleavedVBO);

                Gl.glInterleavedArrays(Gl.GL_C4F_N3F_V3F, stride, IntPtr.Zero);
                Gl.glDrawArrays(Gl.GL_POINTS, 0, vbo.NumberOfPoints);
            }
        }
Esempio n. 6
0
        public static void RenderVBO(VBOStorageInformation vbo)
        {
            if (LasMetrics.GetInstance().renderToggle == false)
            {
                return;
            }

            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo.InterleavedVBO);

            //array is interleaved like this: VVVNNNCCCC - this is 10*4 bytes.


            //try glInterleavedArrays instead of this three calls, should be faster
            Gl.glInterleavedArrays(Gl.GL_C4F_N3F_V3F, PointInformationSize, IntPtr.Zero);

            Gl.glDrawArrays(Gl.GL_POINTS, 0, vbo.NumberOfPoints);

            pointsDrawnInPass += vbo.NumberOfPoints;

            //add vbo for fast second pass rendering
            secondPassVBOs.Add(vbo);
        }
Esempio n. 7
0
        unsafe public static VBOStorageInformation GenerateVBOs(int numberOfPoints)
        {
            //generate free buffer names for 3 different buffers
            int bufferId = 0;

            Gl.glGenBuffers(1, out bufferId);

            VBOUtils.CheckGlError("Tried first binding of VBO during glBegin() and glEnd()");

            if (bufferId == 0)
            {
                throw new ApplicationException("ID of VBO should be set but was not!!!");
            }

            VBOStorageInformation vboSI = new VBOStorageInformation();

            vboSI.InterleavedVBO = bufferId;
            vboSI.NumberOfPoints = numberOfPoints;

            LasMetrics.GetInstance().numberOfExistingVBOs++;
            return(vboSI);
        }
Esempio n. 8
0
        internal void SetInvisibleAndUnbuffered()
        {
            visible = false;

            if (ClearAllPoints())
            {
                numberOfLoadedPoints = 0;

                if (serverBufferId != null)
                {
                    VBOUtils.DeleteFromGPU(serverBufferId);
                    serverBufferId = null;

                    if (parentVBOs.Count > 0)
                    {
                        ParentNode.RemoveVBO(parentVBOs);
                    }
                }

                State = LoadedState.UNLOADED;
            }
        }
Esempio n. 9
0
        protected unsafe void LoadIntoVBO()
        {
            if (serverBufferId != null)
            {
                throw new ApplicationException("should not occur");
            }

            if (parentVBOs == null)
            {
                parentVBOs = new Stack <VBOStorageInformation>();
            }

            QTreeWrapper parentTree = LasDataManager.GetInstance().GetQtreeByGuid(ParentTreeID);

            #region Create vertex arrays
            //form three arrays to copy to server memory

            ColorPalette pallette = LasDataManager.ColorPallette;

            //code that reduces given points
            //how many points to skip when loading
            int step = (int)Math.Ceiling((1.0 / ReductionToParentCoef));        //be conservative

            int allLevels = parentTree.qtree.NumberOfTreeLevels;

            int pointsOnLevel     = NumberOfPoints / allLevels;
            int pointsOnLastLevel = pointsOnLevel + NumberOfPoints - pointsOnLevel * allLevels;


            if (pointsOnLevel < 5)
            {
                //no need to overburden the system with separate arrays for very small amounts of points
                allLevels         = 1;
                pointsOnLastLevel = NumberOfPoints;
            }

            float[][] interleavedArrayAtLevel = new float[allLevels][];

            int interleavedDataStride = VBOUtils.PointInformationSize;
            int byteStride            = interleavedDataStride / 4;

            for (int i = 0; i < allLevels; i++)
            {
                if (i == (allLevels - 1))
                {
                    //last(leaf) level also contains all remaining points
                    interleavedArrayAtLevel[i] = new float[pointsOnLastLevel * byteStride]; //10 is for 3*V,3*N and 4*C bytes
                }
                else if (pointsOnLevel > 0)
                {
                    interleavedArrayAtLevel[i] = new float[pointsOnLevel * byteStride];
                }
            }

            int currentLevel        = 0;                                                  //we will iterate mod allLevels so the points are distributed fairly
            int pointIndex          = 0;                                                  //point index inside an array for a level. increased only when we return to locating points to the frst level
            int numAllocatedPoints  = 0;                                                  //counts total number of allcoated point
            int lastPointsThreshold = NumberOfPoints - pointsOnLastLevel + pointsOnLevel; //threshold which determines from where on points are only on the last level

            //generate points for all levels in one iteration over all the points
            for (int j = 0; j < ContainedPointLists.Count; j++)
            {
                Point3D[] pts = ContainedPointLists[j];
                int       len = pts.Length;

                for (int k = 0; k < len; k++)
                {
                    Point3D p = pts[k];

                    //C4
                    GetColorFromPalette(interleavedArrayAtLevel[currentLevel], pallette, pointIndex, p);
                    interleavedArrayAtLevel[currentLevel][pointIndex + 3] = 1;

                    //N3
                    interleavedArrayAtLevel[currentLevel][pointIndex + 4] = p.nx;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 5] = p.nz;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 6] = p.ny;

                    //V3
                    interleavedArrayAtLevel[currentLevel][pointIndex + 7] = p.x + parentTree.positionOffset.x;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 8] = p.z;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 9] = p.y + parentTree.positionOffset.y;

                    numAllocatedPoints++; //increased for every point

                    if (numAllocatedPoints < lastPointsThreshold)
                    {
                        currentLevel++;

                        if (currentLevel == allLevels)
                        {
                            //increase point index only when going back to the first level
                            pointIndex  += byteStride; //3 values for vertices, 3 for colors and 3 for normals
                            currentLevel = 0;
                        }
                    }
                    else
                    {
                        currentLevel = allLevels - 1;
                        pointIndex  += byteStride; //point index is always updated, because we only insert points to the last layer now
                    }
                }
            }
            #endregion

            //only if points wil bedistributed between nodes propagate them up the hierarchy
            if (allLevels > 1)
            {
                //load all arrays into VBOStorageInformation objects and pass them along to parents
                Stack <VBOStorageInformation> vbosForParents = new Stack <VBOStorageInformation>(allLevels - 1); //for parents
                parentVBOs.Clear();

                for (int i = 0; i < allLevels - 1; i++)
                {
                    VBOStorageInformation vbos = VBOUtils.GenerateVBOs(pointsOnLevel);

                    VBOUtils.CopyPointsToVBOs(interleavedArrayAtLevel[i], vbos);

                    //insert into stack so parents can take them out
                    vbosForParents.Push(vbos);
                    parentVBOs.Push(vbos);
                }

                ParentNode.AddVBO(vbosForParents);
            }

            //load also into this leafs VBO
            serverBufferId = VBOUtils.GenerateVBOs(pointsOnLastLevel);

            VBOUtils.CopyPointsToVBOs(interleavedArrayAtLevel[allLevels - 1], serverBufferId);

            ClearAllPoints();
            State = LoadedState.BUFFERED_IN_GPU;
        }