Текстура OpenTK работает, только если она не связана - PullRequest
3 голосов
/ 01 апреля 2020

Я обычно не работаю с низкоуровневыми связями, так что это может быть что-то глупое, что я упускаю из виду, но я не знаю.

Когда я создаю текстуру из файла, подобного этому

public Texture ( List<byte> pixels, int width, int height ) {
    handle = GL.GenTexture();
    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat );
    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat );
    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest );
    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear );
    GL.TexImage2D( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels.ToArray() );
}

public void Use () {
    GL.Enable( EnableCap.Texture2D );
    GL.ActiveTexture( TextureUnit.Texture0 );
    GL.BindTexture( TextureTarget.Texture2D, handle );
}

А затем визуализируйте это так:

public void Draw () {
    GL.BindVertexArray( VAO );

    //texture.Use();
    shader.Use();

    GL.DrawElements( PrimitiveType.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0 );
}

Практически все работает нормально, пока я не загрузлю другую текстуру. (из-за этого все становится второй текстурой) Возвращаясь к одной текстуре, когда я раскомментирую texture.Use(); Все мои треугольники становятся черными. Что происходит?

Я проверил, какие значения дает GL.GenTexture();, и это 1 и 2, в то время как единственное время, когда текстура рендерится, дескриптор GL.BindTexture равен 0. Установка его в 1 или 2 приводит к треугольники черные.

1 Ответ

2 голосов
/ 01 апреля 2020

GL.GenTexture() не генерирует текстуру, он генерирует (резервирует) идентификатор текстуры (имени), который можно использовать для создания объекта текстуры. Объект текстуры генерируется, когда идентификатор текстуры привязан к цели в первый раз, с помощью GL.BindTexture. GL.TexImage2D указывает двухмерное изображение текстуры (оно резервирует память для изображения и инициализирует изображение) существующего объекта текстуры. GL.TexParameter устанавливает параметры для существующего объекта текстуры. Это означает, что вам необходимо создать объект текстуры с помощью GL.BindTexture, прежде чем вы сможете установить какой-либо параметр текстуры или указать любое изображение текстуры:

public Texture ( List<byte> pixels, int width, int height ) {
    handle = GL.GenTexture();

    GL.BindTexture( TextureTarget.Texture2D, handle ); # <--- THAT IS MISSING

    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat );
    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat );
    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest );
    GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear );
    GL.TexImage2D( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels.ToArray() );
}

Обратите внимание, что текущая связанная текстура является глобальными состояниями, и это состояние сохранено, пока это не изменено снова. GL.TexImage2D определяет изображение текстуры текущей связанной текстуры.
Поскольку ваша исходная функция Texture не связывает какой-либо объект текстуры, GL.TexImage2D указывает изображение текстуры этой текстуры, которое случайно связано с Texture2D цель текущего текстурного блока в то время.

...