Текстуры

GLTexture — OpenGL текстура

Структура для управления текстурами на GPU.

Создание текстуры

// Из RawImage
var image = new RawImage(width, height, pixelData);
var texture = context.CreateTexture(image);

// Текстура готова к использованию
Console.WriteLine($"Размер: {texture.Width}x{texture.Height}");

Параметры текстуры

Параметры устанавливаются через RawImage.Parameters перед созданием:

var image = new RawImage(width, height, pixelData);

image.Parameters = new[]
{
    // Фильтрация
    new TexParameter(TextureParameterName.TextureMinFilter, 
        (int)TextureMinFilter.LinearMipmapLinear),
    new TexParameter(TextureParameterName.TextureMagFilter, 
        (int)TextureMagFilter.Linear),
    
    // Повторение
    new TexParameter(TextureParameterName.TextureWrapS, 
        (int)TextureWrapMode.Repeat),
    new TexParameter(TextureParameterName.TextureWrapT, 
        (int)TextureWrapMode.Repeat),
    
    // Ширина границы (для GL_CLAMP_TO_BORDER)
    new TexParameter(TextureParameterName.TextureBorderColor, 
        new[] { 0f, 0f, 0f, 1f })
};

var texture = context.CreateTexture(image);

Типовые параметры

Параметр Значение Использование
MinFilter Linear плавная фильтрация при уменьшении
MinFilter LinearMipmapLinear с миpmapами (лучше)
MagFilter Linear плавная фильтрация при увеличении
MagFilter Nearest резкая фильтрация (пиксельный стиль)
WrapS/T Repeat плитка (повторение)
WrapS/T ClampToEdge растяжение краёв
WrapS/T MirroredRepeat зеркальное повторение

Использование текстуры

Привязка и отвязка

// Привязать к текущему текстурному блоку
texture.Bind();

// Использовать в шейдере
shader.Apply();
shader.SetUniform("uTexture", 0); // Texture0

// Отвязать
texture.Unbind();

Множественные текстуры

// Активировать блоки и привязать текстуры
context.SetActiveTexture(TextureUnit.Texture0);
albedoTexture.Bind();
shader.SetUniform("uAlbedo", 0);

context.SetActiveTexture(TextureUnit.Texture1);
normalTexture.Bind();
shader.SetUniform("uNormal", 1);

context.SetActiveTexture(TextureUnit.Texture2);
roughnessTexture.Bind();
shader.SetUniform("uRoughness", 2);

// Отрисовка...

Мипмапы

Генерируются автоматически при создании:

// Это происходит в GLTexture конструкторе
var texture = context.CreateTexture(image);
// GL.GenerateMipmap(TextureTarget.Texture2D) уже вызван

Для использования миpmapов установите фильтр:

image.Parameters = new[]
{
    new TexParameter(TextureParameterName.TextureMinFilter,
        (int)TextureMinFilter.LinearMipmapLinear)
};

Загрузка текстур в рендер-системе

Встроенный загрузчик

public class TextureLoadingTask : GraphicsLoadingTask
{
    private readonly string _name;
    private readonly RawImage _image;
    private ITexture _texture;

    public TextureLoadingTask(string name, RawImage image)
    {
        _name = name;
        _image = image;
    }

    protected override void OnLoad()
    {
        _texture = Igdrasil.Context.CreateTexture(_image);
        Igdrasil.Context.GetTextureBuffer().Add(_name, _texture);
        Igdrasil.Logger.Info("Loaded texture: {0}", _name);
    }

    protected override void OnUnload()
    {
        _texture.Dispose();
    }
}

Использование

Igdrasil.AddLoadingTask(
    new TextureLoadingTask("player_albedo", playerImage)
);

// Позже использовать:
var textures = Igdrasil.Context.GetTextureBuffer();
var playerTex = textures["player_albedo"];

Типовый цикл отрисовки текстурированного меша

Igdrasil.OnRender += (ctx, dt) =>
{
    // Очистка
    ctx.ClearColor(new FVector4(0.2f, 0.2f, 0.2f, 1f));
    ctx.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
    
    // Шейдер
    shader.Apply();
    
    // Матрицы
    shader.SetUniform("uModel", modelMatrix, transpose: false);
    shader.SetUniform("uView", viewMatrix, transpose: false);
    shader.SetUniform("uProjection", projMatrix, transpose: false);
    
    // Текстура
    ctx.SetActiveTexture(TextureUnit.Texture0);
    texture.Bind();
    shader.SetUniform("uTexture", 0);
    
    // Геометрия
    vao.Bind();
    vbo.Bind();
    ebo.Bind();
    
    // Отрисовка
    ctx.DrawElements(PrimitiveType.Triangles, 0, indexCount, DrawElementsType.UnsignedInt);
    
    // Очистка
    texture.Unbind();
};

Очистка

texture.Dispose(); // освобождает GPU-память

Версия: 1.0