This repository has been archived by the owner on Jan 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
SLMCImporter.cs
130 lines (106 loc) · 4.71 KB
/
SLMCImporter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#region License
// Copyright 2019 Kastellanos Nikolaos
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Graphics;
namespace tainicom.Aether.Content.Pipeline
{
[ContentImporter(".slmc", DisplayName = "SLMC Importer - Aether", DefaultProcessor = "SLMCProcessor")]
public class SLMCImporter : ContentImporter<TextureContent>
{
public override TextureContent Import(string filename, ContentImporterContext context)
{
Texture2DContent output;
if (Path.GetExtension(filename) != ".slmc")
throw new InvalidContentException("File type not supported.");
var images = ImportSLMC(filename, context);
if (images.Count < 1)
throw new InvalidContentException("Element 'channels' must have at least one 'image'.");
if (images.Count > 4)
throw new InvalidContentException("No more than 4 images are supported.");
int width = images[0].Mipmaps[0].Width;
int height = images[0].Mipmaps[0].Height;
// validate size
foreach (var image in images)
{
if (image.Mipmaps[0].Width != width|| image.Mipmaps[0].Height != height)
throw new InvalidContentException("Images must be of the same size.");
}
var pixelCount = width * height;
var byteCount = pixelCount * 4;
byte[] data = new byte[byteCount];
for (int i = 0; i < images.Count; i++)
{
var image = images[i];
var face = image.Faces[0][0];
var pixelData = face.GetPixelData();
for (int d = 0; d < pixelCount; d++)
{
data[d * 4 + i] = pixelData[d * 4];
}
}
var bitmap = new PixelBitmapContent<Color>(width, height);
bitmap.SetPixelData(data);
output = new Texture2DContent();
output.Faces[0].Add(bitmap);
return output;
}
private IList<Texture2DContent> ImportSLMC(string filename, ContentImporterContext context)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
var channels = xmlDoc.DocumentElement;
if (channels.Name != "channels")
throw new InvalidContentException(String.Format("Root element must be 'channels'."));
TextureImporter txImporter = new TextureImporter();
List<Texture2DContent> images = new List<Texture2DContent>();
foreach (XmlNode imageNode in channels.ChildNodes)
{
if (imageNode.Name != "image")
throw new InvalidContentException(String.Format("Element '{0}' not supported in 'channels'.", imageNode.Name));
var imageSource = GetAttribute(imageNode, "source");
var fullImageSource = Path.Combine(Path.GetDirectoryName(filename), imageSource);
var textureContent = (Texture2DContent)txImporter.Import(fullImageSource, context);
textureContent.Name = Path.GetFileNameWithoutExtension(fullImageSource);
images.Add(textureContent);
}
return images;
}
private static string GetAttribute(XmlNode xmlNode, string attributeName)
{
var attribute = xmlNode.Attributes[attributeName];
if (attribute == null) return null;
return attribute.Value;
}
internal static int GetBitmapSize(SurfaceFormat format, int width, int height)
{
int pixels = width * height;
switch (format)
{
case SurfaceFormat.Dxt1:
return Math.Max(8, (pixels / 2));
default:
throw new NotImplementedException();
}
}
}
}