Yakov Galka
Yakov Galka

Reputation: 72479

Get texture target by texture id

glBindTextures is a nice function, not only because it binds multiple textures in one call, but also because it knows to bind each texture to "the target [...] that was specified when the object was created". This way I can specify the target only at texture creation and then forget about it, which helps in generic code.

Unfortunately, I must know the target when calling functions like glGetTexParamater. Is there a way to retrieve the texture target from the texture id? Widely supported extensions are also ok.

Upvotes: 7

Views: 3931

Answers (3)

Yakov Galka
Yakov Galka

Reputation: 72479

Since OpenGL 4.5 this can be done by:

GLenum target;
glGetTextureParameteriv(textureId, GL_TEXTURE_TARGET, (GLint*)&target);

It's also true that since the introduction of the direct-state-access API (DSA) in OpenGL 4.5, knowing the target of the texture became not as useful.

Upvotes: 3

Reto Koradi
Reto Koradi

Reputation: 54592

There really isn't a pretty way to do this that I could find, even after looking at the state tables in the specs. Two possibilities that are both far from attractive:

  1. Try binding it to various targets, and see if you get a GL_INVALID_OPERATION error:

    glBindTexture(GL_TEXTURE_1D, texId);
    if (glGetError() != GL_INVALID_OPERATION) {
        return GL_TEXTURE_1D;
    }
    glBindTexture(GL_TEXTURE_2D, texId);
    if (glGetError() != GL_INVALID_OPERATION) {
        return GL_TEXTURE_2D;
    }
    ...
    
  2. This is similar to what @glamplert suggested. Bind the texture to a given texture unit with glBindTextures(), and then query the textures bound to the various targets for that unit:

    glBindTextures(texUnit, 1, &texId);
    glActiveTexture(GL_TEXTURE0 + texUnit);
    GLuint boundId = 0;
    glGetIntegerv(GL_TEXTURE_BINDING_1D, &boundId);
    if (boundId == texId) {
        return GL_TEXTURE_1D;
    }
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundId);
    if (boundId == texId) {
        return GL_TEXTURE_2D;
    }
    

But I think you would be much happier if you simply store away which target is used for each texture when you first create it.

Upvotes: 2

glampert
glampert

Reputation: 4411

As far as I know, there isn't.

A possible workaround could be querying the current binding for every texture target used by your application and compare the current texture against the id you have.

GLuint currentTex;

glGetIntegerv(GL_TEXTURE_BINDING_1D, &currentTex);
if (currentTex == testTex)
{
    target = GL_TEXTURE_1D;
    return;
}

glGetIntegerv(GL_TEXTURE_BINDING_2D, &currentTex);
if (currentTex == testTex)
{
    target = GL_TEXTURE_2D;
    return
}

// and so on ...

Of course that you must have a texture bound for this to work. If binding with glBindTexture then you need the target anyway.

But this solution is so clumsy and non-scalable that it is generally much easier to just keep an extra int together with the id for the texture target.

Upvotes: 4

Related Questions