protected override void Write(ContentWriter output, TerrainShadeInfo value) { TerrainShadeTag tst = (TerrainShadeTag)value.tag_; output.WriteExternalReference <CompiledEffect>(tst.effect_); output.WriteExternalReference <TextureContent>(tst.splatControl_); output.WriteExternalReference <TextureContent>(tst.base_); output.WriteExternalReference <TextureContent>(tst.r_); output.WriteExternalReference <TextureContent>(tst.g_); output.WriteExternalReference <TextureContent>(tst.b_); output.WriteExternalReference <TextureContent>(tst.a_); output.WriteExternalReference <TextureContent>(tst.nDetail_); output.WriteObject <Texture2DContent>(tst.normalMap_); }
public override TOutput Process(TInput input, ContentProcessorContext context) { input.ConvertBitmapType(typeof(PixelBitmapContent <Single>)); PixelBitmapContent <Single> bm = input.Mipmaps[0] as PixelBitmapContent <Single>; int w = bm.Width; int h = bm.Height; if (((w - 2) & (w - 1)) != 0 || ((h - 2) & (h - 1)) != 0 || w < Page.DataSizeWithoutPad || h < Page.DataSizeWithoutPad) { throw new Microsoft.Xna.Framework.Content.Pipeline.InvalidContentException( String.Format("PageSource texture must be power of 2 plus 1 in each direction, at least {0} pixels; got {1}x{2}.", Page.DataSizeWithPad, w, h), input.Identity); } int wt = (w - 1) / Page.DataSizeWithoutPad; int ht = (h - 1) / Page.DataSizeWithoutPad; int minx = -wt / 2; int minz = -ht / 2; int maxx = minx + wt; int maxz = minz + ht; TOutput ps = new TOutput(); float f = bm.GetPixel(0, 0); bool ok = false; unchecked { for (int z = minz; z < maxz; ++z) { for (int x = minx; x < maxx; ++x) { Page p = new Page(); PageAddress pa = new PageAddress(); pa.X = x; pa.Z = z; PageRect pr = PageAddress.RectFor(pa); p.SetAddress(pa, pr); ushort[] data = new ushort[Page.DataSizeWithPad * Page.DataSizeWithPad]; int[] count = new int[65536]; for (int v = 0; v < Page.DataSizeWithPad; ++v) { for (int u = 0; u < Page.DataSizeWithPad; ++u) { float q = bm.GetPixel(u + (x - minx) * Page.DataSizeWithoutPad, v + (z - minz) * Page.DataSizeWithoutPad); if (q != f) { ok = true; } ushort b; if (q < 0) { b = 0; } else if (q > 1) { b = 65535; } else { b = (ushort)(q * 65535); } count[b]++; data[v * Page.DataSizeWithPad + u] = b; } } int numBins = 0; for (int i = 0; i < 65536; ++i) { if (count[i] != 0) { ++numBins; } } p.SetData(data); ps.AddPage(p); } } } if (!ok) { throw new Microsoft.Xna.Framework.Content.Pipeline.InvalidContentException( String.Format("The input data has all the same value ({0}).", f), input.Identity); } TerrainShadeTag tst = new TerrainShadeTag(); tst.effect_ = context.BuildAsset <EffectContent, CompiledEffect>( new ExternalReference <EffectContent>(tsi_.terrainEffectName_), "EffectProcessor"); tst.splatControl_ = BuildControlTexture(context, tsi_.splatTextureName_); tst.base_ = BuildTexture(context, tsi_.baseSplatTextureName_); tst.r_ = BuildTexture(context, tsi_.rSplatTextureName_); tst.g_ = BuildTexture(context, tsi_.gSplatTextureName_); tst.b_ = BuildTexture(context, tsi_.bSplatTextureName_); tst.a_ = BuildTexture(context, tsi_.aSplatTextureName_); tst.nDetail_ = BuildTexture(context, tsi_.nDetailTextureName_); PixelBitmapContent <Color> normalPixels = new PixelBitmapContent <Color>(w - 1, h - 1); BuildNormalMap(bm, normalPixels); tst.normalMap_ = new Texture2DContent(); tst.normalMap_.Mipmaps = new MipmapChain(normalPixels); tst.normalMap_.GenerateMipmaps(true); NormalizeMipmaps(tst.normalMap_.Mipmaps); tsi_.tag_ = tst; ps.ShadeInfo = tsi_; return(ps); }