Search code examples
c++opengltextures

What is the difference between glGenTextures and glGenSamplers?


I am following a tutorial to handle loading in textures, it has this method in it :

void CTexture::CreateEmptyTexture(int a_iWidth, int a_iHeight, GLenum format)
{
glGenTextures(1, &uiTexture);
glBindTexture(GL_TEXTURE_2D, uiTexture);
if(format == GL_RGBA || format == GL_BGRA)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, a_iWidth, a_iHeight, 0, format, GL_UNSIGNED_BYTE, NULL);
// We must handle this because of internal format parameter
else if(format == GL_RGB || format == GL_BGR)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, a_iWidth, a_iHeight, 0, format, GL_UNSIGNED_BYTE, NULL);
else
    glTexImage2D(GL_TEXTURE_2D, 0, format, a_iWidth, a_iHeight, 0, format, GL_UNSIGNED_BYTE, NULL);

glGenSamplers(1, &uiSampler);
}

glGenSamplers is undefined, i assume because it needs GL v3.3 or higher, the labs at my university have GL v3.2 so I can't use it.

I am struggling to work out the difference between glGenTextures and glGenSamplers, are they interchangable?


Solution

  • The can't be used interchangably. Texture objects and sampler objects are different things, but somewhat related in the GL.

    A texture object contains the image data, so it represents what we typically call just "texture". However, traditionally, the texture object in the GL also contains the sampler state. This controls parameters influencing the actual sampling operation of the texture, like filtering, texture coordinate wrap modes, border color, LOD bias and so on. This is not part of what one usually thinks of when the term "texture" is mentioned.

    This combination of texture data and sampler state in a single object is also not how GPUs work. The sampler state is totally independent of the texture image data. A texture can be sampled with GL_NEAREST flitering in one situation and with GL_LINEAR in some other situation. To reflect this, the GL_ARB_sampler_objects GL extension was created.

    A sampler object contains only the state for sampling the texture. It does not contain the image data itself. If a sampler object is currently bound, the sampler state of the texture itself is completely overriden, so only the sampler object defines these parameters. If no sampler object is bound (sampler name 0), the old behavior is used, so that the per-texture sampling parameters are used.

    Using sampler objects is not strictly necessary. In many use cases, the concept of defining the sampling parameters in the texture object itself is quite suitable. And you always can switch the state in the texture object between different draw calls. However, it can be more efficient to use samplers. If you use them, binding a new texture does not require the GL to update the sampler state. Also, with samplers, you can do tricks like binding the same texture to differen units, while using different sampling modes.