Skip to content

Commit

Permalink
1.1 - Adds RGB/RGBA support provided by shaw/ducakar in #1
Browse files Browse the repository at this point in the history
  • Loading branch information
sarbian committed Oct 14, 2014
1 parent c77c798 commit 475acfc
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 23 deletions.
112 changes: 92 additions & 20 deletions DatabaseLoaderTexture_DDS.cs
@@ -1,4 +1,6 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
Expand All @@ -8,7 +10,13 @@ namespace DDSLoader
[DatabaseLoaderAttrib(new[] {"dds"})]
public class DatabaseLoaderTexture_DDS : DatabaseLoader<GameDatabase.TextureInfo>
{
private const int DDSD_MIPMAPCOUNT_BIT = 0x00020000;
private const int DDPF_ALPHAPIXELS = 0x00000001;
private const int DDPF_FOURCC = 0x00000004;
private const int DDPF_RGB = 0x00000040;

private static string error;
private static bool isCompressed;

public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo file)
{
Expand All @@ -20,16 +28,12 @@ public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo file)
successful = false;
obj = null;
}
else if (!Path.GetFileNameWithoutExtension(file.Name).EndsWith("NRM"))
{
GameDatabase.TextureInfo textureInfo = new GameDatabase.TextureInfo(texture, false, false, true);
obj = textureInfo;
successful = true;
}
else
{
// This assume the loaded normal texture is already in the right format
GameDatabase.TextureInfo textureInfo = new GameDatabase.TextureInfo(texture, true, false, true);
bool isNormalMap = Path.GetFileNameWithoutExtension(file.Name).EndsWith("NRM");
GameDatabase.TextureInfo textureInfo = new GameDatabase.TextureInfo(texture, isNormalMap, false,
isCompressed);
obj = textureInfo;
successful = true;
}
Expand All @@ -42,11 +46,23 @@ public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo file)
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205578(v=vs.85).aspx
public static Texture2D LoadDDS(string filename)
{
if (!File.Exists(filename))
{
error = "File does not exist";
return null;
}
using (BinaryReader reader = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
{
int dwMagic = (int)reader.ReadUInt32();
byte[] dwMagic = reader.ReadBytes(4);

if (!fourCCEquals(dwMagic, "DDS "))
{
error = "Invalid DDS file";
return null;
}

int dwSize = (int)reader.ReadUInt32();

//this header byte should be 124 for DDS image files
if (dwSize != 124)
{
Expand All @@ -62,6 +78,11 @@ public static Texture2D LoadDDS(string filename)
int dwDepth = (int)reader.ReadUInt32();
int dwMipMapCount = (int)reader.ReadUInt32();

if ((dwFlags & DDSD_MIPMAPCOUNT_BIT) == 0)
{
dwMipMapCount = 1;
}

// dwReserved1
for (int i = 0; i < 11; i++)
{
Expand All @@ -86,28 +107,79 @@ public static Texture2D LoadDDS(string filename)
int dwReserved2 = (int)reader.ReadUInt32();

long dxtBytesLength = reader.BaseStream.Length - 128;

TextureFormat textureFormat = TextureFormat.ARGB32;
isCompressed = false;

if ((dds_pxlf_dwFlags & DDPF_FOURCC) != 0)
{
// Texture dos not contain RGB data, check FourCC for format
isCompressed = true;

if (fourCC == "DXT1")
if (fourCCEquals(dds_pxlf_dwFourCC, "DXT1"))
{
textureFormat = TextureFormat.DXT1;
}
else if (fourCCEquals(dds_pxlf_dwFourCC, "DXT5"))
{
textureFormat = TextureFormat.DXT5;
}
}
else if ((dds_pxlf_dwFlags & DDPF_RGB) != 0)
{
textureFormat = TextureFormat.DXT1;
// RGB or RGBA format
textureFormat = (dds_pxlf_dwFlags & DDPF_ALPHAPIXELS) != 0
? TextureFormat.RGBA32
: TextureFormat.RGB24;
}
else if (fourCC == "DXT5")
else
{
textureFormat = TextureFormat.DXT5;
error = "Only DXT1, DXT5, RGB24 and RGBA32 are supported";
return null;
}

byte[] dxtBytes = reader.ReadBytes((int)dxtBytesLength);

if (textureFormat == TextureFormat.DXT1 || textureFormat == TextureFormat.DXT5)
// Swap red and blue.
if (!isCompressed)
{
Texture2D texture = new Texture2D(dwWidth, dwHeight, textureFormat, dwMipMapCount > 0);
texture.LoadRawTextureData(dxtBytes);
texture.Apply();
return texture;
int mipmapWidth = dwWidth;
int mipmapHeight = dwHeight;
int lineStart = 0;

for (int i = 0; i < dwMipMapCount; ++i)
{
int mipmapPitch = ((mipmapWidth * dds_pxlf_dwRGBBitCount + 3) / 4) * 4;

for (int y = 0; y < mipmapHeight; ++y, lineStart += mipmapPitch)
{
int pos = lineStart;

for (int x = 0; x < mipmapWidth; ++x, pos += dds_pxlf_dwRGBBitCount)
{
byte r = dxtBytes[pos + 0];
byte b = dxtBytes[pos + 2];

dxtBytes[pos + 0] = b;
dxtBytes[pos + 2] = r;
}
}

mipmapWidth = Math.Max(1, mipmapWidth / 2);
mipmapHeight = Math.Max(1, mipmapHeight / 2);
}
}
error = "Only DXT1 and DXT5 are supported";
return null;

Texture2D texture = new Texture2D(dwWidth, dwHeight, textureFormat, dwMipMapCount > 1);
texture.LoadRawTextureData(dxtBytes);
texture.Apply();
return texture;
}
}

private static bool fourCCEquals(IList<byte> bytes, string s)
{
return bytes[0] == s[0] && bytes[1] == s[1] && bytes[2] == s[2] && bytes[3] == s[3];
}
}
}
6 changes: 3 additions & 3 deletions Properties/AssemblyInfo.cs
Expand Up @@ -32,6 +32,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: KSPAssembly("DDSLoader", 1, 0)]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: KSPAssembly("DDSLoader", 1, 1)]

0 comments on commit 475acfc

Please sign in to comment.