Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get texture target by texture id

Tags:

opengl

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.

like image 337
Yakov Galka Avatar asked Aug 09 '14 17:08

Yakov Galka


3 Answers

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.

like image 181
glampert Avatar answered Oct 27 '22 01:10

glampert


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.

like image 27
Yakov Galka Avatar answered Oct 27 '22 02:10

Yakov Galka


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.

like image 2
Reto Koradi Avatar answered Oct 27 '22 00:10

Reto Koradi