os/graphics/m3g/m3gcore11/src/m3g_texture.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: Texture2D implementation
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
/*!
sl@0
    20
 * \internal
sl@0
    21
 * \file
sl@0
    22
 * \brief Texture2D implementation
sl@0
    23
 */
sl@0
    24
sl@0
    25
#ifndef M3G_CORE_INCLUDE
sl@0
    26
#   error included by m3g_core.c; do not compile separately.
sl@0
    27
#endif
sl@0
    28
sl@0
    29
/*
sl@0
    30
 * Uncomment this line to switch tracing on for this file's functions
sl@0
    31
 */
sl@0
    32
/* #define M3G_LOCAL_TRACEF_ON */
sl@0
    33
sl@0
    34
#include "m3g_object.h"
sl@0
    35
sl@0
    36
#include "m3g_image.h"
sl@0
    37
#include "m3g_math.h"
sl@0
    38
#include "m3g_texture.h"
sl@0
    39
#include "m3g_animationtrack.h"
sl@0
    40
#include "m3g_transformable.h"
sl@0
    41
sl@0
    42
/*!
sl@0
    43
 * \internal
sl@0
    44
 * \brief Texture object
sl@0
    45
 */
sl@0
    46
struct M3GTextureImpl
sl@0
    47
{
sl@0
    48
    Transformable transformable;
sl@0
    49
sl@0
    50
    Image *image;
sl@0
    51
sl@0
    52
    M3Guint blendColor;
sl@0
    53
    M3Genum blendFunc;
sl@0
    54
sl@0
    55
    M3Genum levelFilter;
sl@0
    56
    M3Genum imageFilter;
sl@0
    57
sl@0
    58
    M3Genum wrapS;
sl@0
    59
    M3Genum wrapT;
sl@0
    60
};
sl@0
    61
sl@0
    62
/*
sl@0
    63
 * Uncomment this line to switch tracing on for this file's functions
sl@0
    64
 */
sl@0
    65
/* #define M3G_LOCAL_TRACEF_ON */
sl@0
    66
sl@0
    67
/*----------------------------------------------------------------------
sl@0
    68
 * Internal functions
sl@0
    69
 *--------------------------------------------------------------------*/
sl@0
    70
sl@0
    71
/*!
sl@0
    72
 * \internal
sl@0
    73
 * \brief Destroys this Texture object.
sl@0
    74
 *
sl@0
    75
 * \param obj Texture object
sl@0
    76
 */
sl@0
    77
static void m3gDestroyTexture(Object *obj)
sl@0
    78
{
sl@0
    79
    Texture *tex = (Texture *) obj;
sl@0
    80
    M3G_VALIDATE_OBJECT(tex);
sl@0
    81
sl@0
    82
    M3G_ASSIGN_REF(tex->image, NULL);
sl@0
    83
    m3gDestroyTransformable(obj);
sl@0
    84
}
sl@0
    85
sl@0
    86
/*!
sl@0
    87
 * \internal
sl@0
    88
 * \brief Disables all texturing units and texture coordinate arrays
sl@0
    89
 */
sl@0
    90
static void m3gDisableTextures(void)
sl@0
    91
{
sl@0
    92
    M3Gint i;
sl@0
    93
    for (i = 0; i < M3G_NUM_TEXTURE_UNITS; ++i) {
sl@0
    94
        glClientActiveTexture(GL_TEXTURE0 + i);
sl@0
    95
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
sl@0
    96
        glActiveTexture(GL_TEXTURE0 + i);
sl@0
    97
        glDisable(GL_TEXTURE_2D);
sl@0
    98
    }
sl@0
    99
}
sl@0
   100
sl@0
   101
/*!
sl@0
   102
 * \internal
sl@0
   103
 * \brief Applies texture to OpenGL.
sl@0
   104
 *
sl@0
   105
 * \param texture Texture object
sl@0
   106
 */
sl@0
   107
static void m3gBindTexture(Texture *texture)
sl@0
   108
{
sl@0
   109
    M3Gfloat colors[4];
sl@0
   110
    M3Gint mode;
sl@0
   111
sl@0
   112
    M3G_VALIDATE_OBJECT(texture);
sl@0
   113
    
sl@0
   114
    m3gBindTextureImage(texture->image,
sl@0
   115
                        texture->levelFilter,
sl@0
   116
                        texture->imageFilter); 
sl@0
   117
sl@0
   118
    /* setting up texturing mode */
sl@0
   119
    {
sl@0
   120
        M3GMatrix mtx;
sl@0
   121
        M3Gfloat matrixValues[16];
sl@0
   122
        m3gGetCompositeTransform((Transformable *) texture, &mtx);
sl@0
   123
        m3gGetMatrixColumns(&mtx, matrixValues);
sl@0
   124
        glMatrixMode(GL_TEXTURE);
sl@0
   125
        glLoadMatrixf(matrixValues);
sl@0
   126
    }
sl@0
   127
    glMatrixMode(GL_MODELVIEW);
sl@0
   128
sl@0
   129
    mode = GL_REPLACE;
sl@0
   130
    switch (texture->blendFunc) {
sl@0
   131
    case M3G_FUNC_REPLACE:
sl@0
   132
        mode = GL_REPLACE;
sl@0
   133
        break;
sl@0
   134
    case M3G_FUNC_ADD:
sl@0
   135
        mode = GL_ADD;
sl@0
   136
        break;
sl@0
   137
    case M3G_FUNC_BLEND:
sl@0
   138
        mode = GL_BLEND;
sl@0
   139
        break;
sl@0
   140
    case M3G_FUNC_DECAL:
sl@0
   141
        mode = GL_DECAL;
sl@0
   142
        break;
sl@0
   143
    case M3G_FUNC_MODULATE:
sl@0
   144
        mode = GL_MODULATE;
sl@0
   145
        break;
sl@0
   146
    default:
sl@0
   147
        /* This should never happen */
sl@0
   148
        M3G_ASSERT(0);
sl@0
   149
        break;
sl@0
   150
    }
sl@0
   151
    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, (GLfixed)mode);
sl@0
   152
sl@0
   153
    m3gFloatColor(texture->blendColor, 1.f, colors);
sl@0
   154
    glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, colors);
sl@0
   155
sl@0
   156
    /* setting up wrapping */
sl@0
   157
    if (texture->wrapS  == M3G_WRAP_CLAMP) {
sl@0
   158
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
sl@0
   159
    }
sl@0
   160
    else {
sl@0
   161
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
sl@0
   162
    }
sl@0
   163
    if (texture->wrapT == M3G_WRAP_CLAMP) {
sl@0
   164
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
sl@0
   165
    }
sl@0
   166
    else {
sl@0
   167
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
sl@0
   168
    }
sl@0
   169
sl@0
   170
    M3G_ASSERT_GL;
sl@0
   171
}
sl@0
   172
sl@0
   173
/*!
sl@0
   174
 * \internal
sl@0
   175
 * \brief Releases a bound texture from the current texture unit
sl@0
   176
 *
sl@0
   177
 */
sl@0
   178
static void m3gReleaseTexture(Texture *texture)
sl@0
   179
{
sl@0
   180
    m3gReleaseTextureImage(texture->image);
sl@0
   181
}
sl@0
   182
sl@0
   183
#if defined(M3G_NGL_TEXTURE_API)
sl@0
   184
/*!
sl@0
   185
 * \internal
sl@0
   186
 * \brief Make sure that mipmaps are allocated if needed
sl@0
   187
 */
sl@0
   188
static M3Gbool m3gValidateTextureMipmapping(Texture *texture)
sl@0
   189
{
sl@0
   190
    return (texture->levelFilter == M3G_FILTER_BASE_LEVEL
sl@0
   191
            || texture->image->mipData);
sl@0
   192
}
sl@0
   193
#endif
sl@0
   194
sl@0
   195
/*!
sl@0
   196
 * \internal
sl@0
   197
 * \brief Overloaded Object3D method.
sl@0
   198
 *
sl@0
   199
 * \param property      animation property
sl@0
   200
 * \retval M3G_TRUE     property supported
sl@0
   201
 * \retval M3G_FALSE    property not supported
sl@0
   202
 */
sl@0
   203
static M3Gbool m3gTextureIsCompatible(M3Gint property)
sl@0
   204
{
sl@0
   205
    switch (property) {
sl@0
   206
    case M3G_ANIM_COLOR:
sl@0
   207
        return M3G_TRUE;
sl@0
   208
    default:
sl@0
   209
        return m3gTransformableIsCompatible(property);
sl@0
   210
    }
sl@0
   211
}
sl@0
   212
sl@0
   213
/*!
sl@0
   214
 * \internal
sl@0
   215
 * \brief Overloaded Object3D method.
sl@0
   216
 *
sl@0
   217
 * \param self          Texture object
sl@0
   218
 * \param property      animation property
sl@0
   219
 * \param valueSize     size of value array
sl@0
   220
 * \param value         value array
sl@0
   221
 */
sl@0
   222
static void m3gTextureUpdateProperty(Object *self,
sl@0
   223
                                     M3Gint property,
sl@0
   224
                                     M3Gint valueSize,
sl@0
   225
                                     const M3Gfloat *value)
sl@0
   226
{
sl@0
   227
    Texture *texture = (Texture *)self;
sl@0
   228
    M3G_VALIDATE_OBJECT(texture);
sl@0
   229
    M3G_ASSERT_PTR(value);
sl@0
   230
sl@0
   231
    switch (property) {
sl@0
   232
    case M3G_ANIM_COLOR:
sl@0
   233
        M3G_ASSERT(valueSize >= 3);
sl@0
   234
        texture->blendColor =
sl@0
   235
            (valueSize == 3
sl@0
   236
             ? m3gColor3f(value[0], value[1], value[2])
sl@0
   237
             : m3gColor4f(value[0], value[1], value[2], value[3]));
sl@0
   238
        break;
sl@0
   239
    default:
sl@0
   240
        m3gTransformableUpdateProperty(self, property, valueSize, value);
sl@0
   241
    }
sl@0
   242
}
sl@0
   243
sl@0
   244
/*!
sl@0
   245
 * \internal
sl@0
   246
 * \brief Overloaded Object3D method.
sl@0
   247
 *
sl@0
   248
 * \param self Texture object
sl@0
   249
 * \param references array of reference objects
sl@0
   250
 * \return number of references
sl@0
   251
 */
sl@0
   252
static M3Gint m3gTextureDoGetReferences(Object *self, Object **references)
sl@0
   253
{
sl@0
   254
    Texture *texture = (Texture *)self;
sl@0
   255
    M3Gint num = m3gObjectDoGetReferences(self, references);
sl@0
   256
    if (texture->image != NULL) {
sl@0
   257
        if (references != NULL)
sl@0
   258
            references[num] = (Object *)texture->image;
sl@0
   259
        num++;
sl@0
   260
    }
sl@0
   261
    return num;
sl@0
   262
}
sl@0
   263
sl@0
   264
/*!
sl@0
   265
 * \internal
sl@0
   266
 * \brief Overloaded Object3D method.
sl@0
   267
 */
sl@0
   268
static Object *m3gTextureFindID(Object *self, M3Gint userID)
sl@0
   269
{
sl@0
   270
    Texture *texture = (Texture *)self;
sl@0
   271
    Object *found = m3gObjectFindID(self, userID);
sl@0
   272
    
sl@0
   273
    if (!found && texture->image != NULL) {
sl@0
   274
        found = m3gFindID((Object*) texture->image, userID);
sl@0
   275
    }
sl@0
   276
    return found;
sl@0
   277
}
sl@0
   278
sl@0
   279
/*!
sl@0
   280
 * \internal
sl@0
   281
 * \brief Overloaded Object3D method.
sl@0
   282
 *
sl@0
   283
 * \param originalObj original Texture object
sl@0
   284
 * \param cloneObj pointer to cloned Texture object
sl@0
   285
 * \param pairs array for all object-duplicate pairs
sl@0
   286
 * \param numPairs number of pairs
sl@0
   287
 */
sl@0
   288
static M3Gbool m3gTextureDuplicate(const Object *originalObj,
sl@0
   289
                                   Object **cloneObj,
sl@0
   290
                                   Object **pairs,
sl@0
   291
                                   M3Gint *numPairs)
sl@0
   292
{
sl@0
   293
    Texture *original = (Texture *)originalObj;
sl@0
   294
    Texture *clone;
sl@0
   295
    M3G_ASSERT(*cloneObj == NULL); /* no derived classes */
sl@0
   296
sl@0
   297
    /* Create the clone object */
sl@0
   298
    
sl@0
   299
    clone = (Texture *)m3gCreateTexture(originalObj->interface,
sl@0
   300
                                        original->image);
sl@0
   301
    if (!clone) {
sl@0
   302
        return M3G_FALSE;
sl@0
   303
    }
sl@0
   304
    *cloneObj = (Object *)clone;
sl@0
   305
sl@0
   306
    /* Duplicate base class data */
sl@0
   307
    
sl@0
   308
    if (!m3gTransformableDuplicate(originalObj, cloneObj, pairs, numPairs)) {
sl@0
   309
        return M3G_FALSE;
sl@0
   310
    }
sl@0
   311
sl@0
   312
    /* Duplicate our own data */
sl@0
   313
    
sl@0
   314
    clone->blendColor = original->blendColor;
sl@0
   315
    clone->blendFunc = original->blendFunc;
sl@0
   316
    clone->levelFilter = original->levelFilter;
sl@0
   317
    clone->imageFilter = original->imageFilter;
sl@0
   318
    clone->wrapS = original->wrapS;
sl@0
   319
    clone->wrapT = original->wrapT;
sl@0
   320
sl@0
   321
    return M3G_TRUE;
sl@0
   322
}
sl@0
   323
sl@0
   324
/*!
sl@0
   325
 * \internal
sl@0
   326
 * \brief Check texture dimensions.
sl@0
   327
 *
sl@0
   328
 * \retval M3G_TRUE dimensions valid
sl@0
   329
 * \retval M3G_FALSE dimensions invalid
sl@0
   330
 */
sl@0
   331
static M3Gbool m3gIsValidDimensions(M3Gint width, M3Gint height)
sl@0
   332
{
sl@0
   333
    return (       m3gInRange(width,  1, M3G_MAX_TEXTURE_DIMENSION)
sl@0
   334
                && m3gInRange(height, 1, M3G_MAX_TEXTURE_DIMENSION)
sl@0
   335
                && m3gIsPowerOfTwo(width)
sl@0
   336
                && m3gIsPowerOfTwo(height) );
sl@0
   337
}
sl@0
   338
sl@0
   339
/*----------------------------------------------------------------------
sl@0
   340
 * Virtual function table
sl@0
   341
 *--------------------------------------------------------------------*/
sl@0
   342
sl@0
   343
static const ObjectVFTable m3gvf_Texture = {
sl@0
   344
    m3gObjectApplyAnimation,
sl@0
   345
    m3gTextureIsCompatible,
sl@0
   346
    m3gTextureUpdateProperty,
sl@0
   347
    m3gTextureDoGetReferences,
sl@0
   348
    m3gTextureFindID,
sl@0
   349
    m3gTextureDuplicate,
sl@0
   350
    m3gDestroyTexture
sl@0
   351
};
sl@0
   352
sl@0
   353
sl@0
   354
/*----------------------------------------------------------------------
sl@0
   355
 * Public API functions
sl@0
   356
 *--------------------------------------------------------------------*/
sl@0
   357
sl@0
   358
/*!
sl@0
   359
 * \brief Texture constructor, creates a texture with
sl@0
   360
 * default values.
sl@0
   361
 *
sl@0
   362
 *
sl@0
   363
 * \param interface             M3G interface
sl@0
   364
 * \param hImage                texture Image object
sl@0
   365
 * \retval Texture new Texture object
sl@0
   366
 * \retval NULL Texture creating failed
sl@0
   367
 */
sl@0
   368
M3G_API M3GTexture m3gCreateTexture(M3GInterface interface,
sl@0
   369
                                    M3GImage hImage)
sl@0
   370
{
sl@0
   371
    Interface *m3g = (Interface *) interface;
sl@0
   372
    Image* image = (Image *)hImage;
sl@0
   373
    M3G_VALIDATE_INTERFACE(m3g);
sl@0
   374
sl@0
   375
    /* Check inputs */
sl@0
   376
    if (image == NULL) {
sl@0
   377
        m3gRaiseError(m3g, M3G_NULL_POINTER);
sl@0
   378
        return NULL;
sl@0
   379
    }
sl@0
   380
sl@0
   381
    if (!m3gIsValidDimensions(image->width, image->height)) {
sl@0
   382
        m3gRaiseError(m3g, M3G_INVALID_VALUE);
sl@0
   383
        return NULL;
sl@0
   384
    }
sl@0
   385
sl@0
   386
    /* Allocate and initialize the object */
sl@0
   387
    {
sl@0
   388
        Texture *texture;
sl@0
   389
        texture = m3gAllocZ(m3g, sizeof(Texture));
sl@0
   390
        if (texture != NULL) {
sl@0
   391
            m3gInitTransformable(&texture->transformable, m3g,
sl@0
   392
                                 M3G_CLASS_TEXTURE);
sl@0
   393
sl@0
   394
            M3G_ASSIGN_REF(texture->image, image);
sl@0
   395
    
sl@0
   396
            texture->blendColor = 0x00000000;   /* Black */
sl@0
   397
            texture->blendFunc = M3G_FUNC_MODULATE;
sl@0
   398
            texture->levelFilter = M3G_FILTER_BASE_LEVEL;
sl@0
   399
            texture->imageFilter = M3G_FILTER_NEAREST;
sl@0
   400
            texture->wrapS = M3G_WRAP_REPEAT;
sl@0
   401
            texture->wrapT = M3G_WRAP_REPEAT;
sl@0
   402
        }
sl@0
   403
sl@0
   404
        return (M3GTexture)texture;
sl@0
   405
    }
sl@0
   406
}
sl@0
   407
sl@0
   408
/*!
sl@0
   409
 * \brief Set texture image.
sl@0
   410
 *
sl@0
   411
 * \param hTexture  Texture object
sl@0
   412
 * \param hImage    Image object
sl@0
   413
 */
sl@0
   414
M3G_API void m3gSetTextureImage(M3GTexture hTexture, M3GImage hImage)
sl@0
   415
{
sl@0
   416
    Texture *texture = (Texture*)hTexture;
sl@0
   417
    Image *image = (Image *)hImage;
sl@0
   418
    M3G_VALIDATE_OBJECT(texture);
sl@0
   419
sl@0
   420
    if (image == NULL) {
sl@0
   421
        m3gRaiseError(M3G_INTERFACE(texture), M3G_NULL_POINTER);
sl@0
   422
        return;
sl@0
   423
    }
sl@0
   424
sl@0
   425
    if (!m3gIsValidDimensions(image->width, image->height)) {
sl@0
   426
        m3gRaiseError(M3G_INTERFACE(texture), M3G_INVALID_VALUE);
sl@0
   427
        return;
sl@0
   428
    }
sl@0
   429
sl@0
   430
    M3G_ASSIGN_REF(texture->image, image);
sl@0
   431
}
sl@0
   432
sl@0
   433
/*!
sl@0
   434
 * \brief Get texture image.
sl@0
   435
 *
sl@0
   436
 * \param hTexture  Texture object
sl@0
   437
 * \return          Image object
sl@0
   438
 */
sl@0
   439
M3G_API M3GImage m3gGetTextureImage(M3GTexture hTexture)
sl@0
   440
{
sl@0
   441
    const Texture *texture = (const Texture *) hTexture;
sl@0
   442
    M3G_VALIDATE_OBJECT(texture);
sl@0
   443
sl@0
   444
    return (M3GImage)(texture->image);
sl@0
   445
}
sl@0
   446
sl@0
   447
/*!
sl@0
   448
 * \brief Set texture filtering.
sl@0
   449
 *
sl@0
   450
 * \param hTexture      Texture object
sl@0
   451
 * \param levelFilter   level filter type
sl@0
   452
 * \param imageFilter   image filter type
sl@0
   453
 */
sl@0
   454
M3G_API void m3gSetFiltering(M3GTexture hTexture,
sl@0
   455
                             M3Gint levelFilter,
sl@0
   456
                             M3Gint imageFilter)
sl@0
   457
{
sl@0
   458
    Texture *texture = (Texture*)hTexture;
sl@0
   459
    if ((levelFilter != M3G_FILTER_LINEAR &&
sl@0
   460
         levelFilter != M3G_FILTER_NEAREST &&
sl@0
   461
         levelFilter != M3G_FILTER_BASE_LEVEL)
sl@0
   462
        || (imageFilter != M3G_FILTER_LINEAR &&
sl@0
   463
            imageFilter != M3G_FILTER_NEAREST)) {
sl@0
   464
        m3gRaiseError(M3G_INTERFACE(texture), M3G_INVALID_VALUE);
sl@0
   465
        return;
sl@0
   466
    }
sl@0
   467
    texture->levelFilter = levelFilter;
sl@0
   468
    texture->imageFilter = imageFilter;
sl@0
   469
}
sl@0
   470
sl@0
   471
/*!
sl@0
   472
 * \brief Set texture S & T wrapping mode.
sl@0
   473
 *
sl@0
   474
 * \param hTexture  Texture object
sl@0
   475
 * \param wrapS     S wrap mode
sl@0
   476
 * \param wrapT     T wrap mode
sl@0
   477
 */
sl@0
   478
M3G_API void m3gSetWrapping(M3GTexture hTexture, M3Gint wrapS, M3Gint wrapT)
sl@0
   479
{
sl@0
   480
    Texture *texture = (Texture*)hTexture;
sl@0
   481
    if (wrapS != M3G_WRAP_CLAMP && wrapS != M3G_WRAP_REPEAT) {
sl@0
   482
        m3gRaiseError(M3G_INTERFACE(texture), M3G_INVALID_VALUE);
sl@0
   483
        return;
sl@0
   484
    }
sl@0
   485
    if (wrapT != M3G_WRAP_CLAMP && wrapT != M3G_WRAP_REPEAT) {
sl@0
   486
        m3gRaiseError(M3G_INTERFACE(texture), M3G_INVALID_VALUE);
sl@0
   487
        return;
sl@0
   488
    }
sl@0
   489
    texture->wrapS = wrapS;
sl@0
   490
    texture->wrapT = wrapT;
sl@0
   491
}
sl@0
   492
sl@0
   493
/*!
sl@0
   494
 * \brief Get texture S wrapping mode.
sl@0
   495
 *
sl@0
   496
 * \param hTexture  Texture object
sl@0
   497
 * \return S wrapping mode
sl@0
   498
 */
sl@0
   499
M3G_API M3Gint m3gGetWrappingS(M3GTexture hTexture)
sl@0
   500
{
sl@0
   501
    Texture *texture = (Texture*)hTexture;
sl@0
   502
    return texture->wrapS;
sl@0
   503
}
sl@0
   504
sl@0
   505
/*!
sl@0
   506
 * \brief Get texture T wrapping mode.
sl@0
   507
 *
sl@0
   508
 * \param hTexture  Texture object
sl@0
   509
 * \return T wrapping mode
sl@0
   510
 */
sl@0
   511
M3G_API M3Gint m3gGetWrappingT(M3GTexture hTexture)
sl@0
   512
{
sl@0
   513
    Texture *texture = (Texture*)hTexture;
sl@0
   514
    return texture->wrapT;
sl@0
   515
}
sl@0
   516
sl@0
   517
/*!
sl@0
   518
 * \brief Set texture blending function.
sl@0
   519
 *
sl@0
   520
 * \param hTexture  Texture object
sl@0
   521
 * \param func      blending function
sl@0
   522
 */
sl@0
   523
M3G_API void m3gTextureSetBlending(M3GTexture hTexture, M3Gint func)
sl@0
   524
{
sl@0
   525
    Texture *texture = (Texture*)hTexture;
sl@0
   526
sl@0
   527
    switch (func) {
sl@0
   528
    case M3G_FUNC_ADD:
sl@0
   529
    case M3G_FUNC_BLEND:
sl@0
   530
    case M3G_FUNC_DECAL:
sl@0
   531
    case M3G_FUNC_MODULATE:
sl@0
   532
    case M3G_FUNC_REPLACE:
sl@0
   533
        texture->blendFunc = func;
sl@0
   534
        break;
sl@0
   535
    default:
sl@0
   536
        m3gRaiseError(M3G_INTERFACE(texture), M3G_INVALID_VALUE);
sl@0
   537
        break;
sl@0
   538
    }
sl@0
   539
}
sl@0
   540
sl@0
   541
/*!
sl@0
   542
 * \brief Get texture blending function.
sl@0
   543
 *
sl@0
   544
 * \param hTexture  Texture object
sl@0
   545
 * \return          blending function
sl@0
   546
 */
sl@0
   547
M3G_API M3Gint m3gTextureGetBlending(M3GTexture hTexture)
sl@0
   548
{
sl@0
   549
    Texture *texture = (Texture*)hTexture;
sl@0
   550
    return texture->blendFunc;
sl@0
   551
}
sl@0
   552
sl@0
   553
/*!
sl@0
   554
 * \brief Set texture blend color as RGB.
sl@0
   555
 *
sl@0
   556
 * \param hTexture  Texture object
sl@0
   557
 * \param RGB       blend color as RGB
sl@0
   558
 */
sl@0
   559
M3G_API void m3gSetBlendColor(M3GTexture hTexture, M3Guint RGB)
sl@0
   560
{
sl@0
   561
    Texture *texture = (Texture*)hTexture;
sl@0
   562
    texture->blendColor = RGB & M3G_RGB_MASK;
sl@0
   563
}
sl@0
   564
sl@0
   565
/*!
sl@0
   566
 * \brief Get texture blend color as RGB.
sl@0
   567
 *
sl@0
   568
 * \param hTexture  Texture object
sl@0
   569
 * \return          blend color as RGB
sl@0
   570
 */
sl@0
   571
M3G_API M3Guint m3gGetBlendColor(M3GTexture hTexture)
sl@0
   572
{
sl@0
   573
    Texture *texture = (Texture*)hTexture;
sl@0
   574
    return texture->blendColor;
sl@0
   575
}
sl@0
   576
sl@0
   577
/*!
sl@0
   578
 * \brief Get texture filtering
sl@0
   579
 *
sl@0
   580
 * \param hTexture      Texture object
sl@0
   581
 * \param levelFilter   pointer to store level filter
sl@0
   582
 * \param imageFilter   pointer to store image filter
sl@0
   583
 */
sl@0
   584
M3G_API void m3gGetFiltering(M3GTexture hTexture, M3Gint *levelFilter, M3Gint *imageFilter)
sl@0
   585
{
sl@0
   586
    Texture *texture = (Texture*)hTexture;
sl@0
   587
    *levelFilter = texture->levelFilter;
sl@0
   588
    *imageFilter = texture->imageFilter;
sl@0
   589
}
sl@0
   590
sl@0
   591
/*
sl@0
   592
 * Uncomment these lines' opening pair at the begining of the file
sl@0
   593
 * if you want to switch tracing on for this file.
sl@0
   594
 */
sl@0
   595
#ifdef M3G_LOCAL_TRACEF_ON
sl@0
   596
#undef M3G_LOCAL_TRACEF_ON
sl@0
   597
#endif
sl@0
   598