Skip to content

Commit

Permalink
Merge pull request MonoGame#1645 from SickheadGames/GenerateMipmaps
Browse files Browse the repository at this point in the history
DXT and PVRTC Mipmap Generation
  • Loading branch information
KonajuGames committed Apr 15, 2013
2 parents 397b0e2 + cf377a4 commit a3b0db9
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 25 deletions.
64 changes: 46 additions & 18 deletions MonoGame.Framework.Content.Pipeline/Graphics/GraphicsUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ protected bool writeData(IntPtr data, int length)
Marshal.Copy(data, dataBuffer, 0, length);

var texContent = new DXTBitmapContent(_format == Format.DXT1 ? 8 : 16, _levelWidth, _levelHeight);
_content.Faces[0][_currentMipLevel] = texContent;

if (_content.Faces[0].Count == _currentMipLevel)
_content.Faces[0].Add(texContent);
else
_content.Faces[0][_currentMipLevel] = texContent;

_content.Faces[0][_currentMipLevel].SetPixelData(dataBuffer);

return true;
Expand Down Expand Up @@ -143,7 +148,7 @@ internal static bool ColorsEqual(this System.Drawing.Color a, Color b)
/// <summary>
/// Compresses TextureContent in a format appropriate to the platform
/// </summary>
public static void CompressTexture(TextureContent content, TargetPlatform platform, bool premultipliedAlpha)
public static void CompressTexture(TextureContent content, TargetPlatform platform, bool generateMipmaps, bool premultipliedAlpha)
{
// TODO: At the moment, only DXT compression from windows machine is supported
// Add more here as they become available.
Expand All @@ -159,34 +164,49 @@ public static void CompressTexture(TextureContent content, TargetPlatform platfo
case TargetPlatform.MacOSX:
case TargetPlatform.NativeClient:
case TargetPlatform.Xbox360:
CompressDXT(content);
CompressDXT(content, generateMipmaps);
break;

case TargetPlatform.iOS:
CompressPVRTC(content, premultipliedAlpha);
CompressPVRTC(content, generateMipmaps, premultipliedAlpha);
break;

default:
throw new NotImplementedException(string.Format("Texture Compression it not implemented for {0}", platform));
}
}

private static void CompressPVRTC(TextureContent content, bool premultipliedAlpha)
private static void CompressPVRTC(TextureContent content, bool generateMipmaps, bool premultipliedAlpha)
{
// Note: MipGeneration will be done by NVTT, rather than PVRTC's tool.
// This way we have the same implementation across platforms.
// TODO: Once uncompressed mipmap generation is supported, first use NVTT to generate mipmaps,
// then compress them withthe PVRTC tool, so we have the same implementation of mipmap generation
// across platforms.

// Calculate number of mip levels
var width = content.Faces[0][0].Height;
var height = content.Faces[0][0].Width;
var numberOfMipLevels = 1;
if (generateMipmaps)
{
while (height != 1 || width != 1)
{
height = Math.Max(height / 2, 1);
width = Math.Max(width / 2, 1);
numberOfMipLevels++;
}
}

IntPtr dataSizesPtr = IntPtr.Zero;
var texDataPtr = ManagedPVRTC.ManagedPVRTC.CompressTexture(content.Faces[0][0].GetPixelData(),
content.Faces[0][0].Height,
content.Faces[0][0].Width,
1,
numberOfMipLevels,
premultipliedAlpha,
true,
ref dataSizesPtr);

// Store the size of each mipLevel
var dataSizesArray = new int[1];
// Store the size of each mip level
var dataSizesArray = new int[numberOfMipLevels];
Marshal.Copy(dataSizesPtr, dataSizesArray, 0, dataSizesArray.Length);

var levelSize = 0;
Expand All @@ -196,17 +216,25 @@ private static void CompressPVRTC(TextureContent content, bool premultipliedAlph

content.Faces[0].Clear();

levelSize = dataSizesArray[0];
levelData = new byte[levelSize];
for (int x = 0; x < numberOfMipLevels; x++)
{
levelSize = dataSizesArray[x];
levelData = new byte[levelSize];

Marshal.Copy(texDataPtr, levelData, 0, levelSize);

Marshal.Copy(texDataPtr, levelData, 0, levelSize);
var levelWidth = Math.Max(sourceWidth >> x, 1);
var levelHeight = Math.Max(sourceHeight >> x, 1);

var bmpContent = new PVRTCBitmapContent(4, sourceWidth, sourceHeight);
bmpContent.SetPixelData(levelData);
content.Faces[0].Add(bmpContent);
var bmpContent = new PVRTCBitmapContent(4, sourceWidth, sourceHeight);
bmpContent.SetPixelData(levelData);
content.Faces[0].Add(bmpContent);

texDataPtr = IntPtr.Add(texDataPtr, levelSize);
}
}

private static void CompressDXT(TextureContent content)
private static void CompressDXT(TextureContent content, bool generateMipmaps)
{
var texData = content.Faces[0][0];

Expand All @@ -227,7 +255,7 @@ private static void CompressDXT(TextureContent content)
var dataPtr = dataHandle.AddrOfPinnedObject();

inputOptions.SetMipmapData(dataPtr, texData.Width, texData.Height, 1, 0, 0);
inputOptions.SetMipmapGeneration(false);
inputOptions.SetMipmapGeneration(generateMipmaps);

var containsFracAlpha = ContainsFractionalAlpha(pixelData);
var outputOptions = new OutputOptions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public override SpriteFontContent Process(FontDescription input,
output.Texture.Faces.Add(new MipmapChain(bitmapContent));
}

GraphicsUtil.CompressTexture(output.Texture, context.TargetPlatform, false);
GraphicsUtil.CompressTexture(output.Texture, context.TargetPlatform, false, false);

return output;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,15 @@ public override TextureContent Process(TextureContent input, ContentProcessorCon
}
}

if (GenerateMipmaps)
throw new NotImplementedException();

// TODO: Set all mip level data
// Set the first layer
input.Faces[0][0].SetPixelData(input._bitmap.GetData());

if (TextureFormat == TextureProcessorOutputFormat.NoChange)
return input;

if (TextureFormat == TextureProcessorOutputFormat.DXTCompressed ||
TextureFormat == TextureProcessorOutputFormat.Compressed )
GraphicsUtil.CompressTexture(input, context.TargetPlatform, PremultiplyAlpha);
GraphicsUtil.CompressTexture(input, context.TargetPlatform, GenerateMipmaps, PremultiplyAlpha);

return input;
}
Expand Down
1 change: 1 addition & 0 deletions Tools/MGCB/BuildContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public void AddProcessorParam(string nameAndValue)
return;
}

_processorParams.Remove(keyAndValue[0]);
_processorParams.Add(keyAndValue[0], keyAndValue[1]);
}

Expand Down
4 changes: 3 additions & 1 deletion Tools/MGCB/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;

namespace MGCB
Expand All @@ -22,7 +23,8 @@ static int Main(string[] args)
#if WINDOWS
// Set the correct directory for our dependency files.
var is32Bit = IntPtr.Size == 4;
var directory = string.Format("Dependencies{0}{1}", Path.DirectorySeparatorChar, is32Bit ? "x32" : "x64");
var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
string.Format("Dependencies{0}{1}", Path.DirectorySeparatorChar, is32Bit ? "x32" : "x64"));
SetDllDirectory(directory);
#endif

Expand Down

0 comments on commit a3b0db9

Please sign in to comment.