예제 #1
0
        private VertexData buildVertexData()
        {
            VertexData vertexData = new VertexData();

            vertexData.vertexCount = numSamples * numSamples;
            vertexData.vertexStart = 0;

            // set up the vertex declaration
            int vDecOffset = 0;

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float2);

            // create the hardware vertex buffer and set up the buffer binding
            HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(
                vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount,
                BufferUsage.StaticWriteOnly, false);

            vertexData.vertexBufferBinding.SetBinding(0, hvBuffer);

            // lock the vertex buffer
            IntPtr ipBuf = hvBuffer.Lock(BufferLocking.Discard);

            int bufferOff = 0;

            unsafe
            {
                float *buffer          = (float *)ipBuf.ToPointer();
                int    heightMapOffset = 0;

                for (int zIndex = 0; zIndex < numSamples; zIndex++)
                {
                    float z = (zIndex * metersPerSample * WorldManager.oneMeter);

                    for (int xIndex = 0; xIndex < numSamples; xIndex++)
                    {
                        float height = heightMap[heightMapOffset++];

                        // Position
                        float x = (xIndex * metersPerSample * WorldManager.oneMeter);
                        buffer[bufferOff++] = x;
                        buffer[bufferOff++] = height;
                        buffer[bufferOff++] = z;

                        // normals
                        // XXX - this can be optimized quite a bit
                        Vector3 norm = tile.GetNormalAt(new Vector3(x + tile.Location.x, height, z + tile.Location.z));

                        buffer[bufferOff++] = norm.x;
                        buffer[bufferOff++] = norm.y;
                        buffer[bufferOff++] = norm.z;

                        // Texture
                        // XXX - assumes one unit of texture space is one page.
                        //   how does the vertex shader deal with texture coords?
                        buffer[bufferOff++] = (x + location.x - tile.Page.Location.x) /
                                              (WorldManager.Instance.PageSize * WorldManager.oneMeter);
                        buffer[bufferOff++] = (z + location.z - tile.Page.Location.z) /
                                              (WorldManager.Instance.PageSize * WorldManager.oneMeter);
                    }
                }
            }
            hvBuffer.Unlock();

            return(vertexData);
        }