OpenGL 3.3 Sampler Objects: Control your Texture Units (Tutorial)



Screenshot from MSI Kombustor
Sampler objects used in MSI Kombustor


This article is also available in french: Les Sampler States OpenGL 3.3: Configurer les Unités de Texture.


I tested today for the first time the sampler objects available with OpenGL 3.3 (more than one year…) in MSI’s Kombustor 2.2.x (in dev). Sampler states or sampler objects are used to define the state of a texture unit, no matter the texture object currently bound to a texture unit. Samplers objects are fully described in this OpenGL spec: GL_ARB_sampler_objects.

OpenGL 3.3 sampler states allow to stick to Direct3D 11 logic and its D3D11_SAMPLER_DESC structure and CreateSamplerState (D3D11 device) and PSSetSamplers (immediat context) functions (lost with device an immediate context? If so check this page out). Before OpenGL 3.3, the state of a texture unit was defined by a texture object (created with glGenTextures) that also includes information about texture data (pixmap). Many things for a texture! Sampler state objects simplify the code with a clear separation between sampler states and texture data and provide a better abstraction of the GPU. And good news: GL sampler states are easy to use.

Now let’s see how to use OpenGL sampler objects.

1 – Sampler object creation and initialization:

GLuint sampler_state = 0;
glGenSamplers(1, &sampler_state);
glSamplerParameteri(sampler_state, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(sampler_state, GL_TEXTURE_WRAP_T, GL_REPEAT);
glSamplerParameteri(sampler_state, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glSamplerParameteri(sampler_state, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glSamplerParameterf(sampler_state, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);

I just created a sampler object that enables linear filtering and 16X anisotropic filtering on any texture unit. The parameters are the same than for a texture object.

2 – Use of the sampler

GLuint texture_unit = 0;
glBindSampler(texture_unit, sampler_state);
...

Really simple: just specify on which texture unit the sample object must be bound. Once bound on a texture unit, the settings of the sampler have priority over the texture object ones. Result: no need to modify the existing code base to add sampler objects. You can leave the creation of the textures like they are (with their own sampler states) and just add the code to manage and use sampler objects.

When a sampler is no longer necessary on a texture unit, just bind the sampler zero:

glBindSampler(texture_unit, 0);

The texture unit will use the sampling states of the current bound texture object.

3 – Sampler releasing:

glDeleteSamplers(1, &sampler_state);

OpenGL logo



Additional readings




Geeks3D.com

↑ Grab this Headline Animator