TextureColor.A32B32G32R32F[][] FixupHeightmap(Texture t, int level, int levelSize, TextureColor.A32B32G32R32F[][][] olddata) { /* Ok so we want to store extra "blending" information * The mipmaps are already calculated * In the R channel we store the heightmap * In the B channel we store the next level blend * * IMPORTANT: Last row and last column are unhandled! * */ TextureColor.A32B32G32R32F[][] data = olddata[level]; for (int y = 0; y < levelSize - 2; y += 2) { for (int x = 0; x < levelSize - 2; x += 2) { TextureColor.A32B32G32R32F cur = olddata[level + 1][y / 2][x / 2]; TextureColor.A32B32G32R32F bottom = olddata[level + 1][y / 2 + 1][x / 2]; TextureColor.A32B32G32R32F right = olddata[level + 1][y / 2][x / 2 + 1]; TextureColor.A32B32G32R32F bottomright = olddata[level + 1][y / 2 + 1][x / 2 + 1]; data[y][x].G = cur.G; data[y][x + 1].G = (cur.G + right.G) / 2; data[y + 1][x].G = (cur.G + bottom.G) / 2; data[y + 1][x + 1].G = (cur.G + bottomright.G) / 2; } } DataRectangle r = t.LockRectangle(level, LockFlags.Discard); for (int y = 0; y < levelSize; y++) { r.Data.WriteRange(data[y]); } t.UnlockRectangle(level); return(data); }
void FixupHeightmap(Texture t, int textureSize) { int levels = (int)Math.Log(textureSize, 2); TextureColor.A32B32G32R32F[][][] data = new TextureColor.A32B32G32R32F[levels][][]; DataRectangle r = t.LockRectangle(0, LockFlags.ReadOnly); data[0] = TextureUtil.ReadTexture <TextureColor.A32B32G32R32F>(r, textureSize); t.UnlockRectangle(0); for (int i = 1; i < levels; i++) { int levelSize = (int)Math.Pow(2, levels - i); data[i] = new TextureColor.A32B32G32R32F[levelSize][]; for (int y = 0; y < levelSize; y++) { data[i][y] = new TextureColor.A32B32G32R32F[levelSize]; for (int x = 0; x < levelSize; x++) { data[i][y][x] = (data[i - 1][y * 2][x * 2] + data[i - 1][y * 2][x * 2 + 1] + data[i - 1][y * 2 + 1][x * 2] + data[i - 1][y * 2 + 1][x * 2 + 1]) / 4f; } } } for (int i = 0; i < levels; i++) { FixupHeightmap(t, i, (int)Math.Pow(2, levels - i), data); } }