Esempio n. 1
0
        /// <summary>
        ///     Dispose the hardware index and vertex buffers
        /// </summary>
        public virtual void Dispose()
        {
            indexData.indexBuffer.Dispose();
            VertexBufferBinding bindings = vertexData.vertexBufferBinding;

            for (ushort b = 0; b < bindings.BindingCount; ++b)
            {
                bindings.GetBuffer(b).Dispose();
            }
        }
        public unsafe void CalculateNormals()
        {
            Vector3 normal;

            HardwareVertexBuffer buffer  = null;
            VertexBufferBinding  binding = terrain.vertexBufferBinding;

            if (binding != null)
            {
                buffer = binding.GetBuffer(NORMAL);
            }
            else
            {
                // int i = 0;
            }


            IntPtr norm = buffer.Lock(BufferLocking.Discard);

            float *normPtr = (float *)norm.ToPointer();
            int    count   = 0;

            for (int j = 0; j < size; j++)
            {
                for (int i = 0; i < size; i++)
                {
                    GetNormalAt(GetVertex(i, j, 0), GetVertex(i, j, 2), out normal);

                    normPtr[count++] = normal.x;
                    normPtr[count++] = normal.y;
                    normPtr[count++] = normal.z;
                }
            }

            buffer.Unlock();
        }
Esempio n. 3
0
        public void Build(bool stencilShadows, bool logDetails)
        {
            // Ok, here's where we transfer the vertices and indexes to the shared buffers
            VertexDeclaration   dcl   = vertexData.vertexDeclaration;
            VertexBufferBinding binds = vertexData.vertexBufferBinding;

            // create index buffer, and lock
            if (logDetails)
            {
                log.InfoFormat("GeometryBucket.Build: Creating index buffer indexType {0} indexData.indexCount {1}",
                               indexType, indexData.indexCount);
            }
            indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(indexType, indexData.indexCount, BufferUsage.StaticWriteOnly);
            IntPtr indexBufferIntPtr = indexData.indexBuffer.Lock(BufferLocking.Discard);

            // create all vertex buffers, and lock
            ushort b;
            ushort posBufferIdx = dcl.FindElementBySemantic(VertexElementSemantic.Position).Source;

            List <List <VertexElement> > bufferElements = new List <List <VertexElement> >();

            unsafe {
                byte *[] destBufferPtrs = new byte *[binds.BindingCount];
                for (b = 0; b < binds.BindingCount; ++b)
                {
                    int vertexCount = vertexData.vertexCount;
                    if (logDetails)
                    {
                        log.InfoFormat("GeometryBucket.Build b {0}, binds.BindingCount {1}, vertexCount {2}, dcl.GetVertexSize(b) {3}",
                                       b, binds.BindingCount, vertexCount, dcl.GetVertexSize(b));
                    }
                    // Need to double the vertex count for the position buffer
                    // if we're doing stencil shadows
                    if (stencilShadows && b == posBufferIdx)
                    {
                        vertexCount = vertexCount * 2;
                        if (vertexCount > maxVertexIndex)
                        {
                            throw new Exception("Index range exceeded when using stencil shadows, consider " +
                                                "reducing your region size or reducing poly count");
                        }
                    }
                    HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(dcl.GetVertexSize(b), vertexCount, BufferUsage.StaticWriteOnly);
                    binds.SetBinding(b, vbuf);
                    IntPtr pLock = vbuf.Lock(BufferLocking.Discard);
                    destBufferPtrs[b] = (byte *)pLock.ToPointer();
                    // Pre-cache vertex elements per buffer
                    bufferElements.Add(dcl.FindElementBySource(b));
                }

                // iterate over the geometry items
                int         indexOffset  = 0;
                IEnumerator iter         = queuedGeometry.GetEnumerator();
                Vector3     regionCenter = parent.Parent.Parent.Center;
                int *       pDestInt     = (int *)indexBufferIntPtr.ToPointer();
                ushort *    pDestUShort  = (ushort *)indexBufferIntPtr.ToPointer();
                foreach (QueuedGeometry geom in queuedGeometry)
                {
                    // copy indexes across with offset
                    IndexData srcIdxData = geom.geometry.indexData;
                    IntPtr    srcIntPtr  = srcIdxData.indexBuffer.Lock(BufferLocking.ReadOnly);
                    if (indexType == IndexType.Size32)
                    {
                        int *pSrcInt = (int *)srcIntPtr.ToPointer();
                        for (int i = 0; i < srcIdxData.indexCount; i++)
                        {
                            *pDestInt++ = (*pSrcInt++) + indexOffset;
                        }
                    }
                    else
                    {
                        ushort *pSrcUShort = (ushort *)(srcIntPtr.ToPointer());
                        for (int i = 0; i < srcIdxData.indexCount; i++)
                        {
                            *pDestUShort++ = (ushort)((*pSrcUShort++) + indexOffset);
                        }
                    }
                    srcIdxData.indexBuffer.Unlock();

                    // Now deal with vertex buffers
                    // we can rely on buffer counts / formats being the same
                    VertexData          srcVData = geom.geometry.vertexData;
                    VertexBufferBinding srcBinds = srcVData.vertexBufferBinding;
                    for (b = 0; b < binds.BindingCount; ++b)
                    {
                        // Iterate over vertices
                        destBufferPtrs[b] = CopyVertices(srcBinds.GetBuffer(b), destBufferPtrs[b], bufferElements[b], geom, regionCenter);
                    }
                    indexOffset += geom.geometry.vertexData.vertexCount;
                }
            }

            // unlock everything
            indexData.indexBuffer.Unlock();
            for (b = 0; b < binds.BindingCount; ++b)
            {
                binds.GetBuffer(b).Unlock();
            }

            // If we're dealing with stencil shadows, copy the position data from
            // the early half of the buffer to the latter part
            if (stencilShadows)
            {
                unsafe
                {
                    HardwareVertexBuffer buf = binds.GetBuffer(posBufferIdx);
                    IntPtr src  = buf.Lock(BufferLocking.Normal);
                    byte * pSrc = (byte *)src.ToPointer();
                    // Point dest at second half (remember vertexcount is original count)
                    byte *pDst = pSrc + buf.VertexSize * vertexData.vertexCount;

                    int count = buf.VertexSize * buf.VertexCount;
                    while (count-- > 0)
                    {
                        *pDst++ = *pSrc++;
                    }
                    buf.Unlock();

                    // Also set up hardware W buffer if appropriate
                    RenderSystem rend = Root.Instance.RenderSystem;
                    if (null != rend && rend.Caps.CheckCap(Capabilities.VertexPrograms))
                    {
                        buf = HardwareBufferManager.Instance.CreateVertexBuffer(sizeof(float), vertexData.vertexCount * 2, BufferUsage.StaticWriteOnly, false);
                        // Fill the first half with 1.0, second half with 0.0
                        float *pW = (float *)buf.Lock(BufferLocking.Discard).ToPointer();
                        for (int v = 0; v < vertexData.vertexCount; ++v)
                        {
                            *pW++ = 1.0f;
                        }
                        for (int v = 0; v < vertexData.vertexCount; ++v)
                        {
                            *pW++ = 0.0f;
                        }
                        buf.Unlock();
                        vertexData.hardwareShadowVolWBuffer = buf;
                    }
                }
            }
        }
        public void Init(TerrainOptions options)
        {
            this.options = options;

            numMipMaps = options.maxMipmap;
            size       = options.size;

            terrain             = new VertexData();
            terrain.vertexStart = 0;
            // Turbo: appended factor 3
            //        Not sure about that, but without that the terrain manager seems
            //        to mess up memory because of buffer overruns
            //terrain.vertexCount = options.size * options.size;
            terrain.vertexCount = options.size * options.size * 3;

            VertexDeclaration   decl    = terrain.vertexDeclaration;
            VertexBufferBinding binding = terrain.vertexBufferBinding;

            int offset = 0;

            // Position/Normal
            decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position);
            decl.AddElement(NORMAL, 0, VertexElementType.Float3, VertexElementSemantic.Normal);

            // TexCoords
            decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            // TODO: Color

            HardwareVertexBuffer buffer =
                HardwareBufferManager.Instance.CreateVertexBuffer(
                    decl.GetVertexSize(POSITION),
                    terrain.vertexCount,
                    BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(POSITION, buffer);


            buffer =
                HardwareBufferManager.Instance.CreateVertexBuffer(
                    decl.GetVertexSize(NORMAL),
                    terrain.vertexCount,
                    BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(NORMAL, buffer);

            buffer =
                HardwareBufferManager.Instance.CreateVertexBuffer(
                    offset,
                    terrain.vertexCount,
                    BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(TEXCOORD, buffer);

            minLevelDistSqr = new float[numMipMaps];

            int endx = options.startx + options.size;
            int endz = options.startz + options.size;

            // TODO: name buffers different so we can unlock
            HardwareVertexBuffer posBuffer = binding.GetBuffer(POSITION);
            IntPtr pos = posBuffer.Lock(BufferLocking.Discard);

            HardwareVertexBuffer texBuffer = binding.GetBuffer(TEXCOORD);
            IntPtr tex = texBuffer.Lock(BufferLocking.Discard);

            float min = 99999999, max = 0;

            unsafe {
                float *posPtr = (float *)pos.ToPointer();
                float *texPtr = (float *)tex.ToPointer();

                int posCount = 0;
                int texCount = 0;

                for (int j = options.startz; j < endz; j++)
                {
                    for (int i = options.startx; i < endx; i++)
                    {
                        float height = options.GetWorldHeight(i, j) * options.scaley;

                        posPtr[posCount++] = (float)i * options.scalex;
                        posPtr[posCount++] = height;
                        posPtr[posCount++] = (float)j * options.scalez;

                        texPtr[texCount++] = (float)i / (float)options.worldSize;
                        texPtr[texCount++] = (float)j / (float)options.worldSize;

                        texPtr[texCount++] = ((float)i / (float)options.size) * (float)options.detailTile;
                        texPtr[texCount++] = ((float)j / (float)options.size) * (float)options.detailTile;

                        if (height < min)
                        {
                            min = height;
                        }

                        if (height > max)
                        {
                            max = height;
                        }
                    } // for i
                }     // for j
            }         // unsafe

            // unlock the buffers
            posBuffer.Unlock();
            texBuffer.Unlock();

            box.SetExtents(
                new Vector3((float)options.startx * options.scalex, min, (float)options.startz * options.scalez),
                new Vector3((float)(endx - 1) * options.scalex, max, (float)(endz - 1) * options.scalez));


            center = new Vector3((options.startx * options.scalex + endx - 1) / 2,
                                 (min + max) / 2,
                                 (options.startz * options.scalez + endz - 1) / 2);

            float C = CalculateCFactor();

            CalculateMinLevelDist2(C);
        }
Esempio n. 5
0
        public void Init(TerrainOptions options)
        {
            this.options = options;

            this.numMipMaps = options.maxMipmap;
            this.size       = options.size;

            this.terrain             = new VertexData();
            this.terrain.vertexStart = 0;

            this.terrain.vertexCount = options.size * options.size;

            VertexDeclaration   decl    = this.terrain.vertexDeclaration;
            VertexBufferBinding binding = this.terrain.vertexBufferBinding;

            int offset = 0;

            // Position/Normal
            decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position);
            decl.AddElement(NORMAL, 0, VertexElementType.Float3, VertexElementSemantic.Normal);

            // TexCoords
            decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1);
            offset += VertexElement.GetTypeSize(VertexElementType.Float2);
            // TODO: Color

            HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(POSITION),
                                                                                            this.terrain.vertexCount,
                                                                                            BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(POSITION, buffer);

            buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(NORMAL), this.terrain.vertexCount,
                                                                       BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(NORMAL, buffer);

            buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(TEXCOORD), this.terrain.vertexCount,
                                                                       BufferUsage.StaticWriteOnly, true);

            binding.SetBinding(TEXCOORD, buffer);

            this.minLevelDistSqr = new float[this.numMipMaps];

            int endx = options.startx + options.size;
            int endz = options.startz + options.size;

            // TODO: name buffers different so we can unlock
            HardwareVertexBuffer posBuffer = binding.GetBuffer(POSITION);
            var pos = posBuffer.Lock(BufferLocking.Discard);

            HardwareVertexBuffer texBuffer = binding.GetBuffer(TEXCOORD);
            var tex = texBuffer.Lock(BufferLocking.Discard);

            float min = 99999999, max = 0;

#if !AXIOM_SAFE_ONLY
            unsafe
#endif
            {
                var posPtr = pos.ToFloatPointer();
                var texPtr = tex.ToFloatPointer();

                int posCount = 0;
                int texCount = 0;

                for (int j = options.startz; j < endz; j++)
                {
                    for (int i = options.startx; i < endx; i++)
                    {
                        float height = options.GetWorldHeight(i, j) * options.scaley;

                        posPtr[posCount++] = i * options.scalex;
                        posPtr[posCount++] = height;
                        posPtr[posCount++] = j * options.scalez;

                        texPtr[texCount++] = (float)i / options.worldSize;
                        texPtr[texCount++] = (float)j / options.worldSize;

                        texPtr[texCount++] = ((float)i / options.size) * options.detailTile;
                        texPtr[texCount++] = ((float)j / options.size) * options.detailTile;

                        if (height < min)
                        {
                            min = height;
                        }

                        if (height > max)
                        {
                            max = height;
                        }
                    }     // for i
                }         // for j
            }             // unsafe

            // unlock the buffers
            posBuffer.Unlock();
            texBuffer.Unlock();

            this.box.SetExtents(new Vector3(options.startx * options.scalex, min, options.startz * options.scalez),
                                new Vector3((endx - 1) * options.scalex, max, (endz - 1) * options.scalez));

            this.center = new Vector3((options.startx * options.scalex + endx - 1) / 2, (min + max) / 2,
                                      (options.startz * options.scalez + endz - 1) / 2);

            float C = CalculateCFactor();

            CalculateMinLevelDist2(C);
        }
Esempio n. 6
0
        public void Load()
        {
            if (inUse == false)
            {
                return;
            }

            bool bLit             = Options.Instance.Lit;
            bool bColored         = Options.Instance.Colored;
            bool bCoverage        = Options.Instance.Coverage_Vertex_Color;
            bool bBase            = Options.Instance.Base_Vertex_Color;
            bool bShadowed        = Options.Instance.Vertex_Shadowed;
            bool bInstant_colored = Options.Instance.Vertex_Instant_Colored;

            float scale_x = Options.Instance.Scale.x;
            float scale_z = Options.Instance.Scale.z;

//			VertexDeclaration decl = renderOp.vertexData.vertexDeclaration;
            VertexBufferBinding bind = renderOp.vertexData.vertexBufferBinding;

//		    float[] matHeight = new float[2];
//		    matHeight[0] = Options.Instance.MatHeight[0];
//			matHeight[1] = Options.Instance.MatHeight[1];
//			float absmaxHeight = Data2DManager.Instance.GetMaxHeight();

            // Calculate the offset in the data
            long tileSize = Options.Instance.TileSize;
//			long offSetX = info.TileX * tileSize;
//			long offSetZ = info.TileZ * tileSize;
            long offSetX = 0;
            long offSetZ = 0;
            long endx    = offSetX + tileSize;
            long endz    = offSetZ + tileSize;

            //calculate min and max heights;
            float min = 99999999.9f;
            float max = 0.0f;

            float Aux1 = ( float )1.0f / (Options.Instance.PageSize - 1);

            long pageSize = Options.Instance.PageSize;

            float[] HeightData = Data2DManager.Instance.GetData2D(info.PageX, info.PageZ).HeightData;
//			long HeightDataPos = offSetZ * pageSize;
            long  HeightDataPos = (info.TileZ * tileSize * pageSize) + (info.TileX * tileSize);
            float Tex1DataPos   = info.TileX * tileSize;
            float Tex2DataPos   = info.TileZ * tileSize;

            HardwareVertexBuffer vVertices = bind.GetBuffer(POSITION);
//			HardwareVertexBuffer vNormals;
//			HardwareVertexBuffer vTextures = bind.GetBuffer(TEXCOORD);
//			HardwareVertexBuffer vColors;
//			if (  Options.Instance.Lit) vNormals  = bind.GetBuffer(NORMAL);;
//			if (Options.Instance.Colored  ||
//				Options.Instance.Coverage_Vertex_Color ||
//				Options.Instance.Base_Vertex_Color)
//			{
//				vColors = bind.GetBuffer(COLORS);
//			}
//
            IntPtr ipPos = vVertices.Lock(BufferLocking.Discard);
//			IntPtr ipTex = vTextures.Lock(BufferLocking.Discard);
//			IntPtr ipNrm = vNormals.Lock(BufferLocking.Discard);
//			IntPtr ipClr = vColors.Lock(BufferLocking.Discard);

            int cntPos = 0;

//			int cntTex = 0;
//			int cntNrm = 0;
//			int cntClr = 0;

            unsafe
            {
                float *pPos = (float *)ipPos.ToPointer();
//				float* pNrm = (float *)ipNrm.ToPointer();
//				float* pTex = (float *)ipTex.ToPointer();
//				float* pClr = (float *)ipClr.ToPointer();

                for (long k = offSetZ; k <= endz; k++)
                {
                    float posZ = ( float )(k - offSetZ) * scale_z;

                    for (long i = offSetX; i <= endx; i++)
                    {
                        float height = HeightData[i + HeightDataPos];
//
//						min = Math.Min(height, min);
//						max = Math.Max(height, max);
                        min = height < min ? height : min;
                        max = height > max ? height : max;
//
//						// Position
                        pPos[cntPos++] = ( float )((i - offSetX) * scale_x);                                    //X
                        pPos[cntPos++] = height;                                                                //Y
                        pPos[cntPos++] = posZ;                                                                  //Z
//
                        // normals
                        Vector3 norm;
                        if (bLit == true)
                        {
                            norm           = Data2DManager.Instance.GetNormalAt(info.PageX, info.PageZ, (info.TileX * tileSize) + i, (info.TileZ * tileSize) + k);
                            pPos[cntPos++] = norm.x;
                            pPos[cntPos++] = norm.y;
                            pPos[cntPos++] = norm.z;
#if _VisibilityCheck
                            //TODO: This must be moved to Preprocessing phase
                            mTmpAngle = mConeNormal.dotProduct(norm);
                            if (mTmpAngle > mAngle)
                            {
                                mAngle = mTmpAngle;
                            }
                            mConeNormal += norm;
                            mConeNormal.normalise();
#endif
                        }

                        // Texture
                        pPos[cntPos++] = (Tex1DataPos + i) * Aux1;                         //Tex1DataPos;
                        pPos[cntPos++] = (Tex2DataPos + k) * Aux1;                         //Tex2DataPos;
//						pTex[cntTex++] = (Tex1DataPos + k) * Aux1; //Tex2DataPos;
//						pTex[cntTex++] = (Tex2DataPos + i) * Aux1; //Tex1DataPos;

                        // Colors
                        //Tex2DataPos += Aux1;
                    }
                    //Tex2DataPos += Aux1;
                    HeightDataPos += pageSize;
                }
            }
            vVertices.Unlock();
//			vTextures.Unlock();

            box.SetExtents(new Vector3(0.0F,
                                       min,
                                       0.0F),
                           new Vector3(((float)tileSize) * scale_x,
                                       max,
                                       ((float)tileSize) * scale_z));

            worldBoundingSphere.Center = box.Center;
            worldBoundingSphere.Radius = box.Maximum.Length;

            isLoaded   = true;
            needReload = false;
        }