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

4 thoughts on “OpenGL 3.3 Sampler Objects: Control your Texture Units (Tutorial)”

  1. zqueezy

    wow, didn’t know that either… will simplify some code management in engines (for D3D and OpenGL)

  2. hlide

    It works perfect for nvidia. With ATI (up to 11.8 at least) you must bind a shader program to draw a texture properly when binding a sampler object to it. It looks as if there is a bug when using fix pipeline and sampler objects together on ATI cards (ATI drivers 10.7 and 11.8 were checked buggy). I noticed this bug were relative to fix pipeline because sampler object was only fine when I activated hq2x or FXAA shaders when rendering a texture on the screen buffer.

  3. hlide

    A bug… or not. It’s true that “ARB_sampler_objects” is an OpenGL 3.3 extension, which is probably not supposed to work with fix pipeline according to ATI/AMD viewpoint.

Comments are closed.