Загрузка ресурсов
GraphicsLoadingTask
GraphicsLoadingTask — базовый класс для асинхронной загрузки/выгрузки GPU-ресурсов (шейдеры, текстуры, буферы и т.д.).
Базовая реализация
public abstract class GraphicsLoadingTask
{
public bool Loaded { get; private set; }
public void Load()
{
if (Loaded) return;
OnLoad(); // вызовите реализацию
Loaded = true;
}
public void Unload()
{
if (!Loaded) return;
OnUnload();
Loaded = false;
}
protected abstract void OnLoad();
protected abstract void OnUnload();
}
Примеры встроенных задач
ShaderLoadingTask
Загружает шейдер из исходного текста:
// Создаём из исходника
var shaders = new List<ShaderScript>
{
new ShaderScript(ShaderType.Vertex, vertexSource),
new ShaderScript(ShaderType.Fragment, fragmentSource)
};
Igdrasil.LoadShader("myShader", shaders);
// Выгружаем
Igdrasil.UnloadShader("myShader");
RawShaderLoadingTask
Загружает уже скомпилированный шейдер (если у вас есть кеш):
var compiled = new CompiledShaderProgram { /* ... */ };
Igdrasil.LoadShader("precompiled", compiled);
TextureLoadingTask
Загружает текстуру из RawImage:
var image = new RawImage(width, height, pixelData);
Igdrasil.LoadTexture("albedo", image);
Igdrasil.UnloadTexture("albedo");
Очередь загрузки
Все задачи хранятся в глобальной очереди:
// Добавить задачу
var task = new MyLoadingTask();
Igdrasil.AddLoadingTask(task);
// Если Context уже есть, автоматически вызовется task.Load()
// Удалить задачу (выгружает ресурс)
Igdrasil.RemoveLoadingTask(task);
// Получить все задачи
var allTasks = Igdrasil.GraphicsLoaders;
Кастомные задачи
public class TextMeshLoadingTask : GraphicsLoadingTask
{
private readonly string _fontPath;
private Font _font;
public TextMeshLoadingTask(string fontPath)
{
_fontPath = fontPath;
}
protected override void OnLoad()
{
// Загружаем шрифт в GPU
_font = Font.Load(_fontPath);
Igdrasil.Logger.Info("Font loaded: {0}", _fontPath);
}
protected override void OnUnload()
{
// Выгружаем из GPU
_font?.Dispose();
Igdrasil.Logger.Info("Font unloaded: {0}", _fontPath);
}
}
// Использование
Igdrasil.AddLoadingTask(new TextMeshLoadingTask("fonts/arial.ttf"));
Порядок загрузки
Все задачи в очереди выполняются пайплайном в порядке добавления:
// Очередь выполнения:
Igdrasil.AddLoadingTask(task1); // выполнится первой
Igdrasil.AddLoadingTask(task2); // выполнится второй
Igdrasil.AddLoadingTask(task3); // выполнится третьей
// На выгрузку ― в обратном порядке:
// task3, task2, task1
Это важно для зависимостей (например, шейдер перед использованием его текстур).
Обработка ошибок
public class SafeTextureLoadingTask : GraphicsLoadingTask
{
private readonly string _path;
private readonly RawImage _fallback;
private Texture _texture;
public SafeTextureLoadingTask(string path, RawImage fallback)
{
_path = path;
_fallback = fallback;
}
protected override void OnLoad()
{
try
{
var image = Image.Load(_path);
_texture = CreateTexture(image);
Igdrasil.Logger.Info("Loaded texture: {0}", _path);
}
catch (Exception ex)
{
Igdrasil.Logger.Warning("Failed to load {0}, using fallback: {1}", _path, ex.Message);
_texture = CreateTexture(_fallback);
}
}
protected override void OnUnload()
{
_texture?.Dispose();
}
}
Асинхронная загрузка
Для длительной загрузки используйте TaskManager:
public class AsyncTextureLoadingTask : GraphicsLoadingTask
{
private readonly string _path;
private Texture _texture;
protected override void OnLoad()
{
// Загружаем файл в отдельном потоке
TaskManager.AddTask(async () =>
{
var data = await LoadImageAsync(_path);
// Используем GPU только в главном потоке
_texture = CreateTextureOnMainThread(data);
Igdrasil.Logger.Info("Async loaded: {0}", _path);
});
}
protected override void OnUnload()
{
_texture?.Dispose();
}
}
Версия: 1.0