/*
Copyright © 2010 , 2011 , 2012 Vladimír Vondruš < mosra @ centrum . cz >
This file is part of Magnum .
Magnum is free software : you can redistribute it and / or modify
it under the terms of the GNU Lesser General Public License version 3
only , as published by the Free Software Foundation .
Magnum is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Lesser General Public License version 3 for more details .
*/
# include "AbstractTexture.h"
# include "Buffer.h"
# include "BufferImage.h"
# include "Context.h"
# include "Extensions.h"
# include "Implementation/State.h"
# include "Implementation/TextureState.h"
namespace Magnum {
AbstractTexture : : BindImplementation AbstractTexture : : bindImplementation =
& AbstractTexture : : bindImplementationDefault ;
AbstractTexture : : ParameteriImplementation AbstractTexture : : parameteriImplementation =
& AbstractTexture : : parameterImplementationDefault ;
AbstractTexture : : ParameterfImplementation AbstractTexture : : parameterfImplementation =
& AbstractTexture : : parameterImplementationDefault ;
AbstractTexture : : ParameterfvImplementation AbstractTexture : : parameterfvImplementation =
& AbstractTexture : : parameterImplementationDefault ;
AbstractTexture : : MipmapImplementation AbstractTexture : : mipmapImplementation =
& AbstractTexture : : mipmapImplementationDefault ;
# ifndef MAGNUM_TARGET_GLES
AbstractTexture : : Storage1DImplementation AbstractTexture : : storage1DImplementation =
& AbstractTexture : : storageImplementationDefault ;
# endif
AbstractTexture : : Storage2DImplementation AbstractTexture : : storage2DImplementation =
& AbstractTexture : : storageImplementationDefault ;
AbstractTexture : : Storage3DImplementation AbstractTexture : : storage3DImplementation =
& AbstractTexture : : storageImplementationDefault ;
# ifndef MAGNUM_TARGET_GLES
AbstractTexture : : Image1DImplementation AbstractTexture : : image1DImplementation =
& AbstractTexture : : imageImplementationDefault ;
# endif
AbstractTexture : : Image2DImplementation AbstractTexture : : image2DImplementation =
& AbstractTexture : : imageImplementationDefault ;
AbstractTexture : : Image3DImplementation AbstractTexture : : image3DImplementation =
& AbstractTexture : : imageImplementationDefault ;
# ifndef MAGNUM_TARGET_GLES
AbstractTexture : : SubImage1DImplementation AbstractTexture : : subImage1DImplementation =
& AbstractTexture : : subImageImplementationDefault ;
# endif
AbstractTexture : : SubImage2DImplementation AbstractTexture : : subImage2DImplementation =
& AbstractTexture : : subImageImplementationDefault ;
AbstractTexture : : SubImage3DImplementation AbstractTexture : : subImage3DImplementation =
& AbstractTexture : : subImageImplementationDefault ;
AbstractTexture : : InvalidateImplementation AbstractTexture : : invalidateImplementation = & AbstractTexture : : invalidateImplementationNoOp ;
AbstractTexture : : InvalidateSubImplementation AbstractTexture : : invalidateSubImplementation = & AbstractTexture : : invalidateSubImplementationNoOp ;
# ifndef DOXYGEN_GENERATING_OUTPUT
/* Check correctness of binary OR in setMinificationFilter(). If nobody fucks
anything up , this assert should produce the same results on all dimensions ,
thus testing only on AbstractTexture . */
# define filter_or(filter, mipmap) \
( static_cast < GLint > ( AbstractTexture : : Filter : : filter ) | static_cast < GLint > ( AbstractTexture : : Mipmap : : mipmap ) )
static_assert ( ( filter_or ( NearestNeighbor , BaseLevel ) = = GL_NEAREST ) & &
( filter_or ( NearestNeighbor , NearestLevel ) = = GL_NEAREST_MIPMAP_NEAREST ) & &
( filter_or ( NearestNeighbor , LinearInterpolation ) = = GL_NEAREST_MIPMAP_LINEAR ) & &
( filter_or ( LinearInterpolation , BaseLevel ) = = GL_LINEAR ) & &
( filter_or ( LinearInterpolation , NearestLevel ) = = GL_LINEAR_MIPMAP_NEAREST ) & &
( filter_or ( LinearInterpolation , LinearInterpolation ) = = GL_LINEAR_MIPMAP_LINEAR ) ,
" Unsupported constants for GL texture filtering " ) ;
# undef filter_or
# endif
GLint AbstractTexture : : maxSupportedLayerCount ( ) {
return Context : : current ( ) - > state ( ) - > texture - > maxSupportedLayerCount ;
}
GLfloat AbstractTexture : : maxSupportedAnisotropy ( ) {
GLfloat & value = Context : : current ( ) - > state ( ) - > texture - > maxSupportedAnisotropy ;
/** @todo Re-enable when extension header is available */
# ifndef MAGNUM_TARGET_GLES
/* Get the value, if not already cached */
if ( value = = 0.0f )
glGetFloatv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & value ) ;
# endif
return value ;
}
void AbstractTexture : : destroy ( ) {
/* Moved out */
if ( ! _id ) return ;
/* Remove all bindings */
for ( GLuint & binding : Context : : current ( ) - > state ( ) - > texture - > bindings )
if ( binding = = _id ) binding = 0 ;
glDeleteTextures ( 1 , & _id ) ;
}
void AbstractTexture : : move ( ) {
_id = 0 ;
}
AbstractTexture : : ~ AbstractTexture ( ) { destroy ( ) ; }
AbstractTexture : : AbstractTexture ( AbstractTexture & & other ) : _target ( other . _target ) , _id ( other . _id ) {
other . move ( ) ;
}
AbstractTexture & AbstractTexture : : operator = ( AbstractTexture & & other ) {
destroy ( ) ;
_target = other . _target ;
_id = other . _id ;
other . move ( ) ;
return * this ;
}
void AbstractTexture : : bind ( GLint layer ) {
Implementation : : TextureState * const textureState = Context : : current ( ) - > state ( ) - > texture ;
/* If already bound in given layer, nothing to do */
if ( textureState - > bindings [ layer ] = = _id ) return ;
( this - > * bindImplementation ) ( layer ) ;
}
void AbstractTexture : : bindImplementationDefault ( GLint layer ) {
Implementation : : TextureState * const textureState = Context : : current ( ) - > state ( ) - > texture ;
/* Change to given layer, if not already there */
if ( textureState - > currentLayer ! = layer )
glActiveTexture ( GL_TEXTURE0 + ( textureState - > currentLayer = layer ) ) ;
/* Bind the texture to the layer */
glBindTexture ( _target , ( textureState - > bindings [ layer ] = _id ) ) ;
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : bindImplementationDSA ( GLint layer ) {
glBindMultiTextureEXT ( GL_TEXTURE0 + layer , _target , ( Context : : current ( ) - > state ( ) - > texture - > bindings [ layer ] = _id ) ) ;
}
# endif
AbstractTexture * AbstractTexture : : setMinificationFilter ( Filter filter , Mipmap mipmap ) {
# ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT ( _target ! = GL_TEXTURE_RECTANGLE | | mipmap = = Mipmap : : BaseLevel , " AbstractTexture: rectangle textures cannot have mipmaps " , this ) ;
# endif
( this - > * parameteriImplementation ) ( GL_TEXTURE_MIN_FILTER ,
static_cast < GLint > ( filter ) | static_cast < GLint > ( mipmap ) ) ;
return this ;
}
AbstractTexture * AbstractTexture : : generateMipmap ( ) {
# ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT ( _target ! = GL_TEXTURE_RECTANGLE , " AbstractTexture: rectangle textures cannot have mipmaps " , this ) ;
# endif
( this - > * mipmapImplementation ) ( ) ;
return this ;
}
void AbstractTexture : : mipmapImplementationDefault ( ) {
bindInternal ( ) ;
glGenerateMipmap ( _target ) ;
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : mipmapImplementationDSA ( ) {
glGenerateTextureMipmapEXT ( _id , _target ) ;
}
# endif
# ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractTexture : : bindInternal ( ) {
Implementation : : TextureState * const textureState = Context : : current ( ) - > state ( ) - > texture ;
/* If the texture is already bound in current layer, nothing to do */
if ( textureState - > bindings [ textureState - > currentLayer ] = = _id )
return ;
/* Set internal layer as active if not already */
const GLint internalLayer = textureState - > maxSupportedLayerCount - 1 ;
if ( textureState - > currentLayer ! = internalLayer )
glActiveTexture ( GL_TEXTURE0 + ( textureState - > currentLayer = internalLayer ) ) ;
/* Bind the texture to internal layer, if not already */
if ( textureState - > bindings [ internalLayer ] ! = _id )
glBindTexture ( _target , ( textureState - > bindings [ internalLayer ] = _id ) ) ;
}
# endif
void AbstractTexture : : initializeContextBasedFunctionality ( Context * context ) {
Implementation : : TextureState * const textureState = context - > state ( ) - > texture ;
GLint & value = textureState - > maxSupportedLayerCount ;
/* Get the value and resize bindings array */
glGetIntegerv ( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS , & value ) ;
textureState - > bindings . resize ( value ) ;
# ifndef MAGNUM_TARGET_GLES
if ( context - > isExtensionSupported < Extensions : : GL : : EXT : : direct_state_access > ( ) ) {
Debug ( ) < < " AbstractTexture: using " < < Extensions : : GL : : EXT : : direct_state_access : : string ( ) < < " features " ;
bindImplementation = & AbstractTexture : : bindImplementationDSA ;
parameteriImplementation = & AbstractTexture : : parameterImplementationDSA ;
parameterfImplementation = & AbstractTexture : : parameterImplementationDSA ;
parameterfvImplementation = & AbstractTexture : : parameterImplementationDSA ;
mipmapImplementation = & AbstractTexture : : mipmapImplementationDSA ;
storage1DImplementation = & AbstractTexture : : storageImplementationDSA ;
storage2DImplementation = & AbstractTexture : : storageImplementationDSA ;
storage3DImplementation = & AbstractTexture : : storageImplementationDSA ;
image1DImplementation = & AbstractTexture : : imageImplementationDSA ;
image2DImplementation = & AbstractTexture : : imageImplementationDSA ;
image3DImplementation = & AbstractTexture : : imageImplementationDSA ;
subImage1DImplementation = & AbstractTexture : : subImageImplementationDSA ;
subImage2DImplementation = & AbstractTexture : : subImageImplementationDSA ;
subImage3DImplementation = & AbstractTexture : : subImageImplementationDSA ;
}
if ( context - > isExtensionSupported < Extensions : : GL : : ARB : : invalidate_subdata > ( ) ) {
Debug ( ) < < " AbstractTexture: using " < < Extensions : : GL : : ARB : : invalidate_subdata : : string ( ) < < " features " ;
invalidateImplementation = & AbstractTexture : : invalidateImplementationARB ;
invalidateSubImplementation = & AbstractTexture : : invalidateSubImplementationARB ;
}
# endif
}
void AbstractTexture : : parameterImplementationDefault ( GLenum parameter , GLint value ) {
bindInternal ( ) ;
glTexParameteri ( _target , parameter , value ) ;
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : parameterImplementationDSA ( GLenum parameter , GLint value ) {
glTextureParameteriEXT ( _id , _target , parameter , value ) ;
}
# endif
void AbstractTexture : : parameterImplementationDefault ( GLenum parameter , GLfloat value ) {
bindInternal ( ) ;
glTexParameterf ( _target , parameter , value ) ;
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : parameterImplementationDSA ( GLenum parameter , GLfloat value ) {
glTextureParameterfEXT ( _id , _target , parameter , value ) ;
}
# endif
void AbstractTexture : : parameterImplementationDefault ( GLenum parameter , const GLfloat * values ) {
bindInternal ( ) ;
glTexParameterfv ( _target , parameter , values ) ;
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : parameterImplementationDSA ( GLenum parameter , const GLfloat * values ) {
glTextureParameterfvEXT ( _id , _target , parameter , values ) ;
}
void AbstractTexture : : storageImplementationDefault ( GLenum target , GLsizei levels , AbstractTexture : : InternalFormat internalFormat , const Math : : Vector < 1 , GLsizei > & size ) {
bindInternal ( ) ;
/** @todo Re-enable when extension wrangler is available for ES2 */
# ifndef MAGNUM_TARGET_GLES2
glTexStorage1D ( target , levels , GLenum ( internalFormat ) , size [ 0 ] ) ;
# else
//glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
static_cast < void > ( target ) ;
static_cast < void > ( levels ) ;
static_cast < void > ( internalFormat ) ;
static_cast < void > ( size ) ;
# endif
}
void AbstractTexture : : storageImplementationDSA ( GLenum target , GLsizei levels , AbstractTexture : : InternalFormat internalFormat , const Math : : Vector < 1 , GLsizei > & size ) {
glTextureStorage1DEXT ( _id , target , levels , GLenum ( internalFormat ) , size [ 0 ] ) ;
}
# endif
void AbstractTexture : : storageImplementationDefault ( GLenum target , GLsizei levels , AbstractTexture : : InternalFormat internalFormat , const Vector2i & size ) {
bindInternal ( ) ;
/** @todo Re-enable when extension wrangler is available for ES2 */
# ifndef MAGNUM_TARGET_GLES2
glTexStorage2D ( target , levels , GLenum ( internalFormat ) , size . x ( ) , size . y ( ) ) ;
# else
//glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
static_cast < void > ( target ) ;
static_cast < void > ( levels ) ;
static_cast < void > ( internalFormat ) ;
static_cast < void > ( size ) ;
# endif
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : storageImplementationDSA ( GLenum target , GLsizei levels , AbstractTexture : : InternalFormat internalFormat , const Vector2i & size ) {
glTextureStorage2DEXT ( _id , target , levels , GLenum ( internalFormat ) , size . x ( ) , size . y ( ) ) ;
}
# endif
void AbstractTexture : : storageImplementationDefault ( GLenum target , GLsizei levels , AbstractTexture : : InternalFormat internalFormat , const Vector3i & size ) {
bindInternal ( ) ;
/** @todo Re-enable when extension wrangler is available for ES2 */
# ifndef MAGNUM_TARGET_GLES2
glTexStorage3D ( target , levels , GLenum ( internalFormat ) , size . x ( ) , size . y ( ) , size . z ( ) ) ;
# else
//glTexStorage3DEXT(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
static_cast < void > ( target ) ;
static_cast < void > ( levels ) ;
static_cast < void > ( internalFormat ) ;
static_cast < void > ( size ) ;
# endif
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : storageImplementationDSA ( GLenum target , GLsizei levels , AbstractTexture : : InternalFormat internalFormat , const Vector3i & size ) {
glTextureStorage3DEXT ( _id , target , levels , GLenum ( internalFormat ) , size . x ( ) , size . y ( ) , size . z ( ) ) ;
}
void AbstractTexture : : imageImplementationDefault ( GLenum target , GLint level , InternalFormat internalFormat , const Math : : Vector < 1 , GLsizei > & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
bindInternal ( ) ;
glTexImage1D ( target , level , static_cast < GLint > ( internalFormat ) , size [ 0 ] , 0 , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
void AbstractTexture : : imageImplementationDSA ( GLenum target , GLint level , InternalFormat internalFormat , const Math : : Vector < 1 , GLsizei > & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
glTextureImage1DEXT ( _id , target , level , GLint ( internalFormat ) , size [ 0 ] , 0 , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# endif
void AbstractTexture : : imageImplementationDefault ( GLenum target , GLint level , InternalFormat internalFormat , const Vector2i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
bindInternal ( ) ;
glTexImage2D ( target , level , GLint ( internalFormat ) , size . x ( ) , size . y ( ) , 0 , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : imageImplementationDSA ( GLenum target , GLint level , InternalFormat internalFormat , const Vector2i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
glTextureImage2DEXT ( _id , target , level , GLint ( internalFormat ) , size . x ( ) , size . y ( ) , 0 , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# endif
void AbstractTexture : : imageImplementationDefault ( GLenum target , GLint level , InternalFormat internalFormat , const Vector3i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
bindInternal ( ) ;
/** @todo Get some extension wrangler instead to avoid linker errors to glTexImage3D() on ES2 */
# ifndef MAGNUM_TARGET_GLES2
glTexImage3D ( target , level , GLint ( internalFormat ) , size . x ( ) , size . y ( ) , size . z ( ) , 0 , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
# else
static_cast < void > ( target ) ;
static_cast < void > ( level ) ;
static_cast < void > ( internalFormat ) ;
static_cast < void > ( size ) ;
static_cast < void > ( format ) ;
static_cast < void > ( type ) ;
static_cast < void > ( data ) ;
# endif
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : imageImplementationDSA ( GLenum target , GLint level , InternalFormat internalFormat , const Vector3i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
glTextureImage3DEXT ( _id , target , level , GLint ( internalFormat ) , size . x ( ) , size . y ( ) , size . z ( ) , 0 , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# endif
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : subImageImplementationDefault ( GLenum target , GLint level , const Math : : Vector < 1 , GLint > & offset , const Math : : Vector < 1 , GLsizei > & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
bindInternal ( ) ;
glTexSubImage1D ( target , level , offset [ 0 ] , size [ 0 ] , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
void AbstractTexture : : subImageImplementationDSA ( GLenum target , GLint level , const Math : : Vector < 1 , GLint > & offset , const Math : : Vector < 1 , GLsizei > & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
glTextureSubImage1DEXT ( _id , target , level , offset [ 0 ] , size [ 0 ] , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# endif
void AbstractTexture : : subImageImplementationDefault ( GLenum target , GLint level , const Vector2i & offset , const Vector2i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
bindInternal ( ) ;
glTexSubImage2D ( target , level , offset . x ( ) , offset . y ( ) , size . x ( ) , size . y ( ) , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : subImageImplementationDSA ( GLenum target , GLint level , const Vector2i & offset , const Vector2i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
glTextureSubImage2DEXT ( _id , target , level , offset . x ( ) , offset . y ( ) , size . x ( ) , size . y ( ) , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# endif
void AbstractTexture : : subImageImplementationDefault ( GLenum target , GLint level , const Vector3i & offset , const Vector3i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
bindInternal ( ) ;
/** @todo Get some extension wrangler instead to avoid linker errors to glTexSubImage3D() on ES2 */
# ifndef MAGNUM_TARGET_GLES2
glTexSubImage3D ( target , level , offset . x ( ) , offset . y ( ) , offset . z ( ) , size . x ( ) , size . y ( ) , size . z ( ) , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
# else
static_cast < void > ( target ) ;
static_cast < void > ( level ) ;
static_cast < void > ( offset ) ;
static_cast < void > ( size ) ;
static_cast < void > ( format ) ;
static_cast < void > ( type ) ;
static_cast < void > ( data ) ;
# endif
}
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : subImageImplementationDSA ( GLenum target , GLint level , const Vector3i & offset , const Vector3i & size , AbstractImage : : Format format , AbstractImage : : Type type , const GLvoid * data ) {
glTextureSubImage3DEXT ( _id , target , level , offset . x ( ) , offset . y ( ) , offset . z ( ) , size . x ( ) , size . y ( ) , size . z ( ) , static_cast < GLenum > ( format ) , static_cast < GLenum > ( type ) , data ) ;
}
# endif
void AbstractTexture : : invalidateImplementationNoOp ( GLint ) { }
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : invalidateImplementationARB ( GLint level ) {
glInvalidateTexImage ( _id , level ) ;
}
# endif
void AbstractTexture : : invalidateSubImplementationNoOp ( GLint , const Vector3i & , const Vector3i & ) { }
# ifndef MAGNUM_TARGET_GLES
void AbstractTexture : : invalidateSubImplementationARB ( GLint level , const Vector3i & offset , const Vector3i & size ) {
glInvalidateTexSubImage ( _id , level , offset . x ( ) , offset . y ( ) , offset . z ( ) , size . x ( ) , size . y ( ) , size . z ( ) ) ;
}
# endif
# ifndef DOXYGEN_GENERATING_OUTPUT
# ifndef MAGNUM_TARGET_GLES2
namespace Implementation {
template < std : : uint8_t dimensions > const GLvoid * ImageHelper < BufferImage < dimensions > > : : dataOrPixelUnpackBuffer ( BufferImage < dimensions > * image ) {
image - > buffer ( ) - > bind ( Buffer : : Target : : PixelUnpack ) ;
return nullptr ;
}
template class ImageHelper < BufferImage1D > ;
template class ImageHelper < BufferImage2D > ;
template class ImageHelper < BufferImage3D > ;
}
# endif
void AbstractTexture : : DataHelper < 2 > : : setWrapping ( AbstractTexture * texture , const Array2D < Wrapping > & wrapping ) {
# ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT ( texture - > _target ! = GL_TEXTURE_RECTANGLE | | ( ( wrapping . x ( ) = = Wrapping : : ClampToEdge | | wrapping . x ( ) = = Wrapping : : ClampToBorder ) & & ( wrapping . y ( ) = = Wrapping : : ClampToEdge | | wrapping . y ( ) = = Wrapping : : ClampToEdge ) ) , " AbstractTexture: rectangle texture wrapping must either clamp to border or to edge " , ) ;
# endif
( texture - > * parameteriImplementation ) ( GL_TEXTURE_WRAP_S , static_cast < GLint > ( wrapping . x ( ) ) ) ;
( texture - > * parameteriImplementation ) ( GL_TEXTURE_WRAP_T , static_cast < GLint > ( wrapping . y ( ) ) ) ;
}
void AbstractTexture : : DataHelper < 3 > : : setWrapping ( AbstractTexture * texture , const Array3D < Wrapping > & wrapping ) {
( texture - > * parameteriImplementation ) ( GL_TEXTURE_WRAP_S , static_cast < GLint > ( wrapping . x ( ) ) ) ;
( texture - > * parameteriImplementation ) ( GL_TEXTURE_WRAP_T , static_cast < GLint > ( wrapping . y ( ) ) ) ;
# ifndef MAGNUM_TARGET_GLES
( texture - > * parameteriImplementation ) ( GL_TEXTURE_WRAP_R , static_cast < GLint > ( wrapping . z ( ) ) ) ;
# endif
}
# endif
}