1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/OpenGl/OpenGl_TextureBox.cxx
kgv 5f8b738ea5 0023022: This is desirable to access OpenGl extensions and core API (1.2+) in one place
Extend OpenGl_Context to provide GL2.0 core functionality

Added 'glext.h' header provided by Khronos group with definitions
and GL functions' types.
Added OpenGl_GlCoreXX structures with function list
to appropriate GL core functionality.
Fixed memory leak in OpenGl_Context destructor.
Eliminate inclusions of gl.h header
Use OpenGl_GlCore11.hxx instead.
Removed obsolote M_PI redefinitions.
Slightly cleaned up included headers.
Reuse definitions from glext.h
OpenGl_ArbVBO and OpenGl_ExtFBO originally provide own definitions
for OpenGL extensions.
2012-03-15 13:58:13 +04:00

1077 lines
29 KiB
C++
Executable File

/*
* Fonction
* ~~~~~~~~
* Gestion des textures sous OpenGL
*
*
* Notes
* ~~~~~
* Les textures sont toujours initialisee avec des parametres par defaut
* texture 1D: WRAP_S = CLAMP
* MAG_FILTER = NEAREST
* generation de texture automatique en OBJECT_LINEAR
* rendu avec DECAL
*
* texture 2D: WRAP_S/T = REPEAT
* MAG/MIN_FILTER = LINEAR
* generation de texture automatique en OBJECT_LINEAR
* rendu avec MODULATE
*
* texture 2D MipMap: WRAP_S/T = REPEAT
* MAG_FILTER = LINEAR
* MIN_FILTER = LINEAR_MIPMAP_NEAREST
* generation de texture automatique en OBJECT_LINEAR
* rendu avec MODULATE
*
* Historique des modifications
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 22-05-97: PCT ; Creation
* 18-06-97: FMN ; Ajout entete
* 20-06-97: PCT ; Correction bug parametres par defaut texture 1D
* 30-06-97: PCT ; Correction bug rechargement de la texture courante
* 04-07-97: PCT ; suppression de l'utilisation de libimage.a de SGI
* 01-08-97: PCT ; suppression InitializeTextureBox()
* 04-08-97: FMN,PCT ; Portage WNT
* 05-08-97: FMN ; ajout GetTextureData...
* 10-09-97: PCT ; ajout commentaires. GetTexture() ne doit pas
* etre utilisee dans Cas.Cade ( le chargement est
* fait par Graphic3d )
* 06-10-97: FMN ; Portage HP
* 14-10-97: FMN ; Ajout OpenGl_Extension
* 22-10-97: FMN ; Meilleure gestion de l'extension glXGetCurrentDisplayEXT
* 04-11-97: FMN ; Gestion des differentes versions GLX
* 19-11-97: FMN ; Ajout GetCurrentDisplay plus simple que glXGetCurrentDisplayEXT
* 04-12-97: FMN ; On suppose que l'on travaille en OpenGL1.1 (cf OpenGl_Extension)
* 17-12-97: FMN ; Probleme compilation SGI
* 17-12-97: FMN ; Probleme sur Optimisation sur MyBindTextureEXT()
* Le test sur la texture courante doit tenir compte du contexte.
* 22-07-98: FGU ; Ajout fonctions TransferTexture_To_Data() et TransferData_To_Texture()
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <OpenGl_GlCore11.hxx>
#include <OpenGl_Display.hxx>
#include <OpenGl_TextureBox.hxx>
#include <OpenGl_ImageBox.hxx>
#include <OpenGl_Memory.hxx>
#include <OpenGl_ResourceCleaner.hxx>
#include <OpenGl_ResourceTexture.hxx>
#include <GL/glu.h> // gluBuild2DMipmaps()
#define GROW_TEXTURES 8
#define GROW_TEXTURES_DATA 8
#define GROW_CONTEXT 8
typedef enum {TEXDATA_NONE, TEXDATA_1D, TEXDATA_2D, TEXDATA_2DMM} texDataStatus;
typedef enum {TEX_NONE, TEX_ALLOCATED} texStatus;
typedef GLfloat SizeType[4];
typedef int TextureDataID;
#define TEXTUREDATA_ERROR -1
struct texData
{
char imageFileName[128];
int imageWidth, imageHeight;
GLubyte *image;
texDataStatus status;
GLint type;
int share_count;
DEFINE_STANDARD_ALLOC
};
struct texDraw
{
TextureDataID data;
GLuint *number;
GLDRAWABLE *drawable;
GLCONTEXT *context;
char *use_bind_texture;
int context_count;
int context_size;
texStatus status;
GLint Gen;
GLint Light;
GLint Wrap;
GLfloat Plane1[4];
GLfloat Plane2[4];
GLint Render;
GLfloat scalex, scaley;
GLfloat transx, transy;
GLfloat angle;
DEFINE_STANDARD_ALLOC
};
/*----------------------------------------------------------------------*/
/*
* Variables statiques
*/
static texDraw *textab = NULL;
static int textures_count = 0;
static int textures_size = 0;
static texData *texdata = NULL;
static int textures_data_count = 0;
static int textures_data_size = 0;
static TextureDataID current_texture_data = TEXTUREDATA_ERROR;
static TextureID current_texture = TEXTUREBOX_ERROR;
static GLfloat sgenparams[] = { 1.0 ,0.0 ,0.0 ,0.0};
static GLfloat tgenparams[] = { 0.0 ,1.0 ,0.0 ,0.0};
static GLenum status2type[] = { GL_NONE, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_2D };
/*----------------------------------------------------------------------*/
/*
* Fonctions privees
*/
/*----------------------------------------------------------------------*/
/*
* recherche l'existence de datas de texture par son nom
*/
static TextureDataID FindTextureData(char *FileName)
{
int i;
for (i=0; i<textures_data_size; i++)
if ( texdata[i].status!=TEXDATA_NONE && strcmp(FileName, texdata[i].imageFileName)==0 )
return i;
return TEXTUREDATA_ERROR;
}
/*----------------------------------------------------------------------*/
/*
* recherche un emplacement de data texture libre
*/
static TextureDataID FindFreeTextureData(void)
{
int i;
/* ya encore de la place ? */
if (textures_data_count == textures_data_size)
{
textures_data_size += GROW_TEXTURES_DATA;
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
texdata = (texData*)realloc(texdata, textures_data_size*sizeof(texData));
#else
texdata = cmn_resizemem<texData>(texdata, textures_data_size);
#endif
if (texdata == NULL) return TEXTUREDATA_ERROR;
for (i=textures_data_count; i<textures_data_size; i++)
texdata[i].status = TEXDATA_NONE;
/* on a deja assez perdu de temps comme ca => retourne un ID rapidement... */
return textures_data_count++;
}
/* recherche d'un ID libre */
for (i=0; i<textures_data_size; i++)
if (texdata[i].status == TEXDATA_NONE)
{
textures_data_count = Max (textures_data_count, i + 1);
return i;
}
return TEXTUREDATA_ERROR;
}
/*----------------------------------------------------------------------*/
/*
* recherche un emplacement de texture libre
*/
static TextureID FindFreeTexture(void)
{
int i;
/* ya encore de la place ? */
if (textures_count == textures_size)
{
textures_size += GROW_TEXTURES;
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
textab = (texDraw*)realloc(textab, textures_size*sizeof(texDraw));
#else
textab = cmn_resizemem<texDraw>(textab, textures_size);
#endif
if (textab == NULL) return TEXTUREBOX_ERROR;
for (i=textures_count; i<textures_size; i++)
textab[i].status = TEX_NONE;
/* on a deja assez perdu de temps comme ca => retourne un ID rapidement... */
return textures_count++;
}
for (i=0; i<textures_size; i++)
if (textab[i].status == TEX_NONE)
{
textures_count = Max (textures_count, i + 1);
return i;
}
return TEXTUREBOX_ERROR;
}
/*----------------------------------------------------------------------*/
/*
* regarde si la texture a ete definie pour le contexte courant
*/
static int FindTextureContext(TextureID ID)
{
int i;
GLCONTEXT cur = GET_GL_CONTEXT();
for (i=0; i<textab[ID].context_count; i++)
if (textab[ID].context[i] == cur)
return i;
return TEXTUREBOX_ERROR;
}
/*----------------------------------------------------------------------*/
/*
* chargement d'une texture suivant son type
*/
static void LoadTexture(TextureID ID)
{
TextureDataID data;
data = textab[ID].data;
switch (texdata[data].status)
{
case TEXDATA_1D:
glTexImage1D(GL_TEXTURE_1D, 0, 4,
texdata[data].imageWidth, 0,
GL_RGBA, GL_UNSIGNED_BYTE, texdata[data].image);
break;
case TEXDATA_2D:
glTexImage2D(GL_TEXTURE_2D, 0, 4,
texdata[data].imageWidth, texdata[data].imageHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, texdata[data].image);
break;
case TEXDATA_2DMM:
gluBuild2DMipmaps(GL_TEXTURE_2D, 4,
texdata[data].imageWidth,
texdata[data].imageHeight,
GL_RGBA, GL_UNSIGNED_BYTE, texdata[data].image);
break;
default:
break;
}
}
/*----------------------------------------------------------------------*/
/*
* les parametres d'initialisation d'une texture
* NE PAS METTRE DANS UNE DISPLAY LIST POUR L'INSTANT ( pb avec les matrices )
*/
static void SetTextureParam(TextureID ID)
{
GLint cur_matrix;
TextureDataID data;
data = textab[ID].data;
glGetIntegerv(GL_MATRIX_MODE, &cur_matrix);
/*
* MISE EN PLACE DE LA MATRICE DE TEXTURE
*/
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
/* if (textab[ID].Gen != GL_SPHERE_MAP)
{*/
glScalef(textab[ID].scalex, textab[ID].scaley, 1.0);
glTranslatef(-textab[ID].transx, -textab[ID].transy, 0.0);
glRotatef(-textab[ID].angle, 0.0, 0.0, 1.0);
/*}*/
/*
* GENERATION AUTOMATIQUE DE TEXTURE
*/
switch (textab[ID].Gen)
{
case GL_OBJECT_LINEAR:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, textab[ID].Plane1);
if (texdata[data].status != TEXDATA_1D)
{
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_T, GL_OBJECT_PLANE, textab[ID].Plane2);
}
break;
case GL_SPHERE_MAP:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
if (texdata[data].status != TEXDATA_1D)
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
break;
case GL_EYE_LINEAR:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textab[ID].Plane1);
if (texdata[data].status != TEXDATA_1D)
{
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textab[ID].Plane2);
}
glPopMatrix();
break;
}
/*
* RENDU DE LA TEXTURE AVEC LES LUMIERES
*/
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textab[ID].Light);
/*
* LISSAGE DE LA TEXTURE
*/
switch (texdata[data].status)
{
case TEXDATA_1D:
case TEXDATA_2D:
glTexParameteri(texdata[data].type, GL_TEXTURE_MAG_FILTER, textab[ID].Render);
glTexParameteri(texdata[data].type, GL_TEXTURE_MIN_FILTER, textab[ID].Render);
break;
case TEXDATA_2DMM:
if (textab[ID].Render == GL_NEAREST)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}
break;
default:
break;
}
/*
* WRAP DE LA TEXTURE
*/
switch (texdata[data].status)
{
case TEXDATA_1D:
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, textab[ID].Wrap);
break;
case TEXDATA_2D:
case TEXDATA_2DMM:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, textab[ID].Wrap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, textab[ID].Wrap);
break;
default:
break;
}
glMatrixMode(cur_matrix);
}
/*----------------------------------------------------------------------*/
/*
* simulation du glGenTexturesEXT pour un context
*/
static void MyGenTextureEXT (TextureID ID)
{
int Context = textab[ID].context_count;
TextureDataID data = textab[ID].data;
textab[ID].context[Context] = GET_GL_CONTEXT();
textab[ID].drawable[Context] = GET_GLDEV_CONTEXT();
textab[ID].use_bind_texture[Context] = (char )GL_TRUE;
glGenTextures (1, &textab[ID].number[Context]);
glBindTexture (texdata[data].type, textab[ID].number[Context]);
LoadTexture (ID);
textab[ID].context_count++;
}
/*----------------------------------------------------------------------*/
/*
* simulation du glBindTextureEXT
*/
static void MyBindTextureEXT (TextureID ID, int Context)
{
TextureDataID data = textab[ID].data;
if (texdata[data].status == TEXDATA_NONE)
return;
GLenum aParamName = texdata[data].status == TEXDATA_1D ?
GL_TEXTURE_BINDING_1D : GL_TEXTURE_BINDING_2D;
GLint aCurrTex = -1;
glGetIntegerv (aParamName, &aCurrTex);
if (textab[ID].number[Context] != aCurrTex)
{
glBindTexture (texdata[data].type, textab[ID].number[Context]);
}
}
/*----------------------------------------------------------------------*/
/*
* installation de la texture pour le dernier contexte
*/
static int InstallTextureInContext(TextureID ID)
{
#ifdef PRINT
printf("InstallTextureInContext::installation de la texture dans le context\n");
#endif
/* ya encore de la place dans le tableau de context ? */
if (textab[ID].context_count == textab[ID].context_size)
{
#ifdef PRINT
printf("InstallTextureInContext::allocation dans le context\n");
#endif
textab[ID].context_size += GROW_CONTEXT;
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
textab[ID].number =
(GLuint*)realloc(textab[ID].number, textab[ID].context_size*sizeof(GLuint));
textab[ID].context =
(GLCONTEXT*)realloc(textab[ID].context, textab[ID].context_size*sizeof(GLCONTEXT));
textab[ID].drawable =
(GLDRAWABLE*)realloc(textab[ID].drawable, textab[ID].context_size*sizeof(GLDRAWABLE));
textab[ID].use_bind_texture =
(char*)realloc(textab[ID].use_bind_texture, textab[ID].context_size);
#else
textab[ID].number =
cmn_resizemem<GLuint>(textab[ID].number, textab[ID].context_size);
textab[ID].context =
cmn_resizemem<GLCONTEXT>(textab[ID].context, textab[ID].context_size);
textab[ID].drawable =
cmn_resizemem<GLDRAWABLE>(textab[ID].drawable, textab[ID].context_size);
textab[ID].use_bind_texture =
cmn_resizemem<char>(textab[ID].use_bind_texture, textab[ID].context_size);
#endif
if ( (textab[ID].number == NULL) ||
(textab[ID].context == NULL) ||
(textab[ID].drawable == NULL) ||
(textab[ID].use_bind_texture == NULL) )
{
/* erreur => libere tout */
free(textab[ID].number);
free(textab[ID].context);
free(textab[ID].drawable);
free(textab[ID].use_bind_texture);
textab[ID].context_size = 0;
return TEXTUREBOX_ERROR;
}
}
MyGenTextureEXT(ID);
SetTextureParam(ID);
#ifdef PRINT
printf("InstallTextureInContext::context ok\n");
#endif
return 0;
}
/*----------------------------------------------------------------------*/
static TextureID GetTexture(char *FileName, texDataStatus status)
{
TextureDataID i;
TextureID j;
int dummy;
/* essait de trouver la texture */
i = FindTextureData(FileName);
if (i == TEXTUREDATA_ERROR)
{
#ifdef PRINT
printf("GetTexture::la texture %s n'existe pas => chargement\n", FileName);
#endif
/* creation d'une texture */
i = FindFreeTextureData();
if (i == TEXTUREDATA_ERROR) return TEXTUREBOX_ERROR;
texdata[i].share_count = 0;
strcpy(texdata[i].imageFileName, FileName);
texdata[i].image = (GLubyte *)read_texture(FileName,
&texdata[i].imageWidth,
&texdata[i].imageHeight,
&dummy);
if (texdata[i].image == NULL) return TEXTUREBOX_ERROR;
texdata[i].status = status;
texdata[i].type = status2type[status];
}
j = FindFreeTexture();
if (j != TEXTUREBOX_ERROR)
{
#ifdef PRINT
printf("GetTexture::installation texture pour obj %d\n", j);
#endif
textab[j].context_count = 0;
textab[j].context_size = 0;
textab[j].number = NULL;
textab[j].drawable = NULL;
textab[j].context = NULL;
textab[j].use_bind_texture = NULL;
textab[j].data = i;
textab[j].status = TEX_ALLOCATED;
texdata[i].share_count++;
SetTextureDefaultParams(j);
#ifdef PRINT
printf("GetTexture::texture %s(%d) texture %d count=%d\n", texdata[i].imageFileName, i, j, texdata[i].share_count);
#endif
}
else
if (texdata[i].share_count != 0)
free(texdata[i].image);
return j;
}
/*----------------------------------------------------------------------*/
static TextureID GetTextureData(char *FileName, texDataStatus status, const GLint width, const GLint height, const void *data)
{
TextureDataID i;
TextureID j;
/* essait de trouver la texture */
i = FindTextureData(FileName);
if (i == TEXTUREDATA_ERROR)
{
#ifdef PRINT
printf("GetTextureData::la texture %s n'existe pas => chargement\n", FileName);
#endif
/* creation d'une texture */
i = FindFreeTextureData();
if (i == TEXTUREDATA_ERROR) return TEXTUREBOX_ERROR;
texdata[i].share_count = 0;
strcpy(texdata[i].imageFileName, FileName);
texdata[i].image = (GLubyte *)malloc(width*height*4*sizeof(GLubyte));
memcpy(texdata[i].image, data, (width*height*4));
texdata[i].imageWidth = width;
texdata[i].imageHeight = height;
if (texdata[i].image == NULL) return TEXTUREBOX_ERROR;
texdata[i].status = status;
texdata[i].type = status2type[status];
}
j = FindFreeTexture();
if (j != TEXTUREBOX_ERROR)
{
#ifdef PRINT
printf("GetTextureData::installation texture pour obj %d\n", j);
#endif
textab[j].context_count = 0;
textab[j].context_size = 0;
textab[j].number = NULL;
textab[j].drawable = NULL;
textab[j].context = NULL;
textab[j].use_bind_texture = NULL;
textab[j].data = i;
textab[j].status = TEX_ALLOCATED;
texdata[i].share_count++;
SetTextureDefaultParams(j);
#ifdef PRINT
printf("GetTextureData::texture %s(%d) texture %d count=%d\n", texdata[i].imageFileName, i, j, texdata[i].share_count);
#endif
}
else
if (texdata[i].share_count != 0)
free(texdata[i].image);
return j;
}
/*----------------------------------------------------------------------*/
/*
* Fonctions publiques
*/
/*----------------------------------------------------------------------*/
GLboolean IsTextureValid(TextureID ID)
{
if ((ID<0) | (ID>=textures_count))
return GL_FALSE;
if (textab)
return textab[ID].status == TEX_ALLOCATED;
else
return GL_TRUE;
}
/*----------------------------------------------------------------------*/
TextureID GetTexture1D(char *FileName)
{
#ifdef PRINT
printf("GetTexture1D::loading 1d %s \n", FileName);
#endif
return GetTexture(FileName, TEXDATA_1D);
}
/*----------------------------------------------------------------------*/
TextureID GetTexture2D(char *FileName)
{
#ifdef PRINT
printf("GetTexture2D::loading 2d %s \n", FileName);
#endif
return GetTexture(FileName, TEXDATA_2D);
}
/*----------------------------------------------------------------------*/
TextureID GetTexture2DMipMap(char *FileName)
{
#ifdef PRINT
printf("GetTexture2DMipMap::loading 2dmm %s \n", FileName);
#endif
return GetTexture(FileName, TEXDATA_2DMM);
}
/*----------------------------------------------------------------------*/
TextureID GetTextureData1D(char *FileName, const GLint width, const GLint height, const void *data)
{
#ifdef PRINT
printf("GetTextureData1D::loading 1d %s \n", FileName);
#endif
return GetTextureData(FileName, TEXDATA_1D, width, height, data);
}
/*----------------------------------------------------------------------*/
TextureID GetTextureData2D(char *FileName, const GLint width, const GLint height, const void *data)
{
#ifdef PRINT
printf("GetTextureData2D::loading 2d %s \n", FileName);
#endif
return GetTextureData(FileName, TEXDATA_2D, width, height, data);
}
/*----------------------------------------------------------------------*/
TextureID GetTextureData2DMipMap(char *FileName, const GLint width, const GLint height, const void *data)
{
#ifdef PRINT
printf("GetTextureData2DMipMap::loading 2dmm %s \n", FileName);
#endif
return GetTextureData(FileName, TEXDATA_2DMM, width, height, data);
}
/*----------------------------------------------------------------------*/
void SetCurrentTexture(TextureID ID)
{
int context;
if (!IsTextureValid(ID)) return;
context = FindTextureContext(ID);
/* la texture n'existe pas dans ce contexte */
if (context == TEXTUREBOX_ERROR)
{
#ifdef PRINT
printf("SetCurrentTexture::installation texture %d dans context\n", ID);
#endif
/* si on a une erreur pendant l'installation dans le context
* alors on installe la texture sans bind */
if (InstallTextureInContext(ID) == TEXTUREBOX_ERROR)
{
LoadTexture(ID);
SetTextureParam(ID);
}
}
/*oui, alors on bind directement */
else
{
#ifdef PRINT
printf("SetCurrentTexture: utilisation du bind %d\n", ID);
#endif
MyBindTextureEXT(ID, context);
SetTextureParam(ID);
}
current_texture = ID;
current_texture_data = textab[ID].data;
}
/*----------------------------------------------------------------------*/
void FreeTexture(TextureID ID)
{
TextureDataID data;
bool notResource = false; // if there old-style texture deletion
GLCONTEXT cur_context;
GLDRAWABLE cur_drawable;
int i;
if (!IsTextureValid(ID)) return;
data = textab[ID].data;
texdata[data].share_count--;
if (texdata[data].share_count == 0)
{
// liberation des datas de la textures
free(texdata[data].image);
// liberation de la texture dans tous les contextes
cur_drawable = GET_GLDEV_CONTEXT();
for (i = 0; i < textab[ID].context_count; ++i)
{
cur_context = 0;
bool isResource = false;
if (textab[ID].use_bind_texture[i])
{
if( !OpenGl_ResourceCleaner::GetInstance()->AddResource(textab[ID].context[i],
new OpenGl_ResourceTexture(textab[ID].number[i])) )
{
GL_MAKE_CURRENT((openglDisplay.IsNull() ? (Display* )NULL : (Display* )openglDisplay->GetDisplay()),
textab[ID].drawable[i],
textab[ID].context[i]);
// This check has been added to avoid exception,
// which is raised when trying to delete textures when no rendering context is available
cur_context = GET_GL_CONTEXT();
if (cur_context)
glDeleteTextures (1, &textab[ID].number[i]);
notResource = true;
}
else
{
isResource = true;
}
}
if( !isResource && cur_context )
glFinish();
}
if( notResource )
GL_MAKE_CURRENT((openglDisplay.IsNull() ? (Display* )NULL : (Display* )openglDisplay->GetDisplay()),
cur_drawable, cur_context);
texdata[data].status = TEXDATA_NONE;
if (data + 1 == textures_data_count)
{
--textures_data_count;
}
free(textab[ID].context);
free(textab[ID].drawable);
free(textab[ID].use_bind_texture);
free(textab[ID].number);
}
textab[ID].status = TEX_NONE;
if (ID + 1 == textures_count)
{
--textures_count;
}
current_texture_data = TEXTUREDATA_ERROR;
}
/*----------------------------------------------------------------------*/
void EnableTexture(void)
{
if (!IsTextureValid(current_texture)) return;
switch (texdata[current_texture_data].status)
{
case TEXDATA_1D:
if (textab[current_texture].Gen != GL_NONE)
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_1D);
break;
case TEXDATA_2D:
case TEXDATA_2DMM:
if (textab[current_texture].Gen != GL_NONE)
{
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
glEnable(GL_TEXTURE_2D);
break;
default:
break;
}
}
/*----------------------------------------------------------------------*/
void DisableTexture(void)
{
if ( !IsTextureEnabled() )
return;
if ( !IsTextureValid( current_texture ) )
return;
switch (texdata[current_texture_data].status)
{
case TEXDATA_1D:
if (textab[current_texture].Gen != GL_NONE)
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_1D);
break;
case TEXDATA_2D:
case TEXDATA_2DMM:
if (textab[current_texture].Gen != GL_NONE)
{
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
}
glDisable(GL_TEXTURE_2D);
break;
default:
break;
}
}
/*----------------------------------------------------------------------*/
GLboolean IsTextureEnabled(void)
{
GLboolean isEnabled1D= GL_FALSE, isEnabled2D= GL_FALSE;
glGetBooleanv( GL_TEXTURE_1D, &isEnabled1D );
glGetBooleanv( GL_TEXTURE_2D, &isEnabled2D );
return isEnabled1D || isEnabled2D;
}
/*----------------------------------------------------------------------*/
void SetTextureModulate(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Light = GL_MODULATE;
}
/*----------------------------------------------------------------------*/
void SetTextureDecal(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Light = GL_DECAL;
}
/*----------------------------------------------------------------------*/
void SetTextureClamp(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Wrap = GL_CLAMP;
}
/*----------------------------------------------------------------------*/
void SetTextureRepeat(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Wrap = GL_REPEAT;
}
/*----------------------------------------------------------------------*/
/* gestion de la facon d'appliquer la texture */
void SetModeObject(TextureID ID, const GLfloat sparams[4], const GLfloat tparams[4])
{
if (!IsTextureValid(ID)) return;
textab[ID].Gen = GL_OBJECT_LINEAR;
if (sparams != NULL) memcpy(textab[ID].Plane1, sparams, sizeof(sgenparams));
else memcpy(textab[ID].Plane1, sgenparams, sizeof(sgenparams));
if (texdata[textab[ID].data].status != TEXDATA_1D) {
if (tparams != NULL) memcpy(textab[ID].Plane2, tparams, sizeof(tgenparams));
else memcpy(textab[ID].Plane2, tgenparams, sizeof(tgenparams));
}
}
/*----------------------------------------------------------------------*/
void SetModeSphere(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Gen = GL_SPHERE_MAP;
}
/*----------------------------------------------------------------------*/
void SetModeEye(TextureID ID, const GLfloat sparams[4], const GLfloat tparams[4])
{
if (!IsTextureValid(ID)) return;
textab[ID].Gen = GL_EYE_LINEAR;
if (sparams != NULL) memcpy(textab[ID].Plane1, sparams, sizeof(sgenparams));
else memcpy(textab[ID].Plane1, sgenparams, sizeof(sgenparams));
if (texdata[textab[ID].data].status != TEXDATA_1D) {
if (tparams != NULL) memcpy(textab[ID].Plane2, tparams, sizeof(tgenparams));
else memcpy(textab[ID].Plane2, tgenparams, sizeof(tgenparams));
}
}
/*----------------------------------------------------------------------*/
void SetModeManual(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Gen = GL_NONE;
}
/*----------------------------------------------------------------------*/
void SetRenderNearest(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Render = GL_NEAREST;
}
/*----------------------------------------------------------------------*/
void SetRenderLinear(TextureID ID)
{
if (!IsTextureValid(ID)) return;
textab[ID].Render = GL_LINEAR;
}
/*----------------------------------------------------------------------*/
void SetTexturePosition(TextureID ID,
GLfloat scalex, GLfloat scaley,
GLfloat transx, GLfloat transy,
GLfloat angle)
{
textab[ID].scalex = scalex;
textab[ID].scaley = scaley;
textab[ID].transx = transx;
textab[ID].transy = transy;
textab[ID].angle = angle;
}
/*----------------------------------------------------------------------*/
void SetTextureDefaultParams(TextureID ID)
{
if (!IsTextureValid(ID)) return;
#ifdef PRINT
printf("SetTextureDefaultParams::set parm par defaut textures\n");
#endif
textab[ID].scalex = 1.0;
textab[ID].scaley = 1.0;
textab[ID].transx = 0.0;
textab[ID].transy = 0.0;
textab[ID].angle = 0.0;
textab[ID].Gen = GL_OBJECT_LINEAR;
textab[ID].Light = texdata[textab[ID].data].status == TEXDATA_1D ? GL_DECAL : GL_MODULATE;
textab[ID].Wrap = texdata[textab[ID].data].status == TEXDATA_1D ? GL_CLAMP : GL_REPEAT;
memcpy(textab[ID].Plane1, sgenparams, sizeof(sgenparams));
memcpy(textab[ID].Plane2, tgenparams, sizeof(tgenparams));
textab[ID].Render = texdata[textab[ID].data].status == TEXDATA_1D ? GL_NEAREST : GL_LINEAR;
}
/*----------------------------------------------------------------------*/
/* Transfere de donnee des donnees internes a la structure TransferData */
void TransferTexture_To_Data(TextureID ID, TextureData *TransfDt)
{
/* affectations */
strcpy(TransfDt->path, texdata[textab[ID].data].imageFileName);
TransfDt->gen = textab[ID].Gen;
TransfDt->wrap = textab[ID].Wrap;
TransfDt->render = textab[ID].Light;
TransfDt->scalex = textab[ID].scalex;
TransfDt->scaley = textab[ID].scaley;
TransfDt->transx = textab[ID].transx;
TransfDt->transy = textab[ID].transy;
TransfDt->angle = textab[ID].angle;
memcpy(TransfDt->plane1, textab[ID].Plane1, sizeof(SizeType));
memcpy(TransfDt->plane2, textab[ID].Plane2, sizeof(SizeType));
}
/*----------------------------------------------------------------------*/
/* Transfere de donnee de la structure TransferData aux donnees internes */
void TransferData_To_Texture(TextureData *TransfDt, TextureID *newID)
{
TextureID ID;
/* Affectations */
FreeTexture(*newID);
ID = GetTexture2DMipMap(TransfDt->path);
if(IsTextureValid(ID))
{
/* Affectation de l id courant */
*newID = ID;
/* Donnees concernant les caracteristiques de la texture */
strcpy(texdata[textab[ID].data].imageFileName, TransfDt->path);
textab[ID].Gen = TransfDt->gen;
textab[ID].Wrap = TransfDt->wrap;
textab[ID].Light = TransfDt->render;
textab[ID].scalex = TransfDt->scalex;
textab[ID].scaley = TransfDt->scaley;
textab[ID].transx = TransfDt->transx;
textab[ID].transy = TransfDt->transy;
textab[ID].angle = TransfDt->angle;
memcpy(textab[ID].Plane1, TransfDt->plane1, sizeof(SizeType));
memcpy(textab[ID].Plane2, TransfDt->plane2, sizeof(SizeType));
}
}