4 using System.Runtime.InteropServices;
5 using System.Collections.Generic;
7 using SiliconStudio.Core;
8 using SiliconStudio.Core.Diagnostics;
9 using SiliconStudio.TextureConverter.Requests;
11 namespace SiliconStudio.TextureConverter.TexLibraries
18 private static Logger Log = GlobalLogger.GetLogger(
"ArrayTexLib");
29 case RequestType.ArrayCreation:
30 case RequestType.ArrayExtraction:
31 case RequestType.ArrayUpdate:
32 case RequestType.ArrayInsertion:
33 case RequestType.ArrayElementRemoval:
34 case RequestType.CubeCreation:
46 case RequestType.ArrayCreation:
49 case RequestType.ArrayExtraction:
52 case RequestType.ArrayUpdate:
55 case RequestType.ArrayInsertion:
58 case RequestType.ArrayElementRemoval:
61 case RequestType.CubeCreation:
66 Log.Error(
"ArrayTexLib can't handle this request: " + request.Type);
74 Marshal.FreeHGlobal(image.Data);
95 array.Width = request.TextureList[0].Width;
96 array.Height = request.TextureList[0].Height;
97 array.Depth = request.TextureList[0].Depth;
98 array.RowPitch = request.TextureList[0].RowPitch;
99 array.SlicePitch = request.TextureList[0].SlicePitch;
100 array.Format = request.TextureList[0].Format;
101 array.FaceCount = request.TextureList[0].FaceCount;
102 array.MipmapCount = request.TextureList[0].MipmapCount;
103 array.DisposingLibrary =
this;
105 array.Name = request.TextureList[0].Name +
"_array";
106 array.ArraySize = request.TextureList.Count;
108 array.SubImageArray =
new TexImage.SubImage[request.TextureList.Count * request.TextureList[0].SubImageArray.Length];
111 array.DataSize = request.TextureList[0].DataSize * array.ArraySize;
113 array.Data = Marshal.AllocHGlobal(array.DataSize);
115 int offset1, offset2;
116 long arrayData = array.Data.ToInt64();
122 for (
int i = 0; i < request.TextureList.Count; ++i)
124 current = request.TextureList[i];
125 buffer =
new IntPtr(arrayData + offset1);
126 offset1 += current.DataSize;
127 Utilities.CopyMemory(buffer, current.Data, current.DataSize);
130 currentData = buffer.ToInt64();
131 for (
int j = 0; j < current.SubImageArray.Length; ++j)
133 array.SubImageArray[i * current.SubImageArray.Length + j] = current.SubImageArray[j];
134 array.SubImageArray[i * current.SubImageArray.Length + j].Data =
new IntPtr(currentData + offset2);
135 offset2 += current.SubImageArray[j].DataSize;
148 Log.Info(
"Creating texture array ...");
150 Create(array, request);
161 Log.Info(
"Creating texture cube ...");
165 image.Dimension = TexImage.TextureDimension.TextureCube;
176 int subImageCount = image.SubImageArray.Length / image.ArraySize;
179 int subImageCountWanted = 0;
180 int newMipMapCount = 0;
181 int curDepth = image.Depth == 1 ? 1 : image.Depth << 1;
182 for (
int i = 0; i < image.MipmapCount; ++i)
184 curDepth = curDepth > 1 ? curDepth >>= 1 : curDepth;
188 subImageCountWanted += curDepth;
193 subImageCountWanted += curDepth;
198 Log.Info(
"Extracting texture " + request.Indice +
" from the texture array ...");
200 request.Texture = (TexImage)image.Clone(
false);
201 request.Texture.ArraySize = 1;
202 request.Texture.MipmapCount = newMipMapCount;
204 request.Texture.SubImageArray =
new TexImage.SubImage[subImageCountWanted];
207 for (
int i = 0; i < subImageCountWanted; ++i)
209 request.Texture.SubImageArray[i] = image.SubImageArray[request.Indice * subImageCount + i];
210 dataSize += request.Texture.SubImageArray[i].SlicePitch;
213 request.Texture.Data = request.Texture.SubImageArray[0].Data;
214 request.Texture.DataSize = dataSize;
218 Log.Info(
"Extracting each texture from the texture array ...");
221 for (
int i = 0; i < image.ArraySize; ++i)
223 texture = (TexImage)image.Clone(
false);
224 texture.ArraySize = 1;
225 texture.SubImageArray =
new TexImage.SubImage[subImageCountWanted];
226 texture.MipmapCount = newMipMapCount;
229 for (
int j = 0; j < subImageCountWanted; ++j)
231 texture.SubImageArray[j] = image.SubImageArray[i * subImageCount + j];
232 dataSize += texture.SubImageArray[j].SlicePitch;
235 texture.Data = texture.SubImageArray[0].Data;
236 texture.DataSize = dataSize;
238 request.Textures.Add(texture);
252 Log.Info(
"Updating texture "+request.Indice+
" in the texture array ...");
254 CheckConformity(array, request.
Texture);
256 int subImageCount = array.SubImageArray.Length / array.ArraySize;
257 int indice = request.Indice * subImageCount;
259 for (
int i = 0; i < subImageCount; ++i)
261 Utilities.CopyMemory(array.SubImageArray[indice].Data, request.Texture.SubImageArray[i].Data, request.Texture.SubImageArray[i].DataSize);
275 Log.Info(
"Inserting texture at rank " + request.Indice +
" in the texture array ...");
277 if (array.Dimension == TexImage.TextureDimension.TextureCube)
279 Log.Error(
"You can't add a texture to a texture cube.");
280 throw new TextureToolsException(
"You can't add a texture to a texture cube.");
283 CheckConformity(array, request.
Texture);
285 int subImageCount = array.SubImageArray.Length / array.ArraySize;
286 int indice = request.Indice * subImageCount;
289 int newSize = array.DataSize + request.Texture.DataSize;
290 IntPtr buffer = Marshal.AllocHGlobal(newSize);
292 long bufferData = buffer.ToInt64();
293 TexImage.SubImage[] subImages =
new TexImage.SubImage[array.SubImageArray.Length + subImageCount];
297 for (
int i = 0; i < indice; ++i)
299 subImages[i] = array.SubImageArray[i];
300 subImages[i].Data =
new IntPtr(bufferData + offset);
301 Utilities.CopyMemory(subImages[i].Data, array.SubImageArray[i].Data, array.SubImageArray[i].DataSize);
302 offset += array.SubImageArray[i].DataSize;
307 for (
int i = 0; i < subImageCount; ++i)
309 subImages[ct] = request.Texture.SubImageArray[i];
310 Utilities.CopyMemory(subImages[ct].Data, request.Texture.SubImageArray[i].Data, request.Texture.SubImageArray[i].DataSize);
311 offset += request.Texture.SubImageArray[i].DataSize;
316 for (
int i = indice; i < array.SubImageArray.Length; ++i)
318 subImages[ct] = array.SubImageArray[i];
319 subImages[ct].Data =
new IntPtr(bufferData + offset);
320 Utilities.CopyMemory(subImages[ct].Data, array.SubImageArray[i].Data, array.SubImageArray[i].DataSize);
321 offset += array.SubImageArray[i].DataSize;
326 if (array.DisposingLibrary != null) array.DisposingLibrary.Dispose(array);
330 array.DataSize = newSize;
332 array.SubImageArray = subImages;
333 array.DisposingLibrary =
this;
345 Log.Info(
"Removing texture at rank " + request.Indice +
" from the texture array ...");
347 if (array.Dimension == TexImage.TextureDimension.TextureCube)
349 Log.Error(
"You can't remove a texture from a texture cube.");
350 throw new TextureToolsException(
"You can't remove a texture from a texture cube.");
353 int subImageCount = array.SubImageArray.Length / array.ArraySize;
354 int indice = request.Indice * subImageCount;
358 for (
int i = 0; i < subImageCount; ++i) elementSize += array.SubImageArray[i].DataSize;
359 int newSize = array.DataSize - elementSize;
360 IntPtr buffer = Marshal.AllocHGlobal(newSize);
362 long bufferData = buffer.ToInt64();
363 TexImage.SubImage[] subImages =
new TexImage.SubImage[array.SubImageArray.Length - subImageCount];
366 for (
int i = 0; i < indice; ++i)
368 subImages[i] = array.SubImageArray[i];
369 subImages[i].Data =
new IntPtr(bufferData + offset);
370 Utilities.CopyMemory(subImages[i].Data, array.SubImageArray[i].Data, array.SubImageArray[i].DataSize);
371 offset += array.SubImageArray[i].DataSize;
375 for (
int i = indice + subImageCount; i < array.SubImageArray.Length; ++i)
377 subImages[indice] = array.SubImageArray[i];
378 subImages[indice].Data =
new IntPtr(bufferData + offset);
379 Utilities.CopyMemory(subImages[indice].Data, array.SubImageArray[i].Data, array.SubImageArray[i].DataSize);
380 offset += array.SubImageArray[i].DataSize;
385 if (array.DisposingLibrary != null) array.DisposingLibrary.Dispose(array);
389 array.DataSize = newSize;
391 array.SubImageArray = subImages;
392 array.DisposingLibrary =
this;
402 private void CheckConformity(TexImage array, TexImage candidate)
404 int subImageCount = array.SubImageArray.Length / array.ArraySize;
405 if (candidate.Width != array.Width || candidate.Height != array.Height || candidate.Depth != array.Depth || candidate.SubImageArray.Length != subImageCount)
407 Log.Error(
"The given texture must match the dimensions of the texture array.");
408 throw new TextureToolsException(
"The given texture must match the dimensions of the texture array.");
List< TexImage > TextureList
The texture list that will populate the cube.
ArrayTexLib()
Initializes a new instance of the ArrayTexLib class.
bool CanHandleRequest(TexImage image, IRequest request)
Allows the creation and manipulation of texture arrays.
void Dispose(TexImage image)
void Execute(TexImage image, IRequest request)
Base implementation for ILogger.
Request to insert a specific texture in a texture array.
TexImage Texture
The new texture.
Request to create a texture array from a texture list.
Request to remove the texture at a specified position from a texture array.
Request to update a specific texture in a texture array.
Request to create a texture cube from a texture list.
Creates a new file, always. If a file exists, the function overwrites the file, clears the existing a...
A structure describing an image of one mip map level (of one member in an array texture).
void StartLibrary(TexImage image)
The remove mixin to remove a mixin from current mixins.
Temporary format containing texture data and information. Used as buffer between texture libraries...
void EndLibrary(TexImage image)
TexImage Texture
The new texture.
Output message to log right away.
override RequestType Type