1
votes

I have a terrible behavior with one of my textures on OpenGL.

After deleting a texture, I create a new one, it generates the same tex number as before, but the texture is incorrect. Also glGetError returns always 0 on every line ! I tried to add glFlush/glFinish after glDeleteTextures but it doesn't change anything ! the texture number seems locked somewhere...why ?

It's single threaded, here the behavior :

//myTexture == 24 is loaded and works correctly
GLboolean bIsTexture = glIsTexture(myTexture); //returns 1 = > ok
glDeleteTextures(1,&myTexture);
bIsTexture = glIsTexture(myTexture); //returns 0 => ok

//Let's create a new texture
glGenTextures(1,&myTexture);//myTexture == 24 (as the glDelete was ok)
glBindTexture(GL_TEXTURE_2D,myTexture);     
bIsTexture = glIsTexture(myTexture); //returns 0 => FAILS
3
It was a mistake in my copy/paste, now it's okPoppyto
FYI, for testing a case like this, probably good idea to manually set myTexture to a different value (maybe max uint) between the two calls, to be sure that myTexture really is being set to the same number in the second call, rather than "doing nothing".ToolmakerSteve

3 Answers

6
votes

Call BindTexture to 0 before creating a texture already bind :

//Let's create a new texture
glBindTexture(GL_TEXTURE_2D,0); // free the old bind texture if deleted
glGenTextures(1,&myTexture);//myTexture == 24 (as the glDelete was ok)
glBindTexture(GL_TEXTURE_2D,myTexture);     
bIsTexture = glIsTexture(myTexture); //returns 1 => Ok
2
votes

Well, you're missing one important step in the commonly used sequence of operations for creating a new texture: Actually allocating it.

//Let's create a new texture

glGenTextures(1,&myTexture);//myTexture == 24 (as the glDelete was ok)
glBindTexture(GL_TEXTURE_2D,myTexture);     

Here you must call either glTexImage2D or glTexStorage to actually allocate the texture object. Before doing so, there's no texture data associated with the generated texture name. This is important: The value(s) generated by glGenTextures are not textures, but texture names (i.e. handles) and while OpenGL states that this should be a texture object already, a buggy driver may interpret it wrongly.

glTexImage2D(…); // <<<<<
bIsTexture = glIsTexture(myTexture); //returns …

Update:

As Andon M. Coleman points out (thanks for that), binding a texture name to a texture target makes texture object (associated to said name). So one should expect glIsTexture to return GL_TRUE in that case. Now here's how reality differs from the ideal world of specification: An actual (buggy) driver may be wrongly implemented and assume a name being associated with a texture object only if there's an actual data storage present, so it might be necessary to do the actual allocation to see the effect.

In practice you normally do the storage allocation quite soon after the name allocation. I presume the test suite the implementer of your driver used does not check for this corner case. Time for writing a bug report.

2
votes

The only thing glIsTexture (...) does is let you know if an OpenGL name (handle) belongs to a texture or not. In fact, OpenGL names are not actually tied to their final purpose until first-use. In the case of your texture name, glIsTexture merely checks to see if the name is associated with a texture; this association takes place the first time you call glBindTexture (...) using the name. glIsTexture does not tell you if the name has an asociated data store (e.g. you called glTexImage2D (...) or in OpenGL 4+ glTexStorage (...)).

Here's an interesting bit of trivia: before OpenGL 3.0, the spec. allowed you to come up with any unused number for an object name and OpenGL would treat it like you had used a glGen___ (...) function to generate the name; this can still be done in compatibility profiles. That is how unimportant the name generation functions were in the grand scheme of things.

The big takeaway here is that names are given their function upon fist use. More importantly glIs___ (...) merely tells you if a name is associated with a particular kind of OpenGL object (not if it is a valid/initialized/... object).


The official explanation of what I just mentioned comes from the OpenGL spec, which states:

The command:

void GenTextures( sizei n, uint *textures );

returns n previously unused texture names in textures. These names are marked as used, for the purposes of GenTextures only, but they acquire texture state and a dimensionality only when they are first bound, just as if they were unused.

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. The resulting texture object is a new state vector, comprising all the state and with the same initial values listed in section 8.21 The new texture object bound to target is, and remains a texture of the dimensionality and type specified by target until it is deleted.



Since this is all that glIsTexture (...) is supposed to do, I would have to assume that this is a driver bug.