texobj.c

来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,053 行 · 第 1/3 页

C
1,053
字号
/** * \file texobj.c * Texture object management. *//* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include "glheader.h"#include "colortab.h"#include "context.h"#include "enums.h"#include "fbobject.h"#include "hash.h"#include "imports.h"#include "macros.h"#include "teximage.h"#include "texstate.h"#include "texobj.h"#include "mtypes.h"#ifdef __VMS#define _mesa_sprintf sprintf#endif/**********************************************************************//** \name Internal functions *//*@{*//** * Return the gl_texture_object for a given ID. */struct gl_texture_object *_mesa_lookup_texture(GLcontext *ctx, GLuint id){   return (struct gl_texture_object *)      _mesa_HashLookup(ctx->Shared->TexObjects, id);}/** * Allocate and initialize a new texture object.  But don't put it into the * texture object hash table. * * Called via ctx->Driver.NewTextureObject, unless overridden by a device * driver. *  * \param shared the shared GL state structure to contain the texture object * \param name integer name for the texture object * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV.  zero is ok for the sake * of GenTextures() * * \return pointer to new texture object. */struct gl_texture_object *_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target ){   struct gl_texture_object *obj;   (void) ctx;   obj = MALLOC_STRUCT(gl_texture_object);   _mesa_initialize_texture_object(obj, name, target);   return obj;}/** * Initialize a new texture object to default values. * \param obj  the texture object * \param name  the texture name * \param target  the texture target */void_mesa_initialize_texture_object( struct gl_texture_object *obj,                                 GLuint name, GLenum target ){   ASSERT(target == 0 ||          target == GL_TEXTURE_1D ||          target == GL_TEXTURE_2D ||          target == GL_TEXTURE_3D ||          target == GL_TEXTURE_CUBE_MAP_ARB ||          target == GL_TEXTURE_RECTANGLE_NV);   _mesa_bzero(obj, sizeof(*obj));   /* init the non-zero fields */   _glthread_INIT_MUTEX(obj->Mutex);   obj->RefCount = 1;   obj->Name = name;   obj->Target = target;   obj->Priority = 1.0F;   if (target == GL_TEXTURE_RECTANGLE_NV) {      obj->WrapS = GL_CLAMP_TO_EDGE;      obj->WrapT = GL_CLAMP_TO_EDGE;      obj->WrapR = GL_CLAMP_TO_EDGE;      obj->MinFilter = GL_LINEAR;   }   else {      obj->WrapS = GL_REPEAT;      obj->WrapT = GL_REPEAT;      obj->WrapR = GL_REPEAT;      obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;   }   obj->MagFilter = GL_LINEAR;   obj->MinLod = -1000.0;   obj->MaxLod = 1000.0;   obj->LodBias = 0.0;   obj->BaseLevel = 0;   obj->MaxLevel = 1000;   obj->MaxAnisotropy = 1.0;   obj->CompareFlag = GL_FALSE;                      /* SGIX_shadow */   obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX;  /* SGIX_shadow */   obj->CompareMode = GL_NONE;         /* ARB_shadow */   obj->CompareFunc = GL_LEQUAL;       /* ARB_shadow */   obj->DepthMode = GL_LUMINANCE;      /* ARB_depth_texture */   obj->ShadowAmbient = 0.0F;          /* ARB/SGIX_shadow_ambient */   _mesa_init_colortable(&obj->Palette);}/** * Deallocate a texture object struct.  It should have already been * removed from the texture object pool. * * \param shared the shared GL state to which the object belongs. * \param texOjb the texture object to delete. */void_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ){   GLuint i, face;   (void) ctx;   _mesa_free_colortable_data(&texObj->Palette);   /* free the texture images */   for (face = 0; face < 6; face++) {      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {	 if (texObj->Image[face][i]) {	    _mesa_delete_texture_image( ctx, texObj->Image[face][i] );	 }      }   }   /* destroy the mutex -- it may have allocated memory (eg on bsd) */   _glthread_DESTROY_MUTEX(texObj->Mutex);   /* free this object */   _mesa_free(texObj);}/** * Copy texture object state from one texture object to another. * Use for glPush/PopAttrib. * * \param dest destination texture object. * \param src source texture object. */void_mesa_copy_texture_object( struct gl_texture_object *dest,                           const struct gl_texture_object *src ){   dest->Name = src->Name;   dest->Priority = src->Priority;   dest->BorderColor[0] = src->BorderColor[0];   dest->BorderColor[1] = src->BorderColor[1];   dest->BorderColor[2] = src->BorderColor[2];   dest->BorderColor[3] = src->BorderColor[3];   dest->WrapS = src->WrapS;   dest->WrapT = src->WrapT;   dest->WrapR = src->WrapR;   dest->MinFilter = src->MinFilter;   dest->MagFilter = src->MagFilter;   dest->MinLod = src->MinLod;   dest->MaxLod = src->MaxLod;   dest->LodBias = src->LodBias;   dest->BaseLevel = src->BaseLevel;   dest->MaxLevel = src->MaxLevel;   dest->MaxAnisotropy = src->MaxAnisotropy;   dest->CompareFlag = src->CompareFlag;   dest->CompareOperator = src->CompareOperator;   dest->ShadowAmbient = src->ShadowAmbient;   dest->CompareMode = src->CompareMode;   dest->CompareFunc = src->CompareFunc;   dest->DepthMode = src->DepthMode;   dest->_MaxLevel = src->_MaxLevel;   dest->_MaxLambda = src->_MaxLambda;   dest->GenerateMipmap = src->GenerateMipmap;   dest->Palette = src->Palette;   dest->Complete = src->Complete;}/** * Report why a texture object is incomplete.   * * \param t texture object. * \param why string describing why it's incomplete. * * \note For debug purposes only. */#if 0static voidincomplete(const struct gl_texture_object *t, const char *why){   _mesa_printf("Texture Obj %d incomplete because: %s\n", t->Name, why);}#else#define incomplete(t, why)#endif/** * Examine a texture object to determine if it is complete. * * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE * accordingly. * * \param ctx GL context. * \param t texture object. * * According to the texture target, verifies that each of the mipmaps is * present and has the expected size. */void_mesa_test_texobj_completeness( const GLcontext *ctx,                                struct gl_texture_object *t ){   const GLint baseLevel = t->BaseLevel;   GLint maxLog2 = 0, maxLevels = 0;   t->Complete = GL_TRUE;  /* be optimistic */   /* Always need the base level image */   if (!t->Image[0][baseLevel]) {      char s[100];      _mesa_sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",              (void *) t, t->Name, baseLevel);      incomplete(t, s);      t->Complete = GL_FALSE;      return;   }   /* Check width/height/depth for zero */   if (t->Image[0][baseLevel]->Width == 0 ||       t->Image[0][baseLevel]->Height == 0 ||       t->Image[0][baseLevel]->Depth == 0) {      incomplete(t, "texture width = 0");      t->Complete = GL_FALSE;      return;   }   /* Compute _MaxLevel */   if (t->Target == GL_TEXTURE_1D) {      maxLog2 = t->Image[0][baseLevel]->WidthLog2;      maxLevels = ctx->Const.MaxTextureLevels;   }   else if (t->Target == GL_TEXTURE_2D) {      maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,                     t->Image[0][baseLevel]->HeightLog2);      maxLevels = ctx->Const.MaxTextureLevels;   }   else if (t->Target == GL_TEXTURE_3D) {      GLint max = MAX2(t->Image[0][baseLevel]->WidthLog2,                       t->Image[0][baseLevel]->HeightLog2);      maxLog2 = MAX2(max, (GLint)(t->Image[0][baseLevel]->DepthLog2));      maxLevels = ctx->Const.Max3DTextureLevels;   }   else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {      maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,                     t->Image[0][baseLevel]->HeightLog2);      maxLevels = ctx->Const.MaxCubeTextureLevels;   }   else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {      maxLog2 = 0;  /* not applicable */      maxLevels = 1;  /* no mipmapping */   }   else {      _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");      return;   }   ASSERT(maxLevels > 0);   t->_MaxLevel = baseLevel + maxLog2;   t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);   t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1);   /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */   t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel);   if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {      /* make sure that all six cube map level 0 images are the same size */      const GLuint w = t->Image[0][baseLevel]->Width2;      const GLuint h = t->Image[0][baseLevel]->Height2;      GLuint face;      for (face = 1; face < 6; face++) {	 if (t->Image[face][baseLevel] == NULL ||	     t->Image[face][baseLevel]->Width2 != w ||	     t->Image[face][baseLevel]->Height2 != h) {	    t->Complete = GL_FALSE;	    incomplete(t, "Non-quare cubemap image");	    return;	 }      }   }   /* extra checking for mipmaps */   if (t->MinFilter != GL_NEAREST && t->MinFilter != GL_LINEAR) {      /*       * Mipmapping: determine if we have a complete set of mipmaps       */      GLint i;      GLint minLevel = baseLevel;      GLint maxLevel = t->_MaxLevel;      if (minLevel > maxLevel) {         t->Complete = GL_FALSE;         incomplete(t, "minLevel > maxLevel");         return;      }      /* Test dimension-independent attributes */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?