3

I don't usually work with low level binds so this might be something silly that I'm overlooking, but I wouldn't know.

When I create a texture from a file like this

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 );
}

And then render it like this:

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

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

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

Pretty much everything works fine, until I load another texture. ( that makes everything the second texture ) Back to just one texture, when I uncomment texture.Use(); All My triangles turn black. What is going on?

I checked what values the GL.GenTexture(); yields, and it's 1 and 2, while the only time the texture renders, the GL.BindTexture handle is 0. Setting it to 1 or 2 makes the triangles black.

Peri
  • 574
  • 1
  • 3
  • 19
  • `GL.Enable( EnableCap.Texture2D );` is deprecated, its for a compatibility profile context only. It is useless and superfluous, when using a shader program, but that's not causing the issue. – Rabbid76 Apr 01 '20 at 11:30

1 Answers1

2

GL.GenTexture() does not generate a texture, it generates (reserves) a texture (name) id, which can be used to generate a texture object. The texture object is generated when the texture id is bound to a target the first time, by GL.BindTexture. GL.TexImage2D specify a two-dimensional texture image (it reserves the memory for the image and initializes the image) of an existing texture object. GL.TexParameter sets parameters to an existing texture object. That means you have to create the texture object by GL.BindTexture, before you can set any texture parameter or specify any texture image:

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() );
}

Note, the currently bound texture is a global states and that state is kept until it is changed again. GL.TexImage2D specifies the texture image of the currently bound texture.
Since the your original function Texture, doesn't bind any texture object, GL.TexImage2D specifies the texture image of that texture, which is randomly bound to the Texture2D target of the current texture unit, at that time.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174