public void SetTileShifts(int tileCountX, int tileCountY, int tileSize, int levelSize, int maxShift, float2[] flow)
        {
            _tileCount = tileCountX * tileCountY;
            float w, h;
            float increment;
            float maxSize;
            float shiftBorder = (float)(maxShift * levelSize);

            if (_realImageWidth < _realImageHeight)
            {
                float factor = _realImageWidth / (float)_realImageHeight;
                w            = factor * 0.5f;
                h            = 0.5f;
                increment    = (float)tileSize * (float)levelSize / (float)_realImageHeight;
                maxSize      = 1.0f / _realImageHeight;
                shiftBorder /= _realImageHeight;
            }
            else
            {
                float factor = _realImageHeight / (float)_realImageWidth;
                w            = 0.5f;
                h            = factor * 0.5f;
                increment    = (float)tileSize * (float)levelSize / (float)_realImageWidth;
                maxSize      = 1.0f / _realImageWidth;
                shiftBorder /= _realImageWidth;
            }

            uint color = 0xff00ff00; //green

            linevertex[] linevertices = new linevertex[(_tileCount) * 2];

            for (int y = 0; y < tileCountY; y++)
            {
                for (int x = 0; x < tileCountX; x++)
                {
                    int index = y * tileCountX + x;

                    float2 shift = flow[index] * levelSize * maxSize;

                    float posx = -w + shiftBorder + (x + 0.5f) * increment;
                    float posy = -h + shiftBorder + (y + 0.5f) * increment;
                    linevertices[2 * index]     = new linevertex(posx, posy, 0.1f, color);
                    linevertices[2 * index + 1] = new linevertex(posx + shift.x, posy + shift.y, 0.1f, color);
                }
            }

            if (_vertexBufferFlow != null)
            {
                _vertexBufferFlow.Dispose();
            }

            _vertexBufferFlow = new VertexBuffer(_device, 2 * (_tileCount) * Marshal.SizeOf(typeof(linevertex)), Usage.None, VertexFormat.Position, Pool.Default);


            DataStream str = _vertexBufferFlow.Lock(0, 2 * (_tileCount) * Marshal.SizeOf(typeof(linevertex)), LockFlags.None);

            str.Position = 0;
            str.WriteRange <linevertex>(linevertices);
            _vertexBufferFlow.Unlock();

            updateFrame();
        }
        public void SetTiling(int tileCountX, int tileCountY, int tileSize, int levelSize, int maxShift)
        {
            _tileCount = tileCountX * tileCountY;
            float w, h;
            float increment;
            float shiftBorder = (float)(maxShift * levelSize);

            if (_realImageWidth < _realImageHeight)
            {
                float factor = _realImageWidth / (float)_realImageHeight;
                w            = factor * 0.5f;
                h            = 0.5f;
                increment    = (float)tileSize * (float)levelSize / (float)_realImageHeight;
                shiftBorder /= _realImageHeight;
            }
            else
            {
                float factor = _realImageHeight / (float)_realImageWidth;
                w            = 0.5f;
                h            = factor * 0.5f;
                increment    = (float)tileSize * (float)levelSize / (float)_realImageWidth;
                shiftBorder /= _realImageWidth;
            }

            uint color = 0xffff0000; //red

            linevertex[] linevertices = new linevertex[(_tileCount + 2) * 2];
            int          index        = 0;

            for (int i = 0; i < tileCountX + 1; i++)
            {
                linevertices[index]     = new linevertex(-w + shiftBorder + i * increment, -h + shiftBorder, 0.1f, color);
                linevertices[index + 1] = new linevertex(-w + shiftBorder + i * increment, -h + shiftBorder + tileCountY * increment, 0.1f, color);
                index += 2;
            }
            for (int i = 0; i < tileCountY + 1; i++)
            {
                linevertices[index]     = new linevertex(-w + shiftBorder, -h + shiftBorder + i * increment, 0.1f, color);
                linevertices[index + 1] = new linevertex(-w + shiftBorder + tileCountX * increment, -h + shiftBorder + i * increment, 0.1f, color);
                index += 2;
            }

            if (_vertexBufferTileGrid != null)
            {
                _vertexBufferTileGrid.Dispose();
                _vertexBufferFlow?.Dispose();
                _vertexBufferFlow = null;
            }

            _vertexBufferTileGrid = new VertexBuffer(_device, 2 * (_tileCount + 2) * Marshal.SizeOf(typeof(linevertex)), Usage.None, VertexFormat.Position, Pool.Default);


            DataStream str = _vertexBufferTileGrid.Lock(0, 2 * (_tileCount + 2) * Marshal.SizeOf(typeof(linevertex)), LockFlags.None);

            str.Position = 0;
            str.WriteRange <linevertex>(linevertices);
            _vertexBufferTileGrid.Unlock();

            //_device.SetStreamSource(0, _vertexBufferTileGrid, 0, Marshal.SizeOf(typeof(linevertex)));
            //_device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse;
            //_device.DrawPrimitives(PrimitiveType.LineList, 0, _tileCount + 2);

            updateFrame();
        }