简体   繁体   中英

How do you “free” a texture unit?

In order to use a texture unit, we usually bind it to the current process more or less like this:

glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);

GLint loc = glGetUniformLocation(program, "uniform");
//error check

glUniform1i(loc,0);

How do you "free" the texture unit. In other words how do you detach the texture from the texture unit binding point in the current program?

How do you "free" the texture unit. In other words how do you detach the texture from the texture unit binding point in the current program?


You can't "free" the texture unit, but you can bind the default texture object to the texture unit.

See OpenGL 4.6 API Compatibility Profile Specification; 8.1 Texture Objects; page 178 :

Textures in GL are represented by named objects. The name space for texture objects is the unsigned integers, with zero reserved by the GL to represent the default texture object .

...

The binding is effected by calling

 void BindTexture( enum target, uint texture ); 

with target set to the desired texture target and texture set to the unused name.

This means

GLuint defaultTextureObjectID = 0;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, defaultTextureObjectID);

will bind the default texture object to texture unit 0.


Since OpenGL 4.5 it can be used glBindTextureUnit

The command

 void BindTextureUnit( uint unit, uint texture ); 

binds an existing texture object to the texture unit numbered unit . texture must be zero or the name of an existing texture object . When texture is the name of an existing texture object, that object is bound to the target, in the corresponding texture unit, that was specified when the object was created.

So you can use the following too:

glBindTextureUnit( 0, 0 ); // texture unit 0, default texture object (0)

In a strict sense... you can't. You can bind texture object 0, but that is considered a valid texture object (though one with decidedly bizarre behavior). You can use non-DSA functions to fill it with data and use it (mostly) like a regular texture.

Now yes, most modern OpenGL users never use texture object 0. They leave it in the default state, and they treat binding it as having the texture unit not be used. Indeed, passing 0 to glBindTextureUnit causes all texture targets for that texture unit to have 0 bound to them (whereas using a regular object only binds that object's target to that unit, leaving other targets within the unit undisturbed).

All that being said, permit me to give an unusual view on this: you don't have to unbind textures from the context.

If a program isn't using a texture unit, then the fact that something is bound to that unit is irrelevant. A texture being bound to a texture unit doesn't stop you from using other texture units; only the ones the program uses (which match the correct texture type) will actually matter. And deleting textures will cause them to be automatically unbound from the context (but only from the current context; if you have multiple contexts, they'll still be bound there).

So it doesn't really serve a purpose to unbind the texture. Indeed, it can have certain advantages.

If you accidentally use a texture unit with 0 bound (that you conceptually unbound), you may get an OpenGL error. But you may not. If you don't, then you get a texture that contains white pixels. This may or may not be obviously wrong to your code.

By contrast, if you accidentally use a texture unit that has old data bound to it, you will either get an OpenGL error or you will definitely get something that is obviously wrong.

So if you leave the texture there, you are more likely to see a problem if you accidentally don't bind something.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM